Skip to content

feat: add support for from-to-www-redirect#337

Open
chakravardhan wants to merge 2 commits intokubernetes-sigs:mainfrom
chakravardhan:feature/nginx-redirects
Open

feat: add support for from-to-www-redirect#337
chakravardhan wants to merge 2 commits intokubernetes-sigs:mainfrom
chakravardhan:feature/nginx-redirects

Conversation

@chakravardhan
Copy link
Contributor

@chakravardhan chakravardhan commented Feb 6, 2026

What type of PR is this?

/kind feature

What this PR does / why we need it:

When the from-to-www-redirect annotation is encountered and set to "true", the translator generates a completely separate, dedicated HTTPRoute for the redirect.

Compatibility with permanent-redirect (#299)

There is a potential edge case where a user specifies both from-to-www-redirect and permanent-redirect on the same Ingress resource.

How this is handled:

  • This PR (from-to-www-redirect) generates a completely separate HTTPRoute dedicated to the www/non-www redirect. Because they operate on different HTTPRoute objects or distinct hostnames, they do not overwrite each other during the Intermediate Representation (IR) generation. When emitted, the Gateway API handles this overlap natively and gracefully by selecting the most specific Hostname match for routing the request.

Which issue(s) this PR fixes:

Fixes #

Does this PR introduce a user-facing change?:

Add translation support for NGINX Ingress annotations  `from-to-www-redirect`.

@k8s-ci-robot k8s-ci-robot added the kind/feature Categorizes issue or PR as related to a new feature. label Feb 6, 2026
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: chakravardhan
Once this PR has been reviewed and has the lgtm label, please assign robscott for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Feb 6, 2026
@k8s-ci-robot
Copy link
Contributor

Hi @chakravardhan. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Feb 6, 2026
@Stevenjin8
Copy link
Contributor

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Feb 6, 2026
@Stevenjin8
Copy link
Contributor

@chakravardhan the from-www-redirect seems reasonable to me, but have you how it would work with #299? what happens if you have from-www-redirect and that the ones in #299? I'm hoping #299 merges soon. Otherwise, the implementation seems good at a quick glance.

As for force-ssl-redirect, I'm not sure if we want or event need this annotation. My understanding as follows:

  1. User configures Ingress resource to point to TLS certs
  2. Ingress NGINX creates a self signed cert for hosts that do not have a configured TLS cert
  3. For requests with a host without a configured cert, ingress nginx will not redirect HTTP to HTTPS unless force-ssl-redirect is explicitly enabled.

The problem is that gateway API doesn't have a "listen on 443 with a runtime-generate self-signed cert". That is, we might redirect to HTTPS, but not have an HTTPS listener at all! Haven't looked at the code too much, but LMK what you think.

@chakravardhan
Copy link
Contributor Author

@chakravardhan the from-www-redirect seems reasonable to me, but have you how it would work with #299? what happens if you have from-www-redirect and that the ones in #299? I'm hoping #299 merges soon. Otherwise, the implementation seems good at a quick glance.

As for force-ssl-redirect, I'm not sure if we want or event need this annotation. My understanding as follows:

  1. User configures Ingress resource to point to TLS certs
  2. Ingress NGINX creates a self signed cert for hosts that do not have a configured TLS cert
  3. For requests with a host without a configured cert, ingress nginx will not redirect HTTP to HTTPS unless force-ssl-redirect is explicitly enabled.

The problem is that gateway API doesn't have a "listen on 443 with a runtime-generate self-signed cert". That is, we might redirect to HTTPS, but not have an HTTPS listener at all! Haven't looked at the code too much, but LMK what you think.

Thanks for your reply! @Stevenjin8

Regarding force-ssl-redirect:

You are absolutely right. Gateway API doesn't have the concept of generating self-signed listener certificates on the fly like NGINX does. If we force a redirect to 443 without actual TLS secrets configured, most Gateway implementations (like GKE) will just reject the route or fail to open the listener, leading to a broken state.
I completely agree that we don't need this annotation translation since the architecture paradigms don't align. I will drop force-ssl-redirect from this PR.

Regarding from-to-www-redirect and #299 compatibility:

In our current implementation, we generate an entirely separate HTTPRoute dedicated to the www redirect (e.g., routeName-www-redirect).

Because #299 adds RequestRedirect filters to the existing route based on the permanent-redirect annotation, these two features should naturally avoid stepping on each other's toes—one modifies the primary route, and the other creates an additional standalone route specifically for the WWW redirect.

If there is an overlap where a user configures both from-to-www-redirect and a manual permanent-redirect that also points to www, the Gateway API should handle this cleanly: the underlying controller will simply use the most specific matching rule (or fallback to the oldest creation timestamp) to cleanly serve the redirect, rather than crashing or causing route conflicts. wdyt?

@chakravardhan chakravardhan changed the title feat(ingressnginx): add support for force-ssl-redirect and from-to-www-redirect feat: add support for from-to-www-redirect Feb 6, 2026
@Stevenjin8
Copy link
Contributor

@chakravardhan I don't think this is quite right. Do you mind writing an e2e/integration test just to verify that behavior is correct/taking a quick look at https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#redirect-fromto-www ?

For example, the annotation can redirect host.com to www.host.com and from www.host.com to host.com, depending on the initial configuration.

Also when I run it with

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: httpbin
                port:
                  number: 8000

I get

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  annotations:
    gateway.networking.k8s.io/generator: ingress2gateway-dev
  name: nginx
  namespace: default
spec:
  gatewayClassName: nginx
  listeners:
  - hostname: example.com
    name: example-com-http
    port: 80
    protocol: HTTP
status: {}
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  annotations:
    gateway.networking.k8s.io/generator: ingress2gateway-dev
  name: example-ingress-example-com
  namespace: default
spec:
  hostnames:
  - example.com
  parentRefs:
  - name: nginx
  rules:
  - backendRefs:
    - name: httpbin
      port: 8000
    matches:
    - path:
        type: PathPrefix
        value: /
    name: rule-0
status:
  parents: []
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  annotations:
    gateway.networking.k8s.io/generator: ingress2gateway-dev
  name: example-ingress-example-com-www-redirect
  namespace: default
spec:
  hostnames:
  - example.com
  parentRefs:
  - name: nginx
  rules:
  - filters:
    - requestRedirect:
        hostname: www.example.com
        statusCode: 308
      type: RequestRedirect
status:
  parents: null

We have two http routes with the same host name, the last httproute should be

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  annotations:
    gateway.networking.k8s.io/generator: ingress2gateway-dev
  name: example-ingress-example-com-www-redirect
  namespace: default
spec:
  hostnames:
-  - example.com
+  - www.example.com
  parentRefs:
  - name: nginx
  rules:
  - filters:
    - requestRedirect:
-        hostname: www.example.com
+        hostname: example.com
        statusCode: 308
      type: RequestRedirect
status:
  parents: null

Also, the gateway would need to be updated

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  annotations:
    gateway.networking.k8s.io/generator: ingress2gateway-dev
  name: nginx
  namespace: default
spec:
  gatewayClassName: nginx
  listeners:
  - hostname: example.com
    name: example-com-http
    port: 80
    protocol: HTTP
+ - hostname: www.example.com
+    name: www.example-com-http
+   port: 80
+   protocol: HTTP
status: {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants