diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index c3e4cec23d6..73eb874376c 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -16,6 +16,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" @@ -71,6 +72,9 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv gatewayMap[key] = &policyGatewayTargetContext{GatewayContext: gw} } + // Map of Gateway to the routes attached to it + gatewayRouteMap := make(map[string]sets.Set[string]) + // Translate // 1. First translate Policies targeting xRoutes // 2.. Finally, the policies targeting Gateways @@ -87,6 +91,26 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv continue } + // Find the Gateway that the route belongs to and add it to the + // gatewayRouteMap, which will be used to check policy overrides + for _, p := range GetParentReferences(route) { + if p.Kind == nil || *p.Kind == KindGateway { + namespace := route.GetNamespace() + if p.Namespace != nil { + namespace = string(*p.Namespace) + } + gw := types.NamespacedName{ + Namespace: namespace, + Name: string(p.Name), + }.String() + + if _, ok := gatewayRouteMap[gw]; !ok { + gatewayRouteMap[gw] = make(sets.Set[string]) + } + gatewayRouteMap[gw].Insert(utils.NamespacedName(route).String()) + } + } + t.translateBackendTrafficPolicyForRoute(policy, route, xdsIR) message := "BackendTrafficPolicy has been accepted." @@ -110,6 +134,24 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv message := "BackendTrafficPolicy has been accepted." status.SetBackendTrafficPolicyAcceptedIfUnset(&policy.Status, message) + + // Check if this policy is overridden by other policies targeting at + // route level + gw := utils.NamespacedName(gateway).String() + if r, ok := gatewayRouteMap[gw]; ok { + // Maintain order here to ensure status/string does not change with the same data + routes := r.UnsortedList() + sort.Strings(routes) + message := fmt.Sprintf( + "This policy is being overridden by other backendTrafficPolicies for these routes: %v", + routes) + status.SetBackendTrafficPolicyCondition(policy, + egv1a1.PolicyConditionOverridden, + metav1.ConditionTrue, + egv1a1.PolicyReasonOverridden, + message, + ) + } } } diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index 636b7316e11..9656f2672d8 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -19,6 +19,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" @@ -65,6 +66,9 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security gatewayMap[key] = &policyGatewayTargetContext{GatewayContext: gw} } + // Map of Gateway to the routes attached to it + gatewayRouteMap := make(map[string]sets.Set[string]) + // Translate // 1. First translate Policies targeting xRoutes // 2. Finally, the policies targeting Gateways @@ -81,6 +85,26 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security continue } + // Find the Gateway that the route belongs to and add it to the + // gatewayRouteMap, which will be used to check policy overrides + for _, p := range GetParentReferences(route) { + if p.Kind == nil || *p.Kind == KindGateway { + namespace := route.GetNamespace() + if p.Namespace != nil { + namespace = string(*p.Namespace) + } + gw := types.NamespacedName{ + Namespace: namespace, + Name: string(p.Name), + }.String() + + if _, ok := gatewayRouteMap[gw]; !ok { + gatewayRouteMap[gw] = make(sets.Set[string]) + } + gatewayRouteMap[gw].Insert(utils.NamespacedName(route).String()) + } + } + err := t.translateSecurityPolicyForRoute(policy, route, resources, xdsIR) if err != nil { status.SetSecurityPolicyCondition(policy, @@ -119,6 +143,24 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security message := "SecurityPolicy has been accepted." status.SetSecurityPolicyAccepted(&policy.Status, message) } + + // Check if this policy is overridden by other policies targeting + // at route level + gw := utils.NamespacedName(gateway).String() + if r, ok := gatewayRouteMap[gw]; ok { + // Maintain order here to ensure status/string does not change with the same data + routes := r.UnsortedList() + sort.Strings(routes) + message := fmt.Sprintf( + "This policy is being overridden by other securityPolicies for these routes: %v", + routes) + status.SetSecurityPolicyCondition(policy, + egv1a1.PolicyConditionOverridden, + metav1.ConditionTrue, + egv1a1.PolicyReasonOverridden, + message, + ) + } } } diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml index 429b235bb9e..72aa59947d9 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml @@ -76,6 +76,12 @@ backendTrafficPolicies: reason: Accepted status: "True" type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicies for + these routes: [envoy-gateway/httproute-1]' + reason: Overridden + status: "True" + type: Overridden - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml index d712794bd95..206efb84d6d 100755 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml @@ -74,6 +74,12 @@ backendTrafficPolicies: reason: Accepted status: "True" type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicies for + these routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml index bab8fe348b4..cdb4de42bbc 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml @@ -89,6 +89,12 @@ backendTrafficPolicies: reason: Accepted status: "True" type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicies for + these routes: [default/httproute-1 default/httproute-2]' + reason: Overridden + status: "True" + type: Overridden gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml index a0317b8cb59..8cca6b5c0cc 100644 --- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml @@ -318,6 +318,12 @@ securityPolicies: reason: Accepted status: "True" type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other securityPolicies for these + routes: [envoy-gateway/httproute-1]' + reason: Overridden + status: "True" + type: Overridden - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml index 76d0285f006..8879fdb22dd 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml @@ -189,6 +189,12 @@ securityPolicies: reason: Accepted status: "True" type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other securityPolicies for these + routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden xdsIR: default/gateway-1: accessLog: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml index 17072300d82..6e5d2d09d03 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml @@ -209,6 +209,12 @@ securityPolicies: reason: Invalid status: "False" type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other securityPolicies for these + routes: [default/httproute-2]' + reason: Overridden + status: "True" + type: Overridden xdsIR: envoy-gateway/gateway-1: accessLog: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml index a0953830c23..70a43981261 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml @@ -199,6 +199,12 @@ securityPolicies: reason: Accepted status: "True" type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other securityPolicies for these + routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden xdsIR: envoy-gateway/gateway-1: accessLog: