Skip to content

Commit 2f29977

Browse files
committed
Implement tls support for the app
1 parent e8d71ac commit 2f29977

File tree

16 files changed

+454
-76
lines changed

16 files changed

+454
-76
lines changed

operator/controller/src/main/java/io/apicurio/registry/operator/Constants.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ public class Constants {
3636
.withInitialDelaySeconds(15).withTimeoutSeconds(5).withPeriodSeconds(10).withSuccessThreshold(1)
3737
.withFailureThreshold(3).build();
3838

39+
public static final Probe TLS_DEFAULT_READINESS_PROBE = new ProbeBuilder().withNewHttpGet()
40+
.withScheme("HTTPS").withPath("/health/ready").withNewPort().withValue(8443).endPort().endHttpGet()
41+
.withInitialDelaySeconds(15).withTimeoutSeconds(5).withPeriodSeconds(10).withSuccessThreshold(1)
42+
.withFailureThreshold(3).build();
43+
44+
public static final Probe TLS_DEFAULT_LIVENESS_PROBE = new ProbeBuilder().withNewHttpGet()
45+
.withScheme("HTTPS").withPath("/health/live").withNewPort().withValue(8443).endPort().endHttpGet()
46+
.withInitialDelaySeconds(15).withTimeoutSeconds(5).withPeriodSeconds(10).withSuccessThreshold(1)
47+
.withFailureThreshold(3).build();
48+
3949
public static final Map<String, String> BASIC_LABELS = Map.of(MANAGED_BY_LABEL, MANAGED_BY_VALUE,
4050
LABEL_SELECTOR_KEY, LABEL_SELECTOR_VALUE);
4151

operator/controller/src/main/java/io/apicurio/registry/operator/EnvironmentVariables.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ public class EnvironmentVariables {
66
public static final String QUARKUS_HTTP_ACCESS_LOG_ENABLED = "QUARKUS_HTTP_ACCESS_LOG_ENABLED";
77
public static final String QUARKUS_HTTP_CORS_ORIGINS = "QUARKUS_HTTP_CORS_ORIGINS";
88

9+
public static final String QUARKUS_HTTP_INSECURE_REQUESTS = "QUARKUS_HTTP_INSECURE_REQUESTS";
10+
public static final String QUARKUS_TLS_KEY_STORE_P12_PATH = "QUARKUS_TLS_KEY_STORE_P12_PATH";
11+
public static final String QUARKUS_TLS_KEY_STORE_P12_PASSWORD = "QUARKUS_TLS_KEY_STORE_P12_PASSWORD";
12+
public static final String QUARKUS_TLS_TRUST_STORE_P12_PATH = "QUARKUS_TLS_TRUST_STORE_P12_PATH";
13+
public static final String QUARKUS_TLS_TRUST_STORE_P12_PASSWORD = "QUARKUS_TLS_TRUST_STORE_P12_PASSWORD";
914
public static final String APICURIO_REST_DELETION_ARTIFACT_VERSION_ENABLED = "APICURIO_REST_DELETION_ARTIFACT-VERSION_ENABLED";
1015
public static final String APICURIO_REST_DELETION_ARTIFACT_ENABLED = "APICURIO_REST_DELETION_ARTIFACT_ENABLED";
1116
public static final String APICURIO_REST_DELETION_GROUP_ENABLED = "APICURIO_REST_DELETION_GROUP_ENABLED";
12-
1317
public static final String APICURIO_REST_MUTABILITY_ARTIFACT_VERSION_CONTENT_ENABLED = "APICURIO_REST_MUTABILITY_ARTIFACT-VERSION-CONTENT_ENABLED";
1418

1519
private static final String KAFKA_PREFIX = "APICURIO_KAFKA_COMMON_";
@@ -29,8 +33,6 @@ public class EnvironmentVariables {
2933
public static final String APICURIO_UI_AUTH_OIDC_LOGOUT_URL = "APICURIO_UI_AUTH_OIDC_LOGOUT_URL";
3034
public static final String APICURIO_REGISTRY_AUTH_SERVER_URL = "QUARKUS_OIDC_AUTH_SERVER_URL";
3135
public static final String OIDC_TLS_VERIFICATION = "QUARKUS_OIDC_TLS_VERIFICATION";
32-
public static final String OIDC_TLS_TRUSTSTORE_LOCATION = "QUARKUS_OIDC_TLS_TRUST_STORE_FILE";
33-
public static final String OIDC_TLS_TRUSTSTORE_PASSWORD = "QUARKUS_OIDC_TLS_TRUST_STORE_PASSWORD";
3436

3537
public static final String APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_ENABLED = "APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_ENABLED";
3638
public static final String APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_CACHE_EXPIRATION = "APICURIO_AUTHN_BASIC_CLIENT_CREDENTIALS_CACHE_EXPIRATION";
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package io.apicurio.registry.operator.feat;
2+
3+
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3;
4+
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3Spec;
5+
import io.apicurio.registry.operator.api.v1.spec.AppSpec;
6+
import io.apicurio.registry.operator.api.v1.spec.TLSSpec;
7+
import io.apicurio.registry.operator.utils.SecretKeyRefTool;
8+
import io.fabric8.kubernetes.api.model.EnvVar;
9+
import io.fabric8.kubernetes.api.model.apps.Deployment;
10+
11+
import java.util.Map;
12+
import java.util.Optional;
13+
14+
import static io.apicurio.registry.operator.EnvironmentVariables.*;
15+
import static io.apicurio.registry.operator.resource.app.AppDeploymentResource.addEnvVar;
16+
import static java.util.Optional.ofNullable;
17+
18+
public class TLS {
19+
20+
public static void configureTLS(ApicurioRegistry3 primary, Deployment deployment,
21+
String containerName, Map<String, EnvVar> env) {
22+
23+
addEnvVar(env, QUARKUS_HTTP_INSECURE_REQUESTS, Optional.ofNullable(primary.getSpec())
24+
.map(ApicurioRegistry3Spec::getApp)
25+
.map(AppSpec::getTls)
26+
.map(TLSSpec::getInsecureRequests)
27+
.orElse("enabled"));
28+
29+
var keystore = new SecretKeyRefTool(getTlsSpec(primary)
30+
.map(TLSSpec::getKeystoreSecretRef)
31+
.orElse(null), "user.p12");
32+
33+
var keystorePassword = new SecretKeyRefTool(getTlsSpec(primary)
34+
.map(TLSSpec::getKeystorePasswordSecretRef)
35+
.orElse(null), "user.password");
36+
37+
var truststore = new SecretKeyRefTool(getTlsSpec(primary)
38+
.map(TLSSpec::getTruststoreSecretRef)
39+
.orElse(null), "ca.p12");
40+
41+
var truststorePassword = new SecretKeyRefTool(getTlsSpec(primary)
42+
.map(TLSSpec::getTruststorePasswordSecretRef)
43+
.orElse(null), "ca.password");
44+
45+
if (truststore.isValid() && truststorePassword.isValid()) {
46+
// ===== Truststore
47+
truststore.applySecretVolume(deployment, containerName);
48+
addEnvVar(env, QUARKUS_TLS_TRUST_STORE_P12_PATH, truststore.getSecretVolumeKeyPath());
49+
truststorePassword.applySecretEnvVar(env, QUARKUS_TLS_TRUST_STORE_P12_PASSWORD);
50+
}
51+
52+
if (keystore.isValid()
53+
&& keystorePassword.isValid()) {
54+
// ===== Keystore
55+
keystore.applySecretVolume(deployment, containerName);
56+
addEnvVar(env, QUARKUS_TLS_KEY_STORE_P12_PATH, keystore.getSecretVolumeKeyPath());
57+
keystorePassword.applySecretEnvVar(env, QUARKUS_TLS_KEY_STORE_P12_PASSWORD);
58+
}
59+
}
60+
61+
private static Optional<TLSSpec> getTlsSpec(ApicurioRegistry3 primary) {
62+
return ofNullable(primary)
63+
.map(ApicurioRegistry3::getSpec)
64+
.map(ApicurioRegistry3Spec::getApp)
65+
.map(AppSpec::getTls);
66+
}
67+
}

operator/controller/src/main/java/io/apicurio/registry/operator/feat/security/Auth.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import io.apicurio.registry.operator.EnvironmentVariables;
44
import io.apicurio.registry.operator.api.v1.spec.auth.AuthSpec;
55
import io.fabric8.kubernetes.api.model.EnvVar;
6-
import io.fabric8.kubernetes.api.model.apps.Deployment;
76

87
import java.util.Map;
98
import java.util.Optional;
@@ -20,11 +19,10 @@ public class Auth {
2019
* Configures authentication-related environment variables for the Apicurio Registry.
2120
*
2221
* @param env The map of environment variables to be configured.
23-
* @param deployment The application deployment to configure TLS.
2422
* @param authSpec The authentication specification containing required auth settings. If null, no changes
2523
* will be made to envVars.
2624
*/
27-
public static void configureAuth(AuthSpec authSpec, Deployment deployment, Map<String, EnvVar> env) {
25+
public static void configureAuth(AuthSpec authSpec, Map<String, EnvVar> env) {
2826
if (authSpec == null) {
2927
return;
3028
}
@@ -53,7 +51,9 @@ public static void configureAuth(AuthSpec authSpec, Deployment deployment, Map<S
5351
authSpec.getBasicAuth().getCacheExpiration());
5452
}
5553

56-
AuthTLS.configureAuthTLS(authSpec, deployment, env);
54+
putIfNotBlank(env, EnvironmentVariables.OIDC_TLS_VERIFICATION,
55+
authSpec.getTlsVerificationType());
56+
5757
Authz.configureAuthz(authSpec.getAuthz(), env);
5858
}
5959
}

operator/controller/src/main/java/io/apicurio/registry/operator/feat/security/AuthTLS.java

Lines changed: 0 additions & 51 deletions
This file was deleted.

operator/controller/src/main/java/io/apicurio/registry/operator/resource/ResourceFactory.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3Spec;
88
import io.apicurio.registry.operator.api.v1.spec.AppSpec;
99
import io.apicurio.registry.operator.api.v1.spec.StudioUiSpec;
10+
import io.apicurio.registry.operator.api.v1.spec.TLSSpec;
1011
import io.apicurio.registry.operator.api.v1.spec.UiSpec;
1112
import io.apicurio.registry.operator.status.ValidationErrorConditionManager;
1213
import io.apicurio.registry.operator.status.StatusManager;
@@ -23,7 +24,7 @@
2324
import java.util.Map;
2425
import java.util.Optional;
2526

26-
import static io.apicurio.registry.operator.Constants.DEFAULT_REPLICAS;
27+
import static io.apicurio.registry.operator.Constants.*;
2728
import static io.apicurio.registry.operator.api.v1.ContainerNames.*;
2829
import static io.apicurio.registry.operator.resource.Labels.getSelectorLabels;
2930
import static io.apicurio.registry.operator.resource.app.AppDeploymentResource.getContainerFromPodTemplateSpec;
@@ -56,6 +57,19 @@ public Deployment getDefaultAppDeployment(ApicurioRegistry3 primary) {
5657
.map(AppSpec::getReplicas).orElse(DEFAULT_REPLICAS),
5758
ofNullable(primary.getSpec()).map(ApicurioRegistry3Spec::getApp)
5859
.map(AppSpec::getPodTemplateSpec).orElse(null)); // TODO:
60+
61+
var readinessProbe = DEFAULT_READINESS_PROBE;
62+
var livenessProbe = DEFAULT_LIVENESS_PROBE;
63+
64+
Optional<TLSSpec> tlsSpec = ofNullable(primary.getSpec())
65+
.map(ApicurioRegistry3Spec::getApp)
66+
.map(AppSpec::getTls);
67+
68+
if (tlsSpec.isPresent()) {
69+
readinessProbe = TLS_DEFAULT_READINESS_PROBE;
70+
livenessProbe = TLS_DEFAULT_LIVENESS_PROBE;
71+
}
72+
5973
// Replicas
6074
mergeDeploymentPodTemplateSpec(
6175
COMPONENT_APP_SPEC_FIELD_NAME,
@@ -64,11 +78,12 @@ public Deployment getDefaultAppDeployment(ApicurioRegistry3 primary) {
6478
REGISTRY_APP_CONTAINER_NAME,
6579
Configuration.getAppImage(),
6680
List.of(new ContainerPortBuilder().withName("http").withProtocol("TCP").withContainerPort(8080).build()),
67-
new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/health/ready").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(),
68-
new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/health/live").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(),
81+
readinessProbe,
82+
livenessProbe,
6983
Map.of("cpu", new Quantity("500m"), "memory", new Quantity("512Mi")),
7084
Map.of("cpu", new Quantity("1"), "memory", new Quantity("1Gi"))
7185
);
86+
7287
addDefaultLabels(r.getMetadata().getLabels(), primary, COMPONENT_APP);
7388
addSelectorLabels(r.getSpec().getSelector().getMatchLabels(), primary, COMPONENT_APP);
7489
addDefaultLabels(r.getSpec().getTemplate().getMetadata().getLabels(), primary, COMPONENT_APP);

operator/controller/src/main/java/io/apicurio/registry/operator/resource/app/AppDeploymentResource.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import io.apicurio.registry.operator.feat.Cors;
1212
import io.apicurio.registry.operator.feat.KafkaSql;
1313
import io.apicurio.registry.operator.feat.PostgresSql;
14+
import io.apicurio.registry.operator.feat.TLS;
1415
import io.apicurio.registry.operator.feat.security.Auth;
1516
import io.apicurio.registry.operator.status.ReadyConditionManager;
1617
import io.apicurio.registry.operator.status.StatusManager;
@@ -81,12 +82,15 @@ protected Deployment desired(ApicurioRegistry3 primary, Context<ApicurioRegistry
8182
if (authEnabled) {
8283
Auth.configureAuth(requireNonNull(ofNullable(primary.getSpec().getApp())
8384
.map(AppSpec::getAuth)
84-
.orElse(null)), deployment, envVars);
85+
.orElse(null)), envVars);
8586
}
8687

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

91+
// Configure the TLS env vars
92+
TLS.configureTLS(primary, deployment, REGISTRY_APP_CONTAINER_NAME, envVars);
93+
9094
// Enable the "mutability" feature in Registry, but only if Studio is deployed. It is based on Service
9195
// in case a custom Ingress is used.
9296
var sOpt = context.getSecondaryResource(STUDIO_UI_SERVICE_KEY.getKlass(),

operator/controller/src/main/java/io/apicurio/registry/operator/resource/app/AppNetworkPolicyResource.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package io.apicurio.registry.operator.resource.app;
22

33
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3;
4+
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3Spec;
5+
import io.apicurio.registry.operator.api.v1.spec.AppSpec;
46
import io.apicurio.registry.operator.resource.LabelDiscriminators.AppNetworkPolicyDiscriminator;
7+
import io.fabric8.kubernetes.api.model.IntOrStringBuilder;
58
import io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicy;
9+
import io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicyIngressRuleBuilder;
610
import io.javaoperatorsdk.operator.api.reconciler.Context;
711
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
812
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
913
import org.slf4j.Logger;
1014
import org.slf4j.LoggerFactory;
1115

16+
import java.util.List;
17+
import java.util.Optional;
18+
1219
import static io.apicurio.registry.operator.resource.ResourceFactory.COMPONENT_APP;
1320
import static io.apicurio.registry.operator.resource.ResourceKey.APP_NETWORK_POLICY_KEY;
1421
import static io.apicurio.registry.operator.utils.Mapper.toYAML;
@@ -31,6 +38,30 @@ public AppNetworkPolicyResource() {
3138
@Override
3239
protected NetworkPolicy desired(ApicurioRegistry3 primary, Context<ApicurioRegistry3> context) {
3340
var networkPolicy = APP_NETWORK_POLICY_KEY.getFactory().apply(primary);
41+
42+
Optional.ofNullable(primary.getSpec())
43+
.map(ApicurioRegistry3Spec::getApp)
44+
.map(AppSpec::getTls)
45+
.ifPresent(tls -> {
46+
47+
var httpsPolicy = new io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicyPortBuilder()
48+
.withPort(new IntOrStringBuilder().withValue(8443).build()).build();
49+
50+
var httpPolicy = new io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicyPortBuilder()
51+
.withPort(new IntOrStringBuilder().withValue(8080).build()).build();
52+
53+
if (!tls.getInsecureRequests().equals("enabled")) {
54+
networkPolicy.getSpec().setIngress(List.of(new NetworkPolicyIngressRuleBuilder()
55+
.withPorts(httpsPolicy)
56+
.build()));
57+
}
58+
else {
59+
networkPolicy.getSpec().setIngress(List.of(new NetworkPolicyIngressRuleBuilder()
60+
.withPorts(httpsPolicy, httpPolicy)
61+
.build()));
62+
}
63+
});
64+
3465
log.trace("Desired {} is {}", APP_NETWORK_POLICY_KEY.getId(), toYAML(networkPolicy));
3566
return networkPolicy;
3667
}

operator/controller/src/main/java/io/apicurio/registry/operator/resource/app/AppServiceResource.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
package io.apicurio.registry.operator.resource.app;
22

33
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3;
4+
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3Spec;
5+
import io.apicurio.registry.operator.api.v1.spec.AppSpec;
6+
import io.fabric8.kubernetes.api.model.IntOrStringBuilder;
47
import io.fabric8.kubernetes.api.model.Service;
8+
import io.fabric8.kubernetes.api.model.ServicePortBuilder;
59
import io.javaoperatorsdk.operator.api.reconciler.Context;
610
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
711
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
812
import org.slf4j.Logger;
913
import org.slf4j.LoggerFactory;
1014

15+
import java.util.List;
16+
import java.util.Optional;
17+
1118
import static io.apicurio.registry.operator.resource.LabelDiscriminators.AppServiceDiscriminator;
1219
import static io.apicurio.registry.operator.resource.ResourceKey.APP_SERVICE_KEY;
1320
import static io.apicurio.registry.operator.utils.Mapper.toYAML;
@@ -24,6 +31,31 @@ public AppServiceResource() {
2431
@Override
2532
protected Service desired(ApicurioRegistry3 primary, Context<ApicurioRegistry3> context) {
2633
var s = APP_SERVICE_KEY.getFactory().apply(primary);
34+
35+
Optional.ofNullable(primary.getSpec())
36+
.map(ApicurioRegistry3Spec::getApp)
37+
.map(AppSpec::getTls)
38+
.ifPresent(tls -> {
39+
var httpPort = new ServicePortBuilder()
40+
.withName("http")
41+
.withPort(8080)
42+
.withTargetPort(new IntOrStringBuilder().withValue(8080).build())
43+
.build();
44+
45+
var httpsPort = new ServicePortBuilder()
46+
.withName("https")
47+
.withPort(443)
48+
.withTargetPort(new IntOrStringBuilder().withValue(8443).build())
49+
.build();
50+
51+
if (tls.getInsecureRequests().equals("enabled")) {
52+
s.getSpec().setPorts(List.of(httpsPort, httpPort));
53+
}
54+
else {
55+
s.getSpec().setPorts(List.of(httpsPort));
56+
}
57+
});
58+
2759
log.trace("Desired {} is {}", APP_SERVICE_KEY.getId(), toYAML(s));
2860
return s;
2961
}

0 commit comments

Comments
 (0)