8000 add labels and annotations to service (httpSpec) by gilvansfilho · Pull Request #39925 · keycloak/keycloak · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

add labels and annotations to service (httpSpec) #39925

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

Merged
merged 1 commit into from
Jun 17, 2025

Conversation

gilvansfilho
Copy link
Contributor

closes #23283

closes keycloak#23283

Signed-off-by: Gilvan Filho <gfilho@redhat.com>
Copy link
Contributor
@vmuzikar vmuzikar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gilvansfilho Thank you for the contribution!

Comment on lines +51 to +55
@JsonPropertyDescription("Annotations to be appended to the Service object")
Map<String, String> annotations;

@JsonPropertyDescription("Labels to be appended to the Service object")
Map<String, String> labels;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd argue we should probably add a service spec instead of putting it under http. But leaving the room for @shawkins to chime in as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this but I think everything inside spec.http is about service layer so I don't have sure if make sense have a service spec. I mean, if we had a service spec where will we put httpEnabled, httpPort and so on?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing http spec is a good enough place for this - it's ok to let the cr have some abstraction. If we go down the path of adding a service stanza arguably that will need to be split between the discovery and regular service.

@vmuzikar vmuzikar requested a review from shawkins May 26, 2025 15:04
@vmuzikar
Copy link
Contributor

