Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add support for Port in ParentReference #3778

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
sarthyparty merged 8 commits into main from feature/port-parent-ref
Sep 2, 2025
Merged

Conversation

Copy link
Contributor

@sarthyparty sarthyparty commented Aug 21, 2025
edited
Loading

Proposed changes

Problem: ParentRefs didn't support Port
While adding this feature, I noticed that buildSectionRefs and findAttachableListeners had duplicated logic. I first tried to refactor findAttachableListeners, but that seemed to create much more complexities, so I decided to refactor buildSectionNameRefs and then solve the bug differently in policies. In policies I noticed a really small issue where we weren't looping through hostnames correctly so I fixed that and also added in the fix for the bug.

Solution: I added support for it and enabled conformance

Testing: Unit tests and conformance test

Please focus on (optional): If you any specific areas where you would like reviewers to focus their attention or provide
specific feedback, add them here.

Closes #2946

Checklist

Before creating a PR, run through this checklist and mark each as complete.

  • I have read the CONTRIBUTING doc
  • I have added tests that prove my fix is effective or that my feature works
  • I have checked that all unit tests pass after adding my changes
  • I have updated necessary documentation
  • I have rebased my branch onto main
  • I will ensure my PR is targeting the main branch and pulling from my branch from my own fork

Release notes

If this PR introduces a change that affects users and needs to be mentioned in the release notes,
please add a brief note that summarizes the change.

Copy link

codecov bot commented Aug 21, 2025
edited
Loading

Codecov Report

❌ Patch coverage is 94.11765% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.00%. Comparing base (918b9d4) to head (86b963b).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/controller/state/graph/route_common.go 93.75% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@
## main #3778 +/- ##
==========================================
- Coverage 87.02% 87.00% -0.02% 
==========================================
 Files 128 128 
 Lines 16412 16434 +22 
 Branches 62 62 
==========================================
+ Hits 14283 14299 +16 
- Misses 1954 1959 +5 
- Partials 175 176 +1 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Collaborator

@sjberman sjberman left a comment

Choose a reason for hiding this comment

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

Nice work! You'll also need to update our compatibility doc in the docs repo (merge to branch ngf-release-2.2) with these updates.

sarthyparty reacted with thumbs up emoji
@github-project-automation github-project-automation bot moved this from 🆕 New to 🏗 In Progress in NGINX Gateway Fabric Aug 22, 2025
Copy link
Contributor Author

@sjberman I chose to refactor the attachToListener side, which was weird because we're actually sorting the listeners downstream. I'm not sure the original intention of sorting, but I removed it now. This shouldn't make any functionality changes (besides the port addition)

Copy link
Collaborator

Usually when we are sorting something, it's for good reason :) but I'll take a look.

Copy link
Collaborator

As part of your recent changes, have you verified that the bug that was fixed as part of #3418 was not reintroduced? @bjee19 should probably take a closer look as well.

bjee19 and sarthyparty reacted with thumbs up emoji

Copy link
Contributor

Are we only attaching a single listener based on the port? Meaning, if a port is specified, we attach to the matching port. But if the port is not specified, then the existing rules still apply — such as using the winning hostname or attaching to multiple listeners.

I just want to confirm that listener isolation rules remain unchanged.

Copy link
Contributor Author

If a port is specified, the rules should be the same, with the additional port filtering added

Copy link
Contributor Author

I refactored the code and did fixed the bug from that issue. The reason why I refactored the code was because that the previous fix seemed to introduce bugs, so I had to do it differently, in policies

Copy link
Contributor

bjee19 commented Aug 25, 2025

I refactored the code and did fixed the bug from that issue. The reason why I refactored the code was because that the previous fix seemed to introduce bugs, so I had to do it differently, in policies

@sarthyparty Could you explain a little more about the refactoring that will be introduced in this pr? Also, could you explain some more on what bugs the previous fix seemed to have introduced? Usually that is included in the PR description or just a comment on the PR, and will help us if we ever need to trace back to this PR.

sarthyparty reacted with thumbs up emoji

Copy link
Contributor

If a port is specified, the rules should be the same, with the additional port filtering added

but what is preferred first?

Copy link
Contributor Author

While adding the Port parentRef feature, I noticed that buildSectionRefs and findAttachableListeners had duplicated logic. I first tried to refactor findAttachableListeners, but that seemed to create much more complexities, so I decided to refactor buildSectionNameRefs and then solve the bug differently in policies. In policies I noticed a really small issue where we weren't looping through hostnames correctly so I fixed that and also added in the fix for the bug.

