Skip to content

Commit

Permalink
Merge branch 'main' into feat/operator-java-opts
Browse files Browse the repository at this point in the history
  • Loading branch information
EricWittmann authored Feb 12, 2025
2 parents e2ec14a + 81dafb3 commit a9c0f9c
Show file tree
Hide file tree
Showing 24 changed files with 4,559 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,35 @@ public class EnvironmentVariables {
public static final String KAFKASQL_SSL_TRUSTSTORE_TYPE = KAFKA_PREFIX + "SSL_TRUSTSTORE_TYPE";
public static final String KAFKASQL_SSL_TRUSTSTORE_LOCATION = KAFKA_PREFIX + "SSL_TRUSTSTORE_LOCATION";
public static final String KAFKASQL_SSL_TRUSTSTORE_PASSWORD = KAFKA_PREFIX + "SSL_TRUSTSTORE_PASSWORD";

// Auth related environment variables
public static final String APICURIO_REGISTRY_AUTH_ENABLED = "QUARKUS_OIDC_TENANT_ENABLED";
public static final String APICURIO_REGISTRY_APP_CLIENT_ID = "QUARKUS_OIDC_CLIENT_ID";
public static final String APICURIO_REGISTRY_UI_CLIENT_ID = "APICURIO_UI_AUTH_OIDC_CLIENT_ID";
public static final String APICURIO_UI_AUTH_OIDC_REDIRECT_URI = "APICURIO_UI_AUTH_OIDC_REDIRECT_URI";
public static final String APICURIO_UI_AUTH_OIDC_LOGOUT_URL = "APICURIO_UI_AUTH_OIDC_LOGOUT_URL";
public static final String APICURIO_REGISTRY_AUTH_SERVER_URL = "QUARKUS_OIDC_AUTH_SERVER_URL";
public static final String OIDC_TLS_VERIFICATION = "QUARKUS_OIDC_TLS_VERIFICATION";
public static final String OIDC_TLS_TRUSTSTORE_LOCATION = "QUARKUS_OIDC_TLS_TRUST_STORE_FILE";
public static final String OIDC_TLS_TRUSTSTORE_PASSWORD = "QUARKUS_OIDC_TLS_TRUST_STORE_PASSWORD";

public static final String APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_ENABLED = "APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_ENABLED";
public static final String APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_CACHE_EXPIRATION = "APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_CACHE_EXPIRATION";
public static final String APICURIO_AUTH_ANONYMOUS_READ_ACCESS_ENABLED = "APICURIO_AUTH_ANONYMOUS_READ_ACCESS_ENABLED";

// Authz related environment variables
public static final String APICURIO_AUTH_ROLE_BASED_AUTHORIZATION = "APICURIO_AUTH_ROLE_BASED_AUTHORIZATION";
public static final String APICURIO_AUTH_AUTHENTICATED_READ_ACCESS_ENABLED = "APICURIO_AUTH_AUTHENTICATED_READ_ACCESS_ENABLED";
public static final String APICURIO_AUTH_OWNER_ONLY_AUTHORIZATION_LIMIT_GROUP_ACCESS = "APICURIO_AUTH_OWNER_ONLY_AUTHORIZATION_LIMIT_GROUP_ACCESS";
public static final String APICURIO_AUTH_OWNER_ONLY_AUTHORIZATION = "APICURIO_AUTH_OWNER_ONLY_AUTHORIZATION";
public static final String APICURIO_AUTH_ROLE_SOURCE = "APICURIO_AUTH_ROLE_SOURCE";
public static final String APICURIO_AUTH_ROLES_ADMIN = "APICURIO_AUTH_ROLES_ADMIN";
public static final String APICURIO_AUTH_ROLES_DEVELOPER = "APICURIO_AUTH_ROLES_DEVELOPER";
public static final String APICURIO_AUTH_ROLES_READONLY = "APICURIO_AUTH_ROLES_READONLY";
public static final String APICURIO_AUTH_ADMIN_OVERRIDE_ENABLED = "APICURIO_AUTH_ADMIN_OVERRIDE_ENABLED";
public static final String APICURIO_AUTH_ADMIN_OVERRIDE_ROLE = "APICURIO_AUTH_ADMIN_OVERRIDE_ROLE";
public static final String APICURIO_AUTH_ADMIN_OVERRIDE_FROM = "APICURIO_AUTH_ADMIN_OVERRIDE_FROM";
public static final String APICURIO_AUTH_ADMIN_OVERRIDE_TYPE = "APICURIO_AUTH_ADMIN_OVERRIDE_TYPE";
public static final String APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM = "APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM";
public static final String APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM_VALUE = "APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM_VALUE";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.apicurio.registry.operator.feat.security;

import io.apicurio.registry.operator.EnvironmentVariables;
import io.apicurio.registry.operator.api.v1.spec.auth.AdminOverrideSpec;
import io.fabric8.kubernetes.api.model.EnvVar;

import java.util.Map;

import static io.apicurio.registry.operator.utils.Utils.createEnvVar;
import static io.apicurio.registry.operator.utils.Utils.putIfNotBlank;

/**
* Helper class used to handle Admin Overide related configuration.
*/
public class AdminOverride {

/**
* Configures admin-override-related environment variables for the Apicurio Registry.
*
* @param env The map of environment variables to be configured.
* @param adminOverrideSpec The adminOverride specification containing required admin override settings.
* If null, no changes will be made to envVars.
*/
public static void configureAdminOverride(AdminOverrideSpec adminOverrideSpec, Map<String, EnvVar> env) {
if (adminOverrideSpec == null) {
return;
}

if (adminOverrideSpec.getEnabled() != null && adminOverrideSpec.getEnabled()) {
env.put(EnvironmentVariables.APICURIO_AUTH_ADMIN_OVERRIDE_ENABLED,
createEnvVar(EnvironmentVariables.APICURIO_AUTH_ADMIN_OVERRIDE_ENABLED,
adminOverrideSpec.getEnabled().toString()));

putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ADMIN_OVERRIDE_ROLE,
adminOverrideSpec.getRole());

putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ADMIN_OVERRIDE_FROM,
adminOverrideSpec.getFrom());
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ADMIN_OVERRIDE_TYPE,
adminOverrideSpec.getType());
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM,
adminOverrideSpec.getClaimName());
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM_VALUE,
adminOverrideSpec.getClaimValue());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.apicurio.registry.operator.feat.security;

