-
Notifications
You must be signed in to change notification settings - Fork 99
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
Console fix up with mutual TLS #1402
Conversation
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.
Not a full review will follow up on the test. Seems like we'll want to solve the subcharting problem soon.
charts/redpanda/certs.go
Outdated
@@ -89,7 +89,7 @@ func ClientCerts(dot *helmette.Dot) []certmanagerv1.Certificate { | |||
panic(fmt.Sprintf("Certificate %q referenced but not defined", name)) | |||
} | |||
|
|||
if helmette.Empty(data.SecretRef) || !ClientAuthRequired(dot) { | |||
if !ClientAuthRequired(dot) { |
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 was a bit worried about this. We'll need to ask Azure (cc @c4milo or @ncole ) how they'd like to handle this.
For mTLS to work, the chart needs to be able to get a client certificate for either console or RPK (@RafalKorepta which is it?). This currently works through the cert manager integration but there's not really a fallback. If y'all can mint a cert we can find a field to add a secretRef to or we can talk through relying on the cert-manger integration either partially or fully.
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'm not sure the context on this, but I think you're saying for mTLS we need a client cert. We are already creating a self-signed CA AND a client cert, so we can provide that ref somehow for Console (or RPK, whichever it is @RafalKorepta)?
In fact, in the other providers, if mTLS is enabled, we add a self-signed CA and a cert for kminion to use so we have an existing precedent for this.
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.
For mTLS to work, the chart needs to be able to get a client certificate for either console or RPK (@RafalKorepta which is it?).
In this particular case, client certificate is used for both RPK and console. They will reference and mount the same certificate.
This currently works through the cert manager integration but there's not really a fallback. If y'all can mint a cert we can find a field to add a secretRef to or we can talk through relying on the cert-manger integration either partially or fully.
I agree, that this check needs to accommodate a use case when certificate is provided. I will change that check.
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 agree, that this check needs to accommodate a use case when certificate is provided. I will change that check.
Let's handle that in a follow up PR/commit?
charts/redpanda/client_test.go
Outdated
return event, nil | ||
} | ||
|
||
func (c *Client) GetClusterHealth(ctx context.Context, dot *helmette.Dot) (map[string]any, error) { |
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 love the idea of using *helmette.Dot
here. If there's a bug in some of the Values functions that would surface here and potentially obscure issues from our tests, specifically in the case of TLS configurations.
I think it would be a more robust testing strategy to instead have the Client accept the TLS certificates (extracted from the cluster if using the cert-manger integration) and then use those to actually dial into the various listeners of the Pod, piggy backing on kubectl port-forward
to actually make the connection. Then we can rely on client libraries instead of having to template out CLI commands.
For an initial implementation thought, let's roll with it!
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 will add certificate to the Client.
} | ||
|
||
if values.Connectors.Enabled { | ||
// TODO Do not cal Dig with dot.Values as restPort that is defined in connectors helm chart is not |
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 can think of ~2 ways we could handle this.
- Have a helmette function that runs a "raw" template command (Though it'll be quite difficult to get that to work reliably in go but perhaps that's okay.
helmette.Raw("(include connectors.serviceName $var)")
- Teach gotohelm how to handle subcharts by resolving the name to the appropriate call but not actually transpile the underlying call.
Given that we'll need to convert the connectors and console chart, I'm leaning towards 2 but 1 would certainly be faster.
6ba9d11
to
4ace5f2
Compare
@@ -654,23 +661,14 @@ spec: | |||
- name: kafka-default-cert | |||
secret: | |||
defaultMode: 272 | |||
items: |
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.
huh. Do you know where these diffs are stemming from? It seems incorrect for these to be removed. Could they just be out of date?
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 didn't want transiple the schema, admin and kafka volume definition in the following console deployement:
- https://github.com/redpanda-data/helm-charts/pull/1402/files#diff-0b45ecf3a48bcb79531c1cf2372a743fa93c58bc1ee5193a798e9decd52bf7e4L245
- https://github.com/redpanda-data/helm-charts/pull/1402/files#diff-0b45ecf3a48bcb79531c1cf2372a743fa93c58bc1ee5193a798e9decd52bf7e4L213
- https://github.com/redpanda-data/helm-charts/pull/1402/files#diff-0b45ecf3a48bcb79531c1cf2372a743fa93c58bc1ee5193a798e9decd52bf7e4L185
Regardless of the certification secret reference all will be mounted to console pod.
urls: | ||
- https://redpanda-0.redpanda.default.svc.cluster.local.:8081 | ||
- https://redpanda-1.redpanda.default.svc.cluster.local.:8081 | ||
- https://redpanda-2.redpanda.default.svc.cluster.local.:8081 | ||
tls: | ||
caFilepath: /mnt/cert/kafka/default/ca.crt | ||
certFilepath: "" |
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.
Are empty strings valid values of certFilepath
and keyFilepath
?
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.
Console didn't complain and does not use cert nor key if it has empty string in the kafka, schema registry and admin API clinets.
16a8c2d
to
38b69a1
Compare
I added new CI execution that using kind cluster is performing new mTLS test cases P.S. I don't understand why |
942a159
to
9891e67
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.
This is quite a large PR again 😅 Let's try to get the for loop fix merged externally so we can cut down on the diff a bit.
I'm seeing some concerning looking diffs in the golden files. Do you think they're expected?
charts/redpanda/chart_test.go
Outdated
|
||
record, err := rpk.RetrieveEventFromTopic(ctx, httpTestTopic, 0) | ||
require.NoError(t, err) | ||
require.Equal(t, fmt.Sprintf("[{\"topic\":\"%s\",\"key\":null,\"value\":\"Redpanda\",\"partition\":0,\"offset\":0}]", httpTestTopic), record) |
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.
nit: maybe use JSONEq here unless the key ordering form the proxy is guaranteed?
nit: Using backticks makes for much more readable JSON.
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.
ordering form the proxy is guaranteed
Yes, it's guaranteed.
Using backticks makes for much more readable JSON.
I will use JSONEq here, so the object will be created as map[string]any
@@ -154,3 +158,80 @@ func (c *Ctl) Exec(ctx context.Context, pod *corev1.Pod, opts ExecOptions) error | |||
Stdin: opts.Stdin, | |||
}) | |||
} | |||
|
|||
func (c *Ctl) PortForward(ctx context.Context, pod *corev1.Pod, out, errOut io.Writer) ([]portforward.ForwardedPort, func(), error) { | |||
// Apparently, nothing in the k8s SDK, except exec'ing, uses RESTClientFor. |
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.
Ugh, I remember hitting this issue way back. Most frequently I've seen people make an instance of the type client set which internally does something like this though it's split across 3 different packages if IIRC.
|
||
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", req.URL()) | ||
|
||
var ports []string |
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'm not a huge fan of relying on the "portforwarding" abstraction because it binds to local ports for no reason which adds a bunch of extra goroutines and indirection but it's much easier to get started.
We can rip the guts out of https://github.com/kubernetes/client-go/blob/592d891671b2a09e5f81781b28ebe078d8115e41/tools/portforward/portforward.go#L335 to wrap this up into a Dialer interface that'll place nice with go's networking constructs which is a lot easier to utilize with other client libraries (http.RoundTripper for example).
That's a bigger change for later. Just leaving so notes for ourselves.
b192503
to
65b0f78
Compare
Console TLS configuration needs to have client certificates for mutual TLS communication. With this commit Console go package is imported to have strongly typed Console configuration. As Console configuration has yaml annotation, not json transpiler is trying to parse yaml annotation as a fallback.
65b0f78
to
a7bfd7b
Compare
a7bfd7b
to
1af7f16
Compare
This PR is based on #1386 to solve early return problem in go template.
Client certificates does not relay on secret reference, that's why checks are removed.
Add integration test that setup mTLS for all listeners (Kafka, Admin API, HTTP Proxy, Schema Registry, RPC).
Verification in rpk client is not always done using
rpk
.curl
should be replaced with port-forward and simple go based http client Get/Post/Delete implementation.Fix
ClientAuthRequired
check asDig
function should start fromlisteners
object.Expose, in Redpanda values, Console config and chunk of Connectors values.
Mount all client certificates (ca, certificate and key) in Console deployment.
Move Admin API configuration from env vars to ConfigMap.
Reference
https://docs.redpanda.com/current/develop/http-proxy/
https://docs.redpanda.com/current/manage/schema-reg/schema-reg-api/