Another thought is whether it really makes sense to add labels and annotations specifically to Services. Whether not have it covered in a generic manner for all Operator managed resources (see #15395). @shawkins WDYT?

@gilvansfilho Can you share the use case you are implementing this for?

@gilvansfilho
Copy link
Contributor Author

Another thought is whether it really makes sense to add labels and annotations specifically to Services. Whether not have it covered in a generic manner for all Operator managed resources (see #15395). @shawkins WDYT?

@gilvansfilho Can you share the use case you are implementing this for?

The main motivation is to be possible to add service.alpha.openshift.io/serving-cert-secret-name annotation allowing Openshift to gerente a cluster certificate for keycloak's pods. Today to use reencrypt routes in openshift we need to mimic the default service created by Operator and add this annotation. Then we need to create a new route with reencrypt termination using the custom service.

With this PR we reduce the steps needs to have reencrypt routes with keycloak. Just the route object will be craft by hand.

@shawkins
Copy link
Contributor

Another thought is whether it really makes sense to add labels and annotations specifically to Services. Whether not have it covered in a generic manner for all Operator managed resources (see #15395). @shawkins WDYT?

Given some of the other openshift specific logic in the operator, the alternative here is to directly support reencrypt declaratively just for openshift. If in the near-term we're looking to stop using a cluster role, we'll already have to use a route to auto-determine the hostname.

If we don't want to go down this path, then opening up the labels and annotations like this seems fine.

If we do eventually add a more global control for custom metadata I would expect that to be applied first, then the more specific metadata overlayed on that.

@vmuzikar
Copy link
Contributor

If the only motivation for having dedicated labels and annotations setting for services is the reencrypt, I'd rather go down the path of a first class support for reencrypt. We generally try to avoid adding arbitrary fields to the CR if we can have a better UX by adding a support for specific use cases.

@shawkins
Copy link
Contributor
shawkins commented Jun 2, 2025

If the only motivation for having dedicated labels and annotations setting for services is the reencrypt, I'd rather go down the path of a first class support for reencrypt.

The exisitng issue for this is #20128

Getting this supported end-to-end is not trivial, and of course initially openshift specific.

There are two cases - reencrypt using a serving certificate, and reencrypt using the http key / cert. We'll also need to have the key / cert for the route - there isn't currently a spot for this on the CR, unless you want to somehow make the http key / cert apply which is also discussed on #34777

These cases would look like:

Re-encrypt implied:

http:
  tlsSecret: secret
ingress:
  tlsSecret: other-secret

Re-encrypt using serving certificate would need some way to indciate the annotation needs added. That would either be a mode for the ingress, or something on the http spec to indicate a key / cert should be generated:

http:
  ...
ingress:
  mode: reencrypt
  tlsSecret: secret

@gilvansfilho
Copy link
Contributor Author

At Openshift to use reencrypt one is not mandatory to provide a route certificate. A reencrypt route without an explicit certificate will use the cluster default certificate.

@vmuzikar
Copy link
Contributor
vmuzikar commented Jun 3, 2025

A reencrypt route without an explicit certificate will use the cluster default certificate.

I'd vote for rather using the cert generated for the service via the annotation.

unless you want to somehow make the http key / cert apply

That's a good question. Would there be a real life use case where you'd need different cert and key for Keycloak and the Route in re-encrypt case? Maybe when you don't trust Keycloak so much and don't want to give it the TLS private key that will be also used externally? :D

Maybe we could have something like:

spec:
  http:
    tlsSecret: keycloak-tls
  ingress:
    tls:
      secret: my-other-secret
      generated: true|false # when set to true, secret must be left blank; currently works only on OpenShift

@gilvansfilho
Copy link
Contributor Author

I'd vote for rather using the cert generated for the service via the annotation.

I too. But keep in mind that cert generated via the annotation is for the pod (service layer), not for the route. For the route openshift allows to provide a custom cert or use cluster default cert.

For reencrypt two certs are involved:

  • the service / pod cert (spec.http.tlsSecret)
  • the route / ingress cert (spec.ingress.tlsSecret new property)

So the spec.ingress.generated do not make sense for me (talking about openshift)

@shawkins
Copy link
Contributor
shawkins commented Jun 3, 2025

But keep in mind that cert generated via the annotation is for the pod (service layer), not for the route. For the route openshift allows to provide a custom cert or use cluster default cert.

Ok, so we have either an implicit reencrypt where both tlsSecrets are specified, or an explicit reencrypt mode where both tlsSecrets are optional.

So the spec.ingress.generated do not make sense for me (talking about openshift)

Are you good with an ingress mode or similar flag?

Also I vote to proceed with the additional metadata support proposed in this pr, and tackle the openshift specific reencrypt support under the other issue.

@gilvansfilho
Copy link
Contributor Author
gilvansfilho commented Jun 3, 2025

Are you good with an ingress mode or similar flag?

Sure


To provide first class support to Openshift reencrypt routes I think we need below scenarios...

Scenario http.tlsSecret ingress.tlsSecret ingress.mode service annotation pod certificate route certificate
1 (not defined) (not defined) reencrypt service.alpha.openshift.io/serving-cert-secret-name: generated-tls-secret generated-tls-secret (cluster default certificate)
2 pod-tls-secret (not defined) reencrypt pod-tls-secret (cluster default certificate)
3 (not defined) custom-route-tls reencrypt service.alpha.openshift.io/serving-cert-secret-name: generated-tls-secret generated-tls-secret custom-route-tls
4 pod-tls-secret custom-route-tls reencrypt pod-tls-secret custom-route-tls

Scenario 1: Reencrypt with cluster domain and serving certificate for pod

spec:
  http:
    ...
  ingress:
    mode: reencrypt

Operator will have to:

  • Create a reencrypt route with no cert (so Openshift will use cluster default certificate)
  • Create a service adding the annotation service.alpha.openshift.io/serving-cert-secret-name: generated-tls-secret
  • Under the hoods spec.http.tlsSecret must be set to generated-tls-secret

With that we have:

  • A reencrypt openshift route using cluster default certificate (keycloak exposed using default openshift cluster domain).
  • Pod using certificate generated by Openshift (serving certificate)

Scenario 2: Reencrypt with cluster domain and custom certificate for pod

spec:
  http:    
    tlsSecret: pod-tls-secret
  ingress:
    mode: reencrypt

User must provide:

  • pod-tls-secret to be used by keycloak pods

Operator will have to:

  • Create a reencrypt route with no cert (so Openshift will use cluster default certificate)
  • Create a service in same way is created today

With that we have:

  • A reencrypt openshift route using cluster default certificate (keycloak exposed using default openshift cluster domain).
  • Pod using certificate provided through spec.http.tlsSecret

Scenario 3: Reencrypt with custom domain certificate and serving certificate for service

spec:
  http:
    ...
  ingress:
    mode: reencrypt
    tlsSecret: custom-route-tls

User must provide:

  • custom-route-tls to be used by router

Operator will have to:

  • Create a reencrypt route with the custom certificate
  • Create a service adding the annotation service.alpha.openshift.io/serving-cert-secret-name: generated-tls-secret
  • Under the hoods spec.http.tlsSecret must be set to generated-tls-secret

With that we have:

  • A reencrypt openshift route using custom certificate (keycloak exposed using domain of the certificate provided through spec.ingress.tlsSecret )
  • Pod using certificate generated by Openshift (serving certificate)

Scenario 4: Reencrypt with custom domain certificate and custom certificate for pod

spec:
  http:
    tlsSecret: pod-tls-secret
  ingress:
    mode: reencrypt
    tlsSecret: custom-route-tls

User must provide:

  • pod-tls-secret to be used by keycloak pods
  • custom-route-tls to be used by router

Operator will have to:

  • Create a reencrypt route with the custom certificate
  • Create a service in same way is created today

User must provide pod-tls-secret to be used by keycloak pods

With that we have:

  • A reencrypt openshift route using custom certificate (keycloak exposed using domain of the certificate provided through spec.ingress.tlsSecret )
  • Pod using certificate provided through spec.http.tlsSecret

I guess all exposed above will require a lot of work.

Also I vote to proceed with the additional metadata support proposed in this pr, and tackle the openshift specific reencrypt support under the other issue.

So, I also vote to proceed with this PR, allowing to inject custom labels and annotatios to services, So one who is trying to use reencrypt routes before we have first class support for it will have a easier way to it, like bellow:

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  name: example-kc
spec:
  http:
    tls-secret: generated-tls-secret
    annotations:
      service.alpha.openshift.io/serving-cert-secret-name: generated-tls-secret
  ingress:
    enabled: false

Then will need to manually create a reencrypt route

@shawkins
Copy link
Contributor
shawkins commented Jun 3, 2025

@gilvansfilho our understanding is the same. Scenario 4 is what I was thinking doesn't need to explicitly specify the mode as reencrypt is implied. Can you move / add the previous comment to #20128?

@gilvansfilho
Copy link
Contributor Author

@shawkins

Scenario 4 is what I was thinking doesn't need to explicitly specify the mode as reencrypt is implied

Totally agree

Can you move / add the previous comment to #20128?

Done

@vmuzikar
Copy link
Contributor
vmuzikar commented Jun 5, 2025

@gilvansfilho Thank you for providing the analysis!

Also I vote to proceed with the additional metadata support proposed in this pr, and tackle the openshift specific reencrypt support under the other issue.

Thinking about it more considering the scenarios, I'm gonna agree with @shawkins here. I don't even think we need OpenShift specific support. We could just expose the TLS secret field in the ingress spec and document some use cases (the scenarios above) that will use the service annotations and/or the TLS secret fields. WDYT?

@gilvansfilho
Copy link
Contributor Author

Agree :)

@gilvansfilho
Copy link
Contributor Author

Team, How will we go ahead?
To merge this one allowing other user cases we don't have in mind?
To close this one? Adding explicit reencrypt support through #20128 ?

FYI @vmuzikar @shawkins

@shawkins
Copy link
Contributor

To merge this one allowing other user cases we don't have in mind?

Yes, I think we are good to merge this one and let #20128 and #34777 be used for any additional work.

@shawkins shawkins requested a review from vmuzikar June 17, 2025 00:55
Copy link
Contributor
@shawkins shawkins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you @gilvansfilho

Copy link
Contributor
@vmuzikar vmuzikar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice work @gilvansfilho.

Let's address the reencrypt scenario by adding TLS secret to Ingress in #20128.

@vmuzikar vmuzikar merged commit e5bb7f5 into keycloak:main Jun 17, 2025
76 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow Keycloak operator to parameterize the Service annotations and labels
3 participants
0