import io.apicurio.registry.operator.EnvironmentVariables;
import io.apicurio.registry.operator.api.v1.spec.auth.AuthSpec;
import io.fabric8.kubernetes.api.model.EnvVar;
import io.fabric8.kubernetes.api.model.apps.Deployment;

import java.util.Map;
import java.util.Optional;

import static io.apicurio.registry.operator.utils.Utils.createEnvVar;
import static io.apicurio.registry.operator.utils.Utils.putIfNotBlank;

/**
* Helper class used to handle AUTH related configuration.
*/
public class Auth {

/**
* Configures authentication-related environment variables for the Apicurio Registry.
*
* @param env The map of environment variables to be configured.
* @param deployment The application deployment to configure TLS.
* @param authSpec The authentication specification containing required auth settings. If null, no changes
* will be made to envVars.
*/
public static void configureAuth(AuthSpec authSpec, Deployment deployment, Map<String, EnvVar> env) {
if (authSpec == null) {
return;
}

env.put(EnvironmentVariables.APICURIO_REGISTRY_AUTH_ENABLED,
createEnvVar(EnvironmentVariables.APICURIO_REGISTRY_AUTH_ENABLED,
Optional.ofNullable(authSpec.getEnabled()).orElse(Boolean.FALSE).toString()));

putIfNotBlank(env, EnvironmentVariables.APICURIO_REGISTRY_APP_CLIENT_ID, authSpec.getAppClientId());
putIfNotBlank(env, EnvironmentVariables.APICURIO_REGISTRY_UI_CLIENT_ID, authSpec.getUiClientId());
putIfNotBlank(env, EnvironmentVariables.APICURIO_UI_AUTH_OIDC_REDIRECT_URI,
authSpec.getRedirectURI());
putIfNotBlank(env, EnvironmentVariables.APICURIO_UI_AUTH_OIDC_LOGOUT_URL, authSpec.getLogoutURL());
putIfNotBlank(env, EnvironmentVariables.APICURIO_REGISTRY_AUTH_SERVER_URL,
authSpec.getAuthServerUrl());

if (authSpec.getAnonymousReads() != null && authSpec.getAnonymousReads()) {
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ANONYMOUS_READ_ACCESS_ENABLED,
authSpec.getAnonymousReads().toString());
}

if (authSpec.getBasicAuth() != null && authSpec.getBasicAuth().getEnabled()) {
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_ENABLED,
authSpec.getBasicAuth().getEnabled().toString());
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_CACHE_EXPIRATION,
authSpec.getBasicAuth().getCacheExpiration());
}

AuthTLS.configureAuthTLS(authSpec, deployment, env);
Authz.configureAuthz(authSpec.getAuthz(), env);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.apicurio.registry.operator.feat.security;

import io.apicurio.registry.operator.EnvironmentVariables;
import io.apicurio.registry.operator.api.v1.spec.auth.AuthSpec;
import io.apicurio.registry.operator.api.v1.spec.auth.AuthTLSSpec;
import io.apicurio.registry.operator.utils.SecretKeyRefTool;
import io.fabric8.kubernetes.api.model.EnvVar;
import io.fabric8.kubernetes.api.model.apps.Deployment;

import java.util.Map;
import java.util.Optional;

import static io.apicurio.registry.operator.EnvironmentVariables.*;
import static io.apicurio.registry.operator.api.v1.ContainerNames.REGISTRY_APP_CONTAINER_NAME;
import static io.apicurio.registry.operator.resource.app.AppDeploymentResource.addEnvVar;
import static io.apicurio.registry.operator.utils.Utils.putIfNotBlank;
import static java.util.Optional.ofNullable;

public class AuthTLS {

/**
* Configure TLS for OIDC authentication
*/
public static void configureAuthTLS(AuthSpec authSpec, Deployment deployment, Map<String, EnvVar> env) {

putIfNotBlank(env, EnvironmentVariables.OIDC_TLS_VERIFICATION,
authSpec.getTls().getTlsVerificationType());

// spotless:off
var truststore = new SecretKeyRefTool(getAuthTLSSpec(authSpec)
.map(AuthTLSSpec::getTruststoreSecretRef)
.orElse(null), "ca.p12");

var truststorePassword = new SecretKeyRefTool(getAuthTLSSpec(authSpec)
.map(AuthTLSSpec::getTruststorePasswordSecretRef)
.orElse(null), "ca.password");
// spotless:on
if (truststore.isValid() && truststorePassword.isValid()) {
truststore.applySecretVolume(deployment, REGISTRY_APP_CONTAINER_NAME);
addEnvVar(env, OIDC_TLS_TRUSTSTORE_LOCATION, truststore.getSecretVolumeKeyPath());
truststorePassword.applySecretEnvVar(env, OIDC_TLS_TRUSTSTORE_PASSWORD);
}
}

private static Optional<AuthTLSSpec> getAuthTLSSpec(AuthSpec primary) {
// spotless:off
return ofNullable(primary)
.map(AuthSpec::getTls);
// spotless:on
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.apicurio.registry.operator.feat.security;

import io.apicurio.registry.operator.EnvironmentVariables;
import io.apicurio.registry.operator.api.v1.spec.auth.AuthzSpec;
import io.fabric8.kubernetes.api.model.EnvVar;

import java.util.Map;

import static io.apicurio.registry.operator.utils.Utils.createEnvVar;
import static io.apicurio.registry.operator.utils.Utils.putIfNotBlank;

/**
* Helper class used to handle AUTHZ related configuration.
*/
public class Authz {

/**
* Configures authorization-related environment variables for the Apicurio Registry.
*
* @param env The map of environment variables to be configured.
* @param authzSpec The auhtorization specification containing required authz settings. If null, no
* changes will be made to envVars.
*/
public static void configureAuthz(AuthzSpec authzSpec, Map<String, EnvVar> env) {
if (authzSpec == null) {
return;
}

if (authzSpec.getEnabled()) {
env.put(EnvironmentVariables.APICURIO_AUTH_ROLE_BASED_AUTHORIZATION,
createEnvVar(EnvironmentVariables.APICURIO_AUTH_ROLE_BASED_AUTHORIZATION,
authzSpec.getEnabled().toString()));

if (authzSpec.getGroupAccess() != null && authzSpec.getGroupAccess()) {
putIfNotBlank(env,
EnvironmentVariables.APICURIO_AUTH_OWNER_ONLY_AUTHORIZATION_LIMIT_GROUP_ACCESS,
authzSpec.getGroupAccess().toString());
}

if (authzSpec.getOwnerOnly() != null && authzSpec.getOwnerOnly()) {
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_OWNER_ONLY_AUTHORIZATION,
authzSpec.getOwnerOnly().toString());
}

if (authzSpec.getReadAccess() != null && authzSpec.getReadAccess()) {
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_AUTHENTICATED_READ_ACCESS_ENABLED,
authzSpec.getReadAccess().toString());
}

putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ROLE_SOURCE, authzSpec.getRoleSource());
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ROLES_ADMIN, authzSpec.getAdminRole());
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ROLES_DEVELOPER,
authzSpec.getDeveloperRole());
putIfNotBlank(env, EnvironmentVariables.APICURIO_AUTH_ROLES_READONLY,
authzSpec.getReadOnlyRole());

