diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 31bfebaa0bc..df3a8f4bfc4 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -1008,7 +1008,7 @@ func (t *Translator) processBackendTrafficPolicyForRoute( } // Do need a section name since the policy is targeting to a route. - ancestorRef := getAncestorRefForPolicy(parentNN, p.SectionName) + ancestorRef := getAncestorRefForRouteParent(parentNN, p) ancestorRefs = append(ancestorRefs, &ancestorRef) if parentRefCtx := targetedRoute.GetRouteParentContext(p); parentRefCtx != nil { parentRefCtxs = append(parentRefCtxs, parentRefCtx) @@ -1038,7 +1038,7 @@ func (t *Translator) processBackendTrafficPolicyForRoute( // ListenerSet-attached Route policies report status against the // ListenerSet itself. - ancestorRef := getAncestorRefForListenerSetPolicy(parentNN, p.SectionName) + ancestorRef := getAncestorRefForRouteParent(parentNN, p) ancestorRefs = append(ancestorRefs, &ancestorRef) if parentRefCtx := targetedRoute.GetRouteParentContext(p); parentRefCtx != nil { parentRefCtxs = append(parentRefCtxs, parentRefCtx) diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go index 4d2312cb2f6..117a25e9576 100644 --- a/internal/gatewayapi/contexts.go +++ b/internal/gatewayapi/contexts.go @@ -844,10 +844,7 @@ func (r *RouteParentContext) PolicyAncestorRef() gwapiv1.ParentReference { Namespace: NamespaceDerefOr(r.Namespace, r.routeNamespace()), Name: string(r.Name), } - if r.Kind != nil && *r.Kind == resource.KindListenerSet { - return getAncestorRefForListenerSetPolicy(parentNN, r.SectionName) - } - return getAncestorRefForPolicy(parentNN, r.SectionName) + return getAncestorRefForRouteParent(parentNN, *r.ParentReference) } func (r *RouteParentContext) routeNamespace() string { diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index 3f78be4e212..3ad35381e72 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -457,7 +457,7 @@ func (t *Translator) processEnvoyExtensionPolicyForRoute( } // Do need a section name since the policy is targeting to a route - ancestorRef := getAncestorRefForPolicy(parentNN, p.SectionName) + ancestorRef := getAncestorRefForRouteParent(parentNN, p) ancestorRefs = append(ancestorRefs, &ancestorRef) // Only process parentRefs that were handled by this translator @@ -488,7 +488,7 @@ func (t *Translator) processEnvoyExtensionPolicyForRoute( // ListenerSet-attached Route policies report status against the // ListenerSet itself. - ancestorRef := getAncestorRefForListenerSetPolicy(parentNN, p.SectionName) + ancestorRef := getAncestorRefForRouteParent(parentNN, p) ancestorRefs = append(ancestorRefs, &ancestorRef) // Only process parentRefs that were handled by this translator diff --git a/internal/gatewayapi/extensionserverpolicy.go b/internal/gatewayapi/extensionserverpolicy.go index 916b2dbc0af..5ca5e12503a 100644 --- a/internal/gatewayapi/extensionserverpolicy.go +++ b/internal/gatewayapi/extensionserverpolicy.go @@ -13,6 +13,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" @@ -340,8 +341,7 @@ func (t *Translator) processExtensionServerPolicyForRoute( } policyStatus := ExtServerPolicyStatusAsPolicyStatus(policy) - gatewayNN := utils.NamespacedName(gtwCtx) - ancestorRef := getAncestorRefForPolicy(gatewayNN, p.SectionName) + ancestorRef := parentRefCtx.PolicyAncestorRef() if !supportedRouteKind { status.SetTranslationErrorForPolicyAncestor( @@ -529,10 +529,10 @@ func resolveExtServerPolicyRouteTargetRef( } func PolicyStatusToUnstructured(policyStatus gwapiv1.PolicyStatus) map[string]any { - ret := map[string]any{} - // No need to check the marshal/unmarshal error here - d, _ := json.Marshal(policyStatus) - _ = json.Unmarshal(d, &ret) + // Use the unstructured converter rather than a JSON round trip, so that numbers such as the port of an + // ancestorRef are int64 as in any unstructured object, not float64. + // No need to check the error here, the policyStatus is a typed object. + ret, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(&policyStatus) return ret } diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 6d523c168d4..f577ecedce4 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -789,6 +789,20 @@ func getAncestorRefForListenerSetPolicy(lsNN types.NamespacedName, sectionName * } } +// getAncestorRefForRouteParent returns the Gateway or ListenerSet that a route parentRef refers to +// as an ancestor reference for a policy targeting the route. It keeps the sectionName and port of +// the parentRef, so that parentRefs to different listeners of the same parent get their own ancestors. +func getAncestorRefForRouteParent(parentNN types.NamespacedName, parentRef gwapiv1.ParentReference) gwapiv1.ParentReference { + var ref gwapiv1.ParentReference + if parentRef.Kind != nil && *parentRef.Kind == resource.KindListenerSet { + ref = getAncestorRefForListenerSetPolicy(parentNN, parentRef.SectionName) + } else { + ref = getAncestorRefForPolicy(parentNN, parentRef.SectionName) + } + ref.Port = parentRef.Port + return ref +} + // getAncestorRefForGatewayClassPolicy returns a GatewayClass as an ancestor reference for policy. // Used when a policy directly targets a GatewayClass, which is only meaningful when the Gateways // under that class are merged into a single xDS IR. diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index 219911d9afb..a80fb0089f3 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -470,7 +470,7 @@ func (t *Translator) processSecurityPolicyForRoute( } // Do need a section name since the policy is targeting to a route. - ancestorRef := getAncestorRefForPolicy(parentNN, p.SectionName) + ancestorRef := getAncestorRefForRouteParent(parentNN, p) ancestorRefs = append(ancestorRefs, &ancestorRef) // Only process parentRefs that were handled by this translator @@ -502,7 +502,7 @@ func (t *Translator) processSecurityPolicyForRoute( // ListenerSet-attached Route policies report status against the // ListenerSet itself. - ancestorRef := getAncestorRefForListenerSetPolicy(parentNN, p.SectionName) + ancestorRef := getAncestorRefForRouteParent(parentNN, p) ancestorRefs = append(ancestorRefs, &ancestorRef) // Only process parentRefs that were handled by this translator diff --git a/internal/gatewayapi/status/policy.go b/internal/gatewayapi/status/policy.go index 34679f5a09a..82bfefb2a11 100644 --- a/internal/gatewayapi/status/policy.go +++ b/internal/gatewayapi/status/policy.go @@ -362,6 +362,14 @@ func ancestorRefsEqual(a, b *gwapiv1.ParentReference) bool { return false } + // Compare Port pointers + if (a.Port == nil) != (b.Port == nil) { + return false + } + if a.Port != nil && *a.Port != *b.Port { + return false + } + return true } diff --git a/internal/gatewayapi/status/policy_test.go b/internal/gatewayapi/status/policy_test.go index 25da4c340bf..42e6d19f8a1 100644 --- a/internal/gatewayapi/status/policy_test.go +++ b/internal/gatewayapi/status/policy_test.go @@ -144,6 +144,39 @@ func TestSetWarningForPolicyAncestorMergesWarnings(t *testing.T) { } } +// TestSetConditionForPolicyAncestorPort verifies that ancestors differing only by port are kept +// apart, as route parentRefs to the same Gateway differing only by port attach to different listeners. +func TestSetConditionForPolicyAncestorPort(t *testing.T) { + const controller = "example.com/controller" + policyStatus := &gwapiv1.PolicyStatus{} + + refs := []*gwapiv1.ParentReference{ + {Name: "gw"}, + {Name: "gw", Port: new(gwapiv1.PortNumber(80))}, + {Name: "gw", Port: new(gwapiv1.PortNumber(8080))}, + } + for i, ref := range refs { + SetConditionForPolicyAncestor(policyStatus, ref, controller, + gwapiv1.PolicyConditionAccepted, metav1.ConditionTrue, gwapiv1.PolicyReasonAccepted, fmt.Sprintf("msg-%d", i), 1) + } + // Setting a condition on an existing ancestor updates it instead of adding a new one. + SetConditionForPolicyAncestor(policyStatus, &gwapiv1.ParentReference{Name: "gw", Port: new(gwapiv1.PortNumber(80))}, controller, + gwapiv1.PolicyConditionAccepted, metav1.ConditionFalse, gwapiv1.PolicyReasonInvalid, "updated", 1) + + assert.Len(t, policyStatus.Ancestors, len(refs)) + for i, ref := range refs { + cond := getPolicyAncestorCondition(policyStatus, ref, controller, gwapiv1.PolicyConditionAccepted) + if !assert.NotNil(t, cond) { + continue + } + want := fmt.Sprintf("msg-%d", i) + if i == 1 { + want = "updated" + } + assert.Equal(t, want, cond.Message) + } +} + func TestSetNotMergedForPolicyAncestor(t *testing.T) { const controller = "example.com/controller" ref := &gwapiv1.ParentReference{Name: "gw-1"} diff --git a/internal/gatewayapi/testdata/extensions/extensionpolicy-with-httproute-parentrefs-differing-only-by-port.in.yaml b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-httproute-parentrefs-differing-only-by-port.in.yaml new file mode 100644 index 00000000000..21d384de826 --- /dev/null +++ b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-httproute-parentrefs-differing-only-by-port.in.yaml @@ -0,0 +1,122 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + allowedListeners: + namespaces: + from: All + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + - name: http-8080 + protocol: HTTP + port: 8080 + allowedRoutes: + namespaces: + from: All +listenerSets: +- apiVersion: gateway.networking.k8s.io/v1 + kind: ListenerSet + metadata: + namespace: envoy-gateway + name: listenerset-1 + spec: + parentRef: + name: gateway-1 + listeners: + - name: ls-http-8081 + protocol: HTTP + port: 8081 + allowedRoutes: + namespaces: + from: All + - name: ls-http-8082 + protocol: HTTP + port: 8082 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - foo.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + port: 80 + - namespace: envoy-gateway + name: gateway-1 + port: 8080 + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - bar.example.com + parentRefs: + - namespace: envoy-gateway + name: listenerset-1 + kind: ListenerSet + group: gateway.networking.k8s.io + port: 8081 + - namespace: envoy-gateway + name: listenerset-1 + kind: ListenerSet + group: gateway.networking.k8s.io + port: 8082 + rules: + - matches: + - path: + value: "/bar" + backendRefs: + - name: service-1 + port: 8080 +extensionServerPolicies: +# The parentRefs differ only by port, so the policy reports an ancestor for each of them. +- apiVersion: foo.example.io/v1alpha1 + kind: Bar + metadata: + name: policy-1 + namespace: default + spec: + targetRef: + kind: HTTPRoute + group: gateway.networking.k8s.io + name: httproute-1 + data: "attached to an httproute with parentRefs differing only by port" + +# The parentRefs to the ListenerSet differ only by port, so the policy reports an ancestor for each of them, +# against the ListenerSet rather than its parent Gateway. +- apiVersion: foo.example.io/v1alpha1 + kind: Bar + metadata: + name: policy-2 + namespace: default + spec: + targetRef: + kind: HTTPRoute + group: gateway.networking.k8s.io + name: httproute-2 + data: "attached to an httproute with ListenerSet parentRefs differing only by port" diff --git a/internal/gatewayapi/testdata/extensions/extensionpolicy-with-httproute-parentrefs-differing-only-by-port.out.yaml b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-httproute-parentrefs-differing-only-by-port.out.yaml new file mode 100644 index 00000000000..8c2d3bc3976 --- /dev/null +++ b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-httproute-parentrefs-differing-only-by-port.out.yaml @@ -0,0 +1,703 @@ +extensionServerPolicies: +- apiVersion: foo.example.io/v1alpha1 + kind: Bar + metadata: + name: policy-1 + namespace: default + spec: + data: attached to an httproute with parentRefs differing only by port + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 80 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 8080 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: foo.example.io/v1alpha1 + kind: Bar + metadata: + name: policy-2 + namespace: default + spec: + data: attached to an httproute with ListenerSet parentRefs differing only by port + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-2 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8081 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8082 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + allowedListeners: + namespaces: + from: All + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + name: http-8080 + port: 8080 + protocol: HTTP + status: + attachedListenerSets: 1 + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-8080 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + hostnames: + - foo.example.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + port: 80 + - name: gateway-1 + namespace: envoy-gateway + port: 8080 + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + port: 80 + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-2 + namespace: default + spec: + hostnames: + - bar.example.com + parentRefs: + - group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8081 + - group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8082 + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /bar + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8081 + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8082 +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + - name: envoy-gateway/gateway-1/http-8080 + ports: + - containerPort: 8080 + name: http-8080 + protocol: HTTP + servicePort: 8080 + - name: envoy-gateway/gateway-1/envoy-gateway/listenerset-1/ls-http-8081 + ports: + - containerPort: 8081 + name: http-8081 + protocol: HTTP + servicePort: 8081 + - name: envoy-gateway/gateway-1/envoy-gateway/listenerset-1/ls-http-8082 + ports: + - containerPort: 8082 + name: http-8082 + protocol: HTTP + servicePort: 8082 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: "" +listenerSets: +- apiVersion: gateway.networking.k8s.io/v1 + kind: ListenerSet + metadata: + name: listenerset-1 + namespace: envoy-gateway + spec: + listeners: + - allowedRoutes: + namespaces: + from: All + name: ls-http-8081 + port: 8081 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + name: ls-http-8082 + port: 8082 + protocol: HTTP + parentRef: + name: gateway-1 + status: + conditions: + - lastTransitionTime: null + message: All listeners are accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: All listeners are programmed + reason: Programmed + status: "True" + type: Programmed + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + - lastTransitionTime: null + message: No conflicts detected + reason: NoConflicts + status: "False" + type: Conflicted + name: ls-http-8081 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + - lastTransitionTime: null + message: No conflicts detected + reason: NoConflicts + status: "False" + type: Conflicted + name: ls-http-8082 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + extensionResources: + - name: foo.example.io/bar/default/policy-1 + object: + apiVersion: foo.example.io/v1alpha1 + kind: Bar + metadata: + name: policy-1 + namespace: default + spec: + data: attached to an httproute with parentRefs differing only by port + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 80 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 8080 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - name: foo.example.io/bar/default/policy-2 + object: + apiVersion: foo.example.io/v1alpha1 + kind: Bar + metadata: + name: policy-2 + namespace: default + spec: + data: attached to an httproute with ListenerSet parentRefs differing only + by port + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-2 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8081 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: listenerset-1 + namespace: envoy-gateway + port: 8082 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + globalResources: + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + sectionName: "8080" + name: envoy-gateway/gateway-1 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + sectionName: "8080" + name: envoy-gateway/gateway-1 + protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/0/backend/0 + protocol: HTTP + weight: 1 + extensionServerPolicies: + - name: foo.example.io/bar/default/policy-1 + hostname: foo.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/foo_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + - address: 0.0.0.0 + externalPort: 8080 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-8080 + name: envoy-gateway/gateway-1/http-8080 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/0/backend/0 + protocol: HTTP + weight: 1 + extensionServerPolicies: + - name: foo.example.io/bar/default/policy-1 + hostname: foo.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/foo_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + - address: 0.0.0.0 + externalPort: 8081 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: ls-http-8081 + name: envoy-gateway/gateway-1/envoy-gateway/listenerset-1/ls-http-8081 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8081 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + extensionServerPolicies: + - name: foo.example.io/bar/default/policy-2 + hostname: bar.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/bar_example_com + pathMatch: + distinct: false + name: "" + prefix: /bar + - address: 0.0.0.0 + externalPort: 8082 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: ls-http-8082 + name: envoy-gateway/gateway-1/envoy-gateway/listenerset-1/ls-http-8082 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8082 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + extensionServerPolicies: + - name: foo.example.io/bar/default/policy-2 + hostname: bar.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/bar_example_com + pathMatch: + distinct: false + name: "" + prefix: /bar + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/securitypolicy-route-parentrefs-differing-only-by-port.in.yaml b/internal/gatewayapi/testdata/securitypolicy-route-parentrefs-differing-only-by-port.in.yaml new file mode 100644 index 00000000000..c03b268c767 --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-route-parentrefs-differing-only-by-port.in.yaml @@ -0,0 +1,178 @@ +securityPolicies: +# this policy status +# - Accepted: true +# - Merged: true +# - default/route-merge +# - Overridden: true +# - envoy-gateway/gateway-1/http-8080 +# - default/route +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + cors: + allowOrigins: + - "https://gateway.example.com" +# this policy status +# - Accepted: true +# - Merged: true +# - default/route-merge +# - Overridden: true +# - default/route +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: envoy-gateway + name: policy-for-listener + spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-8080 + cors: + allowOrigins: + - "https://listener.example.com" +# this policy status +# - Accepted: true on gateway-1 port 80 and on gateway-1 port 8080 +# - Merged: true +# - envoy-gateway/policy-for-gateway on gateway-1/http (through the port 80 parentRef) +# - envoy-gateway/policy-for-listener on gateway-1/http-8080 (through the port 8080 parentRef) +# The parentRefs differ only by port, so each of them gets its own ancestor. +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: default + name: policy-for-route-merge + spec: + mergeType: StrategicMerge + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: route-merge + cors: + allowOrigins: + - "https://route.example.com" +# this policy status +# - Accepted: true on gateway-1 port 80, gateway-1 port 8080, ext-listeners port 8081 and ext-listeners port 8082 +# The parentRefs differ only by port, so each of them gets its own ancestor. +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: route + cors: + allowOrigins: + - "https://route.example.com" +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: route-merge + spec: + hostnames: + - merge.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + port: 80 + - namespace: envoy-gateway + name: gateway-1 + port: 8080 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: route + spec: + hostnames: + - route.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + port: 80 + - namespace: envoy-gateway + name: gateway-1 + port: 8080 + - namespace: envoy-gateway + kind: ListenerSet + group: gateway.networking.k8s.io + name: ext-listeners + port: 8081 + - namespace: envoy-gateway + kind: ListenerSet + group: gateway.networking.k8s.io + name: ext-listeners + port: 8082 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + allowedListeners: + namespaces: + from: All + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + - name: http-8080 + protocol: HTTP + port: 8080 + allowedRoutes: + namespaces: + from: All +listenerSets: +- apiVersion: gateway.networking.k8s.io/v1 + kind: ListenerSet + metadata: + namespace: envoy-gateway + name: ext-listeners + spec: + parentRef: + name: gateway-1 + listeners: + - name: ext-http-1 + protocol: HTTP + port: 8081 + allowedRoutes: + namespaces: + from: All + - name: ext-http-2 + protocol: HTTP + port: 8082 + allowedRoutes: + namespaces: + from: All diff --git a/internal/gatewayapi/testdata/securitypolicy-route-parentrefs-differing-only-by-port.out.yaml b/internal/gatewayapi/testdata/securitypolicy-route-parentrefs-differing-only-by-port.out.yaml new file mode 100644 index 00000000000..591e9ca05f3 --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-route-parentrefs-differing-only-by-port.out.yaml @@ -0,0 +1,869 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + allowedListeners: + namespaces: + from: All + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + name: http-8080 + port: 8080 + protocol: HTTP + status: + attachedListenerSets: 1 + listeners: + - attachedRoutes: 2 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 2 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-8080 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: route-merge + namespace: default + spec: + hostnames: + - merge.example.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + port: 80 + - name: gateway-1 + namespace: envoy-gateway + port: 8080 + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + port: 80 + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: route + namespace: default + spec: + hostnames: + - route.example.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + port: 80 + - name: gateway-1 + namespace: envoy-gateway + port: 8080 + - group: gateway.networking.k8s.io + kind: ListenerSet + name: ext-listeners + namespace: envoy-gateway + port: 8081 + - group: gateway.networking.k8s.io + kind: ListenerSet + name: ext-listeners + namespace: envoy-gateway + port: 8082 + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + port: 80 + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + port: 8080 + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: ext-listeners + namespace: envoy-gateway + port: 8081 + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: ext-listeners + namespace: envoy-gateway + port: 8082 +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + - name: envoy-gateway/gateway-1/http-8080 + ports: + - containerPort: 8080 + name: http-8080 + protocol: HTTP + servicePort: 8080 + - name: envoy-gateway/gateway-1/envoy-gateway/ext-listeners/ext-http-1 + ports: + - containerPort: 8081 + name: http-8081 + protocol: HTTP + servicePort: 8081 + - name: envoy-gateway/gateway-1/envoy-gateway/ext-listeners/ext-http-2 + ports: + - containerPort: 8082 + name: http-8082 + protocol: HTTP + servicePort: 8082 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +listenerSets: +- apiVersion: gateway.networking.k8s.io/v1 + kind: ListenerSet + metadata: + name: ext-listeners + namespace: envoy-gateway + spec: + listeners: + - allowedRoutes: + namespaces: + from: All + name: ext-http-1 + port: 8081 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + name: ext-http-2 + port: 8082 + protocol: HTTP + parentRef: + name: gateway-1 + status: + conditions: + - lastTransitionTime: null + message: All listeners are accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: All listeners are programmed + reason: Programmed + status: "True" + type: Programmed + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + - lastTransitionTime: null + message: No conflicts detected + reason: NoConflicts + status: "False" + type: Conflicted + name: ext-http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + - lastTransitionTime: null + message: No conflicts detected + reason: NoConflicts + status: "False" + type: Conflicted + name: ext-http-2 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + name: policy-for-route-merge + namespace: default + spec: + cors: + allowOrigins: + - https://route.example.com + mergeType: StrategicMerge + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: route-merge + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 80 + conditions: + - lastTransitionTime: null + message: Merged with policy envoy-gateway/policy-for-gateway + reason: Merged + status: "True" + type: Merged + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 8080 + conditions: + - lastTransitionTime: null + message: Merged with policy envoy-gateway/policy-for-listener + reason: Merged + status: "True" + type: Merged + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + name: policy-for-route + namespace: default + spec: + cors: + allowOrigins: + - https://route.example.com + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: route + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 80 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + port: 8080 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: ext-listeners + namespace: envoy-gateway + port: 8081 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller + - ancestorRef: + group: gateway.networking.k8s.io + kind: ListenerSet + name: ext-listeners + namespace: envoy-gateway + port: 8082 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + name: policy-for-listener + namespace: envoy-gateway + spec: + cors: + allowOrigins: + - https://listener.example.com + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-8080 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-8080 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: 'This policy is being merged by other securityPolicies for these + routes: [default/route-merge]' + reason: Merged + status: "True" + type: Merged + - lastTransitionTime: null + message: 'This policy is being overridden by other securityPolicies for these + routes: [default/route]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + name: policy-for-gateway + namespace: envoy-gateway + spec: + cors: + allowOrigins: + - https://gateway.example.com + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: 'This policy is being merged by other securityPolicies for these + routes: [default/route-merge]' + reason: Merged + status: "True" + type: Merged + - lastTransitionTime: null + message: 'This policy is being overridden by other securityPolicies for these + gateway listeners: [envoy-gateway/gateway-1/http-8080] and these routes: + [default/route]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + globalResources: + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: route-merge + namespace: default + name: httproute/default/route-merge/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/route-merge/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: merge.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: route-merge + namespace: default + name: httproute/default/route-merge/rule/0/match/0/merge_example_com + pathMatch: + distinct: false + name: "" + prefix: / + security: + cors: + allowOrigins: + - distinct: false + exact: https://route.example.com + name: "" + - destination: + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/route/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: route.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0/match/0/route_example_com + pathMatch: + distinct: false + name: "" + prefix: / + security: + cors: + allowOrigins: + - distinct: false + exact: https://route.example.com + name: "" + - address: 0.0.0.0 + externalPort: 8080 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-8080 + name: envoy-gateway/gateway-1/http-8080 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: route-merge + namespace: default + name: httproute/default/route-merge/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/route-merge/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: merge.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: route-merge + namespace: default + name: httproute/default/route-merge/rule/0/match/0/merge_example_com + pathMatch: + distinct: false + name: "" + prefix: / + security: + cors: + allowOrigins: + - distinct: false + exact: https://route.example.com + name: "" + - destination: + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/route/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: route.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0/match/0/route_example_com + pathMatch: + distinct: false + name: "" + prefix: / + security: + cors: + allowOrigins: + - distinct: false + exact: https://route.example.com + name: "" + - address: 0.0.0.0 + externalPort: 8081 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: ext-http-1 + name: envoy-gateway/gateway-1/envoy-gateway/ext-listeners/ext-http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8081 + routes: + - destination: + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/route/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: route.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0/match/0/route_example_com + pathMatch: + distinct: false + name: "" + prefix: / + security: + cors: + allowOrigins: + - distinct: false + exact: https://route.example.com + name: "" + - address: 0.0.0.0 + externalPort: 8082 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: ext-http-2 + name: envoy-gateway/gateway-1/envoy-gateway/ext-listeners/ext-http-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8082 + routes: + - destination: + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/route/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: route.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: route + namespace: default + name: httproute/default/route/rule/0/match/0/route_example_com + pathMatch: + distinct: false + name: "" + prefix: / + security: + cors: + allowOrigins: + - distinct: false + exact: https://route.example.com + name: "" + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/release-notes/current/bug_fixes/10334-route-policy-ancestor-port.md b/release-notes/current/bug_fixes/10334-route-policy-ancestor-port.md new file mode 100644 index 00000000000..69dd8e6ce2b --- /dev/null +++ b/release-notes/current/bug_fixes/10334-route-policy-ancestor-port.md @@ -0,0 +1 @@ +Fixed route policy status merging the ancestors of route parentRefs to the same Gateway or ListenerSet that differed only by port (with no sectionName). The ancestor built from a route parentRef dropped its port, and ancestor references were compared without it, so both parentRefs reported on a single ancestor. The ancestor now keeps the parentRef's port, so each parentRef gets its own ancestor, as parentRefs differing by sectionName already did.