diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index e676be67aa..2016171f3d 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -125,11 +125,10 @@ type BackendTrafficPolicySpec struct { // RoutingType can be set to "Service" to use the Service Cluster IP for routing to the backend, // or it can be set to "Endpoint" to use Endpoint routing. - // When specified, this overrides the EnvoyProxy-level setting for the relevant targeRefs. + // When specified, this overrides the EnvoyProxy-level setting for the relevant targetRefs. // If not specified, the EnvoyProxy-level setting is used. // // +optional - // +notImplementedHide RoutingType *RoutingType `json:"routingType,omitempty"` } diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 56c666f9e8..c23c6641c0 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -2274,7 +2274,7 @@ spec: description: |- RoutingType can be set to "Service" to use the Service Cluster IP for routing to the backend, or it can be set to "Endpoint" to use Endpoint routing. - When specified, this overrides the EnvoyProxy-level setting for the relevant targeRefs. + When specified, this overrides the EnvoyProxy-level setting for the relevant targetRefs. If not specified, the EnvoyProxy-level setting is used. type: string targetRef: diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 006f1c5a8b..ba504fd168 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -2273,7 +2273,7 @@ spec: description: |- RoutingType can be set to "Service" to use the Service Cluster IP for routing to the backend, or it can be set to "Endpoint" to use Endpoint routing. - When specified, this overrides the EnvoyProxy-level setting for the relevant targeRefs. + When specified, this overrides the EnvoyProxy-level setting for the relevant targetRefs. If not specified, the EnvoyProxy-level setting is used. type: string targetRef: diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 7cc3cc5ae8..bf82e1ca38 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -15,6 +15,7 @@ import ( perr "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" @@ -36,6 +37,127 @@ const ( ResponseBodyConfigMapKey = "response.body" ) +// GetBTPRoutingTypeForRoute resolves the RoutingType from BackendTrafficPolicies +// for a specific route rule and gateway/listener combination. +// It checks BTPs in priority order: +// 1. BTPs targeting a specific route rule via sectionName (most specific) +// 2. BTPs targeting the route (by targetRef or targetSelector) +// 3. BTPs targeting the gateway listener +// 4. BTPs targeting the gateway (by targetRef or targetSelector) +// Returns nil if no BTP with RoutingType targets the route/gateway. +func GetBTPRoutingTypeForRoute( + btps []*egv1a1.BackendTrafficPolicy, + route RouteContext, + gateway *gwapiv1.Gateway, + listenerName *gwapiv1.SectionName, + routeRuleName *gwapiv1.SectionName, +) *egv1a1.RoutingType { + var routeRuleBTPRoutingType *egv1a1.RoutingType + var routeBTPRoutingType *egv1a1.RoutingType + var listenerBTPRoutingType *egv1a1.RoutingType + var gatewayBTPRoutingType *egv1a1.RoutingType + + routeKind := route.GetRouteType() + routeNN := types.NamespacedName{ + Namespace: route.GetNamespace(), + Name: route.GetName(), + } + gatewayNN := types.NamespacedName{ + Namespace: gateway.GetNamespace(), + Name: gateway.GetName(), + } + + for _, btp := range btps { + if btp.Spec.RoutingType == nil { + continue + } + + // Check explicit targetRef/targetRefs + targetRefs := btp.Spec.GetTargetRefs() + for _, ref := range targetRefs { + refNamespace := btp.Namespace + refName := string(ref.Name) + refKind := string(ref.Kind) + + // Check if BTP targets the route + if refKind == string(routeKind) && + refName == routeNN.Name && + refNamespace == routeNN.Namespace { + if ref.SectionName != nil { + // Route-rule-level BTP: only matches if routeRuleName matches + if routeRuleBTPRoutingType == nil && + routeRuleName != nil && + string(*ref.SectionName) == string(*routeRuleName) { + routeRuleBTPRoutingType = btp.Spec.RoutingType + } + } else { + // Route-level BTP + if routeBTPRoutingType == nil { + routeBTPRoutingType = btp.Spec.RoutingType + } + } + } + + // Check if BTP targets the gateway + if refKind == resource.KindGateway && + refName == gatewayNN.Name && + refNamespace == gatewayNN.Namespace { + if ref.SectionName != nil { + // Listener-level BTP + if listenerBTPRoutingType == nil && + listenerName != nil && string(*ref.SectionName) == string(*listenerName) { + listenerBTPRoutingType = btp.Spec.RoutingType + } + } else { + // Gateway-level BTP + if gatewayBTPRoutingType == nil { + gatewayBTPRoutingType = btp.Spec.RoutingType + } + } + } + } + + // Check targetSelectors (label-based targeting) + for _, sel := range btp.Spec.TargetSelectors { + selGroup := string(ptr.Deref(sel.Group, gwapiv1.GroupName)) + selKind := string(sel.Kind) + labelSelector := selectorFromTargetSelector(sel) + + // Check if selector targets the route + if selKind == string(routeKind) && + selGroup == gwapiv1.GroupName && + btp.Namespace == routeNN.Namespace && + labelSelector.Matches(labels.Set(route.GetLabels())) { + if routeBTPRoutingType == nil { + routeBTPRoutingType = btp.Spec.RoutingType + } + } + + // Check if selector targets the gateway + if selKind == resource.KindGateway && + selGroup == gwapiv1.GroupName && + btp.Namespace == gatewayNN.Namespace && + labelSelector.Matches(labels.Set(gateway.GetLabels())) { + if gatewayBTPRoutingType == nil { + gatewayBTPRoutingType = btp.Spec.RoutingType + } + } + } + } + + // Return by priority: routeRule > route > listener > gateway + if routeRuleBTPRoutingType != nil { + return routeRuleBTPRoutingType + } + if routeBTPRoutingType != nil { + return routeBTPRoutingType + } + if listenerBTPRoutingType != nil { + return listenerBTPRoutingType + } + return gatewayBTPRoutingType +} + // deprecatedFieldsUsedInBackendTrafficPolicy returns a map of deprecated field paths to their alternatives. func deprecatedFieldsUsedInBackendTrafficPolicy(policy *egv1a1.BackendTrafficPolicy) map[string]string { deprecatedFields := make(map[string]string) diff --git a/internal/gatewayapi/backendtrafficpolicy_test.go b/internal/gatewayapi/backendtrafficpolicy_test.go index c9db878cab..69e6bb13c4 100644 --- a/internal/gatewayapi/backendtrafficpolicy_test.go +++ b/internal/gatewayapi/backendtrafficpolicy_test.go @@ -872,3 +872,729 @@ func TestBuildRateLimitRuleQueryParams(t *testing.T) { }) } } + +func TestGetBTPRoutingTypeForRoute(t *testing.T) { + serviceRouting := egv1a1.ServiceRoutingType + endpointRouting := egv1a1.EndpointRoutingType + + defaultRoute := &HTTPRouteContext{ + HTTPRoute: &gwapiv1.HTTPRoute{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "route-1", + }, + }, + } + defaultGateway := &gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "gateway-1", + }, + } + + tests := []struct { + name string + btps []*egv1a1.BackendTrafficPolicy + route RouteContext + gateway *gwapiv1.Gateway + listenerName *gwapiv1.SectionName + routeRuleName *gwapiv1.SectionName + expected *egv1a1.RoutingType + }{ + { + name: "no BTPs", + btps: nil, + route: defaultRoute, + gateway: defaultGateway, + expected: nil, + }, + { + name: "BTP targeting route has priority over gateway", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + expected: &serviceRouting, + }, + { + name: "BTP targeting gateway", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + expected: &serviceRouting, + }, + { + name: "BTP targeting listener (sectionName) has priority over gateway", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-listener", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("http")), + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + listenerName: ptr.To(gwapiv1.SectionName("http")), + expected: &serviceRouting, + }, + { + name: "BTP with mismatched listener sectionName falls back to gateway", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-listener", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("https")), + }, + }, + RoutingType: &endpointRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + listenerName: ptr.To(gwapiv1.SectionName("http")), + expected: &serviceRouting, + }, + { + name: "BTP with nil RoutingType is skipped", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route-no-routing", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: nil, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + expected: &serviceRouting, + }, + { + name: "BTP in different namespace does not match", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "other-namespace", + Name: "btp-route", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + expected: nil, + }, + { + name: "BTP using targetRefs instead of targetRef", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-multiple-targets", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRefs: []gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + { + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-2"), + }, + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + expected: &serviceRouting, + }, + { + name: "full priority chain: route > listener > gateway", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-listener", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("http")), + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + listenerName: ptr.To(gwapiv1.SectionName("http")), + expected: &serviceRouting, + }, + { + name: "route-rule BTP has highest priority over route-level", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route-rule", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("rule-0")), + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + routeRuleName: ptr.To(gwapiv1.SectionName("rule-0")), + expected: &serviceRouting, + }, + { + name: "route-rule BTP with mismatched sectionName falls back to route", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route-rule", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("rule-1")), + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + routeRuleName: ptr.To(gwapiv1.SectionName("rule-0")), + expected: &serviceRouting, + }, + { + name: "route-rule BTP with nil routeRuleName does not match at rule level", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route-rule", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("rule-0")), + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + routeRuleName: nil, + expected: nil, + }, + { + name: "BTP with targetSelector matching route labels", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-selector", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetSelectors: []egv1a1.TargetSelector{ + { + Kind: gwapiv1.Kind("HTTPRoute"), + MatchLabels: map[string]string{"app": "web"}, + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: &HTTPRouteContext{ + HTTPRoute: &gwapiv1.HTTPRoute{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "route-1", + Labels: map[string]string{"app": "web"}, + }, + }, + }, + gateway: defaultGateway, + expected: &serviceRouting, + }, + { + name: "BTP with targetSelector matching gateway labels", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-selector", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetSelectors: []egv1a1.TargetSelector{ + { + Kind: gwapiv1.Kind("Gateway"), + MatchLabels: map[string]string{"env": "prod"}, + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: &gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "gateway-1", + Labels: map[string]string{"env": "prod"}, + }, + }, + expected: &serviceRouting, + }, + { + name: "BTP with targetSelector not matching labels returns nil", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-selector", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetSelectors: []egv1a1.TargetSelector{ + { + Kind: gwapiv1.Kind("HTTPRoute"), + MatchLabels: map[string]string{"app": "web"}, + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: &HTTPRouteContext{ + HTTPRoute: &gwapiv1.HTTPRoute{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "route-1", + Labels: map[string]string{"app": "api"}, + }, + }, + }, + gateway: defaultGateway, + expected: nil, + }, + { + name: "explicit route targetRef takes priority over targetSelector gateway", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-selector-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetSelectors: []egv1a1.TargetSelector{ + { + Kind: gwapiv1.Kind("Gateway"), + MatchLabels: map[string]string{"env": "prod"}, + }, + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: &gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "gateway-1", + Labels: map[string]string{"env": "prod"}, + }, + }, + expected: &serviceRouting, + }, + { + name: "full priority chain: routeRule > route > listener > gateway", + btps: []*egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-gateway", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-listener", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("Gateway"), + Name: gwapiv1.ObjectName("gateway-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("http")), + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + }, + }, + RoutingType: &endpointRouting, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "btp-route-rule", + }, + Spec: egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: gwapiv1.Group("gateway.networking.k8s.io"), + Kind: gwapiv1.Kind("HTTPRoute"), + Name: gwapiv1.ObjectName("route-1"), + }, + SectionName: ptr.To(gwapiv1.SectionName("rule-0")), + }, + }, + RoutingType: &serviceRouting, + }, + }, + }, + route: defaultRoute, + gateway: defaultGateway, + listenerName: ptr.To(gwapiv1.SectionName("http")), + routeRuleName: ptr.To(gwapiv1.SectionName("rule-0")), + expected: &serviceRouting, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := GetBTPRoutingTypeForRoute(tt.btps, tt.route, tt.gateway, tt.listenerName, tt.routeRuleName) + require.Equal(t, tt.expected, got) + }) + } +} diff --git a/internal/gatewayapi/ext_service.go b/internal/gatewayapi/ext_service.go index 13ce8ff07e..5b30c21ac5 100644 --- a/internal/gatewayapi/ext_service.go +++ b/internal/gatewayapi/ext_service.go @@ -110,12 +110,12 @@ func (t *Translator) processExtServiceDestination( switch KindDerefOr(backendRef.Kind, resource.KindService) { case resource.KindService: - ds, err = t.processServiceDestinationSetting(settingName, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy) + ds, err = t.processServiceDestinationSetting(settingName, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy, nil) if err != nil { return nil, err } case resource.KindServiceImport: - ds, err = t.processServiceImportDestinationSetting(settingName, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy) + ds, err = t.processServiceImportDestinationSetting(settingName, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy, nil) if err != nil { return nil, err } @@ -136,7 +136,7 @@ func (t *Translator) processExtServiceDestination( } // TODO: support mixed endpointslice address type for the same backendRef - if !t.IsEnvoyServiceRouting(envoyProxy) && ds.AddressType != nil && *ds.AddressType == ir.MIXED { + if !t.IsServiceRouting(envoyProxy, nil) && ds.AddressType != nil && *ds.AddressType == ir.MIXED { return nil, errors.New( "mixed endpointslice address type for the same backendRef is not supported") } diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go index a642b37a0a..2fd5802266 100644 --- a/internal/gatewayapi/filters.go +++ b/internal/gatewayapi/filters.go @@ -1041,7 +1041,7 @@ func (t *Translator) processRequestMirrorFilter( destName := fmt.Sprintf("%s-mirror-%d", irRouteDestinationName(filterContext.Route, filterContext.RuleIdx), filterIdx) settingName := irDestinationSettingName(destName, -1 /*unused*/) - ds, _, err := t.processDestination(settingName, mirrorBackendRef, filterContext.ParentRef, filterContext.Route, resources) + ds, _, err := t.processDestination(settingName, mirrorBackendRef, filterContext.ParentRef, filterContext.Route, resources, nil) if err != nil { return err } diff --git a/internal/gatewayapi/globalresources.go b/internal/gatewayapi/globalresources.go index 4dcaab1449..1000890724 100644 --- a/internal/gatewayapi/globalresources.go +++ b/internal/gatewayapi/globalresources.go @@ -85,7 +85,7 @@ func (t *Translator) processServiceClusterForGateway(gateway *GatewayContext, re Namespace: NamespacePtr(svcCluster.Namespace), Port: PortNumPtr(svcCluster.Spec.Ports[0].Port), } - dst, err := t.processServiceDestinationSetting(irKey, bRef, svcCluster.Namespace, ir.AppProtocol(svcCluster.Spec.Ports[0].Protocol), resources.EnvoyProxyForGatewayClass) + dst, err := t.processServiceDestinationSetting(irKey, bRef, svcCluster.Namespace, ir.AppProtocol(svcCluster.Spec.Ports[0].Protocol), resources.EnvoyProxyForGatewayClass, nil) if err != nil { return "", nil } diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index 551f02f7d0..f7fc5a4c10 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -948,7 +948,7 @@ func (t *Translator) processBackendRefs(name string, backendCluster egv1a1.Backe if err := t.validateBackendRefService(ref.BackendObjectReference, ns, corev1.ProtocolTCP); err != nil { return nil, nil, err } - ds, err := t.processServiceDestinationSetting(name, ref.BackendObjectReference, ns, ir.TCP, envoyProxy) + ds, err := t.processServiceDestinationSetting(name, ref.BackendObjectReference, ns, ir.TCP, envoyProxy, nil) if err != nil { return nil, nil, err } diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index 36215ce253..b9574376c3 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -273,7 +273,7 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe Filters: rule.BackendRefs[i].Filters, } // ds will never be nil here because processDestination returns an empty DestinationSetting for invalid backendRefs. - ds, unstructuredRef, err := t.processDestination(settingName, backendRefCtx, parentRef, httpRoute, resources) + ds, unstructuredRef, err := t.processDestination(settingName, backendRefCtx, parentRef, httpRoute, resources, rule.Name) if err != nil { // Gateway API conformance: When backendRef Service exists but has no endpoints, // the ResolvedRefs condition should NOT be set to False. @@ -993,7 +993,7 @@ func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRe Filters: rule.BackendRefs[i].Filters, } // ds will never be nil here because processDestination returns an empty DestinationSetting for invalid backendRefs. - ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, grpcRoute, resources) + ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, grpcRoute, resources, rule.Name) if err != nil { // Gateway API conformance: When backendRef Service exists but has no endpoints, // the ResolvedRefs condition should NOT be set to False. @@ -1374,7 +1374,7 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour settingName := irDestinationSettingName(destName, i) backendRefCtx := DirectBackendRef{BackendRef: &rule.BackendRefs[i]} // ds will never be nil here because processDestination returns an empty DestinationSetting for invalid backendRefs. - ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, tlsRoute, resources) + ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, tlsRoute, resources, rule.Name) if err != nil { resolveErrs.Add(err) continue @@ -1551,7 +1551,7 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour settingName := irDestinationSettingName(destName, i) backendRefCtx := DirectBackendRef{BackendRef: &udpRoute.Spec.Rules[0].BackendRefs[i]} // ds will never be nil here because processDestination returns an empty DestinationSetting for invalid backendRefs. - ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, udpRoute, resources) + ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, udpRoute, resources, udpRoute.Spec.Rules[0].Name) if err != nil { resolveErrs.Add(err) continue @@ -1701,7 +1701,7 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour for i := range tcpRoute.Spec.Rules[0].BackendRefs { settingName := irDestinationSettingName(destName, i) backendRefCtx := DirectBackendRef{BackendRef: &tcpRoute.Spec.Rules[0].BackendRefs[i]} - ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, tcpRoute, resources) + ds, _, err := t.processDestination(settingName, backendRefCtx, parentRef, tcpRoute, resources, tcpRoute.Spec.Rules[0].Name) // skip adding the route and provide the reason via route status. if err != nil { resolveErrs.Add(err) @@ -1812,6 +1812,7 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour // This will result in a direct 500 response for HTTP-based requests. func (t *Translator) processDestination(name string, backendRefContext BackendRefContext, parentRef *RouteParentContext, route RouteContext, resources *resource.Resources, + routeRuleName *gwapiv1.SectionName, ) (ds *ir.DestinationSetting, unstructuredRef *ir.UnstructuredRef, err status.Error) { var ( routeType = route.GetRouteType() @@ -1848,6 +1849,18 @@ func (t *Translator) processDestination(name string, backendRefContext BackendRe envoyProxy = gatewayCtx.envoyProxy } + // Resolve BTP RoutingType for this route/gateway combination + var btpRoutingType *egv1a1.RoutingType + if gatewayCtx != nil { + btpRoutingType = GetBTPRoutingTypeForRoute( + resources.BackendTrafficPolicies, + route, + gatewayCtx.Gateway, + parentRef.SectionName, + routeRuleName, + ) + } + protocol := inspectAppProtocolByRouteKind(routeType) // Process BackendTLSPolicy first to ensure status is set. @@ -1871,12 +1884,12 @@ func (t *Translator) processDestination(name string, backendRefContext BackendRe switch KindDerefOr(backendRef.Kind, resource.KindService) { case resource.KindServiceImport: - ds, err = t.processServiceImportDestinationSetting(name, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy) + ds, err = t.processServiceImportDestinationSetting(name, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy, btpRoutingType) if err != nil { return emptyDS, nil, err } case resource.KindService: - ds, err = t.processServiceDestinationSetting(name, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy) + ds, err = t.processServiceDestinationSetting(name, backendRef.BackendObjectReference, backendNamespace, protocol, envoyProxy, btpRoutingType) if err != nil { return emptyDS, nil, err } @@ -1918,7 +1931,7 @@ func (t *Translator) processDestination(name string, backendRefContext BackendRe return emptyDS, nil, status.NewRouteStatusError(filtersErr, status.RouteReasonInvalidBackendFilters) } - if err := validateDestinationSettings(ds, t.IsEnvoyServiceRouting(envoyProxy), backendRef.Kind); err != nil { + if err := validateDestinationSettings(ds, t.IsServiceRouting(envoyProxy, btpRoutingType), backendRef.Kind); err != nil { return emptyDS, nil, err } @@ -1963,6 +1976,7 @@ func (t *Translator) processServiceImportDestinationSetting( backendNamespace string, protocol ir.AppProtocol, envoyProxy *egv1a1.EnvoyProxy, + btpRoutingType *egv1a1.RoutingType, ) (*ir.DestinationSetting, status.Error) { var ( endpoints []*ir.DestinationEndpoint @@ -1986,7 +2000,7 @@ func (t *Translator) processServiceImportDestinationSetting( isHeadless := len(backendIps) == 0 // Route to endpoints by default, or if service routing is enabled but ServiceImport is headless - useEndpointRouting := !t.IsEnvoyServiceRouting(envoyProxy) || isHeadless + useEndpointRouting := !t.IsServiceRouting(envoyProxy, btpRoutingType) || isHeadless if useEndpointRouting { endpointSlices := t.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), resource.KindServiceImport) endpoints, addrType = getIREndpointsFromEndpointSlices(endpointSlices, servicePort.Name, getServicePortProtocol(servicePort.Protocol)) @@ -2019,6 +2033,7 @@ func (t *Translator) processServiceDestinationSetting( backendNamespace string, protocol ir.AppProtocol, envoyProxy *egv1a1.EnvoyProxy, + btpRoutingType *egv1a1.RoutingType, ) (*ir.DestinationSetting, status.Error) { var ( endpoints []*ir.DestinationEndpoint @@ -2042,7 +2057,7 @@ func (t *Translator) processServiceDestinationSetting( isHeadless := isServiceHeadless(service) // Route to endpoints by default, or if service routing is enabled but service is headless - useEndpointRouting := !t.IsEnvoyServiceRouting(envoyProxy) || isHeadless + useEndpointRouting := !t.IsServiceRouting(envoyProxy, btpRoutingType) || isHeadless if useEndpointRouting { endpointSlices := t.GetEndpointSlicesForBackend(backendNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, resource.KindService)) endpoints, addrType = getIREndpointsFromEndpointSlices(endpointSlices, servicePort.Name, getServicePortProtocol(servicePort.Protocol)) diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-endpoint-btp-service.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-endpoint-btp-service.in.yaml new file mode 100644 index 0000000000..247458fe6c --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-endpoint-btp-service.in.yaml @@ -0,0 +1,54 @@ +# Test: EnvoyProxy has routingType: Endpoint, BTP overrides to Service +# Expected: Route uses Service routing (ClusterIP) because BTP takes priority +envoyProxyForGatewayClass: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + routingType: Endpoint +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + routingType: Service diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-endpoint-btp-service.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-endpoint-btp-service.out.yaml new file mode 100644 index 0000000000..fe61486454 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-endpoint-btp-service.out.yaml @@ -0,0 +1,216 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-route + namespace: default + spec: + routingType: Service + 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 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + 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 +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + name: test + namespace: envoy-gateway-system + spec: + logging: {} + routingType: Endpoint + status: {} + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - '*' + isHTTP2: false + 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: + - endpoints: + - host: 1.1.1.1 + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-route + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: / + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-service-mixed-btp.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-service-mixed-btp.in.yaml new file mode 100644 index 0000000000..3dd5807a48 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-service-mixed-btp.in.yaml @@ -0,0 +1,75 @@ +# Test: EnvoyProxy has routingType: Service, one route has BTP override to Endpoint +# Expected: +# - httproute-1 (with BTP Endpoint): uses Endpoint routing (pod IP 7.7.7.7) +# - httproute-2 (no BTP): uses Service routing from EnvoyProxy (ClusterIP 1.1.1.1) +envoyProxyForGatewayClass: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + routingType: Service +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + # Route with BTP override to Endpoint + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/endpoint" + backendRefs: + - name: service-1 + port: 8080 + # Route without BTP - inherits EnvoyProxy Service routing + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/service" + backendRefs: + - name: service-2 + port: 8080 +backendTrafficPolicies: + # Only applies to httproute-1, overrides to Endpoint + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-endpoint-override + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + routingType: Endpoint diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-service-mixed-btp.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-service-mixed-btp.out.yaml new file mode 100644 index 0000000000..5337e6a50b --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-envoyproxy-service-mixed-btp.out.yaml @@ -0,0 +1,277 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-endpoint-override + namespace: default + spec: + routingType: Endpoint + 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 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /endpoint + 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 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-2 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + rules: + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: /service + 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 +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + name: test + namespace: envoy-gateway-system + spec: + logging: {} + routingType: Service + status: {} + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - endpoints: + - host: 6.7.8.9 + port: 8080 + 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: + - '*' + isHTTP2: false + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-endpoint-override + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /endpoint + traffic: {} + - destination: + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0 + settings: + - endpoints: + - host: 1.1.1.1 + port: 8080 + metadata: + kind: Service + name: service-2 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /service + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-endpoint.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-endpoint.in.yaml new file mode 100644 index 0000000000..a9bacb1f6a --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-endpoint.in.yaml @@ -0,0 +1,52 @@ +envoyProxyForGatewayClass: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + routingType: Service +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + routingType: Endpoint diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-endpoint.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-endpoint.out.yaml new file mode 100644 index 0000000000..5ae4dabac2 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-endpoint.out.yaml @@ -0,0 +1,215 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-route + namespace: default + spec: + routingType: Endpoint + 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 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + 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 +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + name: test + namespace: envoy-gateway-system + spec: + logging: {} + routingType: Service + status: {} + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - endpoints: + - host: 6.7.8.9 + port: 8080 + 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: + - '*' + isHTTP2: false + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-route + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: / + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-full-priority.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-full-priority.in.yaml new file mode 100644 index 0000000000..7269ca646a --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-full-priority.in.yaml @@ -0,0 +1,110 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - name: rule-0 + matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 + - name: rule-1 + matches: + - path: + value: "/bar" + backendRefs: + - name: service-2 + port: 8080 +# Second route: only affected by gateway and listener BTPs (no route-level or rule-level BTP) +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/baz" + backendRefs: + - name: service-3 + port: 8080 +backendTrafficPolicies: +# Level 4 (lowest): Gateway-level BTP with Service routing +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + routingType: Service +# Level 3: Listener-level BTP with Endpoint routing +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-listener + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http + routingType: Endpoint +# Level 2: Route-level BTP with Service routing (overrides listener for httproute-1) +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + routingType: Service +# Level 1 (highest): Route-rule BTP with Endpoint routing for rule-0 only +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-rule-0 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + sectionName: rule-0 + routingType: Endpoint diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-full-priority.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-full-priority.out.yaml new file mode 100644 index 0000000000..b56600ce74 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-full-priority.out.yaml @@ -0,0 +1,438 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-rule-0 + namespace: default + spec: + routingType: Endpoint + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + sectionName: rule-0 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-route + namespace: default + spec: + routingType: Service + 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 + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicy for + these route rules: [rule-0]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-listener + namespace: envoy-gateway + spec: + routingType: Endpoint + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicies + for these routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-gateway + namespace: envoy-gateway + spec: + routingType: Service + targetRef: + 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: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicies + for these listeners: [http] and these routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + name: rule-0 + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: /bar + name: rule-1 + 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 + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-2 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-3 + port: 8080 + matches: + - path: + value: /baz + 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 + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - '*' + isHTTP2: false + 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 + sectionName: rule-0 + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-rule-0 + namespace: default + sectionName: rule-0 + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /foo + traffic: {} + - destination: + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + sectionName: rule-1 + name: httproute/default/httproute-1/rule/1 + settings: + - endpoints: + - host: 1.1.1.1 + port: 8080 + metadata: + kind: Service + name: service-2 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/1/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-route + namespace: default + sectionName: rule-1 + name: httproute/default/httproute-1/rule/1/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /bar + traffic: {} + - 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-3 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-listener + namespace: envoy-gateway + name: httproute/default/httproute-2/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /baz + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-gateway.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-gateway.in.yaml new file mode 100644 index 0000000000..b2deb1566b --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-gateway.in.yaml @@ -0,0 +1,60 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + 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: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/bar" + backendRefs: + - name: service-2 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + routingType: Service diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-gateway.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-gateway.out.yaml new file mode 100644 index 0000000000..597f1c88de --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-gateway.out.yaml @@ -0,0 +1,273 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-gateway + namespace: envoy-gateway + spec: + routingType: Service + targetRef: + 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: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + 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 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-2 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + rules: + - backendRefs: + - name: service-2 + 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: + name: gateway-1 + namespace: envoy-gateway +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - '*' + isHTTP2: false + 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: + - endpoints: + - host: 1.1.1.1 + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-gateway + namespace: envoy-gateway + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /foo + traffic: {} + - destination: + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0 + settings: + - endpoints: + - host: 1.1.1.1 + port: 8080 + metadata: + kind: Service + name: service-2 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-gateway + namespace: envoy-gateway + name: httproute/default/httproute-2/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /bar + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-listener.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-listener.in.yaml new file mode 100644 index 0000000000..31325011eb --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-listener.in.yaml @@ -0,0 +1,94 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + - name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - name: tls-secret + allowedRoutes: + namespaces: + from: All +secrets: + - apiVersion: v1 + kind: Secret + metadata: + namespace: envoy-gateway + name: tls-secret + type: kubernetes.io/tls + data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNsekNDQVg4Q0ZIZU9wV1lOdFlhRlFlL3lGRWVHMDdEMXNjSWJNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1CTXgKRVRBUEJnTlZCQU1NQ0dvdVpHOXRZV2x1TUI0WERUSXlNVEF5TVRFek1UZzBPVm9YRFRJeU1URXlNREV6TVRnMApPVm93RXpFUk1BOEdBMVVFQXd3SWFpNWtiMjFoYVc0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3CmdnRUtBb0lCQVFESGc2R0ZYbWlhdWl1WDU3R25ycWpYazkvd1JwbTZUcFdkWk9NYjBWQ05PQkVTREhxR1ZBMHEKbEdRdEQzNjZMS3krSDRCcGdJeXBrSG9mOWg4VlpCWi8zaFh5OEVJOUFCTytxTU9xRXVocytWUU5kY2g0Wlp5RAppNGpSZVByRCs3akJEY3Y5czR6ZmNKZjRLMkhJT1dVQUNvWnhTVTRXTWZsZnhqdVE3OFVPM0pJanRtTk1pMHVkClNpbzNsS2NNY3dGejlyUnR4WlNJTUR0VmtHQWJWNzJ6UWdpdUNjVE9TZTEzd3BJQWdNalRVVDZ3S3hqZEpXTGcKeTNDQmpRRVIyT3dGZ1FzaEJVa1p1ZW1vcHVFZU1aL09ncG1GTlR3bjJTN2VYdk1GblpqRVhhdkFpaE9UZUNLUQQ4dUdSSVE0Z3hzMzg3TVVDR1VIbXpLSjg0djhRMUJBdkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCCkFHRm9KZWpBSHhkY2dCWFkzYUxOKzJISm5yR2dHTEpycHFFaXc5T0NvVWJ3Uk0yRFdzVCtJa0ttYWVOeWhiaU4KRHpLazh0VnJGYTN4WDVRTXRGbjJrQXJxZ3lJT0lBa2JZZ1RFUS9Nd2ZPcWMyQzI0RDRqNDB4QXF6NlB5dUl0VgozM2pDTHhYRURJSGV1bVNZV2FjMTBRQlc2UjhOdnE0a0RISXF2bHNHMUQ4SXdlRkNLQjJSMnZ2Nmo1SHhLK041CnpOV0JhTzIrWFVlbkwvQmpKZmtVVkFWRWxsRERaRjFOZk5SL25WeDhLSjFhYXg5RHNLeG1mQStnYXhNZEJMVWMKSEsyLzlzaTBBU2QvVU1WNXA2bm5tWG5GYXJ2WE5mYXVPUGNzSzJPL2NheElmZ0sxOG10RTBnWnpFZVlteG82bgpYdzA5UThVdTgvRXF5S21rR0FFa2JXUT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktZd2dnU2lBZ0VBQW9JQkFRREhnNkdGWG1pYXVpdVgKNTdHbnJxalhrOS93UnBtNlRwV2RaT01iMFZDTk9CRVNESHFHVkEwcWxHUXREMzY2TEt5K0g0QnBnSXlwa0hvZgo5aDhWWkJaLzNoWHk4RUk5QUJPdXFNT3FFdWhzK1ZRTmRjaDRaWnlEaTRqUmVQckQrN2pCRGN2OXM0emZjSmY0CksySElPV1VBQ29aeFNVNFdNZmxmeGp1UTc4VU8zSklqdG1OTWkwdWRTaW8zbEtjTWN3Rno5clJ0eFpTSU1EdFYKa0dBYlY3MnpRZ2l1Q2NUT1NlMTN3cElBZ01qVFVUNndLeGpkSldMZ3kzQ0JqUUVSMk93RmdRc2hCVWtadWVtbwpwdUVlTVovT2dwbUZOVHduMlM3ZVh2TUZuWmpFWGF2QWloT1RlQ0tRRHVHUklRNGd4czM4N01VQ0dVSG16S0o4CjR2OFExQkF2QWdNQkFBRUNnZ0VBYTBYbHo2UUM4VGxVaFdYbVJMM2VSdGFMczFGVjY3bjFjN0RiKzU0R09NRzkKYlg5ckRLTTVkZE9NaXBMR3I3cVdvN3kyblVRNFUxMkdCR3ZJTldNZHRlTHFqSVNVQVk5SkJ0V2JWZEdkcDMxdApXYzVJWU9Mc1VRaUhLQ3Z2azNWK3N0SERUSk5VYitTMERoNzk2bkdTTUE1bXkrWjkyMVVpVXEzTkh1dUNnME5tClUxQUJOWjlRZDdxelhrNEMxNkRtU043dUcrNmxUaU8ybU95dGFuVVJLbDBaVk5FYlEwQkFhVnk5WjNvdWM1Y3IKL1liU1F1U1BMYTFCOW52cXhKTGhJNmUyNmZMWWhPQndHYTBVMlhxQlFKM2dTWFRZZFNnTHVRYkIxN3FGMENURgpac3R6MTkxUEdQMEVpN2RNWmtjT1dzRTdKa3hXY0cwU0wyNEVQZ1JRb1FLQmdRRHN6NHdhZkJ4aFJyU0lFMW1wCi9TQkh1c3dYZXZKeTN2RmZ5blZGRkwxdGFJNHlQT2Y2ZlJ4bzYwL2N1dEhxTW9iUnAvOHRIS3lDY2p5emN4emgKVHhPMFN1NjBMbTFOelY1b0lwRlNKMko4VTR6eFViK3dkdnNWWjZHQitNbFBoZkFQYkR3a3l4ckFEaGsyRkhWeQp2U2lpZVhrQ2cwVkQ3elFBUEhjbU5Nc25Ud0tCZ1FEWHZhUFdaSVNRdWxmRXE3V3U4WHN6OUc1VGloNEVmTy9FCmNYZkFVTFlmSUpHejduVG0vTTQ1K1JtVHpzaTRxTDVMV3N1dzhZNnRTV25xT3FKazBLUk1SZG5KakVUWjdHTGoKWDhqc2dCQXRGcnFieU5lYytXQjBxWjRoV3hTb2FRdXBqalRqQmdZMDl6T2ZOdkI1bzVCeGo5UlFKM3hKRGFOVgpqUm52T2lpOXR3S0JnRmlIUkdqRVg4UVhMSWNISnFzQy9wbis5T1BiVThmaFdXL0hTbjZmWDZsQThnQ3R6S01PCmhnS1VJR0lsUExUclQ1S2JLRTdDNUpNcFZXcndWTkJWUGQ3YjJ5MFlNKzFwZ0Flb0RBWHVUVHdFQUpYQk5UYmwKYXhJYU5icUVPT1FGdGMybkVsTW05T3RFRjBQSHRlOWxPMmZRVExKWExFNHpZVDBvaWxIKytrNUhBb0dBUlhBOQp3SEIwM0RXTnVlMVhnb1hZY3IyUVQxYnFseGEzUjBjRVI1SHlXekI1M3I5N2lESEh4UDBTa1VoN0V2UWd1VHZHCnVFMUQzY2tBeG5BWEdQcXA4NXMxYU5UZUU5SE5reTN4Y1B5VlVGZjI1dW5FNHFGak9XbmhEeG00ckxkOVY2R2oKMFpLS1E3bmdKM0hPZHRqMmxnaXJPclptNlRxSGJZRTVBUHZIdDhNQ2dZQVU1NU9teFNrS2srbnJUMkZuS1JmaApocU5vN0RCOFVCQjdJRDBIYmR6S3p4TTQrU0cxSy9jUHM5cVJJUEFyK1JCT0VnNGNidCt0b3doTVpVZ0dGV25QCnJFSFJJWEE5WWkxTnh2clBBNFAzcENTS29PaHdYYlp5VThrVWpiRTBWL0w2dTVob1FtWnpNRFRxY0dsK3pBTjgKVlo5NHNUTnBCQjQybitEakp6Zk1KUT09Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-http + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-https + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: https + rules: + - matches: + - path: + value: "/bar" + backendRefs: + - name: service-2 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + routingType: Endpoint + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-http-listener + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http + routingType: Service diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-listener.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-listener.out.yaml new file mode 100644 index 0000000000..0caac07319 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-listener.out.yaml @@ -0,0 +1,313 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-http-listener + namespace: envoy-gateway + spec: + routingType: Service + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-gateway + namespace: envoy-gateway + spec: + routingType: Endpoint + targetRef: + 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: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicies + for these listeners: [http]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + name: https + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: null + kind: null + name: tls-secret + mode: Terminate + status: + 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: 'No valid secrets exist: envoy-gateway/tls-secret must contain valid + tls.crt and tls.key, unable to validate certificate in tls.crt: unable to + decode pem data for certificate.' + reason: InvalidCertificateRef + status: "False" + type: ResolvedRefs + - lastTransitionTime: null + message: Listener is invalid, see other Conditions for details. + reason: Invalid + status: "False" + type: Programmed + name: https + 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-http + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + 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 + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-https + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: https + rules: + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: /bar + status: + parents: + - conditions: + - lastTransitionTime: null + message: There are no ready listeners for this parent ref + reason: NoReadyListeners + status: "False" + 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 + sectionName: https +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - '*' + isHTTP2: false + 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-http + namespace: default + name: httproute/default/httproute-http/rule/0 + settings: + - endpoints: + - host: 1.1.1.1 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-http/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-http + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-http-listener + namespace: envoy-gateway + name: httproute/default/httproute-http/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /foo + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-override.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-override.in.yaml new file mode 100644 index 0000000000..455a3e8485 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-override.in.yaml @@ -0,0 +1,71 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + 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: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/bar" + backendRefs: + - name: service-2 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + routingType: Service + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + routingType: Endpoint diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-override.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-override.out.yaml new file mode 100644 index 0000000000..d6bc92f0c5 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-override.out.yaml @@ -0,0 +1,310 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-route + namespace: default + spec: + routingType: Endpoint + 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 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-gateway + namespace: envoy-gateway + spec: + routingType: Service + targetRef: + 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: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicies + for these routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + 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 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-2 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + rules: + - backendRefs: + - name: service-2 + 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: + name: gateway-1 + namespace: envoy-gateway +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - '*' + isHTTP2: false + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-route + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /foo + traffic: {} + - destination: + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0 + settings: + - endpoints: + - host: 1.1.1.1 + port: 8080 + metadata: + kind: Service + name: service-2 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-gateway + namespace: envoy-gateway + name: httproute/default/httproute-2/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /bar + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-rule-override.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-rule-override.in.yaml new file mode 100644 index 0000000000..2c829d870f --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-rule-override.in.yaml @@ -0,0 +1,66 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - name: rule-0 + matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 + - name: rule-1 + matches: + - path: + value: "/bar" + backendRefs: + - name: service-2 + port: 8080 +backendTrafficPolicies: +# Route-level BTP: Service routing for the entire route +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + routingType: Service +# Route-rule BTP: Endpoint routing for rule-0 only (overrides route-level) +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-rule-0 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + sectionName: rule-0 + routingType: Endpoint diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-rule-override.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-rule-override.out.yaml new file mode 100644 index 0000000000..a5f31604f7 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-rule-override.out.yaml @@ -0,0 +1,290 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-rule-0 + namespace: default + spec: + routingType: Endpoint + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + sectionName: rule-0 + 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: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-route + namespace: default + spec: + routingType: Service + 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 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other backendTrafficPolicy for + these route rules: [rule-0]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + name: rule-0 + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: /bar + name: rule-1 + 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 +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - '*' + isHTTP2: false + 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 + sectionName: rule-0 + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-rule-0 + namespace: default + sectionName: rule-0 + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /foo + traffic: {} + - destination: + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + sectionName: rule-1 + name: httproute/default/httproute-1/rule/1 + settings: + - endpoints: + - host: 1.1.1.1 + port: 8080 + metadata: + kind: Service + name: service-2 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/1/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-route + namespace: default + sectionName: rule-1 + name: httproute/default/httproute-1/rule/1/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /bar + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-selector.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-selector.in.yaml new file mode 100644 index 0000000000..1a20148640 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-selector.in.yaml @@ -0,0 +1,76 @@ +envoyProxyForGatewayClass: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + routingType: Service +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +# Route with matching labels: gets Endpoint routing via selector BTP +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + labels: + app: web + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 +# Route without matching labels: keeps default Service routing +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + labels: + app: api + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/bar" + backendRefs: + - name: service-2 + port: 8080 +backendTrafficPolicies: +# BTP with targetSelector matching routes with app=web label +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-selector + spec: + targetSelectors: + - group: gateway.networking.k8s.io + kind: HTTPRoute + matchLabels: + app: web + routingType: Endpoint diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-selector.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-selector.out.yaml new file mode 100644 index 0000000000..8f62d60841 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-selector.out.yaml @@ -0,0 +1,277 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-selector + namespace: default + spec: + routingType: Endpoint + targetSelectors: + - group: gateway.networking.k8s.io + kind: HTTPRoute + matchLabels: + app: web + 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 + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + labels: + app: web + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + 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 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + labels: + app: api + name: httproute-2 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + rules: + - backendRefs: + - name: service-2 + 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: + name: gateway-1 + namespace: envoy-gateway +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + name: test + namespace: envoy-gateway-system + spec: + logging: {} + routingType: Service + status: {} + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - endpoints: + - host: 6.7.8.9 + port: 8080 + 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: + - '*' + isHTTP2: false + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-selector + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /foo + traffic: {} + - destination: + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0 + settings: + - endpoints: + - host: 1.1.1.1 + port: 8080 + metadata: + kind: Service + name: service-2 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: /bar + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-service.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-service.in.yaml new file mode 100644 index 0000000000..ae50f4f110 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-service.in.yaml @@ -0,0 +1,44 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + routingType: Service diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-service.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-service.out.yaml new file mode 100644 index 0000000000..b8b23b15c7 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-routing-type-service.out.yaml @@ -0,0 +1,206 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-route + namespace: default + spec: + routingType: Service + 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 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + 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 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + 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 +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + 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 +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: + - '*' + isHTTP2: false + 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: + - endpoints: + - host: 1.1.1.1 + 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 + hostname: '*' + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-route + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/* + pathMatch: + distinct: false + name: "" + prefix: / + traffic: {} + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 08b72d9f1f..464d78b07c 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -13,7 +13,6 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" @@ -520,24 +519,32 @@ func (t *Translator) buildIR(gateway *GatewayContext) (string, *ir.Xds, *ir.Infr return irKey, gwXdsIR, gwInfraIR } -// IsEnvoyServiceRouting returns true if EnvoyProxy.Spec.RoutingType == ServiceRoutingType -// or, alternatively, if Translator.EndpointRoutingDisabled has been explicitly set to true; -// otherwise, it returns false. -func (t *Translator) IsEnvoyServiceRouting(r *egv1a1.EnvoyProxy) bool { +// IsServiceRouting determines if Service ClusterIP routing should be used. +// It follows the priority hierarchy: +// 1. Translator.EndpointRoutingDisabled (for tests) - if true, always use Service routing +// 2. BTP RoutingType - per-route/gateway override +// 3. EnvoyProxy RoutingType - cluster-wide setting +// 4. Default: Endpoint routing +func (t *Translator) IsServiceRouting(envoyProxy *egv1a1.EnvoyProxy, btpRoutingType *egv1a1.RoutingType) bool { if t.EndpointRoutingDisabled { return true } - if r == nil { - return false + + // BTP RoutingType has priority over EnvoyProxy + if btpRoutingType != nil { + switch *btpRoutingType { + case egv1a1.ServiceRoutingType: + return true + case egv1a1.EndpointRoutingType: + return false + } } - switch ptr.Deref(r.Spec.RoutingType, egv1a1.EndpointRoutingType) { - case egv1a1.ServiceRoutingType: + + // Fall back to EnvoyProxy RoutingType + if envoyProxy != nil && envoyProxy.Spec.RoutingType != nil && *envoyProxy.Spec.RoutingType != egv1a1.EndpointRoutingType { return true - case egv1a1.EndpointRoutingType: - return false - default: - return false } + return false } func infrastructureAnnotations(gtw *gwapiv1.Gateway) map[string]string { diff --git a/release-notes/current.yaml b/release-notes/current.yaml index b4d0c5a0ad..e0418603c2 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -14,6 +14,7 @@ new features: | Added support for shadow mode in local rate limiting. Added `egctl config envoy-gateway` commands to retrieve Envoy Gateway admin config dumps. The DirectResponse body in HTTPFilter now supports Envoy command operators for dynamic content. See https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators for more details. + Implement RoutingType API for BackendTrafficPolicy. Support for configuring weights for locality zones. bug fixes: | diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 08a7b0b8e3..30af81afd7 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -550,6 +550,7 @@ _Appears in:_ | `httpUpgrade` | _[ProtocolUpgradeConfig](#protocolupgradeconfig) array_ | false | | HTTPUpgrade defines the configuration for HTTP protocol upgrades.
If not specified, the default upgrade configuration(websocket) will be used. | | `requestBuffer` | _[RequestBuffer](#requestbuffer)_ | false | | RequestBuffer allows the gateway to buffer and fully receive each request from a client before continuing to send the request
upstream to the backends. This can be helpful to shield your backend servers from slow clients, and also to enforce a maximum size per request
as any requests larger than the buffer size will be rejected.
This can have a negative performance impact so should only be enabled when necessary.
When enabling this option, you should also configure your connection buffer size to account for these request buffers. There will also be an
increase in memory usage for Envoy that should be accounted for in your deployment settings. | | `telemetry` | _[BackendTelemetry](#backendtelemetry)_ | false | | Telemetry configures the telemetry settings for the policy target (Gateway or xRoute).
This will override the telemetry settings in the EnvoyProxy resource. | +| `routingType` | _[RoutingType](#routingtype)_ | false | | RoutingType can be set to "Service" to use the Service Cluster IP for routing to the backend,
or it can be set to "Endpoint" to use Endpoint routing.
When specified, this overrides the EnvoyProxy-level setting for the relevant targetRefs.
If not specified, the EnvoyProxy-level setting is used. | #### BackendType diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index a38447564d..3fc55f77f2 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -23440,7 +23440,7 @@ spec: description: |- RoutingType can be set to "Service" to use the Service Cluster IP for routing to the backend, or it can be set to "Endpoint" to use Endpoint routing. - When specified, this overrides the EnvoyProxy-level setting for the relevant targeRefs. + When specified, this overrides the EnvoyProxy-level setting for the relevant targetRefs. If not specified, the EnvoyProxy-level setting is used. type: string targetRef: diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index ba8d3a77c7..e14193e5a5 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -2770,7 +2770,7 @@ spec: description: |- RoutingType can be set to "Service" to use the Service Cluster IP for routing to the backend, or it can be set to "Endpoint" to use Endpoint routing. - When specified, this overrides the EnvoyProxy-level setting for the relevant targeRefs. + When specified, this overrides the EnvoyProxy-level setting for the relevant targetRefs. If not specified, the EnvoyProxy-level setting is used. type: string targetRef: