fix: honor BackendTrafficPolicy targetRefs.sectionName for Service ports#428
fix: honor BackendTrafficPolicy targetRefs.sectionName for Service ports#428AlinsRan wants to merge 1 commit into
Conversation
AttachBackendTrafficPolicyToUpstream only matched targetRef.Name and ignored sectionName, so a policy scoped to one named Service port was applied to the whole Service. Now when a targetRef sets sectionName, the policy attaches only to the backend whose Service port name matches it; a port-specific targetRef takes precedence over a whole-Service one. Per Gateway API semantics, a sectionName that cannot be resolved does not attach. Closes #421
📝 WalkthroughWalkthrough
ChangesBackendTrafficPolicy sectionName-aware attachment
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/adc/translator/policies.go`:
- Around line 54-60: The policy matching logic in the loop iterating through
po.Spec.TargetRefs only validates the Name field of the targetRef against
ref.Name, which allows policies for different resource kinds (e.g.,
ServiceImport) to incorrectly attach to resources with the same name but
different kinds (e.g., Service). Add validation to also check that the
targetRef's group and kind match the corresponding fields of ref before
proceeding with the name comparison and the subsequent
backendRefMatchesSectionName check. This ensures policies are scoped to the
correct resource type and prevents cross-kind attachment when names collide.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1a7756f5-9f28-46b9-b2fa-ae57f0937e7d
📒 Files selected for processing (8)
internal/adc/translator/grpcroute.gointernal/adc/translator/httproute.gointernal/adc/translator/httproute_test.gointernal/adc/translator/ingress.gointernal/adc/translator/policies.gointernal/adc/translator/tcproute.gointernal/adc/translator/tlsroute.gointernal/adc/translator/udproute.go
| for _, targetRef := range po.Spec.TargetRefs { | ||
| if ref.Name == targetRef.Name { | ||
| policy = po | ||
| break | ||
| if ref.Name != targetRef.Name { | ||
| continue | ||
| } | ||
| if targetRef.SectionName != nil && *targetRef.SectionName != "" { | ||
| if backendRefMatchesSectionName(ref, po.Namespace, string(*targetRef.SectionName), services) { | ||
| specificPolicy = po |
There was a problem hiding this comment.
Validate targetRef group/kind before attaching by name.
At Line 55, matching only by Name allows cross-kind attachment when backend names collide (e.g., a ServiceImport policy attaching to a Service backend). This breaks attachment scoping and can apply the wrong policy.
💡 Suggested fix
import (
"encoding/json"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
adctypes "github.com/apache/apisix-ingress-controller/api/adc"
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
+ internaltypes "github.com/apache/apisix-ingress-controller/internal/types"
)
@@
func (t *Translator) AttachBackendTrafficPolicyToUpstream(ref gatewayv1.BackendRef, policies map[types.NamespacedName]*v1alpha1.BackendTrafficPolicy, upstream *adctypes.Upstream, services map[types.NamespacedName]*corev1.Service) {
@@
+ refKind := internaltypes.KindService
+ if ref.Kind != nil {
+ refKind = string(*ref.Kind)
+ }
+ refGroup := ""
+ if ref.Group != nil {
+ refGroup = string(*ref.Group)
+ }
for _, po := range policies {
@@
for _, targetRef := range po.Spec.TargetRefs {
- if ref.Name != targetRef.Name {
+ if string(ref.Name) != string(targetRef.Name) {
+ continue
+ }
+ if targetRef.Kind != "" && string(targetRef.Kind) != refKind {
+ continue
+ }
+ if targetRef.Group != "" && string(targetRef.Group) != refGroup {
continue
}As per coding guidelines, "Resource access must be scoped to the correct parent entity; validate that child resources (subscription, upstream, route, credential) belong to the requested parent before access or modification."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/adc/translator/policies.go` around lines 54 - 60, The policy
matching logic in the loop iterating through po.Spec.TargetRefs only validates
the Name field of the targetRef against ref.Name, which allows policies for
different resource kinds (e.g., ServiceImport) to incorrectly attach to
resources with the same name but different kinds (e.g., Service). Add validation
to also check that the targetRef's group and kind match the corresponding fields
of ref before proceeding with the name comparison and the subsequent
backendRefMatchesSectionName check. This ensures policies are scoped to the
correct resource type and prevents cross-kind attachment when names collide.
Source: Coding guidelines
conformance test report - apisix modeapiVersion: gateway.networking.k8s.io/v1
date: "2026-06-18T01:16:03Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
contact: null
organization: APISIX
project: apisix-ingress-controller
url: https://github.com/apache/apisix-ingress-controller.git
version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
result: success
statistics:
Failed: 0
Passed: 12
Skipped: 0
name: GATEWAY-GRPC
summary: Core tests succeeded.
- core:
failedTests:
- HTTPRouteInvalidBackendRefUnknownKind
result: failure
skippedTests:
- HTTPRouteHTTPSListener
statistics:
Failed: 1
Passed: 31
Skipped: 1
extended:
result: partial
skippedTests:
- HTTPRouteRedirectPortAndScheme
statistics:
Failed: 0
Passed: 11
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- HTTPRouteBackendProtocolWebSocket
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
unsupportedFeatures:
- GatewayHTTPListenerIsolation
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- HTTPRouteBackendProtocolH2C
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteBackendTimeout
- HTTPRouteParentRefPort
- HTTPRoutePathRedirect
- HTTPRouteRequestMultipleMirrors
- HTTPRouteRequestPercentageMirror
- HTTPRouteRequestTimeout
name: GATEWAY-HTTP
summary: Core tests failed with 1 test failures. Extended tests partially succeeded
with 1 test skips.
- core:
result: partial
skippedTests:
- TLSRouteSimpleSameNamespace
statistics:
Failed: 0
Passed: 10
Skipped: 1
name: GATEWAY-TLS
summary: Core tests partially succeeded with 1 test skips. |
conformance test report - apisix-standalone modeapiVersion: gateway.networking.k8s.io/v1
date: "2026-06-18T01:16:16Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
contact: null
organization: APISIX
project: apisix-ingress-controller
url: https://github.com/apache/apisix-ingress-controller.git
version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
result: success
statistics:
Failed: 0
Passed: 12
Skipped: 0
name: GATEWAY-GRPC
summary: Core tests succeeded.
- core:
result: partial
skippedTests:
- HTTPRouteHTTPSListener
statistics:
Failed: 0
Passed: 32
Skipped: 1
extended:
failedTests:
- HTTPRouteRequestMirror
result: failure
skippedTests:
- HTTPRouteRedirectPortAndScheme
statistics:
Failed: 1
Passed: 10
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- HTTPRouteBackendProtocolWebSocket
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
unsupportedFeatures:
- GatewayHTTPListenerIsolation
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- HTTPRouteBackendProtocolH2C
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteBackendTimeout
- HTTPRouteParentRefPort
- HTTPRoutePathRedirect
- HTTPRouteRequestMultipleMirrors
- HTTPRouteRequestPercentageMirror
- HTTPRouteRequestTimeout
name: GATEWAY-HTTP
summary: Core tests partially succeeded with 1 test skips. Extended tests failed
with 1 test failures.
- core:
result: partial
skippedTests:
- TLSRouteSimpleSameNamespace
statistics:
Failed: 0
Passed: 10
Skipped: 1
name: GATEWAY-TLS
summary: Core tests partially succeeded with 1 test skips. |
conformance test reportapiVersion: gateway.networking.k8s.io/v1
date: "2026-06-18T01:32:33Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
contact: null
organization: APISIX
project: apisix-ingress-controller
url: https://github.com/apache/apisix-ingress-controller.git
version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
failedTests:
- GatewayModifyListeners
result: failure
statistics:
Failed: 1
Passed: 11
Skipped: 0
name: GATEWAY-GRPC
summary: Core tests failed with 1 test failures.
- core:
failedTests:
- GatewayModifyListeners
result: failure
skippedTests:
- HTTPRouteHTTPSListener
statistics:
Failed: 1
Passed: 31
Skipped: 1
extended:
result: partial
skippedTests:
- HTTPRouteRedirectPortAndScheme
statistics:
Failed: 0
Passed: 11
Skipped: 1
supportedFeatures:
- GatewayAddressEmpty
- GatewayPort8080
- HTTPRouteBackendProtocolWebSocket
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
unsupportedFeatures:
- GatewayHTTPListenerIsolation
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- HTTPRouteBackendProtocolH2C
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteBackendTimeout
- HTTPRouteParentRefPort
- HTTPRoutePathRedirect
- HTTPRouteRequestMultipleMirrors
- HTTPRouteRequestPercentageMirror
- HTTPRouteRequestTimeout
name: GATEWAY-HTTP
summary: Core tests failed with 1 test failures. Extended tests partially succeeded
with 1 test skips.
- core:
failedTests:
- GatewayModifyListeners
- TLSRouteSimpleSameNamespace
result: failure
statistics:
Failed: 2
Passed: 9
Skipped: 0
name: GATEWAY-TLS
summary: Core tests failed with 2 test failures. |
What this does
Fixes #421.
AttachBackendTrafficPolicyToUpstreamselected the policy to apply by matching onlytargetRef.Nameand ignoredtargetRef.sectionName. As a result aBackendTrafficPolicyintended for a single named Service port was treated as if it applied to the entire Service.For a
Servicetarget, the Gateway API interpretssectionNameas the port name (see the generated API reference). This PR makes attachment honor it:targetRefwithoutsectionNamestill applies to the whole Service (unchanged behavior).targetRefwithsectionNameattaches only to the backend whose resolved Service port name matches it.targetReftakes precedence over a whole-ServicetargetRefthat matches the same backend.sectionNamethat cannot be resolved does not attach.To resolve a backend's port name, the function now also receives
tctx.Servicesand maps the backend ref port number to the Service port name. All call sites (httproute / grpcroute / ingress / tcproute / tlsroute / udproute) are updated.Tests
Added
TestAttachBackendTrafficPolicyToUpstreamSectionNamecovering: sectionName match, mismatch (no attach), no-sectionName whole-Service attach, and port-specific precedence over whole-Service.go build,go vet, andgo test ./internal/adc/translator/all pass.Summary by CodeRabbit
New Features
Tests