Skip to content
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

fix: support uppercase letters in entrypoint names #1286

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

uvNikita
Copy link

What does this PR do?

Traefik supports entrypoints with uppercase letters (e.g. webSecure), but helm generated manifest fails to apply because port names can only be lowercase.

This forces lower case on port names for entrypoints.

Motivation

We are migrating traefik deployment from raw yaml files to helm chart, but one of our entrypoints has uppercase letter in the name (webSecure).

This issue prevents the migration since helm generates invalid pod template with port name based on entrypoint name with uppercase letter.

From Kubertes Docs:

EndpointPort
name .... must consist of lower case alphanumeric characters ...

More

  • Yes, I updated the tests accordingly
  • Yes, I updated the schema accordingly
  • Yes, I ran make test and all the tests passed

Traefik supports entrypoints with uppercase letters (e.g. webSecure),
but helm generated manifest fails to apply because port names can only be lowercase.

This forces lower case on port names for entrypoints.
@uvNikita
Copy link
Author

uvNikita commented Dec 17, 2024

Added test to show the issue this patch fixes.

@jnoordsij
Copy link
Collaborator

Hey there! Thanks for your contribution.

I have two questions/suggestions:

  1. Although Traefik itself allows uppercase entrypoints, this chart solely defines them in lowercase. For example, the values for websecure are found here:
    websecure:
    ## -- Enable this entrypoint as a default entrypoint. When a service doesn't explicitly set an entrypoint it will only use this entrypoint.
    # asDefault: true
    port: 8443
    hostPort: # @schema type:[integer, null]; minimum:0
    containerPort: # @schema type:[integer, null]; minimum:0
    expose:
    default: true
    exposedPort: 443
    ## -- Different target traefik port on the cluster, useful for IP type LB
    targetPort: # @schema type:[string, integer, null]; minimum:0
    ## -- The port protocol (TCP/UDP)
    protocol: TCP
    # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport)
    nodePort: # @schema type:[integer, null]; minimum:0
    # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol)
    appProtocol: # @schema type:[string, null]
    # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#allowacmebypass)
    allowACMEByPass: false
    http3:
    ## -- Enable HTTP/3 on the entrypoint
    ## Enabling it will also enable http3 experimental feature
    ## https://doc.traefik.io/traefik/routing/entrypoints/#http3
    ## There are known limitations when trying to listen on same ports for
    ## TCP & UDP (Http3). There is a workaround in this chart using dual Service.
    ## https://github.com/kubernetes/kubernetes/issues/47249#issuecomment-587960741
    enabled: false
    advertisedPort: # @schema type:[integer, null]; minimum:0
    forwardedHeaders:
    # -- Trust forwarded headers information (X-Forwarded-*).
    trustedIPs: []
    insecure: false
    proxyProtocol:
    # -- Enable the Proxy Protocol header parsing for the entry point
    trustedIPs: []
    insecure: false
    # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#transport)
    transport:
    respondingTimeouts:
    readTimeout: # @schema type:[string, integer, null]
    writeTimeout: # @schema type:[string, integer, null]
    idleTimeout: # @schema type:[string, integer, null]
    lifeCycle:
    requestAcceptGraceTimeout: # @schema type:[string, integer, null]
    graceTimeOut: # @schema type:[string, integer, null]
    keepAliveMaxRequests: # @schema type:[integer, null]; minimum:0
    keepAliveMaxTime: # @schema type:[string, integer, null]
    # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#tls)
    tls:
    enabled: true
    options: ""
    certResolver: ""
    domains: []
    # -- One can apply Middlewares on an entrypoint
    # https://doc.traefik.io/traefik/middlewares/overview/
    # https://doc.traefik.io/traefik/routing/entrypoints/#middlewares
    # -- /!\ It introduces here a link between your static configuration and your dynamic configuration /!\
    # It follows the provider naming convention: https://doc.traefik.io/traefik/providers/overview/#provider-namespace
    # - namespace-name1@kubernetescrd
    # - namespace-name2@kubernetescrd
    middlewares: []

    Similarly almost all of the docs examples use lowercase entrypoints. (I'm not exactly sure, but some naming might even be converted to lowercase internally.) Considering all that, it might be easier to migrate your values to use the lowercase name. However I understand there may be particular conditions to your use-case that prevent you from doing so.
  2. You propose to change the name field on the port on the pod (see docs for the exact restrictions on this field). However, the same name is also used on the service, which also has (less strict) restrictions (see docs. Therefore, if we were to adopt these changes, I think we should be a little more careful here and introduce some additional helper that can be reused across various places where we reference this.

@uvNikita
Copy link
Author

Considering all that, it might be easier to migrate your values to use the lowercase name.

Our entrypoint is currently defined as webSecure (note capital S) and we don't have direct control of the Ingress / IngressRoute since they are managed by our users. So it will be a big undertaking for us to coordinate a change with multiple teams to modify an entrypoint for all objects.

We can of course automate the change on the running cluster and add a mutation hook to fix incoming objects, but ideally we could perform helm migration without this, since it's a valid entrypoint name at least from the traefik's prospective.

As per the second point, adjusting the name to the lower case at least brings the name field closer to the requirement from the Kubernetes API side.

Maybe some sort of name sanitizer would be even better, but IMHO lowering the case improves the current state iteratively and simple enough change that can be merged now. Further improvement could build on top of it.

@mloiseleur
Copy link
Contributor

@uvNikita thanks for all those details about your use case, which is quite unexpected.

As @jnoordsij said:

However, the same name is also used on the service,

Would you please add a test on Service with an uppercase entrypoint name ?

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.

3 participants