AdminOverride.configureAdminOverride(authzSpec.getAdminOverride(), env);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import io.apicurio.registry.operator.api.v1.spec.AppFeaturesSpec;
import io.apicurio.registry.operator.api.v1.spec.AppSpec;
import io.apicurio.registry.operator.api.v1.spec.StorageSpec;
import io.apicurio.registry.operator.api.v1.spec.auth.AuthSpec;
import io.apicurio.registry.operator.feat.Cors;
import io.apicurio.registry.operator.feat.KafkaSql;
import io.apicurio.registry.operator.feat.PostgresSql;
import io.apicurio.registry.operator.utils.JavaOptsAppend;
import io.apicurio.registry.operator.feat.security.Auth;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.EnvVar;
import io.fabric8.kubernetes.api.model.EnvVarBuilder;
Expand Down Expand Up @@ -69,12 +71,26 @@ protected Deployment desired(ApicurioRegistry3 primary, Context<ApicurioRegistry
.map(AppSpec::getFeatures)
.map(AppFeaturesSpec::getAllowDeletes)
.orElse(Boolean.FALSE);

if (allowDeletes) {
addEnvVar(envVars, new EnvVarBuilder().withName(EnvironmentVariables.APICURIO_REST_DELETION_ARTIFACT_VERSION_ENABLED).withValue("true").build());
addEnvVar(envVars, new EnvVarBuilder().withName(EnvironmentVariables.APICURIO_REST_DELETION_ARTIFACT_ENABLED).withValue("true").build());
addEnvVar(envVars, new EnvVarBuilder().withName(EnvironmentVariables.APICURIO_REST_DELETION_GROUP_ENABLED).withValue("true").build());
}

boolean authEnabled = Optional.ofNullable(primary.getSpec())
.map(ApicurioRegistry3Spec::getApp)
.map(AppSpec::getAuth)
.map(AuthSpec::getEnabled)
.orElse(Boolean.FALSE);

//Configure auth when it's enabled
if (authEnabled) {
Auth.configureAuth(requireNonNull(ofNullable(primary.getSpec().getApp())
.map(AppSpec::getAuth)
.orElse(null)), deployment, envVars);
}

// Configure the CORS_ALLOWED_ORIGINS env var based on the ingress host
Cors.configureAllowedOrigins(primary, envVars);

Expand Down Expand Up @@ -154,4 +170,5 @@ public static Container getContainerFromPodTemplateSpec(PodTemplateSpec pts, Str
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package io.apicurio.registry.operator.utils;

import io.fabric8.kubernetes.api.model.EnvVar;
import io.fabric8.kubernetes.api.model.EnvVarBuilder;

import java.util.Map;

public class Utils {

private Utils() {
Expand All @@ -8,4 +13,28 @@ private Utils() {
public static boolean isBlank(String value) {
return value == null || value.isBlank();
}

/**
* Adds an environment variable to the map only if the value is not null or blank.
*
* @param envVars The environment variables map.
* @param name The name of the environment variable.
* @param value The value to be set (ignored if null or blank).
*/
public static void putIfNotBlank(Map<String, EnvVar> envVars, String name, String value) {
if (!Utils.isBlank(value)) {
envVars.put(name, createEnvVar(name, value));
}
}

/**
* Creates an environment variable using the given name and value.
*
* @param name The name of the environment variable.
* @param value The value of the environment variable.
* @return An {@link EnvVar} instance with the specified name and value.
*/
public static EnvVar createEnvVar(String name, String value) {
return new EnvVarBuilder().withName(name).withValue(value).build();
}
}
Loading

0 comments on commit a9c0f9c

Please sign in to comment.