salonichf5 reacted with thumbs up emoji

Copy link
Contributor Author

The complexities that seemed difficult to address were sorting the L4Route attachable listeners, which didn't happen when the sectionName was nil, and also the parentRef attachment status logic was going to have issues since the parentsRefs were split.

Copy link
Contributor Author

but what is preferred first?

Wdym by this? My main code change was just filtering the attachable listeners by port if port was specified. I don't mess with any of the rules.

Copy link
Contributor

but what is preferred first?

Wdym by this? My main code change was just filtering the attachable listeners by port if port was specified. I don't mess with any of the rules.

Not the rules, but hostnames. So for example if we have two listeners with same hostnames/wildcards and 2 routes also having 2 hostnames with both those hostnames

and port is also specified, we will select listeners based on port or hostname first?

For example

Gateway

 listeners:
 - name: wildcard-example-com
 port: 81
 protocol: HTTP
 hostname: "*.example.com"
 allowedRoutes:
 namespaces:
 from: All
 - name: wildcard-foo-example-com
 port: 81
 protocol: HTTP
 hostname: "*.foo.example.com"
 allowedRoutes:
 namespaces:
 from: All

2 HTTPRoutes

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
 name: route1
spec:
 parentRefs:
 - name: gateway
 sectionName: empty-hostname
 port: 81
 hostnames:
# both hostnames could match both the listener hostname
 - "*.foo.example.com" 
 - "abc.foo.example.com" 
 rules:
 - matches:
 - path:
 type: PathPrefix
 value: /empty-hostname
 backendRefs:
 - name: coffee
 port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
 name: route2
spec:
 parentRefs:
 - name: gateway
 sectionName: wildcard-example-com
 port: 82
 hostnames:
# both hostnames could match both the listener hostname
 - "*.foo.example.com" 
 - "abc.foo.example.com" 
 rules:
 - matches:
 - path:
 type: PathPrefix
 value: /wildcard-example-com
 backendRefs:
 - name: coffee
 port: 82

which listener would attach to which route?

do we prioritize port match or hostname match?

Copy link
Contributor

bjee19 commented Aug 27, 2025
edited
Loading

@sarthyparty after pulling your changes and testing the bug found in #3400. I believe that the bug was reintroduced, did you see anything different when you tested the changes yourself? See below :

kubectl describe observabilitypolicies.gateway.nginx.org -A
Name: coffee
Namespace: coffee
Labels: <none>
Annotations: <none>
API Version: gateway.nginx.org/v1alpha2
Kind: ObservabilityPolicy
Metadata:
 Creation Timestamp: 2025年08月27日T18:34:44Z
 Generation: 1
 Resource Version: 926
 UID: 277cf9e1-a5dd-436a-bc7c-c5b910595bdb
Spec:
 Target Refs:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: coffee
 Tracing:
 Ratio: 75
 Span Attributes:
 Key: coffee
 Value: coffee
 Strategy: ratio
Status:
 Ancestors:
 Ancestor Ref:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: coffee
 Namespace: coffee
 Conditions:
 Last Transition Time: 2025年08月27日T18:34:44Z
 Message: Policy cannot be applied to target "tea/tea" since another Route "tea/tea" shares a hostname:port/path combination with this target
 Observed Generation: 1
 Reason: TargetConflict
 Status: False
 Type: Accepted
 Controller Name: gateway.nginx.org/nginx-gateway-controller
Events: <none>
Name: tea
Namespace: tea
Labels: <none>
Annotations: <none>
API Version: gateway.nginx.org/v1alpha2
Kind: ObservabilityPolicy
Metadata:
 Creation Timestamp: 2025年08月27日T18:34:44Z
 Generation: 1
 Resource Version: 928
 UID: d8d42447-eac0-47a3-8f4f-6f7b04f0f116
Spec:
 Target Refs:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: tea
 Tracing:
 Ratio: 75
 Span Attributes:
 Key: tea
 Value: tea
 Strategy: ratio
Status:
 Ancestors:
 Ancestor Ref:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: tea
 Namespace: tea
 Conditions:
 Last Transition Time: 2025年08月27日T18:34:44Z
 Message: Policy cannot be applied to target "coffee/coffee" since another Route "coffee/coffee" shares a hostname:port/path combination with this target
 Observed Generation: 1
 Reason: TargetConflict
 Status: False
 Type: Accepted
 Controller Name: gateway.nginx.org/nginx-gateway-controller
Events: <none>

Here are the yaml files I used:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: coffee
 namespace: coffee
spec:
 replicas: 1
 selector:
 matchLabels:
 app: coffee
 template:
 metadata:
 labels:
 app: coffee
 spec:
 containers:
 - name: coffee
 image: nginxdemos/nginx-hello:plain-text
 ports:
 - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
 name: coffee
 namespace: coffee
spec:
 ports:
 - port: 80
 targetPort: 8080
 protocol: TCP
 name: http
 selector:
 app: coffee
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: tea
 namespace: tea
spec:
 replicas: 1
 selector:
 matchLabels:
 app: tea
 template:
 metadata:
 labels:
 app: tea
 spec:
 containers:
 - name: tea
 image: nginxdemos/nginx-hello:plain-text
 ports:
 - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
 name: tea
 namespace: tea
spec:
 ports:
 - port: 80
 targetPort: 8080
 protocol: TCP
 name: http
 selector:
 app: tea
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
 name: coffee
 namespace: coffee
spec:
 parentRefs:
 - name: gateway
 namespace: nginx-gateway
 hostnames:
 - "coffee.example.com"
 rules:
 - matches:
 - path:
 type: PathPrefix
 value: /coffee
 backendRefs:
 - name: coffee
 port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
 name: tea
 namespace: tea
spec:
 parentRefs:
 - name: gateway
 namespace: nginx-gateway
 hostnames:
 - "tea.example.com"
 rules:
 - matches:
 - path:
 type: Exact
 value: /tea
 backendRefs:
 - name: tea
 port: 80
apiVersion: v1
kind: Namespace
metadata:
 name: certificate
---
apiVersion: v1
kind: Secret
metadata:
 name: cafe-secret
 namespace: certificate
type: kubernetes.io/tls
data:
 tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNzakNDQVpvQ0NRQzdCdVdXdWRtRkNEQU5CZ2txaGtpRzl3MEJBUXNGQURBYk1Sa3dGd1lEVlFRRERCQmoKWVdabExtVjRZVzF3YkdVdVkyOXRNQjRYRFRJeU1EY3hOREl4TlRJek9Wb1hEVEl6TURjeE5ESXhOVEl6T1ZvdwpHekVaTUJjR0ExVUVBd3dRWTJGbVpTNWxlR0Z0Y0d4bExtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTHFZMnRHNFc5aStFYzJhdnV4Q2prb2tnUUx1ek10U1Rnc1RNaEhuK3ZRUmxIam8KVzFLRnMvQVdlS25UUStyTWVKVWNseis4M3QwRGtyRThwUisxR2NKSE50WlNMb0NEYUlRN0Nhck5nY1daS0o4Qgo1WDNnVS9YeVJHZjI2c1REd2xzU3NkSEQ1U2U3K2Vab3NPcTdHTVF3K25HR2NVZ0VtL1Q1UEMvY05PWE0zZWxGClRPL051MStoMzROVG9BbDNQdTF2QlpMcDNQVERtQ0thaEROV0NWbUJQUWpNNFI4VERsbFhhMHQ5Z1o1MTRSRzUKWHlZWTNtdzZpUzIrR1dYVXllMjFuWVV4UEhZbDV4RHY0c0FXaGRXbElweHlZQlNCRURjczN6QlI2bFF1OWkxZAp0R1k4dGJ3blVmcUVUR3NZdWxzc05qcU95V1VEcFdJelhibHhJZVVDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGCkFBT0NBUUVBcjkrZWJ0U1dzSnhLTGtLZlRkek1ISFhOd2Y5ZXFVbHNtTXZmMGdBdWVKTUpUR215dG1iWjlpbXQKL2RnWlpYVE9hTElHUG9oZ3BpS0l5eVVRZVdGQ2F0NHRxWkNPVWRhbUloOGk0Q1h6QVJYVHNvcUNOenNNLzZMRQphM25XbFZyS2lmZHYrWkxyRi8vblc0VVNvOEoxaCtQeDljY0tpRDZZU0RVUERDRGh1RUtFWXcvbHpoUDJVOXNmCnl6cEJKVGQ4enFyM3paTjNGWWlITmgzYlRhQS82di9jU2lyamNTK1EwQXg4RWpzQzYxRjRVMTc4QzdWNWRCKzQKcmtPTy9QNlA0UFlWNTRZZHMvRjE2WkZJTHFBNENCYnExRExuYWRxamxyN3NPbzl2ZzNnWFNMYXBVVkdtZ2todAp6VlZPWG1mU0Z4OS90MDBHUi95bUdPbERJbWlXMGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
 tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzZtTnJSdUZ2WXZoSE4KbXI3c1FvNUtKSUVDN3N6TFVrNExFeklSNS9yMEVaUjQ2RnRTaGJQd0ZuaXAwMFBxekhpVkhKYy92TjdkQTVLeApQS1VmdFJuQ1J6YldVaTZBZzJpRU93bXF6WUhGbVNpZkFlVjk0RlAxOGtSbjl1ckV3OEpiRXJIUncrVW51L25tCmFMRHF1eGpFTVBweGhuRklCSnYwK1R3djNEVGx6TjNwUlV6dnpidGZvZCtEVTZBSmR6N3Rid1dTNmR6MHc1Z2kKbW9RelZnbFpnVDBJek9FZkV3NVpWMnRMZllHZWRlRVJ1VjhtR041c09va3R2aGxsMU1udHRaMkZNVHgySmVjUQo3K0xBRm9YVnBTS2NjbUFVZ1JBM0xOOHdVZXBVTHZZdFhiUm1QTFc4SjFINmhFeHJHTHBiTERZNmpzbGxBNlZpCk0xMjVjU0hsQWdNQkFBRUNnZ0VBQnpaRE50bmVTdWxGdk9HZlFYaHRFWGFKdWZoSzJBenRVVVpEcUNlRUxvekQKWlV6dHdxbkNRNlJLczUyandWNTN4cU9kUU94bTNMbjNvSHdNa2NZcEliWW82MjJ2dUczYnkwaVEzaFlsVHVMVgpqQmZCcS9UUXFlL2NMdngvSkczQWhFNmJxdFRjZFlXeGFmTmY2eUtpR1dzZk11WVVXTWs4MGVJVUxuRmZaZ1pOCklYNTlSOHlqdE9CVm9Sa3hjYTVoMW1ZTDFsSlJNM3ZqVHNHTHFybmpOTjNBdWZ3ZGRpK1VDbGZVL2l0K1EvZkUKV216aFFoTlRpNVFkRWJLVStOTnYvNnYvb2JvandNb25HVVBCdEFTUE05cmxFemIralQ1WHdWQjgvLzRGY3VoSwoyVzNpcjhtNHVlQ1JHSVlrbGxlLzhuQmZ0eVhiVkNocVRyZFBlaGlPM1FLQmdRRGlrR3JTOTc3cjg3Y1JPOCtQClpoeXltNXo4NVIzTHVVbFNTazJiOTI1QlhvakpZL2RRZDVTdFVsSWE4OUZKZnNWc1JRcEhHaTFCYzBMaTY1YjIKazR0cE5xcVFoUmZ1UVh0UG9GYXRuQzlPRnJVTXJXbDVJN0ZFejZnNkNQMVBXMEg5d2hPemFKZUdpZVpNYjlYTQoybDdSSFZOcC9jTDlYbmhNMnN0Q1lua2Iwd0tCZ1FEUzF4K0crakEyUVNtRVFWNXA1RnRONGcyamsyZEFjMEhNClRIQ2tTazFDRjhkR0Z2UWtsWm5ZbUt0dXFYeXNtekJGcnZKdmt2eUhqbUNYYTducXlpajBEdDZtODViN3BGcVAKQWxtajdtbXI3Z1pUeG1ZMXBhRWFLMXY4SDNINGtRNVl3MWdrTWRybVJHcVAvaTBGaDVpaGtSZS9DOUtGTFVkSQpDcnJjTzhkUVp3S0JnSHA1MzRXVWNCMVZibzFlYStIMUxXWlFRUmxsTWlwRFM2TzBqeWZWSmtFb1BZSEJESnp2ClIrdzZLREJ4eFoyWmJsZ05LblV0YlhHSVFZd3lGelhNcFB5SGxNVHpiZkJhYmJLcDFyR2JVT2RCMXpXM09PRkgKcmppb21TUm1YNmxhaDk0SjRHU0lFZ0drNGw1SHhxZ3JGRDZ2UDd4NGRjUktJWFpLZ0w2dVJSSUpBb0dCQU1CVApaL2p5WStRNTBLdEtEZHUrYU9ORW4zaGxUN3hrNXRKN3NBek5rbWdGMU10RXlQUk9Xd1pQVGFJbWpRbk9qbHdpCldCZ2JGcXg0M2ZlQ1Z4ZXJ6V3ZEM0txaWJVbWpCTkNMTGtYeGh3ZEVteFQwVit2NzZGYzgwaTNNYVdSNnZZR08KditwVVovL0F6UXdJcWZ6dlVmV2ZxdStrMHlhVXhQOGNlcFBIRyt0bEFvR0FmQUtVVWhqeFU0Ym5vVzVwVUhKegpwWWZXZXZ5TW54NWZyT2VsSmRmNzlvNGMvMHhVSjh1eFBFWDFkRmNrZW96dHNpaVFTNkN6MENRY09XVWxtSkRwCnVrdERvVzM3VmNSQU1BVjY3NlgxQVZlM0UwNm5aL2g2Tkd4Z28rT042Q3pwL0lkMkJPUm9IMFAxa2RjY1NLT3kKMUtFZlNnb1B0c1N1eEpBZXdUZmxDMXc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
 name: gateway
 namespace: nginx-gateway
spec:
 gatewayClassName: nginx
 listeners:
 - name: http
 allowedRoutes: 
 namespaces:
 from: All
 port: 80
 protocol: HTTP
 hostname: "*.example.com"
 - name: https
 allowedRoutes: 
 namespaces:
 from: All
 port: 443
 protocol: HTTPS
 hostname: "*.example.com"
 tls:
 mode: Terminate
 certificateRefs:
 - kind: Secret
 name: cafe-secret
 namespace: certificate
apiVersion: gateway.nginx.org/v1alpha2
kind: ObservabilityPolicy
metadata:
 name: coffee
 namespace: coffee
spec:
 targetRefs:
 - group: gateway.networking.k8s.io
 kind: HTTPRoute
 name: coffee
 tracing:
 strategy: ratio
 ratio: 75
 spanAttributes:
 - key: coffee
 value: coffee
---
apiVersion: gateway.nginx.org/v1alpha2
kind: ObservabilityPolicy
metadata:
 name: tea
 namespace: tea
spec:
 targetRefs:
 - group: gateway.networking.k8s.io
 kind: HTTPRoute
 name: tea
 tracing:
 strategy: ratio
 ratio: 75
 spanAttributes:
 - key: tea
 value: tea
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
 name: access-to-cafe-secret
 namespace: certificate
spec:
 to:
 - group: ""
 kind: Secret
 name: cafe-secret # if you omit this name, then Gateways in default ns can access all Secrets in the certificate ns
 from:
 - group: gateway.networking.k8s.io
 kind: Gateway
 namespace: default

Copy link
Contributor Author

@bjee19 I must've messed up my testing then, I will figure this out

Copy link
Contributor

@sarthyparty after pulling your changes and testing the bug found in #3400. I believe that the bug was reintroduced, did you see anything different when you tested the changes yourself? See below :

kubectl describe observabilitypolicies.gateway.nginx.org -A
Name: coffee
Namespace: coffee
Labels: <none>
Annotations: <none>
API Version: gateway.nginx.org/v1alpha2
Kind: ObservabilityPolicy
Metadata:
 Creation Timestamp: 2025年08月27日T18:34:44Z
 Generation: 1
 Resource Version: 926
 UID: 277cf9e1-a5dd-436a-bc7c-c5b910595bdb
Spec:
 Target Refs:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: coffee
 Tracing:
 Ratio: 75
 Span Attributes:
 Key: coffee
 Value: coffee
 Strategy: ratio
Status:
 Ancestors:
 Ancestor Ref:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: coffee
 Namespace: coffee
 Conditions:
 Last Transition Time: 2025年08月27日T18:34:44Z
 Message: Policy cannot be applied to target "tea/tea" since another Route "tea/tea" shares a hostname:port/path combination with this target
 Observed Generation: 1
 Reason: TargetConflict
 Status: False
 Type: Accepted
 Controller Name: gateway.nginx.org/nginx-gateway-controller
Events: <none>
Name: tea
Namespace: tea
Labels: <none>
Annotations: <none>
API Version: gateway.nginx.org/v1alpha2
Kind: ObservabilityPolicy
Metadata:
 Creation Timestamp: 2025年08月27日T18:34:44Z
 Generation: 1
 Resource Version: 928
 UID: d8d42447-eac0-47a3-8f4f-6f7b04f0f116
Spec:
 Target Refs:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: tea
 Tracing:
 Ratio: 75
 Span Attributes:
 Key: tea
 Value: tea
 Strategy: ratio
Status:
 Ancestors:
 Ancestor Ref:
 Group: gateway.networking.k8s.io
 Kind: HTTPRoute
 Name: tea
 Namespace: tea
 Conditions:
 Last Transition Time: 2025年08月27日T18:34:44Z
 Message: Policy cannot be applied to target "coffee/coffee" since another Route "coffee/coffee" shares a hostname:port/path combination with this target
 Observed Generation: 1
 Reason: TargetConflict
 Status: False
 Type: Accepted
 Controller Name: gateway.nginx.org/nginx-gateway-controller
Events: <none>

Here are the yaml files I used:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: coffee
 namespace: coffee
spec:
 replicas: 1
 selector:
 matchLabels:
 app: coffee
 template:
 metadata:
 labels:
 app: coffee
 spec:
 containers:
 - name: coffee
 image: nginxdemos/nginx-hello:plain-text
 ports:
 - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
 name: coffee
 namespace: coffee
spec:
 ports:
 - port: 80
 targetPort: 8080
 protocol: TCP
 name: http
 selector:
 app: coffee
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: tea
 namespace: tea
spec:
 replicas: 1
 selector:
 matchLabels:
 app: tea
 template:
 metadata:
 labels:
 app: tea
 spec:
 containers:
 - name: tea
 image: nginxdemos/nginx-hello:plain-text
 ports:
 - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
 name: tea
 namespace: tea
spec:
 ports:
 - port: 80
 targetPort: 8080
 protocol: TCP
 name: http
 selector:
 app: tea
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
 name: coffee
 namespace: coffee
spec:
 parentRefs:
 - name: gateway
 namespace: nginx-gateway
 hostnames:
 - "coffee.example.com"
 rules:
 - matches:
 - path:
 type: PathPrefix
 value: /coffee
 backendRefs:
 - name: coffee
 port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
 name: tea
 namespace: tea
spec:
 parentRefs:
 - name: gateway
 namespace: nginx-gateway
 hostnames:
 - "tea.example.com"
 rules:
 - matches:
 - path:
 type: Exact
 value: /tea
 backendRefs:
 - name: tea
 port: 80
apiVersion: v1
kind: Namespace
metadata:
 name: certificate
---
apiVersion: v1
kind: Secret
metadata:
 name: cafe-secret
 namespace: certificate
type: kubernetes.io/tls
data:
 tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNzakNDQVpvQ0NRQzdCdVdXdWRtRkNEQU5CZ2txaGtpRzl3MEJBUXNGQURBYk1Sa3dGd1lEVlFRRERCQmoKWVdabExtVjRZVzF3YkdVdVkyOXRNQjRYRFRJeU1EY3hOREl4TlRJek9Wb1hEVEl6TURjeE5ESXhOVEl6T1ZvdwpHekVaTUJjR0ExVUVBd3dRWTJGbVpTNWxlR0Z0Y0d4bExtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBTHFZMnRHNFc5aStFYzJhdnV4Q2prb2tnUUx1ek10U1Rnc1RNaEhuK3ZRUmxIam8KVzFLRnMvQVdlS25UUStyTWVKVWNseis4M3QwRGtyRThwUisxR2NKSE50WlNMb0NEYUlRN0Nhck5nY1daS0o4Qgo1WDNnVS9YeVJHZjI2c1REd2xzU3NkSEQ1U2U3K2Vab3NPcTdHTVF3K25HR2NVZ0VtL1Q1UEMvY05PWE0zZWxGClRPL051MStoMzROVG9BbDNQdTF2QlpMcDNQVERtQ0thaEROV0NWbUJQUWpNNFI4VERsbFhhMHQ5Z1o1MTRSRzUKWHlZWTNtdzZpUzIrR1dYVXllMjFuWVV4UEhZbDV4RHY0c0FXaGRXbElweHlZQlNCRURjczN6QlI2bFF1OWkxZAp0R1k4dGJ3blVmcUVUR3NZdWxzc05qcU95V1VEcFdJelhibHhJZVVDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGCkFBT0NBUUVBcjkrZWJ0U1dzSnhLTGtLZlRkek1ISFhOd2Y5ZXFVbHNtTXZmMGdBdWVKTUpUR215dG1iWjlpbXQKL2RnWlpYVE9hTElHUG9oZ3BpS0l5eVVRZVdGQ2F0NHRxWkNPVWRhbUloOGk0Q1h6QVJYVHNvcUNOenNNLzZMRQphM25XbFZyS2lmZHYrWkxyRi8vblc0VVNvOEoxaCtQeDljY0tpRDZZU0RVUERDRGh1RUtFWXcvbHpoUDJVOXNmCnl6cEJKVGQ4enFyM3paTjNGWWlITmgzYlRhQS82di9jU2lyamNTK1EwQXg4RWpzQzYxRjRVMTc4QzdWNWRCKzQKcmtPTy9QNlA0UFlWNTRZZHMvRjE2WkZJTHFBNENCYnExRExuYWRxamxyN3NPbzl2ZzNnWFNMYXBVVkdtZ2todAp6VlZPWG1mU0Z4OS90MDBHUi95bUdPbERJbWlXMGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
 tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzZtTnJSdUZ2WXZoSE4KbXI3c1FvNUtKSUVDN3N6TFVrNExFeklSNS9yMEVaUjQ2RnRTaGJQd0ZuaXAwMFBxekhpVkhKYy92TjdkQTVLeApQS1VmdFJuQ1J6YldVaTZBZzJpRU93bXF6WUhGbVNpZkFlVjk0RlAxOGtSbjl1ckV3OEpiRXJIUncrVW51L25tCmFMRHF1eGpFTVBweGhuRklCSnYwK1R3djNEVGx6TjNwUlV6dnpidGZvZCtEVTZBSmR6N3Rid1dTNmR6MHc1Z2kKbW9RelZnbFpnVDBJek9FZkV3NVpWMnRMZllHZWRlRVJ1VjhtR041c09va3R2aGxsMU1udHRaMkZNVHgySmVjUQo3K0xBRm9YVnBTS2NjbUFVZ1JBM0xOOHdVZXBVTHZZdFhiUm1QTFc4SjFINmhFeHJHTHBiTERZNmpzbGxBNlZpCk0xMjVjU0hsQWdNQkFBRUNnZ0VBQnpaRE50bmVTdWxGdk9HZlFYaHRFWGFKdWZoSzJBenRVVVpEcUNlRUxvekQKWlV6dHdxbkNRNlJLczUyandWNTN4cU9kUU94bTNMbjNvSHdNa2NZcEliWW82MjJ2dUczYnkwaVEzaFlsVHVMVgpqQmZCcS9UUXFlL2NMdngvSkczQWhFNmJxdFRjZFlXeGFmTmY2eUtpR1dzZk11WVVXTWs4MGVJVUxuRmZaZ1pOCklYNTlSOHlqdE9CVm9Sa3hjYTVoMW1ZTDFsSlJNM3ZqVHNHTHFybmpOTjNBdWZ3ZGRpK1VDbGZVL2l0K1EvZkUKV216aFFoTlRpNVFkRWJLVStOTnYvNnYvb2JvandNb25HVVBCdEFTUE05cmxFemIralQ1WHdWQjgvLzRGY3VoSwoyVzNpcjhtNHVlQ1JHSVlrbGxlLzhuQmZ0eVhiVkNocVRyZFBlaGlPM1FLQmdRRGlrR3JTOTc3cjg3Y1JPOCtQClpoeXltNXo4NVIzTHVVbFNTazJiOTI1QlhvakpZL2RRZDVTdFVsSWE4OUZKZnNWc1JRcEhHaTFCYzBMaTY1YjIKazR0cE5xcVFoUmZ1UVh0UG9GYXRuQzlPRnJVTXJXbDVJN0ZFejZnNkNQMVBXMEg5d2hPemFKZUdpZVpNYjlYTQoybDdSSFZOcC9jTDlYbmhNMnN0Q1lua2Iwd0tCZ1FEUzF4K0crakEyUVNtRVFWNXA1RnRONGcyamsyZEFjMEhNClRIQ2tTazFDRjhkR0Z2UWtsWm5ZbUt0dXFYeXNtekJGcnZKdmt2eUhqbUNYYTducXlpajBEdDZtODViN3BGcVAKQWxtajdtbXI3Z1pUeG1ZMXBhRWFLMXY4SDNINGtRNVl3MWdrTWRybVJHcVAvaTBGaDVpaGtSZS9DOUtGTFVkSQpDcnJjTzhkUVp3S0JnSHA1MzRXVWNCMVZibzFlYStIMUxXWlFRUmxsTWlwRFM2TzBqeWZWSmtFb1BZSEJESnp2ClIrdzZLREJ4eFoyWmJsZ05LblV0YlhHSVFZd3lGelhNcFB5SGxNVHpiZkJhYmJLcDFyR2JVT2RCMXpXM09PRkgKcmppb21TUm1YNmxhaDk0SjRHU0lFZ0drNGw1SHhxZ3JGRDZ2UDd4NGRjUktJWFpLZ0w2dVJSSUpBb0dCQU1CVApaL2p5WStRNTBLdEtEZHUrYU9ORW4zaGxUN3hrNXRKN3NBek5rbWdGMU10RXlQUk9Xd1pQVGFJbWpRbk9qbHdpCldCZ2JGcXg0M2ZlQ1Z4ZXJ6V3ZEM0txaWJVbWpCTkNMTGtYeGh3ZEVteFQwVit2NzZGYzgwaTNNYVdSNnZZR08KditwVVovL0F6UXdJcWZ6dlVmV2ZxdStrMHlhVXhQOGNlcFBIRyt0bEFvR0FmQUtVVWhqeFU0Ym5vVzVwVUhKegpwWWZXZXZ5TW54NWZyT2VsSmRmNzlvNGMvMHhVSjh1eFBFWDFkRmNrZW96dHNpaVFTNkN6MENRY09XVWxtSkRwCnVrdERvVzM3VmNSQU1BVjY3NlgxQVZlM0UwNm5aL2g2Tkd4Z28rT042Q3pwL0lkMkJPUm9IMFAxa2RjY1NLT3kKMUtFZlNnb1B0c1N1eEpBZXdUZmxDMXc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
 name: gateway
 namespace: nginx-gateway
