diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 852cc201d28..1a2df010dae 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -339,8 +339,8 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen } } - for _, ir := range xdsIR { - for _, tcp := range ir.TCP { + for _, x := range xdsIR { + for _, tcp := range x.TCP { for _, r := range tcp.Routes { if strings.HasPrefix(r.Destination.Name, prefix) { r.LoadBalancer = lb @@ -353,34 +353,37 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen } } - for _, udp := range ir.UDP { + for _, udp := range x.UDP { if strings.HasPrefix(udp.Destination.Name, prefix) { udp.LoadBalancer = lb udp.Timeout = to } } - for _, http := range ir.HTTP { + for _, http := range x.HTTP { for _, r := range http.Routes { // Apply if there is a match if strings.HasPrefix(r.Name, prefix) { - r.RateLimit = rl - r.LoadBalancer = lb - r.ProxyProtocol = pp - r.HealthCheck = hc + r.Traffic = &ir.TrafficFeatures{ + RateLimit: rl, + LoadBalancer: lb, + ProxyProtocol: pp, + HealthCheck: hc, + CircuitBreaker: cb, + FaultInjection: fi, + TCPKeepalive: ka, + Retry: rt, + } + // Update the Host field in HealthCheck, now that we have access to the Route Hostname. - r.HealthCheck.SetHTTPHostIfAbsent(r.Hostname) - r.CircuitBreaker = cb - r.FaultInjection = fi - r.TCPKeepalive = ka - r.Retry = rt + r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname) - // some timeout setting originate from the route + // Some timeout setting originate from the route. if policy.Spec.Timeout != nil { if to, err = t.buildTimeout(policy, r); err != nil { return errors.Wrap(err, "Timeout") } - r.Timeout = to + r.Traffic.Timeout = to } if policy.Spec.UseClientProtocol != nil { @@ -445,7 +448,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back // set by a policy attaching to the route irKey := t.getIRKey(gateway.Gateway) // Should exist since we've validated this - ir := xdsIR[irKey] + x := xdsIR[irKey] policyTarget := irStringKey(policy.Namespace, string(policy.Spec.TargetRef.Name)) @@ -455,7 +458,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back } } - for _, tcp := range ir.TCP { + for _, tcp := range x.TCP { gatewayName := tcp.Name[0:strings.LastIndex(tcp.Name, "/")] if t.MergeGateways && gatewayName != policyTarget { continue @@ -481,7 +484,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back } } - for _, udp := range ir.UDP { + for _, udp := range x.UDP { gatewayName := udp.Name[0:strings.LastIndex(udp.Name, "/")] if t.MergeGateways && gatewayName != policyTarget { continue @@ -498,7 +501,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back } } - for _, http := range ir.HTTP { + for _, http := range x.HTTP { gatewayName := http.Name[0:strings.LastIndex(http.Name, "/")] if t.MergeGateways && gatewayName != policyTarget { continue @@ -509,52 +512,29 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back for _, r := range http.Routes { // If any of the features are already set, it means that a more specific // policy(targeting xRoute) has already set it, so we skip it. - // TODO: zhaohuabing group the features into a struct and check if all of them are set - if r.RateLimit != nil || r.LoadBalancer != nil || - r.ProxyProtocol != nil || r.HealthCheck != nil || - r.CircuitBreaker != nil || r.FaultInjection != nil || - r.TCPKeepalive != nil || r.Retry != nil || - r.Timeout != nil { + if r.Traffic != nil { continue } - // Apply if not already set - if r.RateLimit == nil { - r.RateLimit = rl - } - if r.LoadBalancer == nil { - r.LoadBalancer = lb - } - if r.ProxyProtocol == nil { - r.ProxyProtocol = pp - } - if r.HealthCheck == nil { - r.HealthCheck = hc - // Update the Host field in HealthCheck, now that we have access to the Route Hostname. - r.HealthCheck.SetHTTPHostIfAbsent(r.Hostname) + r.Traffic = &ir.TrafficFeatures{ + RateLimit: rl, + LoadBalancer: lb, + ProxyProtocol: pp, + HealthCheck: hc, + CircuitBreaker: cb, + FaultInjection: fi, + TCPKeepalive: ka, + Retry: rt, } - if r.CircuitBreaker == nil { - r.CircuitBreaker = cb - } - if r.FaultInjection == nil { - r.FaultInjection = fi - } - if r.TCPKeepalive == nil { - r.TCPKeepalive = ka - } - if r.Retry == nil { - r.Retry = rt - } + // Update the Host field in HealthCheck, now that we have access to the Route Hostname. + r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname) if policy.Spec.Timeout != nil { if ct, err = t.buildTimeout(policy, r); err != nil { return errors.Wrap(err, "Timeout") } - - if r.Timeout == nil { - r.Timeout = ct - } + r.Traffic.Timeout = ct } if policy.Spec.UseClientProtocol != nil { @@ -1066,13 +1046,17 @@ func (t *Translator) buildTimeout(policy *egv1a1.BackendTrafficPolicy, r *ir.HTT // http request timeout is translated during the gateway-api route resource translation // merge route timeout setting with backendtrafficpolicy timeout settings - if r != nil && r.Timeout != nil && r.Timeout.HTTP != nil && r.Timeout.HTTP.RequestTimeout != nil { + if r != nil && + r.Traffic != nil && + r.Traffic.Timeout != nil && + r.Traffic.Timeout.HTTP != nil && + r.Traffic.Timeout.HTTP.RequestTimeout != nil { if hto == nil { hto = &ir.HTTPTimeout{ - RequestTimeout: r.Timeout.HTTP.RequestTimeout, + RequestTimeout: r.Traffic.Timeout.HTTP.RequestTimeout, } } else { - hto.RequestTimeout = r.Timeout.HTTP.RequestTimeout + hto.RequestTimeout = r.Traffic.Timeout.HTTP.RequestTimeout } } diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index d10331ca21b..8abbac6c8b0 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -248,8 +248,8 @@ func processTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) { var rto *ir.Timeout // Timeout is translated from multiple resources and may already be partially set - if irRoute.Timeout != nil { - rto = irRoute.Timeout.DeepCopy() + if irRoute.Traffic != nil && irRoute.Traffic.Timeout != nil { + rto = irRoute.Traffic.Timeout.DeepCopy() } else { rto = &ir.Timeout{} } @@ -272,7 +272,9 @@ func processTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) { setRequestTimeout(rto, metav1.Duration{Duration: d}) } - irRoute.Timeout = rto + irRoute.Traffic = &ir.TrafficFeatures{ + Timeout: rto, + } } } @@ -681,14 +683,18 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route URLRewrite: routeRoute.URLRewrite, Mirrors: routeRoute.Mirrors, ExtensionRefs: routeRoute.ExtensionRefs, - Timeout: routeRoute.Timeout, - Retry: routeRoute.Retry, IsHTTP2: routeRoute.IsHTTP2, } // Don't bother copying over the weights unless the route has invalid backends. if routeRoute.BackendWeights.Invalid > 0 { hostRoute.BackendWeights = routeRoute.BackendWeights } + if routeRoute.Traffic != nil { + hostRoute.Traffic = &ir.TrafficFeatures{ + Timeout: routeRoute.Traffic.Timeout, + Retry: routeRoute.Traffic.Retry, + } + } perHostRoutes = append(perHostRoutes, hostRoute) } } diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index c7862d3ccb0..e68cf3fabae 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -465,7 +465,7 @@ func (t *Translator) translateSecurityPolicyForGateway( for _, r := range h.Routes { // If any of the features are already set, it means that a more specific // policy(targeting xRoute) has already set it, so we skip it. - if !r.Security.Empty() { + if r.Security != nil { continue } diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml index b6cf931638c..c5ad9495b2f 100755 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml @@ -232,14 +232,15 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - loadBalancer: - consistentHash: - sourceIP: true name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /foo + traffic: + loadBalancer: + consistentHash: + sourceIP: true - backendWeights: invalid: 0 valid: 0 @@ -254,16 +255,17 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - loadBalancer: - random: {} name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /bar - timeout: - http: - connectionIdleTimeout: 21s - maxConnectionDuration: 22s - tcp: - connectTimeout: 20s + traffic: + loadBalancer: + random: {} + timeout: + http: + connectionIdleTimeout: 21s + maxConnectionDuration: 22s + tcp: + connectTimeout: 20s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml index 41088add2e6..edbf09d0398 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml @@ -557,6 +557,7 @@ xdsIR: distinct: false name: "" prefix: / + traffic: {} envoy-gateway/gateway-2: accessLog: text: @@ -584,6 +585,7 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/envoy-gateway/grpcroute-1/rule/0/match/0/* + traffic: {} tcp: - address: 0.0.0.0 name: envoy-gateway/gateway-2/tcp diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml index 7d786784105..31566cafdfa 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml @@ -351,16 +351,17 @@ xdsIR: port: 8080 protocol: GRPC weight: 1 - faultInjection: - abort: - grpcStatus: 14 - percentage: 100 - delay: - fixedDelay: 5.4s - percentage: 80 hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + traffic: + faultInjection: + abort: + grpcStatus: 14 + percentage: 100 + delay: + fixedDelay: 5.4s + percentage: 80 envoy-gateway/gateway-2: accessLog: text: @@ -388,10 +389,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - faultInjection: - abort: - httpStatus: 14 - percentage: 0.01 hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io @@ -399,6 +396,11 @@ xdsIR: distinct: false name: "" prefix: /route2 + traffic: + faultInjection: + abort: + httpStatus: 14 + percentage: 0.01 - backendWeights: invalid: 0 valid: 0 @@ -411,13 +413,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - faultInjection: - abort: - httpStatus: 500 - percentage: 100 - delay: - fixedDelay: 5.4s - percentage: 80 hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io @@ -425,3 +420,11 @@ xdsIR: distinct: false name: "" prefix: / + traffic: + faultInjection: + abort: + httpStatus: 500 + percentage: 100 + delay: + fixedDelay: 5.4s + percentage: 80 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml index 5711eea324e..2f43d16b48b 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml @@ -156,4 +156,5 @@ xdsIR: distinct: false name: "" prefix: / + traffic: {} useClientProtocol: true diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml index aa471f54709..b3f265b9b62 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml @@ -266,12 +266,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - circuitBreaker: - maxConnections: 2048 - maxParallelRequests: 4294967295 - maxParallelRetries: 1024 - maxPendingRequests: 1 - maxRequestsPerConnection: 1 destination: name: grpcroute/default/grpcroute-1/rule/0 settings: @@ -284,6 +278,13 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + traffic: + circuitBreaker: + maxConnections: 2048 + maxParallelRequests: 4294967295 + maxParallelRetries: 1024 + maxPendingRequests: 1 + maxRequestsPerConnection: 1 envoy-gateway/gateway-2: accessLog: text: @@ -302,12 +303,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - circuitBreaker: - maxConnections: 42 - maxParallelRequests: 42 - maxParallelRetries: 24 - maxPendingRequests: 42 - maxRequestsPerConnection: 42 destination: name: httproute/default/httproute-1/rule/0 settings: @@ -324,3 +319,10 @@ xdsIR: distinct: false name: "" prefix: / + traffic: + circuitBreaker: + maxConnections: 42 + maxParallelRequests: 42 + maxParallelRetries: 24 + maxPendingRequests: 42 + maxRequestsPerConnection: 42 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml index b49ec2daf65..ee23bed198b 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml @@ -483,32 +483,33 @@ xdsIR: port: 8080 protocol: GRPC weight: 1 - healthCheck: - active: - healthyThreshold: 1 - http: - expectedResponse: - binary: RXZlcnl0aGluZyBPSw== - expectedStatuses: - - 200 - - 300 - host: '*' - method: GET - path: /healthz - interval: 3s - timeout: 500ms - unhealthyThreshold: 3 - passive: - baseEjectionTime: 2m40s - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - interval: 2s - maxEjectionPercent: 100 - splitExternalLocalOriginErrors: false hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + traffic: + healthCheck: + active: + healthyThreshold: 1 + http: + expectedResponse: + binary: RXZlcnl0aGluZyBPSw== + expectedStatuses: + - 200 + - 300 + host: '*' + method: GET + path: /healthz + interval: 3s + timeout: 500ms + unhealthyThreshold: 3 + passive: + baseEjectionTime: 2m40s + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + interval: 2s + maxEjectionPercent: 100 + splitExternalLocalOriginErrors: false envoy-gateway/gateway-2: accessLog: text: @@ -536,25 +537,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - healthCheck: - active: - healthyThreshold: 3 - interval: 5s - tcp: - receive: - text: pong - send: - text: ping - timeout: 1s - unhealthyThreshold: 3 - passive: - baseEjectionTime: 10s - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - interval: 10s - maxEjectionPercent: 10 - splitExternalLocalOriginErrors: false hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io @@ -562,6 +544,26 @@ xdsIR: distinct: false name: "" prefix: /v2 + traffic: + healthCheck: + active: + healthyThreshold: 3 + interval: 5s + tcp: + receive: + text: pong + send: + text: ping + timeout: 1s + unhealthyThreshold: 3 + passive: + baseEjectionTime: 10s + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + interval: 10s + maxEjectionPercent: 10 + splitExternalLocalOriginErrors: false - backendWeights: invalid: 0 valid: 0 @@ -574,25 +576,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - healthCheck: - active: - healthyThreshold: 1 - interval: 3s - tcp: - receive: - binary: RXZlcnl0aGluZyBPSw== - send: - binary: cGluZw== - timeout: 1s - unhealthyThreshold: 3 - passive: - baseEjectionTime: 2m40s - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - interval: 8ms - maxEjectionPercent: 11 - splitExternalLocalOriginErrors: false hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io @@ -600,6 +583,26 @@ xdsIR: distinct: false name: "" prefix: /v3 + traffic: + healthCheck: + active: + healthyThreshold: 1 + interval: 3s + tcp: + receive: + binary: RXZlcnl0aGluZyBPSw== + send: + binary: cGluZw== + timeout: 1s + unhealthyThreshold: 3 + passive: + baseEjectionTime: 2m40s + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + interval: 8ms + maxEjectionPercent: 11 + splitExternalLocalOriginErrors: false - backendWeights: invalid: 0 valid: 0 @@ -612,29 +615,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - healthCheck: - active: - healthyThreshold: 3 - http: - expectedResponse: - text: pong - expectedStatuses: - - 200 - - 201 - host: gateway.envoyproxy.io - method: GET - path: /healthz - interval: 5s - timeout: 1s - unhealthyThreshold: 3 - passive: - baseEjectionTime: 2m30s - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - interval: 1s - maxEjectionPercent: 100 - splitExternalLocalOriginErrors: false hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io @@ -642,3 +622,27 @@ xdsIR: distinct: false name: "" prefix: / + traffic: + healthCheck: + active: + healthyThreshold: 3 + http: + expectedResponse: + text: pong + expectedStatuses: + - 200 + - 201 + host: gateway.envoyproxy.io + method: GET + path: /healthz + interval: 5s + timeout: 1s + unhealthyThreshold: 3 + passive: + baseEjectionTime: 2m30s + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + interval: 1s + maxEjectionPercent: 100 + splitExternalLocalOriginErrors: false diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml index d308794c035..6114cd008d6 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml @@ -374,9 +374,10 @@ xdsIR: weight: 1 hostname: '*' isHTTP2: true - loadBalancer: - random: {} name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + traffic: + loadBalancer: + random: {} envoy-gateway/gateway-2: accessLog: text: @@ -406,15 +407,16 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - loadBalancer: - leastRequest: - slowStart: - window: 5m0s name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /test2 + traffic: + loadBalancer: + leastRequest: + slowStart: + window: 5m0s - backendWeights: invalid: 0 valid: 0 @@ -429,11 +431,12 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - loadBalancer: - consistentHash: - sourceIP: true name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: / + traffic: + loadBalancer: + consistentHash: + sourceIP: true diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml index dcd8184887d..c55cf63331e 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml @@ -179,34 +179,35 @@ xdsIR: distinct: false name: "" prefix: / - rateLimit: - local: - default: - requests: 4294967295 - unit: Second - rules: - - headerMatches: - - distinct: false - exact: one - name: x-user-id - - distinct: false - exact: foo - name: x-org-id - limit: - requests: 10 - unit: Hour - - cidrMatch: - cidr: 192.168.0.0/16 - distinct: false - ipv6: false - maskLen: 16 - headerMatches: - - distinct: false - exact: two - name: x-user-id - - distinct: false - exact: bar - name: x-org-id - limit: - requests: 10 - unit: Minute + traffic: + rateLimit: + local: + default: + requests: 4294967295 + unit: Second + rules: + - headerMatches: + - distinct: false + exact: one + name: x-user-id + - distinct: false + exact: foo + name: x-org-id + limit: + requests: 10 + unit: Hour + - cidrMatch: + cidr: 192.168.0.0/16 + distinct: false + ipv6: false + maskLen: 16 + headerMatches: + - distinct: false + exact: two + name: x-user-id + - distinct: false + exact: bar + name: x-org-id + limit: + requests: 10 + unit: Minute diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml index b331cd6fa82..9c9d73f35cb 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml @@ -182,34 +182,35 @@ xdsIR: distinct: false name: "" prefix: / - rateLimit: - local: - default: - requests: 10 - unit: Minute - rules: - - headerMatches: - - distinct: false - exact: one - name: x-user-id - - distinct: false - exact: foo - name: x-org-id - limit: - requests: 10 - unit: Hour - - cidrMatch: - cidr: 192.168.0.0/16 - distinct: false - ipv6: false - maskLen: 16 - headerMatches: - - distinct: false - exact: two - name: x-user-id - - distinct: false - exact: bar - name: x-org-id - limit: + traffic: + rateLimit: + local: + default: requests: 10 unit: Minute + rules: + - headerMatches: + - distinct: false + exact: one + name: x-user-id + - distinct: false + exact: foo + name: x-org-id + limit: + requests: 10 + unit: Hour + - cidrMatch: + cidr: 192.168.0.0/16 + distinct: false + ipv6: false + maskLen: 16 + headerMatches: + - distinct: false + exact: two + name: x-user-id + - distinct: false + exact: bar + name: x-org-id + limit: + requests: 10 + unit: Minute diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml index 8e6332a019e..92245edd5cc 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml @@ -270,8 +270,9 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* - proxyProtocol: - version: V1 + traffic: + proxyProtocol: + version: V1 envoy-gateway/gateway-2: accessLog: text: @@ -306,5 +307,6 @@ xdsIR: distinct: false name: "" prefix: / - proxyProtocol: - version: V2 + traffic: + proxyProtocol: + version: V2 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml index d3d6c8eb53a..7a8ea390fff 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml @@ -290,18 +290,19 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* - rateLimit: - global: - rules: - - headerMatches: - - distinct: false - exact: one - name: x-user-id - - distinct: true - name: x-org-id - limit: - requests: 10 - unit: Hour + traffic: + rateLimit: + global: + rules: + - headerMatches: + - distinct: false + exact: one + name: x-user-id + - distinct: true + name: x-org-id + limit: + requests: 10 + unit: Hour envoy-gateway/gateway-2: accessLog: text: @@ -336,15 +337,16 @@ xdsIR: distinct: false name: "" prefix: / - rateLimit: - global: - rules: - - cidrMatch: - cidr: 192.168.0.0/16 - distinct: true - ipv6: false - maskLen: 16 - headerMatches: [] - limit: - requests: 20 - unit: Hour + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: 192.168.0.0/16 + distinct: true + ipv6: false + maskLen: 16 + headerMatches: [] + limit: + requests: 20 + unit: Hour diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml index ae83655a6a1..e2db512f82a 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml @@ -289,15 +289,16 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* - retry: - perRetry: - backOff: - baseInterval: 100ms - maxInterval: 10s - timeout: 250ms - retryOn: - triggers: - - cancelled + traffic: + retry: + perRetry: + backOff: + baseInterval: 100ms + maxInterval: 10s + timeout: 250ms + retryOn: + triggers: + - cancelled envoy-gateway/gateway-2: accessLog: text: @@ -332,17 +333,18 @@ xdsIR: distinct: false name: "" prefix: / - retry: - numRetries: 5 - perRetry: - backOff: - baseInterval: 100ms - maxInterval: 10s - timeout: 250ms - retryOn: - httpStatusCodes: - - 429 - - 503 - triggers: - - connect-failure - - retriable-status-codes + traffic: + retry: + numRetries: 5 + perRetry: + backOff: + baseInterval: 100ms + maxInterval: 10s + timeout: 250ms + retryOn: + httpStatusCodes: + - 429 + - 503 + triggers: + - connect-failure + - retriable-status-codes diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml index c9a22a8334c..ad6bbe269ee 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml @@ -182,10 +182,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - circuitBreaker: - maxConnections: 2048 - maxParallelRequests: 4294967295 - maxPendingRequests: 1 destination: name: httproute/default/httproute-1/rule/0 settings: @@ -202,6 +198,11 @@ xdsIR: distinct: false name: "" prefix: / + traffic: + circuitBreaker: + maxConnections: 2048 + maxParallelRequests: 4294967295 + maxPendingRequests: 1 - backendWeights: invalid: 0 valid: 0 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml index eb796b42f56..902cdd31384 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml @@ -274,10 +274,11 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* - tcpKeepalive: - idleTime: 1200 - interval: 60 - probes: 3 + traffic: + tcpKeepalive: + idleTime: 1200 + interval: 60 + probes: 3 envoy-gateway/gateway-2: accessLog: text: @@ -312,7 +313,8 @@ xdsIR: distinct: false name: "" prefix: / - tcpKeepalive: - idleTime: 10 - interval: 1800 - probes: 6 + traffic: + tcpKeepalive: + idleTime: 10 + interval: 1800 + probes: 6 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml index 27ed1f54077..b7dc2f6a064 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml @@ -278,12 +278,13 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* - timeout: - http: - connectionIdleTimeout: 16s - maxConnectionDuration: 17s - tcp: - connectTimeout: 15s + traffic: + timeout: + http: + connectionIdleTimeout: 16s + maxConnectionDuration: 17s + tcp: + connectTimeout: 15s envoy-gateway/gateway-2: accessLog: text: @@ -318,9 +319,10 @@ xdsIR: distinct: false name: "" prefix: / - timeout: - http: - connectionIdleTimeout: 21s - maxConnectionDuration: 22s - tcp: - connectTimeout: 20s + traffic: + timeout: + http: + connectionIdleTimeout: 21s + maxConnectionDuration: 22s + tcp: + connectTimeout: 20s diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml index b6093872e45..3a85ecb7c9e 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml @@ -163,6 +163,7 @@ xdsIR: distinct: false name: "" prefix: / - timeout: - http: - requestTimeout: 1s + traffic: + timeout: + http: + requestTimeout: 1s diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml index 2f060c2db49..097b37b516a 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml @@ -279,12 +279,13 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* - timeout: - http: - connectionIdleTimeout: 16s - maxConnectionDuration: 17s - tcp: - connectTimeout: 15s + traffic: + timeout: + http: + connectionIdleTimeout: 16s + maxConnectionDuration: 17s + tcp: + connectTimeout: 15s envoy-gateway/gateway-2: accessLog: text: @@ -319,9 +320,9 @@ xdsIR: distinct: false name: "" prefix: / - timeout: - http: - maxConnectionDuration: 22s - requestTimeout: 1s - tcp: - connectTimeout: 20s + traffic: + timeout: + http: + maxConnectionDuration: 22s + tcp: + connectTimeout: 20s diff --git a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml index f56835ccb2e..33076734d2d 100644 --- a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml @@ -129,6 +129,7 @@ xdsIR: distinct: false name: "" prefix: / - timeout: - http: - requestTimeout: 1s + traffic: + timeout: + http: + requestTimeout: 1s diff --git a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml index 3d3f73076ee..49c64cfe615 100644 --- a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml @@ -129,6 +129,7 @@ xdsIR: distinct: false name: "" prefix: / - timeout: - http: - requestTimeout: 5s + traffic: + timeout: + http: + requestTimeout: 5s diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml index 674289ecd64..62df76b1ba8 100755 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml @@ -546,10 +546,11 @@ xdsIR: - x-header-7 - x-header-8 maxAge: 33m20s - tcpKeepalive: - idleTime: 1200 - interval: 60 - probes: 3 + traffic: + tcpKeepalive: + idleTime: 1200 + interval: 60 + probes: 3 timeout: http: requestReceivedTimeout: 5s @@ -598,10 +599,11 @@ xdsIR: - x-header-7 - x-header-8 maxAge: 33m20s - tcpKeepalive: - idleTime: 1200 - interval: 60 - probes: 3 + traffic: + tcpKeepalive: + idleTime: 1200 + interval: 60 + probes: 3 timeout: http: requestReceivedTimeout: 5s diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml index d2bc2693cbf..9c3438bffa9 100644 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml @@ -338,10 +338,11 @@ xdsIR: - x-header-7 - x-header-8 maxAge: 33m20s - tcpKeepalive: - idleTime: 1200 - interval: 60 - probes: 3 + traffic: + tcpKeepalive: + idleTime: 1200 + interval: 60 + probes: 3 - address: 0.0.0.0 hostnames: - '*' diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 126e8f8fbeb..25e3f583461 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -476,6 +476,24 @@ type HTTPRoute struct { Destination *RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"` // Rewrite to be changed for this route. URLRewrite *URLRewrite `json:"urlRewrite,omitempty" yaml:"urlRewrite,omitempty"` + // ExtensionRefs holds unstructured resources that were introduced by an extension and used on the HTTPRoute as extensionRef filters + ExtensionRefs []*UnstructuredRef `json:"extensionRefs,omitempty" yaml:"extensionRefs,omitempty"` + // External Processing extensions + ExtProcs []ExtProc `json:"extProc,omitempty" yaml:"extProc,omitempty"` + // Wasm extensions + Wasms []Wasm `json:"wasm,omitempty" yaml:"wasm,omitempty"` + + // Traffic holds the features associated with BackendTrafficPolicy + Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"` + // Security holds the features associated with SecurityPolicy + Security *SecurityFeatures `json:"security,omitempty" yaml:"security,omitempty"` + // UseClientProtocol enables using the same protocol upstream that was used downstream + UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"` +} + +// TrafficFeatures holds the information associated with the Backend Traffic Policy. +// +k8s:deepcopy-gen=true +type TrafficFeatures struct { // RateLimit defines the more specific match conditions as well as limits for ratelimiting // the requests on this route. RateLimit *RateLimit `json:"rateLimit,omitempty" yaml:"rateLimit,omitempty"` @@ -487,8 +505,6 @@ type HTTPRoute struct { HealthCheck *HealthCheck `json:"healthCheck,omitempty" yaml:"healthCheck,omitempty"` // FaultInjection defines the schema for injecting faults into HTTP requests. FaultInjection *FaultInjection `json:"faultInjection,omitempty" yaml:"faultInjection,omitempty"` - // ExtensionRefs holds unstructured resources that were introduced by an extension and used on the HTTPRoute as extensionRef filters - ExtensionRefs []*UnstructuredRef `json:"extensionRefs,omitempty" yaml:"extensionRefs,omitempty"` // Circuit Breaker Settings CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"` // Request and connection timeout settings @@ -497,15 +513,23 @@ type HTTPRoute struct { TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"` // Retry settings Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` - // External Processing extensions - ExtProcs []ExtProc `json:"extProc,omitempty" yaml:"extProc,omitempty"` - // Wasm extensions - Wasms []Wasm `json:"wasm,omitempty" yaml:"wasm,omitempty"` +} - // Security holds the features associated with SecurityPolicy - Security *SecurityFeatures `json:"security,omitempty" yaml:"security,omitempty"` - // UseClientProtocol enables using the same protocol upstream that was used downstream - UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"` +func (b *TrafficFeatures) Validate() error { + var errs error + + if b.LoadBalancer != nil { + if err := b.LoadBalancer.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + if b.HealthCheck != nil { + if err := b.HealthCheck.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + + return errs } // SecurityFeatures holds the information associated with the Security Policy. @@ -523,19 +547,6 @@ type SecurityFeatures struct { ExtAuth *ExtAuth `json:"extAuth,omitempty" yaml:"extAuth,omitempty"` } -// Empty returns true if all the features are not set. -func (s *SecurityFeatures) Empty() bool { - if s == nil { - return true - } - - return s.CORS == nil && - s.JWT == nil && - s.OIDC == nil && - s.BasicAuth == nil && - s.ExtAuth == nil -} - func (s *SecurityFeatures) Printable() *SecurityFeatures { out := s.DeepCopy() if out.OIDC != nil { @@ -872,8 +883,8 @@ func (h HTTPRoute) Validate() error { occurred.Insert(header) } } - if h.LoadBalancer != nil { - if err := h.LoadBalancer.Validate(); err != nil { + if h.Traffic != nil { + if err := h.Traffic.Validate(); err != nil { errs = errors.Join(errs, err) } } @@ -882,11 +893,6 @@ func (h HTTPRoute) Validate() error { errs = errors.Join(errs, err) } } - if h.HealthCheck != nil { - if err := h.HealthCheck.Validate(); err != nil { - errs = errors.Join(errs, err) - } - } return errs } diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index bd0ce421a7a..514543c80a9 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1021,31 +1021,6 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { *out = new(URLRewrite) (*in).DeepCopyInto(*out) } - if in.RateLimit != nil { - in, out := &in.RateLimit, &out.RateLimit - *out = new(RateLimit) - (*in).DeepCopyInto(*out) - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(LoadBalancer) - (*in).DeepCopyInto(*out) - } - if in.ProxyProtocol != nil { - in, out := &in.ProxyProtocol, &out.ProxyProtocol - *out = new(ProxyProtocol) - **out = **in - } - if in.HealthCheck != nil { - in, out := &in.HealthCheck, &out.HealthCheck - *out = new(HealthCheck) - (*in).DeepCopyInto(*out) - } - if in.FaultInjection != nil { - in, out := &in.FaultInjection, &out.FaultInjection - *out = new(FaultInjection) - (*in).DeepCopyInto(*out) - } if in.ExtensionRefs != nil { in, out := &in.ExtensionRefs, &out.ExtensionRefs *out = make([]*UnstructuredRef, len(*in)) @@ -1057,26 +1032,6 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { } } } - if in.CircuitBreaker != nil { - in, out := &in.CircuitBreaker, &out.CircuitBreaker - *out = new(CircuitBreaker) - (*in).DeepCopyInto(*out) - } - if in.Timeout != nil { - in, out := &in.Timeout, &out.Timeout - *out = new(Timeout) - (*in).DeepCopyInto(*out) - } - if in.TCPKeepalive != nil { - in, out := &in.TCPKeepalive, &out.TCPKeepalive - *out = new(TCPKeepalive) - (*in).DeepCopyInto(*out) - } - if in.Retry != nil { - in, out := &in.Retry, &out.Retry - *out = new(Retry) - (*in).DeepCopyInto(*out) - } if in.ExtProcs != nil { in, out := &in.ExtProcs, &out.ExtProcs *out = make([]ExtProc, len(*in)) @@ -1091,6 +1046,11 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = new(TrafficFeatures) + (*in).DeepCopyInto(*out) + } if in.Security != nil { in, out := &in.Security, &out.Security *out = new(SecurityFeatures) @@ -2424,6 +2384,66 @@ func (in *Tracing) DeepCopy() *Tracing { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) { + *out = *in + if in.RateLimit != nil { + in, out := &in.RateLimit, &out.RateLimit + *out = new(RateLimit) + (*in).DeepCopyInto(*out) + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancer) + (*in).DeepCopyInto(*out) + } + if in.ProxyProtocol != nil { + in, out := &in.ProxyProtocol, &out.ProxyProtocol + *out = new(ProxyProtocol) + **out = **in + } + if in.HealthCheck != nil { + in, out := &in.HealthCheck, &out.HealthCheck + *out = new(HealthCheck) + (*in).DeepCopyInto(*out) + } + if in.FaultInjection != nil { + in, out := &in.FaultInjection, &out.FaultInjection + *out = new(FaultInjection) + (*in).DeepCopyInto(*out) + } + if in.CircuitBreaker != nil { + in, out := &in.CircuitBreaker, &out.CircuitBreaker + *out = new(CircuitBreaker) + (*in).DeepCopyInto(*out) + } + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(Timeout) + (*in).DeepCopyInto(*out) + } + if in.TCPKeepalive != nil { + in, out := &in.TCPKeepalive, &out.TCPKeepalive + *out = new(TCPKeepalive) + (*in).DeepCopyInto(*out) + } + if in.Retry != nil { + in, out := &in.Retry, &out.Retry + *out = new(Retry) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures. +func (in *TrafficFeatures) DeepCopy() *TrafficFeatures { + if in == nil { + return nil + } + out := new(TrafficFeatures) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UDPListener) DeepCopyInto(out *UDPListener) { *out = *in diff --git a/internal/xds/translator/fault.go b/internal/xds/translator/fault.go index 46642934ce1..43fae199c47 100644 --- a/internal/xds/translator/fault.go +++ b/internal/xds/translator/fault.go @@ -36,7 +36,7 @@ var _ httpFilter = &fault{} // patchHCM builds and appends the fault Filters to the HTTP Connection Manager // if applicable, and it does not already exist. -// Note: this method creates an fault filter for each route that contains an Fault config. +// Note: this method creates a fault filter for each route that contains an Fault config. func (*fault) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { if mgr == nil { return errors.New("hcm is nil") @@ -99,7 +99,9 @@ func listenerContainsFault(irListener *ir.HTTPListener) bool { // routeContainsFault returns true if Fault exists for the provided route. func routeContainsFault(irRoute *ir.HTTPRoute) bool { - if irRoute != nil && irRoute.FaultInjection != nil { + if irRoute != nil && + irRoute.Traffic != nil && + irRoute.Traffic.FaultInjection != nil { return true } return false @@ -118,7 +120,7 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.FaultInjection == nil { + if irRoute.Traffic == nil || irRoute.Traffic.FaultInjection == nil { return nil } @@ -131,34 +133,35 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { routeCfgProto := &xdshttpfaultv3.HTTPFault{} - if irRoute.FaultInjection.Delay != nil { + delay := irRoute.Traffic.FaultInjection.Delay + if delay != nil { routeCfgProto.Delay = &xdsfault.FaultDelay{} - if irRoute.FaultInjection.Delay.Percentage != nil { - routeCfgProto.Delay.Percentage = translatePercentToFractionalPercent(irRoute.FaultInjection.Delay.Percentage) + if delay.Percentage != nil { + routeCfgProto.Delay.Percentage = translatePercentToFractionalPercent(delay.Percentage) } - if irRoute.FaultInjection.Delay.FixedDelay != nil { + if delay.FixedDelay != nil { routeCfgProto.Delay.FaultDelaySecifier = &xdsfault.FaultDelay_FixedDelay{ - FixedDelay: durationpb.New(irRoute.FaultInjection.Delay.FixedDelay.Duration), + FixedDelay: durationpb.New(delay.FixedDelay.Duration), } } } - if irRoute.FaultInjection.Abort != nil { + abort := irRoute.Traffic.FaultInjection.Abort + if abort != nil { routeCfgProto.Abort = &xdshttpfaultv3.FaultAbort{} - if irRoute.FaultInjection.Abort.Percentage != nil { - routeCfgProto.Abort.Percentage = translatePercentToFractionalPercent(irRoute.FaultInjection.Abort.Percentage) + if abort.Percentage != nil { + routeCfgProto.Abort.Percentage = translatePercentToFractionalPercent(abort.Percentage) } - if irRoute.FaultInjection.Abort.HTTPStatus != nil { + if abort.HTTPStatus != nil { routeCfgProto.Abort.ErrorType = &xdshttpfaultv3.FaultAbort_HttpStatus{ - HttpStatus: uint32(*irRoute.FaultInjection.Abort.HTTPStatus), + HttpStatus: uint32(*abort.HTTPStatus), } } - if irRoute.FaultInjection.Abort.GrpcStatus != nil { + if abort.GrpcStatus != nil { routeCfgProto.Abort.ErrorType = &xdshttpfaultv3.FaultAbort_GrpcStatus{ - GrpcStatus: uint32(*irRoute.FaultInjection.Abort.GrpcStatus), + GrpcStatus: uint32(*abort.GrpcStatus), } } - } if routeCfgProto.Delay == nil && routeCfgProto.Abort == nil { @@ -179,7 +182,7 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { return nil } -// translatePercentToFractionalPercent translates an v1alpha3 Percent instance +// translatePercentToFractionalPercent translates a v1alpha3 Percent instance // to an envoy.type.FractionalPercent instance. func translatePercentToFractionalPercent(p *float32) *xdstype.FractionalPercent { return &xdstype.FractionalPercent{ diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go index 688461e9fa2..1a0d88d5da0 100644 --- a/internal/xds/translator/local_ratelimit.go +++ b/internal/xds/translator/local_ratelimit.go @@ -96,7 +96,10 @@ func listenerContainsLocalRateLimit(irListener *ir.HTTPListener) bool { } func routeContainsLocalRateLimit(irRoute *ir.HTTPRoute) bool { - if irRoute == nil || irRoute.RateLimit == nil || irRoute.RateLimit.Local == nil { + if irRoute == nil || + irRoute.Traffic == nil || + irRoute.Traffic.RateLimit == nil || + irRoute.Traffic.RateLimit.Local == nil { return false } @@ -113,7 +116,7 @@ func (*localRateLimit) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) e routeAction := route.GetRoute() // Return early if no rate limit config exists. - if irRoute.RateLimit == nil || irRoute.RateLimit.Local == nil || routeAction == nil { + if !routeContainsLocalRateLimit(irRoute) || routeAction == nil { return nil } @@ -125,7 +128,7 @@ func (*localRateLimit) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) e route.Name) } - local := irRoute.RateLimit.Local + local := irRoute.Traffic.RateLimit.Local rateLimits, descriptors, err := buildRouteLocalRateLimits(local) if err != nil { diff --git a/internal/xds/translator/ratelimit.go b/internal/xds/translator/ratelimit.go index 02b1c3d6048..4534f303fe2 100644 --- a/internal/xds/translator/ratelimit.go +++ b/internal/xds/translator/ratelimit.go @@ -73,6 +73,17 @@ func (t *Translator) patchHCMWithRateLimit(mgr *hcmv3.HttpConnectionManager, irL mgr.HttpFilters = append([]*hcmv3.HttpFilter{rateLimitFilter}, mgr.HttpFilters...) } +func routeContainsGlobalRateLimit(irRoute *ir.HTTPRoute) bool { + if irRoute == nil || + irRoute.Traffic == nil || + irRoute.Traffic.RateLimit == nil || + irRoute.Traffic.RateLimit.Global == nil { + return false + } + + return true +} + // isRateLimitPresent returns true if rate limit config exists for the listener. func (t *Translator) isRateLimitPresent(irListener *ir.HTTPListener) bool { // Return false if global ratelimiting is disabled. @@ -81,7 +92,7 @@ func (t *Translator) isRateLimitPresent(irListener *ir.HTTPListener) bool { } // Return true if rate limit config exists. for _, route := range irListener.Routes { - if route.RateLimit != nil && route.RateLimit.Global != nil { + if routeContainsGlobalRateLimit(route) { return true } } @@ -128,11 +139,11 @@ func (t *Translator) buildRateLimitFilter(irListener *ir.HTTPListener) *hcmv3.Ht // patchRouteWithRateLimit builds rate limit actions and appends to the route. func patchRouteWithRateLimit(xdsRouteAction *routev3.RouteAction, irRoute *ir.HTTPRoute) error { //nolint:unparam // Return early if no rate limit config exists. - if irRoute.RateLimit == nil || irRoute.RateLimit.Global == nil || xdsRouteAction == nil { + if !routeContainsGlobalRateLimit(irRoute) || xdsRouteAction == nil { return nil } - rateLimits := buildRouteRateLimits(irRoute.Name, irRoute.RateLimit.Global) + rateLimits := buildRouteRateLimits(irRoute.Name, irRoute.Traffic.RateLimit.Global) xdsRouteAction.RateLimits = rateLimits return nil } @@ -287,8 +298,8 @@ func BuildRateLimitServiceConfig(irListener *ir.HTTPListener) *rlsconfv3.RateLim pbDescriptors := make([]*rlsconfv3.RateLimitDescriptor, 0, len(irListener.Routes)) for _, route := range irListener.Routes { - if route.RateLimit != nil && route.RateLimit.Global != nil { - serviceDescriptors := buildRateLimitServiceDescriptors(route.RateLimit.Global) + if routeContainsGlobalRateLimit(route) { + serviceDescriptors := buildRateLimitServiceDescriptors(route.Traffic.RateLimit.Global) // Get route rule descriptors within each route. // diff --git a/internal/xds/translator/route.go b/internal/xds/translator/route.go index a52371103f0..bf68ac7df45 100644 --- a/internal/xds/translator/route.go +++ b/internal/xds/translator/route.go @@ -10,8 +10,6 @@ import ( "strings" "time" - "github.com/envoyproxy/gateway/internal/utils/protocov" - corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" previoushost "github.com/envoyproxy/go-control-plane/envoy/extensions/retry/host/previous_hosts/v3" @@ -20,6 +18,7 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" "github.com/envoyproxy/gateway/internal/ir" + "github.com/envoyproxy/gateway/internal/utils/protocov" ) const ( @@ -99,13 +98,18 @@ func buildXdsRoute(httpRoute *ir.HTTPRoute) (*routev3.Route, error) { } // Timeouts - if router.GetRoute() != nil && httpRoute.Timeout != nil && httpRoute.Timeout.HTTP != nil && - httpRoute.Timeout.HTTP.RequestTimeout != nil { - router.GetRoute().Timeout = durationpb.New(httpRoute.Timeout.HTTP.RequestTimeout.Duration) + if router.GetRoute() != nil && + httpRoute.Traffic != nil && + httpRoute.Traffic.Timeout != nil && + httpRoute.Traffic.Timeout.HTTP != nil && + httpRoute.Traffic.Timeout.HTTP.RequestTimeout != nil { + router.GetRoute().Timeout = durationpb.New(httpRoute.Traffic.Timeout.HTTP.RequestTimeout.Duration) } // Retries - if router.GetRoute() != nil && httpRoute.Retry != nil { + if router.GetRoute() != nil && + httpRoute.Traffic != nil && + httpRoute.Traffic.Retry != nil { if rp, err := buildRetryPolicy(httpRoute); err == nil { router.GetRoute().RetryPolicy = rp } else { @@ -259,22 +263,24 @@ func buildXdsWeightedRouteAction(httpRoute *ir.HTTPRoute) *routev3.RouteAction { } func idleTimeout(httpRoute *ir.HTTPRoute) *durationpb.Duration { - if httpRoute.Timeout != nil && httpRoute.Timeout.HTTP != nil { - if httpRoute.Timeout.HTTP.RequestTimeout != nil { - timeout := time.Hour // Default to 1 hour + if httpRoute.Traffic != nil && + httpRoute.Traffic.Timeout != nil && + httpRoute.Traffic.Timeout.HTTP != nil && + httpRoute.Traffic.Timeout.HTTP.RequestTimeout != nil { + rt := httpRoute.Traffic.Timeout.HTTP.RequestTimeout + timeout := time.Hour // Default to 1 hour - // Ensure is not less than the request timeout - if timeout < httpRoute.Timeout.HTTP.RequestTimeout.Duration { - timeout = httpRoute.Timeout.HTTP.RequestTimeout.Duration - } - - // Disable idle timeout when request timeout is disabled - if httpRoute.Timeout.HTTP.RequestTimeout.Duration == 0 { - timeout = 0 - } + // Ensure is not less than the request timeout + if timeout < rt.Duration { + timeout = rt.Duration + } - return durationpb.New(timeout) + // Disable idle timeout when request timeout is disabled + if rt.Duration == 0 { + timeout = 0 } + + return durationpb.New(timeout) } return nil } @@ -436,22 +442,27 @@ func buildXdsAddedHeaders(headersToAdd []ir.AddHeader) []*corev3.HeaderValueOpti func buildHashPolicy(httpRoute *ir.HTTPRoute) []*routev3.RouteAction_HashPolicy { // Return early - if httpRoute == nil || httpRoute.LoadBalancer == nil || httpRoute.LoadBalancer.ConsistentHash == nil { + if httpRoute == nil || + httpRoute.Traffic == nil || + httpRoute.Traffic.LoadBalancer == nil || + httpRoute.Traffic.LoadBalancer.ConsistentHash == nil { return nil } + ch := httpRoute.Traffic.LoadBalancer.ConsistentHash + switch { - case httpRoute.LoadBalancer.ConsistentHash.Header != nil: + case ch.Header != nil: hashPolicy := &routev3.RouteAction_HashPolicy{ PolicySpecifier: &routev3.RouteAction_HashPolicy_Header_{ Header: &routev3.RouteAction_HashPolicy_Header{ - HeaderName: httpRoute.LoadBalancer.ConsistentHash.Header.Name, + HeaderName: ch.Header.Name, }, }, } return []*routev3.RouteAction_HashPolicy{hashPolicy} - case httpRoute.LoadBalancer.ConsistentHash.SourceIP != nil: - if !*httpRoute.LoadBalancer.ConsistentHash.SourceIP { + case ch.SourceIP != nil: + if !*ch.SourceIP { return nil } hashPolicy := &routev3.RouteAction_HashPolicy{ @@ -468,68 +479,64 @@ func buildHashPolicy(httpRoute *ir.HTTPRoute) []*routev3.RouteAction_HashPolicy } func buildRetryPolicy(route *ir.HTTPRoute) (*routev3.RetryPolicy, error) { - if route.Retry != nil { - rr := route.Retry - rp := &routev3.RetryPolicy{ - RetryOn: retryDefaultRetryOn, - RetriableStatusCodes: []uint32{retryDefaultRetriableStatusCode}, - NumRetries: &wrapperspb.UInt32Value{Value: retryDefaultNumRetries}, - RetryHostPredicate: []*routev3.RetryPolicy_RetryHostPredicate{ - { - Name: "envoy.retry_host_predicates.previous_hosts", - ConfigType: &routev3.RetryPolicy_RetryHostPredicate_TypedConfig{ - TypedConfig: protocov.ToAny(&previoushost.PreviousHostsPredicate{}), - }, + rr := route.Traffic.Retry + rp := &routev3.RetryPolicy{ + RetryOn: retryDefaultRetryOn, + RetriableStatusCodes: []uint32{retryDefaultRetriableStatusCode}, + NumRetries: &wrapperspb.UInt32Value{Value: retryDefaultNumRetries}, + RetryHostPredicate: []*routev3.RetryPolicy_RetryHostPredicate{ + { + Name: "envoy.retry_host_predicates.previous_hosts", + ConfigType: &routev3.RetryPolicy_RetryHostPredicate_TypedConfig{ + TypedConfig: protocov.ToAny(&previoushost.PreviousHostsPredicate{}), }, }, - HostSelectionRetryMaxAttempts: 5, - } + }, + HostSelectionRetryMaxAttempts: 5, + } - if rr.NumRetries != nil { - rp.NumRetries = &wrapperspb.UInt32Value{Value: *rr.NumRetries} - } + if rr.NumRetries != nil { + rp.NumRetries = &wrapperspb.UInt32Value{Value: *rr.NumRetries} + } - if rr.RetryOn != nil { - if rr.RetryOn.Triggers != nil && len(rr.RetryOn.Triggers) > 0 { - if ro, err := buildRetryOn(rr.RetryOn.Triggers); err == nil { - rp.RetryOn = ro - } else { - return nil, err - } + if rr.RetryOn != nil { + if rr.RetryOn.Triggers != nil && len(rr.RetryOn.Triggers) > 0 { + if ro, err := buildRetryOn(rr.RetryOn.Triggers); err == nil { + rp.RetryOn = ro + } else { + return nil, err } + } - if rr.RetryOn.HTTPStatusCodes != nil && len(rr.RetryOn.HTTPStatusCodes) > 0 { - rp.RetriableStatusCodes = buildRetryStatusCodes(rr.RetryOn.HTTPStatusCodes) - } + if rr.RetryOn.HTTPStatusCodes != nil && len(rr.RetryOn.HTTPStatusCodes) > 0 { + rp.RetriableStatusCodes = buildRetryStatusCodes(rr.RetryOn.HTTPStatusCodes) } + } - if rr.PerRetry != nil { - if rr.PerRetry.Timeout != nil { - rp.PerTryTimeout = durationpb.New(rr.PerRetry.Timeout.Duration) - } + if rr.PerRetry != nil { + if rr.PerRetry.Timeout != nil { + rp.PerTryTimeout = durationpb.New(rr.PerRetry.Timeout.Duration) + } - if rr.PerRetry.BackOff != nil { - bbo := false - rbo := &routev3.RetryPolicy_RetryBackOff{} - if rr.PerRetry.BackOff.BaseInterval != nil { - rbo.BaseInterval = durationpb.New(rr.PerRetry.BackOff.BaseInterval.Duration) - bbo = true - } + if rr.PerRetry.BackOff != nil { + bbo := false + rbo := &routev3.RetryPolicy_RetryBackOff{} + if rr.PerRetry.BackOff.BaseInterval != nil { + rbo.BaseInterval = durationpb.New(rr.PerRetry.BackOff.BaseInterval.Duration) + bbo = true + } - if rr.PerRetry.BackOff.MaxInterval != nil { - rbo.MaxInterval = durationpb.New(rr.PerRetry.BackOff.MaxInterval.Duration) - bbo = true - } + if rr.PerRetry.BackOff.MaxInterval != nil { + rbo.MaxInterval = durationpb.New(rr.PerRetry.BackOff.MaxInterval.Duration) + bbo = true + } - if bbo { - rp.RetryBackOff = rbo - } + if bbo { + rp.RetryBackOff = rbo } } - return rp, nil } - - return nil, nil + return rp, nil } func buildRetryStatusCodes(codes []ir.HTTPStatus) []uint32 { diff --git a/internal/xds/translator/route_test.go b/internal/xds/translator/route_test.go index ed9198b6c01..3d7d6a9727f 100644 --- a/internal/xds/translator/route_test.go +++ b/internal/xds/translator/route_test.go @@ -32,23 +32,39 @@ func Test_buildHashPolicy(t *testing.T) { want: nil, }, { - name: "Nil ConsistentHash in LoadBalancer", - httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{}}, - want: nil, + name: "Nil ConsistentHash in LoadBalancer", + httpRoute: &ir.HTTPRoute{ + Traffic: &ir.TrafficFeatures{ + LoadBalancer: &ir.LoadBalancer{}, + }, + }, + want: nil, }, { - name: "ConsistentHash with nil SourceIP and Header", - httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{}}}, - want: nil, + name: "ConsistentHash with nil SourceIP and Header", + httpRoute: &ir.HTTPRoute{ + Traffic: &ir.TrafficFeatures{ + LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{}}, + }, + }, + want: nil, }, { - name: "ConsistentHash with SourceIP set to false", - httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(false)}}}, - want: nil, + name: "ConsistentHash with SourceIP set to false", + httpRoute: &ir.HTTPRoute{ + Traffic: &ir.TrafficFeatures{ + LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(false)}}, + }, + }, + want: nil, }, { - name: "ConsistentHash with SourceIP set to true", - httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(true)}}}, + name: "ConsistentHash with SourceIP set to true", + httpRoute: &ir.HTTPRoute{ + Traffic: &ir.TrafficFeatures{ + LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(true)}}, + }, + }, want: []*routev3.RouteAction_HashPolicy{ { PolicySpecifier: &routev3.RouteAction_HashPolicy_ConnectionProperties_{ @@ -60,8 +76,12 @@ func Test_buildHashPolicy(t *testing.T) { }, }, { - name: "ConsistentHash with Header", - httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{Header: &ir.Header{Name: "name"}}}}, + name: "ConsistentHash with Header", + httpRoute: &ir.HTTPRoute{ + Traffic: &ir.TrafficFeatures{ + LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{Header: &ir.Header{Name: "name"}}}, + }, + }, want: []*routev3.RouteAction_HashPolicy{ { PolicySpecifier: &routev3.RouteAction_HashPolicy_Header_{ diff --git a/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml index 0f3f9749672..742805ac27d 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml @@ -8,15 +8,16 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - distinct: true - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + distinct: true + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml index 7ff820e7b8f..4fbb48de311 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml @@ -8,17 +8,18 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - cidrMatch: - cidr: "192.168.0.0/16" - ipv6: false - maskLen: 16 - distinct: true - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: "192.168.0.0/16" + ipv6: false + maskLen: 16 + distinct: true + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml b/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml index ca13b2132b9..0de76f96e46 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml @@ -8,12 +8,13 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml index 70531d48a82..4e21ae73cce 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml @@ -8,16 +8,17 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - cidrMatch: - cidr: "192.168.0.0/16" - ipv6: false - maskLen: 16 - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: "192.168.0.0/16" + ipv6: false + maskLen: 16 + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml index 32792f005b4..3f5dba6a9da 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml @@ -8,16 +8,17 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - cidrMatch: - cidr: "192.168.0.10/32" - ipv6: false - maskLen: 32 - limit: - requests: 15 - unit: Hour + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: "192.168.0.10/32" + ipv6: false + maskLen: 32 + limit: + requests: 15 + unit: Hour pathMatch: exact: "foo/bar" destination: @@ -27,16 +28,17 @@ routes: - host: "1.2.3.4" port: 50000 - name: "second-route" - rateLimit: - global: - rules: - - cidrMatch: - cidr: "192.168.0.10/32" - ipv6: false - maskLen: 32 - limit: - requests: 300 - unit: Hour + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: "192.168.0.10/32" + ipv6: false + maskLen: 32 + limit: + requests: 300 + unit: Hour pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml index 67de62abbda..bebb4cb14d7 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml @@ -8,17 +8,18 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - - name: "x-user-id" - exact: "two" - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + - name: "x-user-id" + exact: "two" + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml index c5a768c9b01..6db5c96e86a 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml @@ -8,27 +8,29 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second pathMatch: exact: "foo/baz" - name: "second-route" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "two" - limit: - requests: 10 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "two" + limit: + requests: 10 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml index ef9b8d22885..3267a695b59 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml @@ -8,21 +8,22 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - limit: - requests: 5 - unit: second - - headerMatches: - - name: "x-user-id" - exact: "two" - limit: - requests: 10 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second + - headerMatches: + - name: "x-user-id" + exact: "two" + limit: + requests: 10 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml index 8fc933e923a..a265cab5c27 100644 --- a/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml +++ b/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml @@ -8,15 +8,16 @@ path: escapedSlashesAction: UnescapeAndRedirect routes: - name: "first-route" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml b/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml index a63297e264c..f4dd3bbaa99 100644 --- a/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml @@ -10,12 +10,13 @@ http: routes: - name: "first-route" hostname: "*" - circuitBreaker: - maxConnections: 1 - maxPendingRequests: 1 - maxParallelRequests: 1 - maxParallelRetries: 2 - maxRequestsPerConnection: 10 + traffic: + circuitBreaker: + maxConnections: 1 + maxPendingRequests: 1 + maxParallelRequests: 1 + maxParallelRetries: 2 + maxRequestsPerConnection: 10 destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml index 06c44b051db..6c3cfa3aa4b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml @@ -20,4 +20,3 @@ http: http: requestReceivedTimeout: "5s" idleTimeout: "10s" - diff --git a/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml b/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml index a99b77d5e00..39b351eb6ec 100644 --- a/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml @@ -10,10 +10,11 @@ http: routes: - name: "first-route" hostname: "*" - faultInjection: - abort: - httpStatus: 500 - percentage: 0.01 + traffic: + faultInjection: + abort: + httpStatus: 500 + percentage: 0.01 pathMatch: exact: "foo/bar" destination: @@ -24,10 +25,11 @@ http: port: 50000 - name: "second-route" hostname: "*" - faultInjection: - delay: - fixedDelay: 5.4s - percentage: 80 + traffic: + faultInjection: + delay: + fixedDelay: 5.4s + percentage: 80 pathMatch: exact: "example" destination: @@ -38,13 +40,14 @@ http: port: 50000 - name: "third-route" hostname: "*" - faultInjection: - abort: - httpStatus: 500 - percentage: 100 - delay: - fixedDelay: 5.005s - percentage: 100 + traffic: + faultInjection: + abort: + httpStatus: 500 + percentage: 100 + delay: + fixedDelay: 5.005s + percentage: 100 pathMatch: exact: "test" destination: @@ -55,13 +58,14 @@ http: port: 50000 - name: "fourth-route" hostname: "*" - faultInjection: - abort: - grpcStatus: 14 - percentage: 100 - delay: - fixedDelay: 5.005s - percentage: 100 + traffic: + faultInjection: + abort: + grpcStatus: 14 + percentage: 100 + delay: + fixedDelay: 5.005s + percentage: 100 pathMatch: exact: "test" destination: @@ -72,7 +76,8 @@ http: port: 50000 - name: "fifth-route" hostname: "*" - faultInjection: + traffic: + faultInjection: {} pathMatch: exact: "test" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml index a767bdab208..30ecd2da792 100644 --- a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml @@ -10,28 +10,29 @@ http: routes: - name: "first-route" hostname: "*" - healthCheck: - active: - timeout: "500ms" - interval: "3s" - unhealthyThreshold: 3 - healthyThreshold: 1 - http: - host: "*" - path: "/healthz" - expectedResponse: - text: "ok" - expectedStatuses: - - 200 - - 300 - passive: - baseEjectionTime: 180s - interval: 2s - maxEjectionPercent: 100 - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - splitExternalLocalOriginErrors: false + traffic: + healthCheck: + active: + timeout: "500ms" + interval: "3s" + unhealthyThreshold: 3 + healthyThreshold: 1 + http: + host: "*" + path: "/healthz" + expectedResponse: + text: "ok" + expectedStatuses: + - 200 + - 300 + passive: + baseEjectionTime: 180s + interval: 2s + maxEjectionPercent: 100 + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + splitExternalLocalOriginErrors: false destination: name: "first-route-dest" settings: @@ -40,28 +41,29 @@ http: port: 50000 - name: "second-route" hostname: "*" - healthCheck: - active: - timeout: "1s" - interval: "5s" - unhealthyThreshold: 3 - healthyThreshold: 3 - http: - host: "*" - path: "/healthz" - expectedResponse: - binary: "cG9uZw==" - expectedStatuses: - - 200 - - 201 - passive: - baseEjectionTime: 180s - interval: 1s - maxEjectionPercent: 100 - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - splitExternalLocalOriginErrors: false + traffic: + healthCheck: + active: + timeout: "1s" + interval: "5s" + unhealthyThreshold: 3 + healthyThreshold: 3 + http: + host: "*" + path: "/healthz" + expectedResponse: + binary: "cG9uZw==" + expectedStatuses: + - 200 + - 201 + passive: + baseEjectionTime: 180s + interval: 1s + maxEjectionPercent: 100 + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + splitExternalLocalOriginErrors: false destination: name: "second-route-dest" settings: @@ -70,25 +72,26 @@ http: port: 50000 - name: "third-route" hostname: "*" - healthCheck: - active: - timeout: "1s" - interval: "5s" - unhealthyThreshold: 3 - healthyThreshold: 3 - tcp: - send: - text: "ping" - receive: - text: "pong" - passive: - baseEjectionTime: 160s - interval: 1s - maxEjectionPercent: 100 - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - splitExternalLocalOriginErrors: false + traffic: + healthCheck: + active: + timeout: "1s" + interval: "5s" + unhealthyThreshold: 3 + healthyThreshold: 3 + tcp: + send: + text: "ping" + receive: + text: "pong" + passive: + baseEjectionTime: 160s + interval: 1s + maxEjectionPercent: 100 + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + splitExternalLocalOriginErrors: false destination: name: "third-route-dest" settings: @@ -97,25 +100,26 @@ http: port: 50000 - name: "fourth-route" hostname: "*" - healthCheck: - active: - timeout: "1s" - interval: "5s" - unhealthyThreshold: 3 - healthyThreshold: 3 - tcp: - send: - binary: "cGluZw==" - receive: - binary: "cG9uZw==" - passive: - baseEjectionTime: 180s - interval: 1s - maxEjectionPercent: 90 - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - splitExternalLocalOriginErrors: true + traffic: + healthCheck: + active: + timeout: "1s" + interval: "5s" + unhealthyThreshold: 3 + healthyThreshold: 3 + tcp: + send: + binary: "cGluZw==" + receive: + binary: "cG9uZw==" + passive: + baseEjectionTime: 180s + interval: 1s + maxEjectionPercent: 90 + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + splitExternalLocalOriginErrors: true destination: name: "fourth-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml index fdd2b84ef84..746d4922542 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml @@ -10,9 +10,10 @@ http: routes: - name: "first-route" hostname: "*" - timeout: - http: - requestTimeout: 5s + traffic: + timeout: + http: + requestTimeout: 5s headerMatches: - name: user stringMatch: @@ -25,9 +26,10 @@ http: port: 50000 - name: "second-route" hostname: "*" - timeout: - http: - requestTimeout: 4000s + traffic: + timeout: + http: + requestTimeout: 4000s destination: name: "second-route-dest" settings: @@ -36,9 +38,10 @@ http: port: 50001 - name: "third-route" hostname: "*" - timeout: - http: - requestTimeout: 0s + traffic: + timeout: + http: + requestTimeout: 0s destination: name: "third-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml index 7dd532ab493..a706244dbd4 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml @@ -56,8 +56,9 @@ http: - backendWeights: invalid: 0 valid: 0 - proxyProtocol: - version: "V2" + traffic: + proxyProtocol: + version: "V2" destination: name: httproute/envoy-gateway/httproute-btls-2/rule/0 settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml index a4682250ad4..008b5b9bde6 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml @@ -10,15 +10,16 @@ http: routes: - name: "first-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: @@ -38,15 +39,16 @@ http: uri: https://192.168.1.250/jwt/public-key/jwks.json - name: "second-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - distinct: true - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + distinct: true + limit: + requests: 5 + unit: second pathMatch: exact: "example" destination: @@ -57,12 +59,13 @@ http: port: 50000 - name: "third-route" hostname: "*" - rateLimit: - global: - rules: - - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - limit: + requests: 5 + unit: second pathMatch: exact: "test" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml b/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml index 9c76ca46bff..2d8ef97efb8 100644 --- a/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml @@ -10,8 +10,9 @@ http: routes: - name: "first-route" hostname: "*" - loadBalancer: - roundRobin: {} + traffic: + loadBalancer: + roundRobin: {} destination: name: "first-route-dest" settings: @@ -20,8 +21,9 @@ http: port: 50000 - name: "second-route" hostname: "*" - loadBalancer: - random: {} + traffic: + loadBalancer: + random: {} destination: name: "second-route-dest" settings: @@ -30,8 +32,9 @@ http: port: 50000 - name: "third-route" hostname: "*" - loadBalancer: - leastRequest: {} + traffic: + loadBalancer: + leastRequest: {} destination: name: "third-route-dest" settings: @@ -40,9 +43,10 @@ http: port: 50000 - name: "fourth-route" hostname: "*" - loadBalancer: - consistentHash: - sourceIP: true + traffic: + loadBalancer: + consistentHash: + sourceIP: true destination: name: "fourth-route-dest" settings: @@ -51,10 +55,11 @@ http: port: 50000 - name: "fifth-route" hostname: "*" - loadBalancer: - leastRequest: - slowStart: - window: 60s + traffic: + loadBalancer: + leastRequest: + slowStart: + window: 60s destination: name: "fifth-route-dest" settings: @@ -63,10 +68,11 @@ http: port: 50000 - name: "sixth-route" hostname: "*" - loadBalancer: - roundRobin: - slowStart: - window: 300s + traffic: + loadBalancer: + roundRobin: + slowStart: + window: 300s destination: name: "sixth-route-dest" settings: @@ -75,10 +81,11 @@ http: port: 50000 - name: "seventh-route" hostname: "*" - loadBalancer: - consistentHash: - header: - name: name + traffic: + loadBalancer: + consistentHash: + header: + name: name destination: name: "seventh-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml index 9e818b4d150..fb7baf05cd6 100644 --- a/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml @@ -10,20 +10,21 @@ http: routes: - name: "first-route-ratelimit-single-rule" hostname: "*" - rateLimit: - local: - default: - requests: 10 - unit: Minute - rules: - - headerMatches: - - name: x-user-id - exact: one - - name: x-org-id - exact: foo - limit: + traffic: + rateLimit: + local: + default: requests: 10 - unit: Hour + unit: Minute + rules: + - headerMatches: + - name: x-user-id + exact: one + - name: x-org-id + exact: foo + limit: + requests: 10 + unit: Hour pathMatch: exact: "foo/bar" destination: @@ -34,31 +35,32 @@ http: port: 50000 - name: "second-route-ratelimit-multiple-rules" hostname: "*" - rateLimit: - local: - default: - requests: 10 - unit: Minute - rules: - - headerMatches: - - name: x-user-id - exact: one - - name: x-org-id - exact: foo - limit: - requests: 10 - unit: Hour - - cidrMatch: - cidr: 192.168.0.0/16 - maskLen: 16 - headerMatches: - - name: x-user-id - exact: two - - name: x-org-id - exact: bar - limit: + traffic: + rateLimit: + local: + default: requests: 10 unit: Minute + rules: + - headerMatches: + - name: x-user-id + exact: one + - name: x-org-id + exact: foo + limit: + requests: 10 + unit: Hour + - cidrMatch: + cidr: 192.168.0.0/16 + maskLen: 16 + headerMatches: + - name: x-user-id + exact: two + - name: x-org-id + exact: bar + limit: + requests: 10 + unit: Minute pathMatch: exact: "example" destination: @@ -69,11 +71,12 @@ http: port: 50000 - name: "third-route-ratelimit-no-rule" hostname: "*" - rateLimit: - local: - default: - requests: 10 - unit: Minute + traffic: + rateLimit: + local: + default: + requests: 10 + unit: Minute pathMatch: exact: "test" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml b/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml index adf21ca8fd5..47df0026b9f 100644 --- a/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml @@ -10,8 +10,9 @@ http: routes: - name: "first-route" hostname: "*" - proxyProtocol: - version: "V2" + traffic: + proxyProtocol: + version: "V2" destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml index 8d9c2f5b41e..271d39cfdcb 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml @@ -10,15 +10,16 @@ http: routes: - name: "first-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: @@ -29,15 +30,16 @@ http: port: 50000 - name: "second-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - distinct: true - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + distinct: true + limit: + requests: 5 + unit: second pathMatch: exact: "example" destination: @@ -48,12 +50,13 @@ http: port: 50000 - name: "third-route" hostname: "*" - rateLimit: - global: - rules: - - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - limit: + requests: 5 + unit: second pathMatch: exact: "test" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml index 56a4b8d4869..32f95117283 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml @@ -12,15 +12,16 @@ http: routes: - name: "first-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: @@ -31,15 +32,16 @@ http: port: 50000 - name: "second-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - distinct: true - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + distinct: true + limit: + requests: 5 + unit: second pathMatch: exact: "example" destination: @@ -50,12 +52,13 @@ http: port: 50000 - name: "third-route" hostname: "*" - rateLimit: - global: - rules: - - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - limit: + requests: 5 + unit: second pathMatch: exact: "test" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml index 69b3480fca8..495fa9b7a1f 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml @@ -10,15 +10,16 @@ http: routes: - name: "first-route" hostname: "*" - rateLimit: - global: - rules: - - cidrMatch: - cidr: 192.168.0.0/16 - maskLen: 16 - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: 192.168.0.0/16 + maskLen: 16 + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: @@ -29,15 +30,16 @@ http: port: 50000 - name: "second-route" hostname: "*" - rateLimit: - global: - rules: - - cidrMatch: - cidr: 192.168.0.0/24 - maskLen: 24 - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: 192.168.0.0/24 + maskLen: 24 + limit: + requests: 5 + unit: second pathMatch: exact: "example" destination: @@ -48,12 +50,13 @@ http: port: 50000 - name: "third-route" hostname: "*" - rateLimit: - global: - rules: - - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - limit: + requests: 5 + unit: second pathMatch: exact: "test" destination: @@ -64,16 +67,17 @@ http: port: 50000 - name: "fourth-route" hostname: "*" - rateLimit: - global: - rules: - - cidrMatch: - cidr: 192.168.0.0/16 - maskLen: 16 - distinct: true - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - cidrMatch: + cidr: 192.168.0.0/16 + maskLen: 16 + distinct: true + limit: + requests: 5 + unit: second pathMatch: exact: "distinct" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml index 8d9c2f5b41e..271d39cfdcb 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml @@ -10,15 +10,16 @@ http: routes: - name: "first-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - exact: "one" - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second pathMatch: exact: "foo/bar" destination: @@ -29,15 +30,16 @@ http: port: 50000 - name: "second-route" hostname: "*" - rateLimit: - global: - rules: - - headerMatches: - - name: "x-user-id" - distinct: true - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + distinct: true + limit: + requests: 5 + unit: second pathMatch: exact: "example" destination: @@ -48,12 +50,13 @@ http: port: 50000 - name: "third-route" hostname: "*" - rateLimit: - global: - rules: - - limit: - requests: 5 - unit: second + traffic: + rateLimit: + global: + rules: + - limit: + requests: 5 + unit: second pathMatch: exact: "test" destination: diff --git a/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml index 7f5938fd64d..7483356722d 100644 --- a/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml @@ -10,21 +10,22 @@ http: routes: - name: "first-route" hostname: "*" - retry: - numRetries: 5 - retryOn: - httpStatusCodes: - - 429 - - 503 - triggers: - - reset - - connect-failure - - retriable-status-codes - perRetry: - timeout: 250ms - backoff: - baseInterval: 100ms - maxInterval: 10s + traffic: + retry: + numRetries: 5 + retryOn: + httpStatusCodes: + - 429 + - 503 + triggers: + - reset + - connect-failure + - retriable-status-codes + perRetry: + timeout: 250ms + backoff: + baseInterval: 100ms + maxInterval: 10s destination: name: "first-route-dest" settings: @@ -33,7 +34,8 @@ http: port: 50000 - name: "second-route-defaults" hostname: "foo" - retry: {} + traffic: + retry: {} destination: name: "first-route-dest" settings: @@ -42,10 +44,11 @@ http: port: 50000 - name: "third-route-error" hostname: "bar" - retry: - retryOn: - triggers: - - this-is-not-a-trigger + traffic: + retry: + retryOn: + triggers: + - this-is-not-a-trigger destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/timeout.yaml index daee154f055..8abc0af3cdd 100644 --- a/internal/xds/translator/testdata/in/xds-ir/timeout.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/timeout.yaml @@ -10,12 +10,13 @@ http: routes: - name: "first-route" hostname: "*" - timeout: - tcp: - connectTimeout: "31s" - http: - connectionIdleTimeout: "32s" - maxConnectionDuration: "33s" + traffic: + timeout: + tcp: + connectTimeout: "31s" + http: + connectionIdleTimeout: "32s" + maxConnectionDuration: "33s" destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml b/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml index bb7febec8b7..b00f5e55a3b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml @@ -10,10 +10,11 @@ http: routes: - name: "first-route" hostname: "*" - tcpKeepalive: - idleTime: 1200 - interval: 60 - probes: 3 + traffic: + tcpKeepalive: + idleTime: 1200 + interval: 60 + probes: 3 destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index a88f4e3fc2d..cab26d1f905 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -643,21 +643,28 @@ func findXdsEndpoint(tCtx *types.ResourceVersionTable, name string) *endpointv3. // processXdsCluster processes a xds cluster by its endpoint address type. func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute, http1Settings *ir.HTTP1Settings, metrics *ir.Metrics) error { - if err := addXdsCluster(tCtx, &xdsClusterArgs{ + clusterArgs := &xdsClusterArgs{ name: httpRoute.Destination.Name, settings: httpRoute.Destination.Settings, tSocket: nil, endpointType: buildEndpointType(httpRoute.Destination.Settings), - loadBalancer: httpRoute.LoadBalancer, - proxyProtocol: httpRoute.ProxyProtocol, - circuitBreaker: httpRoute.CircuitBreaker, - healthCheck: httpRoute.HealthCheck, http1Settings: http1Settings, - timeout: httpRoute.Timeout, - tcpkeepalive: httpRoute.TCPKeepalive, metrics: metrics, useClientProtocol: ptr.Deref(httpRoute.UseClientProtocol, false), - }); err != nil && !errors.Is(err, ErrXdsClusterExists) { + } + + // Populate traffic features. + bt := httpRoute.Traffic + if bt != nil { + clusterArgs.loadBalancer = bt.LoadBalancer + clusterArgs.proxyProtocol = bt.ProxyProtocol + clusterArgs.circuitBreaker = bt.CircuitBreaker + clusterArgs.healthCheck = bt.HealthCheck + clusterArgs.timeout = bt.Timeout + clusterArgs.tcpkeepalive = bt.TCPKeepalive + } + + if err := addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err }