-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement tls support for the app #6007
base: main
Are you sure you want to change the base?
Conversation
if (truststore.isValid() && truststorePassword.isValid()) { | ||
// ===== Truststore | ||
truststore.applySecretVolume(deployment, containerName); | ||
addEnvVar(env, QUARKUS_TLS_TRUST_STORE_P12_PATH, truststore.getSecretVolumeKeyPath()); | ||
truststorePassword.applySecretEnvVar(env, QUARKUS_TLS_TRUST_STORE_P12_PASSWORD); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if I will use just PEM cert as truststore? Like
kind: ApicurioRegistry3
apiVersion: registry.apicur.io/v1
metadata:
name: schema-registry
spec:
app:
storage:
type: "kafkasql"
kafkasql:
bootstrapServers: anubis-kafka-bootstrap.strimzi-kafka.svc:9093
tls:
truststoreSecretRef:
name: anubis-cluster-ca-cert
key: ca.crt
wouldn't it cause failure? I would more expect that keystore password will be required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the operator level we're supporting P12 (since it's usually a better practice than just specifying cert by cert). You will still be able to use PEM files using Quarkus own env vars.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thanks.
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
import static io.apicurio.registry.operator.EnvironmentVariables.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a nit, but *
is not much good practice form my pov (different projects, different standards) :)
6e93999
to
7fadf42
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but have some questions. Some of the comments are optional/can be done later.
.map(ApicurioRegistry3Spec::getApp) | ||
.map(AppSpec::getTls) | ||
.map(TLSSpec::getInsecureRequests) | ||
.orElse("enabled")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use boolean for insecureRequests
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the possible values are enabled, disabled and redirect, so I don't think boolean makes sense here.
.map(ApicurioRegistry3Spec::getApp) | ||
.map(AppSpec::getTls); | ||
|
||
if (tlsSpec.isPresent()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming TLS is enabled only by the presence of the tls
object in the CR seems like it could cause user errors. I suggest we also check that the truststore/keystore is valid via io.apicurio.registry.operator.utils.SecretKeyRefTool#isValid
before we assume user wants to enable TLS. Could be done by a static method in io.apicurio.registry.operator.feat.TLS
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but, if it's misconfigured, the application won't even start, which, if you tried to configure TLS, might be even better than a "healthy" application and then having to look at the logs, wdyt?
@@ -56,6 +57,19 @@ public Deployment getDefaultAppDeployment(ApicurioRegistry3 primary) { | |||
.map(AppSpec::getReplicas).orElse(DEFAULT_REPLICAS), | |||
ofNullable(primary.getSpec()).map(ApicurioRegistry3Spec::getApp) | |||
.map(AppSpec::getPodTemplateSpec).orElse(null)); // TODO: | |||
|
|||
var readinessProbe = new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/health/ready").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(); | |||
var livenessProbe = new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/health/live").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you merge the non-tls probes above into io.apicurio.registry.operator.Constants
as well? Some of the values in that class are unused and will need to be removed, but now it's a bit confusing.
public static final String QUARKUS_TLS_KEY_STORE_P12_PASSWORD = "QUARKUS_TLS_KEY_STORE_P12_PASSWORD"; | ||
public static final String QUARKUS_TLS_TRUST_STORE_P12_PATH = "QUARKUS_TLS_TRUST_STORE_P12_PATH"; | ||
public static final String QUARKUS_TLS_TRUST_STORE_P12_PASSWORD = "QUARKUS_TLS_TRUST_STORE_P12_PASSWORD"; | ||
public static final String QUARKUS_OIDC_TLS_TLS_CONFIGURATION_NAME = "QUARKUS_OIDC_TLS_TLS_CONFIGURATION_NAME"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused in this PR
|
||
var keystore = new SecretKeyRefTool(getTlsSpec(primary) | ||
.map(TLSSpec::getKeystoreSecretRef) | ||
.orElse(null), "user.p12"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a constructor that takes Optional would be useful here. We've got this pattern elsewhere, e.g. in io.apicurio.registry.operator.feat.KafkaSqlTLS
. Optional suggestion, could be done in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion, I was just following the pattern from KafkaSqlTLS. I'll let you decide if you want to do it in a separate PR.
@@ -64,11 +78,12 @@ public Deployment getDefaultAppDeployment(ApicurioRegistry3 primary) { | |||
REGISTRY_APP_CONTAINER_NAME, | |||
Configuration.getAppImage(), | |||
List.of(new ContainerPortBuilder().withName("http").withProtocol("TCP").withContainerPort(8080).build()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we set the 8443
port in the container? The probes will succeed even if the connection can't be actually established. Do we make an actual connection in the tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a complete miss on my part, we must add the container to the port. No real connection is made in the tests, but that's expected, we only check for the needed resources to be created and for the deployment to become ready.
import static org.awaitility.Awaitility.await; | ||
|
||
@QuarkusTest | ||
public class TlsITTest extends ITBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should ping the REST API in the tests, port-forwarding should be enough since we do not support yet create HTTPS Ingresses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If https is not properly configured at the application level, the pod won't even start, so I think checking whether the deployment is ready or not should be enough.
await().ignoreExceptions().until(() -> { | ||
assertThat(client.network().v1().networkPolicies().inNamespace(namespace) | ||
.withName("simple-app-networkpolicy").get().getSpec().getIngress() | ||
.get(0).getPorts().get(0).getPort().getIntVal()).isEqualTo(8443); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also check for other ports.
return true; | ||
}); | ||
|
||
// Ingresses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we do not create https Ingresses automatically, this check is probably unnecessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, yes.
host: simple-ui.apps.cluster.example | ||
env: | ||
- name: REGISTRY_API_URL | ||
value: https://simple-app.apps.cluster.example/apis/registry/v3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add a note to this example that the feature is intended for TLS inside of the cluster for now, and they would have to create their own https reencrypt Ingress.
No description provided.