spec:
 gatewayClassName: nginx
 listeners:
 - name: http
 allowedRoutes: 
 namespaces:
 from: All
 port: 80
 protocol: HTTP
 hostname: "*.example.com"
 - name: https
 allowedRoutes: 
 namespaces:
 from: All
 port: 443
 protocol: HTTPS
 hostname: "*.example.com"
 tls:
 mode: Terminate
 certificateRefs:
 - kind: Secret
 name: cafe-secret
 namespace: certificate
apiVersion: gateway.nginx.org/v1alpha2
kind: ObservabilityPolicy
metadata:
 name: coffee
 namespace: coffee
spec:
 targetRefs:
 - group: gateway.networking.k8s.io
 kind: HTTPRoute
 name: coffee
 tracing:
 strategy: ratio
 ratio: 75
 spanAttributes:
 - key: coffee
 value: coffee
---
apiVersion: gateway.nginx.org/v1alpha2
kind: ObservabilityPolicy
metadata:
 name: tea
 namespace: tea
spec:
 targetRefs:
 - group: gateway.networking.k8s.io
 kind: HTTPRoute
 name: tea
 tracing:
 strategy: ratio
 ratio: 75
 spanAttributes:
 - key: tea
 value: tea
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
 name: access-to-cafe-secret
 namespace: certificate
spec:
 to:
 - group: ""
 kind: Secret
 name: cafe-secret # if you omit this name, then Gateways in default ns can access all Secrets in the certificate ns
 from:
 - group: gateway.networking.k8s.io
 kind: Gateway
 namespace: default

do we have an existing unit tests for this ? @bjee19

Copy link
Contributor

bjee19 commented Aug 27, 2025
edited
Loading

@salonichf5 the unit tests were for an underlying logic flaw in our code and they were added in #3418. Nothing is testing specifically for this case (i believe the unit tests in #3418 are sufficient). But those unit tests were removed and refactored in this PR.

salonichf5 reacted with thumbs up emoji

Copy link
Contributor

@salonichf5 the unit tests were for an underlying logic flaw in our code and they were added in #3418. Nothing is testing specifically for this case (i believe the unit tests in #3418 are sufficient). But those unit tests were removed and refactored in this PR.

nice, thanks for testing this in that case.

Copy link
Contributor Author

@bjee19 @salonichf5 @sjberman I've abandoned the refactor and made issues and fixmes in the code. I'll try to resolve them this and next week, but it was getting too difficult and large for this PR, so it'll be a different PR.

salonichf5 reacted with thumbs up emoji

Copy link
Contributor

bjee19 commented Sep 2, 2025

@sarthyparty with your revert of the changes, have you manually verified the revert fixed the re-introduction of the bug?

Copy link
Contributor Author

@bjee19 I just verified again with your config and it does not re introduce that issue

bjee19 reacted with thumbs up emoji

Copy link
Contributor

@bjee19 bjee19 left a comment
edited
Loading

Choose a reason for hiding this comment

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

lgtm, though i have some nits remaining. I also double verified the bug was not re-introduced. nice job!

@sarthyparty sarthyparty merged commit 86841e2 into main Sep 2, 2025
65 of 66 checks passed
@sarthyparty sarthyparty deleted the feature/port-parent-ref branch September 2, 2025 22:32
@github-project-automation github-project-automation bot moved this from 🏗 In Progress to ✅ Done in NGINX Gateway Fabric Sep 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@sjberman sjberman sjberman approved these changes

@bjee19 bjee19 bjee19 approved these changes

Assignees
No one assigned
Labels
enhancement New feature or request tests Pull requests that update tests
Projects
Status: Done
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Support for Port ParentReference

AltStyle によって変換されたページ (->オリジナル) /