From 555f90dad5e4ea47465fd1d6bf5720b55b54bf24 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 29 Oct 2026 18:23:36 +0000 Subject: [PATCH] Update dependency kubernetes-sigs/gateway-api to v1.7.0 Signed-off-by: Renovate Bot --- class/defaults.yml | 2 +- ...tlspolicies.gateway.networking.k8s.io.yaml | 6 +- ...ewayclasses.gateway.networking.k8s.io.yaml | 8 +- .../gateways.gateway.networking.k8s.io.yaml | 6 +- .../grpcroutes.gateway.networking.k8s.io.yaml | 30 +- .../httproutes.gateway.networking.k8s.io.yaml | 238 ++++- ...istenersets.gateway.networking.k8s.io.yaml | 4 +- ...rencegrants.gateway.networking.k8s.io.yaml | 4 +- .../tcproutes.gateway.networking.k8s.io.yaml | 4 +- .../tlsroutes.gateway.networking.k8s.io.yaml | 42 +- .../udproutes.gateway.networking.k8s.io.yaml | 4 +- ...fe-upgrades.gateway.networking.k8s.io.yaml | 11 +- ...fe-upgrades.gateway.networking.k8s.io.yaml | 2 +- ...tlspolicies.gateway.networking.k8s.io.yaml | 56 +- ...ewayclasses.gateway.networking.k8s.io.yaml | 8 +- .../gateways.gateway.networking.k8s.io.yaml | 896 +++++++++++++++++- .../grpcroutes.gateway.networking.k8s.io.yaml | 111 ++- .../httproutes.gateway.networking.k8s.io.yaml | 340 +++++-- ...istenersets.gateway.networking.k8s.io.yaml | 382 +++++++- ...rencegrants.gateway.networking.k8s.io.yaml | 4 +- .../tcproutes.gateway.networking.k8s.io.yaml | 12 +- .../tlsroutes.gateway.networking.k8s.io.yaml | 54 +- .../udproutes.gateway.networking.k8s.io.yaml | 12 +- ...xbackends.gateway.networking.x-k8s.io.yaml | 444 ++++++--- ...cpolicies.gateway.networking.x-k8s.io.yaml | 74 +- .../xmeshes.gateway.networking.x-k8s.io.yaml | 6 +- ...ypolicies.gateway.networking.x-k8s.io.yaml | 830 ++++++++++++++++ ...fe-upgrades.gateway.networking.k8s.io.yaml | 2 +- ...fe-upgrades.gateway.networking.k8s.io.yaml | 2 +- .../gateway-api/30_aggregated_rbac.yaml | 3 + 30 files changed, 3273 insertions(+), 324 deletions(-) create mode 100644 tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xtelemetrypolicies.gateway.networking.x-k8s.io.yaml diff --git a/class/defaults.yml b/class/defaults.yml index 9b7493a..8219f0e 100644 --- a/class/defaults.yml +++ b/class/defaults.yml @@ -5,7 +5,7 @@ parameters: enabled: true channel: standard - version: v1.6.1 + version: v1.7.0 source: https://github.com/kubernetes-sigs/gateway-api/releases/download/${gateway_api:version}/${gateway_api:channel}-install.yaml openshift_version: diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml index c6b65e2..582e913 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard labels: gateway.networking.k8s.io/policy: Direct @@ -169,6 +169,7 @@ spec: resources, SectionName is interpreted as the following: * Gateway: Listener name + * ListenerSet: Listener name * HTTPRoute: HTTPRouteRule name * Service: Port name @@ -846,6 +847,7 @@ spec: resources, SectionName is interpreted as the following: * Gateway: Listener name + * ListenerSet: Listener name * HTTPRoute: HTTPRouteRule name * Service: Port name diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml index 3a744ae..97359ff 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: gatewayclasses.gateway.networking.k8s.io spec: @@ -93,7 +93,7 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string x-kubernetes-validations: - - message: Value is immutable + - message: field is immutable rule: self == oldSelf description: description: Description helps describe a GatewayClass with more @@ -339,7 +339,7 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string x-kubernetes-validations: - - message: Value is immutable + - message: field is immutable rule: self == oldSelf description: description: Description helps describe a GatewayClass with more diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml index fa8cc0c..9366ecd 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: gateways.gateway.networking.k8s.io spec: @@ -1449,6 +1449,7 @@ spec: * "Accepted" * "Programmed" * "Ready" + * "AddressesAssigned" items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -3088,6 +3089,7 @@ spec: * "Accepted" * "Programmed" * "Ready" + * "AddressesAssigned" items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml index 56441ee..872bcfc 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: grpcroutes.gateway.networking.k8s.io spec: @@ -114,11 +114,30 @@ spec: the implementation. The implementation MUST raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. + In the event that multiple GRPCRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the GRPCRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + When multiple GRPCRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. + If a Route (A) of type HTTPRoute or GRPCRoute is attached to a Listener and that listener already has another Route (B) of the other type attached and the intersection of the hostnames of A and B is - non-empty, then the implementation MUST accept exactly one of these two - routes, determined by the following criteria, in order: + non-empty, then the implementation MAY reject one of the two routes. + An implementation that does so MUST accept exactly one of them, + determined by the following criteria, in order: * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by @@ -1812,6 +1831,9 @@ spec: : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() : 0) : 0) <= 128' + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) type: object status: description: Status defines the current state of GRPCRoute. diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml index a05a41f..fd2b705 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: httproutes.gateway.networking.k8s.io spec: @@ -104,8 +104,16 @@ spec: * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. - If ties exist across multiple Routes, the matching precedence rules for - HTTPRouteMatches takes over. + When multiple HTTPRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. Support: Core items: @@ -1188,7 +1196,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -2452,7 +2460,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -3100,6 +3108,104 @@ spec: minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string + retry: + description: |- + Retry defines the configuration for when to retry an HTTP request. + + A request is retried when attempts is greater than 0 and the backend did + not process it. This is the case when the connection could not be + established, or when the backend explicitly rejected the request, either + before processing it or with one of the configured status codes. + + Support: Extended + properties: + attempts: + default: 1 + description: |- + Attempts specifies the maximum number of times an individual request + from the Gateway to a backend should be retried in addition to the + initial request. + + If the maximum number of retries has been attempted without a successful + response from the backend, the Gateway MUST return an error. + + An explicit zero value MUST disable retries. + + Support: Extended + minimum: 0 + type: integer + backoff: + description: |- + Backoff specifies the base interval for a backoff strategy between + retry attempts and is represented in Gateway API Duration formatting. + The duration a Gateway waits before a retry attempt is determined + by the base interval and the implementation's retry strategy. + + Implementations MAY add random jitter and MAY cap the delay at an + implementation-defined maximum, which SHOULD NOT be less than the base + interval. The precise backoff curve and jitter calculation are + implementation-specific and not exposed in the Gateway API specification. + Implementations typically apply exponential backoff with jitter to + mitigate thundering-herd issues. + + If a Request timeout (`rules[].timeouts.request`) is configured on the + route, the entire duration of the initial request and any retry attempts + MUST not exceed the Request timeout duration. If any retry attempts are + still in progress when the Request timeout duration has been reached, + these SHOULD be canceled if possible and the Gateway MUST immediately + return a timeout error. + + If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is + configured on the route, any retry attempts which reach the configured + BackendRequest timeout duration without a response SHOULD be canceled if + possible and the Gateway SHOULD schedule the next retry attempt according + to the configured backoff. + + If a BackendRequest timeout is _not_ configured on the route, retry + attempts MAY time out after an implementation default duration, or MAY + remain pending until a configured Request timeout or implementation + default duration for total request time is reached. + + When this field is unspecified, the backoff strategy and base interval + are implementation-specific. + + Implementations which retry immediately with no backoff MUST NOT advertise + support for this field and MUST set the Accepted Condition for the Route + to `status: False` with a Reason of `UnsupportedValue` when this field is + set. + + Support: Implementation-specific + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + codes: + description: |- + Codes defines the HTTP response status codes for which a backend request + should be retried. + + Support: Extended + items: + description: |- + HTTPRouteRetryStatusCode defines an HTTP response status code for + which a backend request should be retried. + + Implementations MUST support the following status codes as retriable: + + * 500 + * 502 + * 503 + * 504 + + Implementations MAY support specifying additional discrete values in the + 500-599 range. + + Implementations MAY support specifying discrete values in the 400-499 range, + which are often inadvisable to retry. + maximum: 599 + minimum: 400 + type: integer + type: array + x-kubernetes-list-type: set + type: object timeouts: description: |- Timeouts defines the timeouts that can be configured for an HTTP request. @@ -3208,6 +3314,9 @@ spec: type: array x-kubernetes-list-type: atomic x-kubernetes-validations: + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) - message: While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128 @@ -3573,8 +3682,16 @@ spec: * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. - If ties exist across multiple Routes, the matching precedence rules for - HTTPRouteMatches takes over. + When multiple HTTPRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. Support: Core items: @@ -4657,7 +4774,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -5921,7 +6038,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -6569,6 +6686,104 @@ spec: minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string + retry: + description: |- + Retry defines the configuration for when to retry an HTTP request. + + A request is retried when attempts is greater than 0 and the backend did + not process it. This is the case when the connection could not be + established, or when the backend explicitly rejected the request, either + before processing it or with one of the configured status codes. + + Support: Extended + properties: + attempts: + default: 1 + description: |- + Attempts specifies the maximum number of times an individual request + from the Gateway to a backend should be retried in addition to the + initial request. + + If the maximum number of retries has been attempted without a successful + response from the backend, the Gateway MUST return an error. + + An explicit zero value MUST disable retries. + + Support: Extended + minimum: 0 + type: integer + backoff: + description: |- + Backoff specifies the base interval for a backoff strategy between + retry attempts and is represented in Gateway API Duration formatting. + The duration a Gateway waits before a retry attempt is determined + by the base interval and the implementation's retry strategy. + + Implementations MAY add random jitter and MAY cap the delay at an + implementation-defined maximum, which SHOULD NOT be less than the base + interval. The precise backoff curve and jitter calculation are + implementation-specific and not exposed in the Gateway API specification. + Implementations typically apply exponential backoff with jitter to + mitigate thundering-herd issues. + + If a Request timeout (`rules[].timeouts.request`) is configured on the + route, the entire duration of the initial request and any retry attempts + MUST not exceed the Request timeout duration. If any retry attempts are + still in progress when the Request timeout duration has been reached, + these SHOULD be canceled if possible and the Gateway MUST immediately + return a timeout error. + + If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is + configured on the route, any retry attempts which reach the configured + BackendRequest timeout duration without a response SHOULD be canceled if + possible and the Gateway SHOULD schedule the next retry attempt according + to the configured backoff. + + If a BackendRequest timeout is _not_ configured on the route, retry + attempts MAY time out after an implementation default duration, or MAY + remain pending until a configured Request timeout or implementation + default duration for total request time is reached. + + When this field is unspecified, the backoff strategy and base interval + are implementation-specific. + + Implementations which retry immediately with no backoff MUST NOT advertise + support for this field and MUST set the Accepted Condition for the Route + to `status: False` with a Reason of `UnsupportedValue` when this field is + set. + + Support: Implementation-specific + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + codes: + description: |- + Codes defines the HTTP response status codes for which a backend request + should be retried. + + Support: Extended + items: + description: |- + HTTPRouteRetryStatusCode defines an HTTP response status code for + which a backend request should be retried. + + Implementations MUST support the following status codes as retriable: + + * 500 + * 502 + * 503 + * 504 + + Implementations MAY support specifying additional discrete values in the + 500-599 range. + + Implementations MAY support specifying discrete values in the 400-499 range, + which are often inadvisable to retry. + maximum: 599 + minimum: 400 + type: integer + type: array + x-kubernetes-list-type: set + type: object timeouts: description: |- Timeouts defines the timeouts that can be configured for an HTTP request. @@ -6677,6 +6892,9 @@ spec: type: array x-kubernetes-list-type: atomic x-kubernetes-validations: + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) - message: While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128 diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml index 99aa179..4755e8a 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: listenersets.gateway.networking.k8s.io spec: diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml index 5d256dc..2a5aba0 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: referencegrants.gateway.networking.k8s.io spec: diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml index 5e3b596..7588a98 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: tcproutes.gateway.networking.k8s.io spec: diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml index 9f0c222..1c18b91 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: tlsroutes.gateway.networking.k8s.io spec: @@ -61,6 +61,25 @@ spec: 1. IPs are not allowed in SNI hostnames per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. + + + In the event that multiple TLSRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the TLSRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + When multiple TLSRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. items: description: |- Hostname is the fully qualified domain name of a network host. This matches @@ -1469,6 +1488,25 @@ spec: 1. IPs are not allowed in SNI hostnames per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. + + + In the event that multiple TLSRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the TLSRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + When multiple TLSRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. items: description: |- Hostname is the fully qualified domain name of a network host. This matches diff --git a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml index 71e26e6..492b37e 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: udproutes.gateway.networking.k8s.io spec: diff --git a/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml index 6ab0023..be3043d 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml @@ -2,7 +2,7 @@ apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: annotations: - gateway.networking.k8s.io/bundle-version: v1.6.1 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: safe-upgrades.gateway.networking.k8s.io spec: @@ -32,11 +32,10 @@ spec: reason: Invalid - expression: object.spec.group != 'gateway.networking.k8s.io' || (has(object.metadata.annotations) && object.metadata.annotations.exists(k, k == 'gateway.networking.k8s.io/bundle-version') - && ( matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], - '-(rc)') || ( !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], - 'v1.[0-5].\\d+') && !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], - 'v0') ) )) - message: Installing CRDs with version before v1.5.0 is prohibited by default. + && !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], + 'v1.[0-6].\\d+') && !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], + 'v0')) + message: Installing CRDs with version before v1.7.0 is prohibited by default. Uninstall ValidatingAdmissionPolicy safe-upgrades.gateway.networking.k8s.io to install older versions. reason: Invalid diff --git a/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml b/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml index e4d75f6..49201a7 100644 --- a/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml +++ b/tests/golden/defaults/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml @@ -2,7 +2,7 @@ apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: annotations: - gateway.networking.k8s.io/bundle-version: v1.6.1 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: safe-upgrades.gateway.networking.k8s.io spec: diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml index 5d4227d..c77475e 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/backendtlspolicies.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental labels: gateway.networking.k8s.io/policy: Direct @@ -169,6 +169,7 @@ spec: resources, SectionName is interpreted as the following: * Gateway: Listener name + * ListenerSet: Listener name * HTTPRoute: HTTPRouteRule name * Service: Port name @@ -242,6 +243,14 @@ spec: ensure the `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason `NoValidCACertificate`. + + References to cluster-scoped resources (such as ClusterTrustBundle) + are supported: the implementation resolves the scope based on the kind. + A single CACertificateRef to a ClusterTrustBundle uses the cluster-scoped + resource by name. A reference to a namespaced resource (such as ConfigMap + or Secret) uses the local namespace. + + A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific. @@ -249,6 +258,10 @@ spec: Support: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. + + Support: Extended - A single reference to a ClusterTrustBundle (certificates.k8s.io). + + Support: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates. items: @@ -287,6 +300,7 @@ spec: - name type: object maxItems: 8 + minItems: 1 type: array x-kubernetes-list-type: atomic hostname: @@ -400,14 +414,10 @@ spec: - hostname type: object x-kubernetes-validations: - - message: must not contain both CACertificateRefs and WellKnownCACertificates - rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs) - > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates - != "")' - - message: must specify either CACertificateRefs or WellKnownCACertificates - rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs) - > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates - != "") + - message: exactly one of the fields in [caCertificateRefs wellKnownCACertificates] + must be set + rule: (has(self.caCertificateRefs)?1:0)+(has(self.wellKnownCACertificates)?1:0) + == 1 required: - targetRefs - validation @@ -864,6 +874,7 @@ spec: resources, SectionName is interpreted as the following: * Gateway: Listener name + * ListenerSet: Listener name * HTTPRoute: HTTPRouteRule name * Service: Port name @@ -937,6 +948,14 @@ spec: ensure the `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason `NoValidCACertificate`. + + References to cluster-scoped resources (such as ClusterTrustBundle) + are supported: the implementation resolves the scope based on the kind. + A single CACertificateRef to a ClusterTrustBundle uses the cluster-scoped + resource by name. A reference to a namespaced resource (such as ConfigMap + or Secret) uses the local namespace. + + A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific. @@ -944,6 +963,10 @@ spec: Support: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. + + Support: Extended - A single reference to a ClusterTrustBundle (certificates.k8s.io). + + Support: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates. items: @@ -982,6 +1005,7 @@ spec: - name type: object maxItems: 8 + minItems: 1 type: array x-kubernetes-list-type: atomic hostname: @@ -1095,14 +1119,10 @@ spec: - hostname type: object x-kubernetes-validations: - - message: must not contain both CACertificateRefs and WellKnownCACertificates - rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs) - > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates - != "")' - - message: must specify either CACertificateRefs or WellKnownCACertificates - rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs) - > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates - != "") + - message: exactly one of the fields in [caCertificateRefs wellKnownCACertificates] + must be set + rule: (has(self.caCertificateRefs)?1:0)+(has(self.wellKnownCACertificates)?1:0) + == 1 required: - targetRefs - validation diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml index c89ad3f..979417c 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gatewayclasses.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: gatewayclasses.gateway.networking.k8s.io spec: @@ -93,7 +93,7 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string x-kubernetes-validations: - - message: Value is immutable + - message: field is immutable rule: self == oldSelf description: description: Description helps describe a GatewayClass with more @@ -339,7 +339,7 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string x-kubernetes-validations: - - message: Value is immutable + - message: field is immutable rule: self == oldSelf description: description: Description helps describe a GatewayClass with more diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml index e0e40e8..04db2de 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/gateways.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: gateways.gateway.networking.k8s.io spec: @@ -101,6 +101,23 @@ spec: enum: - IPAddress properties: + routability: + description: |- + Routability specifies the requested reachability scope of this address. + Valid values are empty, `Cluster`, or a prefixed implementation-specific value. + The `k8s.io` domain and all its subdomains are reserved. + When unset or empty, this field uses the implementation's default + routability behavior. + + Support: Extended + maxLength: 253 + type: string + x-kubernetes-validations: + - message: Routability must be empty, Cluster, or an implementation-specific + prefixed path; k8s.io and its subdomains are reserved + rule: size(self) == 0 || self == 'Cluster' || (self.matches('^.*/.+$') + && !format.dns1123Subdomain().validate(self.split('/')[0]).hasValue() + && self.split('/')[0] != 'k8s.io' && !self.split('/')[0].endsWith('.k8s.io')) type: default: IPAddress description: Type of the address. @@ -684,6 +701,384 @@ spec: x-kubernetes-map-type: atomic type: object type: object + filters: + description: |- + Filters groups the pre-routing filter lists that run on every + request accepted on this Listener, before route matching is + performed. Filters is only valid when Protocol is `HTTP` or + `HTTPS`; this constraint is enforced by CEL validation on the + enclosing Listener struct. + + Support: Extended + properties: + requests: + description: |- + Implementations MUST execute the filters in the exact order they + appear here and MUST NOT reorder them. If an implementation can + not implement the filters in the order they are specified, the + implementation MUST set the "Accepted" Listener condition to "false" + with the "InvalidListenerFilterOrder" reason. + + Requests only apply to connections with a visible HTTP stream + and metadata (Protocol=HTTP, or Protocol=HTTPS with TLS + terminated at the Gateway). + + Requests may mutate inputs that route matching consumes + (path, request headers, method, computed metadata), with the + explicit exception of the `Host` and `:authority` headers. If a + ListenerFilter attempts to modify either header, implementations + MUST NOT allow that modification to take effect. Implementations + SHOULD satisfy this by ignoring the mutation and continuing to + process the request with the original value; they MAY instead + fail the request with a 5xx response. Implementations MUST + evaluate route matching exactly once after the last + ListenerFilter has run. + + Requests MUST NOT be interpreted as changing which Listener + handles the request. Listener selection is decided from inputs + the client committed to before any pre-routing filter runs: TLS + SNI (for HTTPS) or the request's initial Host header (for HTTP). + Because filters cannot modify Host or :authority, the input to + cleartext-HTTP Listener selection cannot change; Listener + selection therefore does not need to be re-evaluated after + pre-routing filters run, and MUST NOT be. + items: + description: |- + ListenerFilter is one element of a ListenerFilters.Requests list. + Unlike HTTPRouteFilter, which runs after a route is selected and whose + ordering is a SHOULD, ListenerFilter runs before route selection and + its ordering within the containing list is a MUST. + + Only a subset of HTTPRouteFilter variants are permitted: + ExternalAuth (to establish identity that route matching can consume) and + ExtensionRef (the escape hatch for custom pre-routing behavior, for + example body-based routing or JWT-claim projection). The other + HTTPRouteFilter variants are excluded because they either cannot influence + route selection or can already be expressed post-routing with equal + expressiveness. See the GEP text for details. + properties: + extensionRef: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + externalAuth: + description: |- + HTTPExternalAuthFilter defines a filter that modifies requests by sending + request details to an external authorization server. + + Support: Extended + Feature Name: HTTPRouteExternalAuth + properties: + backendRef: + description: |- + BackendRef is a reference to a backend to send authorization + requests to. + + The backend must speak the selected protocol (GRPC or HTTP) on the + referenced port. + + If the backend service requires TLS, use BackendTLSPolicy to tell the + implementation to supply the TLS details to be used to connect to that + backend. + properties: + group: + default: '' + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' + forwardBody: + description: |- + ForwardBody controls if requests to the authorization server should include + the body of the client request; and if so, how big that body is allowed + to be. + + It is expected that implementations will buffer the request body up to + `forwardBody.maxSize` bytes. Bodies over that size must be rejected with a + 4xx series error (413 or 403 are common examples), and fail processing + of the filter. + + If unset, or `forwardBody.maxSize` is set to `0`, then the body will not + be forwarded. + + Feature Name: HTTPRouteExternalAuthForwardBody + properties: + maxSize: + description: |- + MaxSize specifies how large in bytes the largest body that will be buffered + and sent to the authorization server. If the body size is larger than + `maxSize`, then the body sent to the authorization server must be + truncated to `maxSize` bytes. + + Experimental note: This behavior needs to be checked against + various dataplanes; it may need to be changed. + See https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746 + for more. + + If 0, the body will not be sent to the authorization server. + format: int32 + minimum: 0 + type: integer + type: object + grpc: + description: |- + GRPCAuthConfig contains configuration for communication with ext_authz + protocol-speaking backends. + + If unset, implementations must assume the default behavior for each + included field is intended. + properties: + allowedHeaders: + description: |- + AllowedRequestHeaders specifies what headers from the client request + will be sent to the authorization server. + + If this list is empty, then all headers must be sent. + + If the list has entries, only those entries must be sent. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + http: + description: |- + HTTPAuthConfig contains configuration for communication with HTTP-speaking + backends. + + If unset, implementations must assume the default behavior for each + included field is intended. + properties: + allowedHeaders: + description: |- + AllowedRequestHeaders specifies what additional headers from the client request + will be sent to the authorization server. + + The following headers must always be sent to the authorization server, + regardless of this setting: + + * `Host` + * `Method` + * `Path` + * `Content-Length` + * `Authorization` + + If this list is empty, then only those headers must be sent. + + Note that `Content-Length` has a special behavior, in that the length + sent must be correct for the actual request to the external authorization + server - that is, it must reflect the actual number of bytes sent in the + body of the request to the authorization server. + + So if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set + to `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set + to anything other than `0`, then the `Content-Length` of the authorization + request must be set to the actual number of bytes forwarded. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + allowedResponseHeaders: + description: |- + AllowedResponseHeaders specifies what headers from the authorization response + will be copied into the request to the backend. + + If this list is empty, then all headers from the authorization server + except Authority or Host must be copied. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + path: + description: |- + Path sets the prefix that paths from the client request will have added + when forwarded to the authorization server. + + When empty or unspecified, no prefix is added. + + Valid values are the same as the "value" regex for path values in the `match` + stanza, and the validation regex will screen out invalid paths in the same way. + Even with the validation, implementations MUST sanitize this input before using it + directly. + maxLength: 1024 + pattern: ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$ + type: string + type: object + protocol: + description: |- + ExternalAuthProtocol describes which protocol to use when communicating with an + ext_authz authorization server. + + When this is set to GRPC, each backend must use the Envoy ext_authz protocol + on the port specified in `backendRefs`. Requests and responses are defined + in the protobufs explained at: + https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto + + When this is set to HTTP, each backend must respond with a `200` status + code in on a successful authorization. Any other code is considered + an authorization failure. + + Feature Names: + GRPC Support - HTTPRouteExternalAuthGRPC + HTTP Support - HTTPRouteExternalAuthHTTP + enum: + - HTTP + - GRPC + type: string + required: + - backendRef + - protocol + type: object + x-kubernetes-validations: + - message: grpc must be specified when protocol + is set to 'GRPC' + rule: 'self.protocol == ''GRPC'' ? has(self.grpc) + : true' + - message: protocol must be 'GRPC' when grpc is + set + rule: 'has(self.grpc) ? self.protocol == ''GRPC'' + : true' + - message: http must be specified when protocol + is set to 'HTTP' + rule: 'self.protocol == ''HTTP'' ? has(self.http) + : true' + - message: protocol must be 'HTTP' when http is + set + rule: 'has(self.http) ? self.protocol == ''HTTP'' + : true' + type: + description: |- + Type identifies which variant of the discriminated union below is + populated. Uses the same union-discriminator pattern as + HTTPRouteFilter and GRPCRouteFilter. + enum: + - ExternalAuth + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.externalAuth must be nil if the + filter.type is not ExternalAuth + rule: '!(has(self.externalAuth) && self.type != + ''ExternalAuth'')' + - message: filter.externalAuth must be specified for + ExternalAuth filter.type + rule: '!(!has(self.externalAuth) && self.type == + ''ExternalAuth'')' + - message: filter.extensionRef must be nil if the + filter.type is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != + ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == + ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-list-type: atomic + type: object hostname: description: |- Hostname specifies the virtual hostname to match for protocol types that @@ -914,6 +1309,10 @@ spec: - port - protocol type: object + x-kubernetes-validations: + - message: filters may only be set when protocol is HTTP or + HTTPS + rule: '!has(self.filters) || self.protocol in [''HTTP'', ''HTTPS'']' maxItems: 64 minItems: 1 type: array @@ -1075,6 +1474,12 @@ spec: reference, the `ResolvedRefs` on all matching HTTPS listeners condition MUST be set with the Reason `RefNotPermitted`. + + For cluster-scoped resources (such as ClusterTrustBundle), the + `namespace` field MUST be unset. The implementation resolves the scope + based on the kind. + + Implementations MAY choose to perform further validation of the certificate content (e.g., checking expiry or enforcing specific formats). In such cases, an implementation-specific Reason and Message MUST be set. @@ -1092,6 +1497,11 @@ spec: Support: Core - A single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. + + Support: Extended - References to ClusterTrustBundle + (certificates.k8s.io), with `namespace` unset. + + Support: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates. items: @@ -1148,6 +1558,11 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ClusterTrustBundle references must + not specify namespace + rule: self.all(r, !(r.group == 'certificates.k8s.io' + && r.kind == 'ClusterTrustBundle' && has(r.namespace))) mode: default: AllowValidOnly description: |- @@ -1240,6 +1655,12 @@ spec: reference, the `ResolvedRefs` on all matching HTTPS listeners condition MUST be set with the Reason `RefNotPermitted`. + + For cluster-scoped resources (such as ClusterTrustBundle), the + `namespace` field MUST be unset. The implementation resolves the scope + based on the kind. + + Implementations MAY choose to perform further validation of the certificate content (e.g., checking expiry or enforcing specific formats). In such cases, an implementation-specific Reason and Message MUST be set. @@ -1257,6 +1678,11 @@ spec: Support: Core - A single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. + + Support: Extended - References to ClusterTrustBundle + (certificates.k8s.io), with `namespace` unset. + + Support: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates. items: @@ -1314,6 +1740,12 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ClusterTrustBundle references + must not specify namespace + rule: self.all(r, !(r.group == 'certificates.k8s.io' + && r.kind == 'ClusterTrustBundle' && + has(r.namespace))) mode: default: AllowValidOnly description: |- @@ -1406,6 +1838,19 @@ spec: enum: - IPAddress properties: + routability: + description: |- + Routability reports the reachability scope of this address. When empty or + unset, this field uses the implementation's default routability behavior. + The `k8s.io` domain and all its subdomains are reserved for well-known values. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: Routability must be empty, Cluster, or an implementation-specific + prefixed path; k8s.io and its subdomains are reserved + rule: size(self) == 0 || self == 'Cluster' || (self.matches('^.*/.+$') + && !format.dns1123Subdomain().validate(self.split('/')[0]).hasValue() + && self.split('/')[0] != 'k8s.io' && !self.split('/')[0].endsWith('.k8s.io')) type: default: IPAddress description: Type of the address. @@ -1472,6 +1917,7 @@ spec: * "Accepted" * "Programmed" * "Ready" + * "AddressesAssigned" items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -1763,6 +2209,23 @@ spec: enum: - IPAddress properties: + routability: + description: |- + Routability specifies the requested reachability scope of this address. + Valid values are empty, `Cluster`, or a prefixed implementation-specific value. + The `k8s.io` domain and all its subdomains are reserved. + When unset or empty, this field uses the implementation's default + routability behavior. + + Support: Extended + maxLength: 253 + type: string + x-kubernetes-validations: + - message: Routability must be empty, Cluster, or an implementation-specific + prefixed path; k8s.io and its subdomains are reserved + rule: size(self) == 0 || self == 'Cluster' || (self.matches('^.*/.+$') + && !format.dns1123Subdomain().validate(self.split('/')[0]).hasValue() + && self.split('/')[0] != 'k8s.io' && !self.split('/')[0].endsWith('.k8s.io')) type: default: IPAddress description: Type of the address. @@ -2346,6 +2809,384 @@ spec: x-kubernetes-map-type: atomic type: object type: object + filters: + description: |- + Filters groups the pre-routing filter lists that run on every + request accepted on this Listener, before route matching is + performed. Filters is only valid when Protocol is `HTTP` or + `HTTPS`; this constraint is enforced by CEL validation on the + enclosing Listener struct. + + Support: Extended + properties: + requests: + description: |- + Implementations MUST execute the filters in the exact order they + appear here and MUST NOT reorder them. If an implementation can + not implement the filters in the order they are specified, the + implementation MUST set the "Accepted" Listener condition to "false" + with the "InvalidListenerFilterOrder" reason. + + Requests only apply to connections with a visible HTTP stream + and metadata (Protocol=HTTP, or Protocol=HTTPS with TLS + terminated at the Gateway). + + Requests may mutate inputs that route matching consumes + (path, request headers, method, computed metadata), with the + explicit exception of the `Host` and `:authority` headers. If a + ListenerFilter attempts to modify either header, implementations + MUST NOT allow that modification to take effect. Implementations + SHOULD satisfy this by ignoring the mutation and continuing to + process the request with the original value; they MAY instead + fail the request with a 5xx response. Implementations MUST + evaluate route matching exactly once after the last + ListenerFilter has run. + + Requests MUST NOT be interpreted as changing which Listener + handles the request. Listener selection is decided from inputs + the client committed to before any pre-routing filter runs: TLS + SNI (for HTTPS) or the request's initial Host header (for HTTP). + Because filters cannot modify Host or :authority, the input to + cleartext-HTTP Listener selection cannot change; Listener + selection therefore does not need to be re-evaluated after + pre-routing filters run, and MUST NOT be. + items: + description: |- + ListenerFilter is one element of a ListenerFilters.Requests list. + Unlike HTTPRouteFilter, which runs after a route is selected and whose + ordering is a SHOULD, ListenerFilter runs before route selection and + its ordering within the containing list is a MUST. + + Only a subset of HTTPRouteFilter variants are permitted: + ExternalAuth (to establish identity that route matching can consume) and + ExtensionRef (the escape hatch for custom pre-routing behavior, for + example body-based routing or JWT-claim projection). The other + HTTPRouteFilter variants are excluded because they either cannot influence + route selection or can already be expressed post-routing with equal + expressiveness. See the GEP text for details. + properties: + extensionRef: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + externalAuth: + description: |- + HTTPExternalAuthFilter defines a filter that modifies requests by sending + request details to an external authorization server. + + Support: Extended + Feature Name: HTTPRouteExternalAuth + properties: + backendRef: + description: |- + BackendRef is a reference to a backend to send authorization + requests to. + + The backend must speak the selected protocol (GRPC or HTTP) on the + referenced port. + + If the backend service requires TLS, use BackendTLSPolicy to tell the + implementation to supply the TLS details to be used to connect to that + backend. + properties: + group: + default: '' + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' + forwardBody: + description: |- + ForwardBody controls if requests to the authorization server should include + the body of the client request; and if so, how big that body is allowed + to be. + + It is expected that implementations will buffer the request body up to + `forwardBody.maxSize` bytes. Bodies over that size must be rejected with a + 4xx series error (413 or 403 are common examples), and fail processing + of the filter. + + If unset, or `forwardBody.maxSize` is set to `0`, then the body will not + be forwarded. + + Feature Name: HTTPRouteExternalAuthForwardBody + properties: + maxSize: + description: |- + MaxSize specifies how large in bytes the largest body that will be buffered + and sent to the authorization server. If the body size is larger than + `maxSize`, then the body sent to the authorization server must be + truncated to `maxSize` bytes. + + Experimental note: This behavior needs to be checked against + various dataplanes; it may need to be changed. + See https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746 + for more. + + If 0, the body will not be sent to the authorization server. + format: int32 + minimum: 0 + type: integer + type: object + grpc: + description: |- + GRPCAuthConfig contains configuration for communication with ext_authz + protocol-speaking backends. + + If unset, implementations must assume the default behavior for each + included field is intended. + properties: + allowedHeaders: + description: |- + AllowedRequestHeaders specifies what headers from the client request + will be sent to the authorization server. + + If this list is empty, then all headers must be sent. + + If the list has entries, only those entries must be sent. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + http: + description: |- + HTTPAuthConfig contains configuration for communication with HTTP-speaking + backends. + + If unset, implementations must assume the default behavior for each + included field is intended. + properties: + allowedHeaders: + description: |- + AllowedRequestHeaders specifies what additional headers from the client request + will be sent to the authorization server. + + The following headers must always be sent to the authorization server, + regardless of this setting: + + * `Host` + * `Method` + * `Path` + * `Content-Length` + * `Authorization` + + If this list is empty, then only those headers must be sent. + + Note that `Content-Length` has a special behavior, in that the length + sent must be correct for the actual request to the external authorization + server - that is, it must reflect the actual number of bytes sent in the + body of the request to the authorization server. + + So if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set + to `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set + to anything other than `0`, then the `Content-Length` of the authorization + request must be set to the actual number of bytes forwarded. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + allowedResponseHeaders: + description: |- + AllowedResponseHeaders specifies what headers from the authorization response + will be copied into the request to the backend. + + If this list is empty, then all headers from the authorization server + except Authority or Host must be copied. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + path: + description: |- + Path sets the prefix that paths from the client request will have added + when forwarded to the authorization server. + + When empty or unspecified, no prefix is added. + + Valid values are the same as the "value" regex for path values in the `match` + stanza, and the validation regex will screen out invalid paths in the same way. + Even with the validation, implementations MUST sanitize this input before using it + directly. + maxLength: 1024 + pattern: ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$ + type: string + type: object + protocol: + description: |- + ExternalAuthProtocol describes which protocol to use when communicating with an + ext_authz authorization server. + + When this is set to GRPC, each backend must use the Envoy ext_authz protocol + on the port specified in `backendRefs`. Requests and responses are defined + in the protobufs explained at: + https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto + + When this is set to HTTP, each backend must respond with a `200` status + code in on a successful authorization. Any other code is considered + an authorization failure. + + Feature Names: + GRPC Support - HTTPRouteExternalAuthGRPC + HTTP Support - HTTPRouteExternalAuthHTTP + enum: + - HTTP + - GRPC + type: string + required: + - backendRef + - protocol + type: object + x-kubernetes-validations: + - message: grpc must be specified when protocol + is set to 'GRPC' + rule: 'self.protocol == ''GRPC'' ? has(self.grpc) + : true' + - message: protocol must be 'GRPC' when grpc is + set + rule: 'has(self.grpc) ? self.protocol == ''GRPC'' + : true' + - message: http must be specified when protocol + is set to 'HTTP' + rule: 'self.protocol == ''HTTP'' ? has(self.http) + : true' + - message: protocol must be 'HTTP' when http is + set + rule: 'has(self.http) ? self.protocol == ''HTTP'' + : true' + type: + description: |- + Type identifies which variant of the discriminated union below is + populated. Uses the same union-discriminator pattern as + HTTPRouteFilter and GRPCRouteFilter. + enum: + - ExternalAuth + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.externalAuth must be nil if the + filter.type is not ExternalAuth + rule: '!(has(self.externalAuth) && self.type != + ''ExternalAuth'')' + - message: filter.externalAuth must be specified for + ExternalAuth filter.type + rule: '!(!has(self.externalAuth) && self.type == + ''ExternalAuth'')' + - message: filter.extensionRef must be nil if the + filter.type is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != + ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == + ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-list-type: atomic + type: object hostname: description: |- Hostname specifies the virtual hostname to match for protocol types that @@ -2576,6 +3417,10 @@ spec: - port - protocol type: object + x-kubernetes-validations: + - message: filters may only be set when protocol is HTTP or + HTTPS + rule: '!has(self.filters) || self.protocol in [''HTTP'', ''HTTPS'']' maxItems: 64 minItems: 1 type: array @@ -2737,6 +3582,12 @@ spec: reference, the `ResolvedRefs` on all matching HTTPS listeners condition MUST be set with the Reason `RefNotPermitted`. + + For cluster-scoped resources (such as ClusterTrustBundle), the + `namespace` field MUST be unset. The implementation resolves the scope + based on the kind. + + Implementations MAY choose to perform further validation of the certificate content (e.g., checking expiry or enforcing specific formats). In such cases, an implementation-specific Reason and Message MUST be set. @@ -2754,6 +3605,11 @@ spec: Support: Core - A single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. + + Support: Extended - References to ClusterTrustBundle + (certificates.k8s.io), with `namespace` unset. + + Support: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates. items: @@ -2810,6 +3666,11 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ClusterTrustBundle references must + not specify namespace + rule: self.all(r, !(r.group == 'certificates.k8s.io' + && r.kind == 'ClusterTrustBundle' && has(r.namespace))) mode: default: AllowValidOnly description: |- @@ -2902,6 +3763,12 @@ spec: reference, the `ResolvedRefs` on all matching HTTPS listeners condition MUST be set with the Reason `RefNotPermitted`. + + For cluster-scoped resources (such as ClusterTrustBundle), the + `namespace` field MUST be unset. The implementation resolves the scope + based on the kind. + + Implementations MAY choose to perform further validation of the certificate content (e.g., checking expiry or enforcing specific formats). In such cases, an implementation-specific Reason and Message MUST be set. @@ -2919,6 +3786,11 @@ spec: Support: Core - A single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. + + Support: Extended - References to ClusterTrustBundle + (certificates.k8s.io), with `namespace` unset. + + Support: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates. items: @@ -2976,6 +3848,12 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: ClusterTrustBundle references + must not specify namespace + rule: self.all(r, !(r.group == 'certificates.k8s.io' + && r.kind == 'ClusterTrustBundle' && + has(r.namespace))) mode: default: AllowValidOnly description: |- @@ -3068,6 +3946,19 @@ spec: enum: - IPAddress properties: + routability: + description: |- + Routability reports the reachability scope of this address. When empty or + unset, this field uses the implementation's default routability behavior. + The `k8s.io` domain and all its subdomains are reserved for well-known values. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: Routability must be empty, Cluster, or an implementation-specific + prefixed path; k8s.io and its subdomains are reserved + rule: size(self) == 0 || self == 'Cluster' || (self.matches('^.*/.+$') + && !format.dns1123Subdomain().validate(self.split('/')[0]).hasValue() + && self.split('/')[0] != 'k8s.io' && !self.split('/')[0].endsWith('.k8s.io')) type: default: IPAddress description: Type of the address. @@ -3134,6 +4025,7 @@ spec: * "Accepted" * "Programmed" * "Ready" + * "AddressesAssigned" items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml index 0ecc003..c2c83a6 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/grpcroutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: grpcroutes.gateway.networking.k8s.io spec: @@ -114,11 +114,30 @@ spec: the implementation. The implementation MUST raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. + In the event that multiple GRPCRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the GRPCRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + When multiple GRPCRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. + If a Route (A) of type HTTPRoute or GRPCRoute is attached to a Listener and that listener already has another Route (B) of the other type attached and the intersection of the hostnames of A and B is - non-empty, then the implementation MUST accept exactly one of these two - routes, determined by the following criteria, in order: + non-empty, then the implementation MAY reject one of the two routes. + An implementation that does so MUST accept exactly one of them, + determined by the following criteria, in order: * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by @@ -752,6 +771,11 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' fraction: description: |- Fraction represents the fraction of requests that should be @@ -1105,6 +1129,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 type: array x-kubernetes-list-type: atomic @@ -1428,6 +1456,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' fraction: description: |- Fraction represents the fraction of requests that should be @@ -1868,6 +1900,8 @@ spec: type: string sessionPersistence: description: |- + Deprecated: use the Backend resource for session persistence (GEP-4894). + SessionPersistence defines and configures session persistence for the route rule. @@ -1882,9 +1916,9 @@ spec: Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string - cookieConfig: + cookie: description: |- - CookieConfig provides configuration settings that are specific + Cookie provides configuration settings that are specific to cookie-based session persistence. Support: Core @@ -1915,17 +1949,51 @@ spec: - Permanent - Session type: string + name: + description: |- + Name defines the name of the cookie used for session persistence. + If not specified, a unique cookie name SHOULD be generated. + Users should avoid reusing cookie names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Extended + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + path: + default: / + description: |- + Path defines the cookie Path attribute. When not specified, + implementations MUST default the cookie path to "/". + + + Support: Extended + maxLength: 1024 + type: string type: object - sessionName: + header: description: |- - SessionName defines the name of the persistent session token - which may be reflected in the cookie or the header. Users - should avoid reusing session names to prevent unintended - consequences, such as rejection or unpredictable behavior. + Header provides configuration settings that are specific + to header-based session persistence. - Support: Implementation-specific - maxLength: 128 - type: string + Support: Extended + properties: + name: + description: |- + Name defines the name of the header used for session persistence. + The client must include this header in subsequent requests to + maintain the session. + + Support: Core + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + required: + - name + type: object type: default: Cookie description: |- @@ -1944,11 +2012,16 @@ spec: x-kubernetes-validations: - message: AbsoluteTimeout must be specified when cookie lifetimeType is Permanent - rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) - || self.cookieConfig.lifetimeType != ''Permanent'' || - has(self.absoluteTimeout)' - - message: cookieConfig can only be set with type Cookie - rule: '!has(self.cookieConfig) || self.type == ''Cookie''' + rule: '!has(self.cookie) || !has(self.cookie.lifetimeType) + || self.cookie.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)' + - message: cookie must be nil if type is not Cookie + rule: '!has(self.cookie) || self.type == ''Cookie''' + - message: cookie must be specified for Cookie type + rule: self.type != 'Cookie' || has(self.cookie) + - message: header must be nil if type is not Header + rule: '!has(self.header) || self.type == ''Header''' + - message: header must be specified for Header type + rule: self.type != 'Header' || has(self.header) type: object maxItems: 16 type: array diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml index 5f795d3..399cd5e 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/httproutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: httproutes.gateway.networking.k8s.io spec: @@ -104,8 +104,16 @@ spec: * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. - If ties exist across multiple Routes, the matching precedence rules for - HTTPRouteMatches takes over. + When multiple HTTPRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. Support: Core items: @@ -890,6 +898,11 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' forwardBody: description: |- ForwardBody controls if requests to the authorization server should include @@ -919,6 +932,8 @@ spec: for more. If 0, the body will not be sent to the authorization server. + format: int32 + minimum: 0 type: integer type: object grpc: @@ -1302,6 +1317,11 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' fraction: description: |- Fraction represents the fraction of requests that should be @@ -1493,7 +1513,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -1952,6 +1972,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 type: array x-kubernetes-list-type: atomic @@ -2432,6 +2456,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' forwardBody: description: |- ForwardBody controls if requests to the authorization server should include @@ -2461,6 +2489,8 @@ spec: for more. If 0, the body will not be sent to the authorization server. + format: int32 + minimum: 0 type: integer type: object grpc: @@ -2840,6 +2870,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' fraction: description: |- Fraction represents the fraction of requests that should be @@ -3030,7 +3064,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -3701,37 +3735,41 @@ spec: description: |- Retry defines the configuration for when to retry an HTTP request. + A request is retried when attempts is greater than 0 and the backend did + not process it. This is the case when the connection could not be + established, or when the backend explicitly rejected the request, either + before processing it or with one of the configured status codes. + Support: Extended properties: attempts: + default: 1 description: |- Attempts specifies the maximum number of times an individual request - from the gateway to a backend should be retried. + from the Gateway to a backend should be retried in addition to the + initial request. If the maximum number of retries has been attempted without a successful response from the backend, the Gateway MUST return an error. - When this field is unspecified, the number of times to attempt to retry - a backend request is implementation-specific. + An explicit zero value MUST disable retries. Support: Extended - minimum: 1 + minimum: 0 type: integer backoff: description: |- - Backoff specifies the minimum duration a Gateway should wait between + Backoff specifies the base interval for a backoff strategy between retry attempts and is represented in Gateway API Duration formatting. + The duration a Gateway waits before a retry attempt is determined + by the base interval and the implementation's retry strategy. - For example, setting the `rules[].retry.backoff` field to the value - `100ms` will cause a backend request to first be retried approximately - 100 milliseconds after timing out or receiving a response code configured - to be retriable. - - An implementation MAY use an exponential or alternative backoff strategy - for subsequent retry attempts, MAY cap the maximum backoff duration to - some amount greater than the specified minimum, and MAY add arbitrary - jitter to stagger requests, as long as unsuccessful backend requests are - not retried before the configured minimum duration. + Implementations MAY add random jitter and MAY cap the delay at an + implementation-defined maximum, which SHOULD NOT be less than the base + interval. The precise backoff curve and jitter calculation are + implementation-specific and not exposed in the Gateway API specification. + Implementations typically apply exponential backoff with jitter to + mitigate thundering-herd issues. If a Request timeout (`rules[].timeouts.request`) is configured on the route, the entire duration of the initial request and any retry attempts @@ -3743,18 +3781,23 @@ spec: If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is configured on the route, any retry attempts which reach the configured BackendRequest timeout duration without a response SHOULD be canceled if - possible and the Gateway should wait for at least the specified backoff - duration before attempting to retry the backend request again. + possible and the Gateway SHOULD schedule the next retry attempt according + to the configured backoff. If a BackendRequest timeout is _not_ configured on the route, retry attempts MAY time out after an implementation default duration, or MAY remain pending until a configured Request timeout or implementation default duration for total request time is reached. - When this field is unspecified, the time to wait between retry attempts - is implementation-specific. + When this field is unspecified, the backoff strategy and base interval + are implementation-specific. - Support: Extended + Implementations which retry immediately with no backoff MUST NOT advertise + support for this field and MUST set the Accepted Condition for the Route + to `status: False` with a Reason of `UnsupportedValue` when this field is + set. + + Support: Implementation-specific pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string codes: @@ -3788,6 +3831,8 @@ spec: type: object sessionPersistence: description: |- + Deprecated: use the Backend resource for session persistence (GEP-4894). + SessionPersistence defines and configures session persistence for the route rule. @@ -3802,9 +3847,9 @@ spec: Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string - cookieConfig: + cookie: description: |- - CookieConfig provides configuration settings that are specific + Cookie provides configuration settings that are specific to cookie-based session persistence. Support: Core @@ -3835,17 +3880,51 @@ spec: - Permanent - Session type: string + name: + description: |- + Name defines the name of the cookie used for session persistence. + If not specified, a unique cookie name SHOULD be generated. + Users should avoid reusing cookie names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Extended + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + path: + default: / + description: |- + Path defines the cookie Path attribute. When not specified, + implementations MUST default the cookie path to "/". + + + Support: Extended + maxLength: 1024 + type: string type: object - sessionName: + header: description: |- - SessionName defines the name of the persistent session token - which may be reflected in the cookie or the header. Users - should avoid reusing session names to prevent unintended - consequences, such as rejection or unpredictable behavior. + Header provides configuration settings that are specific + to header-based session persistence. - Support: Implementation-specific - maxLength: 128 - type: string + Support: Extended + properties: + name: + description: |- + Name defines the name of the header used for session persistence. + The client must include this header in subsequent requests to + maintain the session. + + Support: Core + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + required: + - name + type: object type: default: Cookie description: |- @@ -3864,11 +3943,16 @@ spec: x-kubernetes-validations: - message: AbsoluteTimeout must be specified when cookie lifetimeType is Permanent - rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) - || self.cookieConfig.lifetimeType != ''Permanent'' || - has(self.absoluteTimeout)' - - message: cookieConfig can only be set with type Cookie - rule: '!has(self.cookieConfig) || self.type == ''Cookie''' + rule: '!has(self.cookie) || !has(self.cookie.lifetimeType) + || self.cookie.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)' + - message: cookie must be nil if type is not Cookie + rule: '!has(self.cookie) || self.type == ''Cookie''' + - message: cookie must be specified for Cookie type + rule: self.type != 'Cookie' || has(self.cookie) + - message: header must be nil if type is not Header + rule: '!has(self.header) || self.type == ''Header''' + - message: header must be specified for Header type + rule: self.type != 'Header' || has(self.header) timeouts: description: |- Timeouts defines the timeouts that can be configured for an HTTP request. @@ -3977,6 +4061,9 @@ spec: type: array x-kubernetes-list-type: atomic x-kubernetes-validations: + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) - message: While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128 @@ -3992,9 +4079,6 @@ spec: : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128' - - message: Rule name must be unique within the route - rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) - && l1.name == l2.name)) useDefaultGateways: description: |- UseDefaultGateways indicates the default Gateway scope to use for this @@ -4381,8 +4465,16 @@ spec: * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. - If ties exist across multiple Routes, the matching precedence rules for - HTTPRouteMatches takes over. + When multiple HTTPRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. Support: Core items: @@ -5167,6 +5259,11 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' forwardBody: description: |- ForwardBody controls if requests to the authorization server should include @@ -5196,6 +5293,8 @@ spec: for more. If 0, the body will not be sent to the authorization server. + format: int32 + minimum: 0 type: integer type: object grpc: @@ -5579,6 +5678,11 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' fraction: description: |- Fraction represents the fraction of requests that should be @@ -5770,7 +5874,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -6229,6 +6333,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 type: array x-kubernetes-list-type: atomic @@ -6709,6 +6817,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' forwardBody: description: |- ForwardBody controls if requests to the authorization server should include @@ -6738,6 +6850,8 @@ spec: for more. If 0, the body will not be sent to the authorization server. + format: int32 + minimum: 0 type: integer type: object grpc: @@ -7117,6 +7231,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' fraction: description: |- Fraction represents the fraction of requests that should be @@ -7307,7 +7425,7 @@ spec: Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. - Support: Core + Support: statusCode 301 and 302 are Core; all others are Extended. enum: - 301 - 302 @@ -7978,37 +8096,41 @@ spec: description: |- Retry defines the configuration for when to retry an HTTP request. + A request is retried when attempts is greater than 0 and the backend did + not process it. This is the case when the connection could not be + established, or when the backend explicitly rejected the request, either + before processing it or with one of the configured status codes. + Support: Extended properties: attempts: + default: 1 description: |- Attempts specifies the maximum number of times an individual request - from the gateway to a backend should be retried. + from the Gateway to a backend should be retried in addition to the + initial request. If the maximum number of retries has been attempted without a successful response from the backend, the Gateway MUST return an error. - When this field is unspecified, the number of times to attempt to retry - a backend request is implementation-specific. + An explicit zero value MUST disable retries. Support: Extended - minimum: 1 + minimum: 0 type: integer backoff: description: |- - Backoff specifies the minimum duration a Gateway should wait between + Backoff specifies the base interval for a backoff strategy between retry attempts and is represented in Gateway API Duration formatting. + The duration a Gateway waits before a retry attempt is determined + by the base interval and the implementation's retry strategy. - For example, setting the `rules[].retry.backoff` field to the value - `100ms` will cause a backend request to first be retried approximately - 100 milliseconds after timing out or receiving a response code configured - to be retriable. - - An implementation MAY use an exponential or alternative backoff strategy - for subsequent retry attempts, MAY cap the maximum backoff duration to - some amount greater than the specified minimum, and MAY add arbitrary - jitter to stagger requests, as long as unsuccessful backend requests are - not retried before the configured minimum duration. + Implementations MAY add random jitter and MAY cap the delay at an + implementation-defined maximum, which SHOULD NOT be less than the base + interval. The precise backoff curve and jitter calculation are + implementation-specific and not exposed in the Gateway API specification. + Implementations typically apply exponential backoff with jitter to + mitigate thundering-herd issues. If a Request timeout (`rules[].timeouts.request`) is configured on the route, the entire duration of the initial request and any retry attempts @@ -8020,18 +8142,23 @@ spec: If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is configured on the route, any retry attempts which reach the configured BackendRequest timeout duration without a response SHOULD be canceled if - possible and the Gateway should wait for at least the specified backoff - duration before attempting to retry the backend request again. + possible and the Gateway SHOULD schedule the next retry attempt according + to the configured backoff. If a BackendRequest timeout is _not_ configured on the route, retry attempts MAY time out after an implementation default duration, or MAY remain pending until a configured Request timeout or implementation default duration for total request time is reached. - When this field is unspecified, the time to wait between retry attempts - is implementation-specific. + When this field is unspecified, the backoff strategy and base interval + are implementation-specific. - Support: Extended + Implementations which retry immediately with no backoff MUST NOT advertise + support for this field and MUST set the Accepted Condition for the Route + to `status: False` with a Reason of `UnsupportedValue` when this field is + set. + + Support: Implementation-specific pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string codes: @@ -8065,6 +8192,8 @@ spec: type: object sessionPersistence: description: |- + Deprecated: use the Backend resource for session persistence (GEP-4894). + SessionPersistence defines and configures session persistence for the route rule. @@ -8079,9 +8208,9 @@ spec: Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string - cookieConfig: + cookie: description: |- - CookieConfig provides configuration settings that are specific + Cookie provides configuration settings that are specific to cookie-based session persistence. Support: Core @@ -8112,17 +8241,51 @@ spec: - Permanent - Session type: string + name: + description: |- + Name defines the name of the cookie used for session persistence. + If not specified, a unique cookie name SHOULD be generated. + Users should avoid reusing cookie names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Extended + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + path: + default: / + description: |- + Path defines the cookie Path attribute. When not specified, + implementations MUST default the cookie path to "/". + + + Support: Extended + maxLength: 1024 + type: string type: object - sessionName: + header: description: |- - SessionName defines the name of the persistent session token - which may be reflected in the cookie or the header. Users - should avoid reusing session names to prevent unintended - consequences, such as rejection or unpredictable behavior. + Header provides configuration settings that are specific + to header-based session persistence. - Support: Implementation-specific - maxLength: 128 - type: string + Support: Extended + properties: + name: + description: |- + Name defines the name of the header used for session persistence. + The client must include this header in subsequent requests to + maintain the session. + + Support: Core + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + required: + - name + type: object type: default: Cookie description: |- @@ -8141,11 +8304,16 @@ spec: x-kubernetes-validations: - message: AbsoluteTimeout must be specified when cookie lifetimeType is Permanent - rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) - || self.cookieConfig.lifetimeType != ''Permanent'' || - has(self.absoluteTimeout)' - - message: cookieConfig can only be set with type Cookie - rule: '!has(self.cookieConfig) || self.type == ''Cookie''' + rule: '!has(self.cookie) || !has(self.cookie.lifetimeType) + || self.cookie.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)' + - message: cookie must be nil if type is not Cookie + rule: '!has(self.cookie) || self.type == ''Cookie''' + - message: cookie must be specified for Cookie type + rule: self.type != 'Cookie' || has(self.cookie) + - message: header must be nil if type is not Header + rule: '!has(self.header) || self.type == ''Header''' + - message: header must be specified for Header type + rule: self.type != 'Header' || has(self.header) timeouts: description: |- Timeouts defines the timeouts that can be configured for an HTTP request. @@ -8254,6 +8422,9 @@ spec: type: array x-kubernetes-list-type: atomic x-kubernetes-validations: + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) - message: While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128 @@ -8269,9 +8440,6 @@ spec: : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128' - - message: Rule name must be unique within the route - rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) - && l1.name == l2.name)) useDefaultGateways: description: |- UseDefaultGateways indicates the default Gateway scope to use for this diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml index 934aac2..3acadf0 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/listenersets.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: listenersets.gateway.networking.k8s.io spec: @@ -255,6 +255,384 @@ spec: x-kubernetes-map-type: atomic type: object type: object + filters: + description: |- + Filters groups the pre-routing filter lists that run on every + request accepted on this Listener, before route matching is + performed. Filters is only valid when Protocol is `HTTP` or + `HTTPS`; this constraint is enforced by CEL validation on the + enclosing Listener struct. + + Support: Extended + properties: + requests: + description: |- + Implementations MUST execute the filters in the exact order they + appear here and MUST NOT reorder them. If an implementation can + not implement the filters in the order they are specified, the + implementation MUST set the "Accepted" Listener condition to "false" + with the "InvalidListenerFilterOrder" reason. + + Requests only apply to connections with a visible HTTP stream + and metadata (Protocol=HTTP, or Protocol=HTTPS with TLS + terminated at the Gateway). + + Requests may mutate inputs that route matching consumes + (path, request headers, method, computed metadata), with the + explicit exception of the `Host` and `:authority` headers. If a + ListenerFilter attempts to modify either header, implementations + MUST NOT allow that modification to take effect. Implementations + SHOULD satisfy this by ignoring the mutation and continuing to + process the request with the original value; they MAY instead + fail the request with a 5xx response. Implementations MUST + evaluate route matching exactly once after the last + ListenerFilter has run. + + Requests MUST NOT be interpreted as changing which Listener + handles the request. Listener selection is decided from inputs + the client committed to before any pre-routing filter runs: TLS + SNI (for HTTPS) or the request's initial Host header (for HTTP). + Because filters cannot modify Host or :authority, the input to + cleartext-HTTP Listener selection cannot change; Listener + selection therefore does not need to be re-evaluated after + pre-routing filters run, and MUST NOT be. + items: + description: |- + ListenerFilter is one element of a ListenerFilters.Requests list. + Unlike HTTPRouteFilter, which runs after a route is selected and whose + ordering is a SHOULD, ListenerFilter runs before route selection and + its ordering within the containing list is a MUST. + + Only a subset of HTTPRouteFilter variants are permitted: + ExternalAuth (to establish identity that route matching can consume) and + ExtensionRef (the escape hatch for custom pre-routing behavior, for + example body-based routing or JWT-claim projection). The other + HTTPRouteFilter variants are excluded because they either cannot influence + route selection or can already be expressed post-routing with equal + expressiveness. See the GEP text for details. + properties: + extensionRef: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + externalAuth: + description: |- + HTTPExternalAuthFilter defines a filter that modifies requests by sending + request details to an external authorization server. + + Support: Extended + Feature Name: HTTPRouteExternalAuth + properties: + backendRef: + description: |- + BackendRef is a reference to a backend to send authorization + requests to. + + The backend must speak the selected protocol (GRPC or HTTP) on the + referenced port. + + If the backend service requires TLS, use BackendTLSPolicy to tell the + implementation to supply the TLS details to be used to connect to that + backend. + properties: + group: + default: '' + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend + reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) + : true' + forwardBody: + description: |- + ForwardBody controls if requests to the authorization server should include + the body of the client request; and if so, how big that body is allowed + to be. + + It is expected that implementations will buffer the request body up to + `forwardBody.maxSize` bytes. Bodies over that size must be rejected with a + 4xx series error (413 or 403 are common examples), and fail processing + of the filter. + + If unset, or `forwardBody.maxSize` is set to `0`, then the body will not + be forwarded. + + Feature Name: HTTPRouteExternalAuthForwardBody + properties: + maxSize: + description: |- + MaxSize specifies how large in bytes the largest body that will be buffered + and sent to the authorization server. If the body size is larger than + `maxSize`, then the body sent to the authorization server must be + truncated to `maxSize` bytes. + + Experimental note: This behavior needs to be checked against + various dataplanes; it may need to be changed. + See https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746 + for more. + + If 0, the body will not be sent to the authorization server. + format: int32 + minimum: 0 + type: integer + type: object + grpc: + description: |- + GRPCAuthConfig contains configuration for communication with ext_authz + protocol-speaking backends. + + If unset, implementations must assume the default behavior for each + included field is intended. + properties: + allowedHeaders: + description: |- + AllowedRequestHeaders specifies what headers from the client request + will be sent to the authorization server. + + If this list is empty, then all headers must be sent. + + If the list has entries, only those entries must be sent. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + http: + description: |- + HTTPAuthConfig contains configuration for communication with HTTP-speaking + backends. + + If unset, implementations must assume the default behavior for each + included field is intended. + properties: + allowedHeaders: + description: |- + AllowedRequestHeaders specifies what additional headers from the client request + will be sent to the authorization server. + + The following headers must always be sent to the authorization server, + regardless of this setting: + + * `Host` + * `Method` + * `Path` + * `Content-Length` + * `Authorization` + + If this list is empty, then only those headers must be sent. + + Note that `Content-Length` has a special behavior, in that the length + sent must be correct for the actual request to the external authorization + server - that is, it must reflect the actual number of bytes sent in the + body of the request to the authorization server. + + So if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set + to `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set + to anything other than `0`, then the `Content-Length` of the authorization + request must be set to the actual number of bytes forwarded. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + allowedResponseHeaders: + description: |- + AllowedResponseHeaders specifies what headers from the authorization response + will be copied into the request to the backend. + + If this list is empty, then all headers from the authorization server + except Authority or Host must be copied. + items: + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + path: + description: |- + Path sets the prefix that paths from the client request will have added + when forwarded to the authorization server. + + When empty or unspecified, no prefix is added. + + Valid values are the same as the "value" regex for path values in the `match` + stanza, and the validation regex will screen out invalid paths in the same way. + Even with the validation, implementations MUST sanitize this input before using it + directly. + maxLength: 1024 + pattern: ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$ + type: string + type: object + protocol: + description: |- + ExternalAuthProtocol describes which protocol to use when communicating with an + ext_authz authorization server. + + When this is set to GRPC, each backend must use the Envoy ext_authz protocol + on the port specified in `backendRefs`. Requests and responses are defined + in the protobufs explained at: + https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto + + When this is set to HTTP, each backend must respond with a `200` status + code in on a successful authorization. Any other code is considered + an authorization failure. + + Feature Names: + GRPC Support - HTTPRouteExternalAuthGRPC + HTTP Support - HTTPRouteExternalAuthHTTP + enum: + - HTTP + - GRPC + type: string + required: + - backendRef + - protocol + type: object + x-kubernetes-validations: + - message: grpc must be specified when protocol + is set to 'GRPC' + rule: 'self.protocol == ''GRPC'' ? has(self.grpc) + : true' + - message: protocol must be 'GRPC' when grpc is + set + rule: 'has(self.grpc) ? self.protocol == ''GRPC'' + : true' + - message: http must be specified when protocol + is set to 'HTTP' + rule: 'self.protocol == ''HTTP'' ? has(self.http) + : true' + - message: protocol must be 'HTTP' when http is + set + rule: 'has(self.http) ? self.protocol == ''HTTP'' + : true' + type: + description: |- + Type identifies which variant of the discriminated union below is + populated. Uses the same union-discriminator pattern as + HTTPRouteFilter and GRPCRouteFilter. + enum: + - ExternalAuth + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.externalAuth must be nil if the + filter.type is not ExternalAuth + rule: '!(has(self.externalAuth) && self.type != + ''ExternalAuth'')' + - message: filter.externalAuth must be specified for + ExternalAuth filter.type + rule: '!(!has(self.externalAuth) && self.type == + ''ExternalAuth'')' + - message: filter.extensionRef must be nil if the + filter.type is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != + ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == + ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-list-type: atomic + type: object hostname: description: |- Hostname specifies the virtual hostname to match for protocol types that diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml index 37e0f14..3f39dbd 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/referencegrants.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: referencegrants.gateway.networking.k8s.io spec: diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml index 700be6d..7b44d7c 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tcproutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: tcproutes.gateway.networking.k8s.io spec: @@ -417,6 +417,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 minItems: 1 type: array @@ -1139,6 +1143,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 minItems: 1 type: array diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml index 9155b23..830288a 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/tlsroutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: tlsroutes.gateway.networking.k8s.io spec: @@ -61,6 +61,25 @@ spec: 1. IPs are not allowed in SNI hostnames per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. + + + In the event that multiple TLSRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the TLSRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + When multiple TLSRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. items: description: |- Hostname is the fully qualified domain name of a network host. This matches @@ -477,6 +496,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 minItems: 1 type: array @@ -1271,6 +1294,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 minItems: 1 type: array @@ -1641,6 +1668,25 @@ spec: 1. IPs are not allowed in SNI hostnames per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. + + + In the event that multiple TLSRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the TLSRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + When multiple TLSRoutes attach to the same Listener and yield identical + Listener/Route intersected hostnames, implementations SHOULD evaluate + precedence using the original hostnames configured on the Route, not the + calculated Listener/Route hostname intersection. + + Resolving Route precedence using original Route hostname specificity is an + Extended feature. Implementations that support this behavior SHOULD claim + support for the `GatewayRouteHostnameIntersectionPrecedence` feature. + Implementations that do not support this feature MAY evaluate precedence + using the calculated Listener/Route hostname intersection. items: description: |- Hostname is the fully qualified domain name of a network host. This matches @@ -2057,6 +2103,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 minItems: 1 type: array diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml index 1c50201..adeee38 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/udproutes.gateway.networking.k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: udproutes.gateway.networking.k8s.io spec: @@ -417,6 +417,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 minItems: 1 type: array @@ -1139,6 +1143,10 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' maxItems: 16 minItems: 1 type: array diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackends.gateway.networking.x-k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackends.gateway.networking.x-k8s.io.yaml index fe1b8bf..0d0d9a3 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackends.gateway.networking.x-k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackends.gateway.networking.x-k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: xbackends.gateway.networking.x-k8s.io spec: @@ -53,6 +53,46 @@ spec: spec: description: Spec defines the desired state of XBackend. properties: + endpointSelector: + description: |- + EndpointSelector specifies the configuration for an EndpointSelector + backend. This field must be set when type is EndpointSelector and must + be unset otherwise. + properties: + matchLabels: + additionalProperties: + description: |- + LabelValue is the value of a label in the Gateway API. This is used for validation + of maps such as Gateway infrastructure labels. This matches the Kubernetes + label validation rules: + * must be 63 characters or less (can be empty), + * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]), + * could contain dashes (-), underscores (_), dots (.), and alphanumerics between. + + Valid values include: + + * MyValue + * my.name + * 123-my-value + maxLength: 63 + minLength: 0 + pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$ + type: string + description: |- + MatchLabels contains a set of required {key,value} pairs. + An object must match every label in this map to be selected. + The matching logic is an AND operation on all entries. + maxProperties: 64 + minProperties: 1 + type: object + x-kubernetes-validations: + - message: Label keys must be in the form of an optional DNS + subdomain prefix not longer than 253 characters followed + by a required name segment of up to 63 characters. + rule: self.all(key, !format.qualifiedName().validate(key).hasValue()) + required: + - matchLabels + type: object externalHostname: description: |- ExternalHostname specifies the configuration for an ExternalHostname @@ -78,29 +118,17 @@ spec: type: object port: description: |- - Port defines the port that the implementation should use when connecting - to this backend. + Port defines the port to connect to on this backend. + For ExternalHostname, this is the port on the external host. + For EndpointSelector, this specifies which endpoint port to connect to. + minProperties: 1 properties: - name: - description: |- - Name represents the name of this port. All ports in a Backend must have - a unique name. Name must either be an empty string or pass DNS_LABEL - validation (lowercase alphanumeric or '-', starting and ending with an - alphanumeric character, at most 63 characters). - maxLength: 63 - type: string - x-kubernetes-validations: - - message: Name must be a valid DNS label - rule: size(self) == 0 || format.dns1123Label().validate(self) - == null - port: - description: Port represents the port number of the endpoint. + number: + description: Number represents the port number of the destination. format: int32 maximum: 65535 minimum: 1 type: integer - required: - - port type: object protocol: description: |- @@ -118,7 +146,7 @@ spec: Support: Core - HTTP, HTTP2, H2C, and HTTP11 - Support: Extended - GRPC, MCP, TCP + Support: Extended - GRPC, MCP, TCP, WSS enum: - TCP - HTTP @@ -126,8 +154,136 @@ spec: - HTTP11 - H2C - MCP + - GRPC + - WSS type: string + sessionPersistence: + description: |- + SessionPersistence defines and configures session persistence + across the endpoints selected by this backend. + + This field can only be configured when type is EndpointSelector. + + Support: Extended + properties: + absoluteTimeout: + description: |- + AbsoluteTimeout defines the absolute timeout of the persistent + session. Once the AbsoluteTimeout duration has elapsed, the + session becomes invalid. + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + cookie: + description: |- + Cookie provides configuration settings that are specific + to cookie-based session persistence. + + Support: Core + properties: + lifetimeType: + default: Session + description: |- + LifetimeType specifies whether the cookie has a permanent or + session-based lifetime. A permanent cookie persists until its + specified expiry time, defined by the Expires or Max-Age cookie + attributes, while a session cookie is deleted when the current + session ends. + + When set to "Permanent", AbsoluteTimeout indicates the + cookie's lifetime via the Expires or Max-Age cookie attributes + and is required. + + When set to "Session", AbsoluteTimeout indicates the + absolute lifetime of the cookie tracked by the gateway and + is optional. + + Defaults to "Session". + + Support: Core for "Session" type + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + name: + description: |- + Name defines the name of the cookie used for session persistence. + If not specified, a unique cookie name SHOULD be generated. + Users should avoid reusing cookie names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Extended + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + path: + default: / + description: |- + Path defines the cookie Path attribute. When not specified, + implementations MUST default the cookie path to "/". + + + Support: Extended + maxLength: 1024 + type: string + type: object + header: + description: |- + Header provides configuration settings that are specific + to header-based session persistence. + + Support: Extended + properties: + name: + description: |- + Name defines the name of the header used for session persistence. + The client must include this header in subsequent requests to + maintain the session. + + Support: Core + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + required: + - name + type: object + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use of a header or cookie. Defaults to cookie based session + persistence. + + Support: Core for "Cookie" type + + Support: Extended for "Header" type + enum: + - Cookie + - Header + type: string + type: object + x-kubernetes-validations: + - message: AbsoluteTimeout must be specified when cookie lifetimeType + is Permanent + rule: '!has(self.cookie) || !has(self.cookie.lifetimeType) || + self.cookie.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)' + - message: cookie must be nil if type is not Cookie + rule: '!has(self.cookie) || self.type == ''Cookie''' + - message: cookie must be specified for Cookie type + rule: self.type != 'Cookie' || has(self.cookie) + - message: header must be nil if type is not Header + rule: '!has(self.header) || self.type == ''Header''' + - message: header must be specified for Header type + rule: self.type != 'Header' || has(self.header) tls: + default: + mode: None description: |- TLS defines the TLS configuration that the implementation should use when connecting to the backend. @@ -135,7 +291,9 @@ spec: ExternalHostname backends SHOULD have TLS configured; the lack of TLS for external hostnames should be considered insecure and a security risk. - Support: Extended + Support: Core - for TLS mode None + + Support: Extended - for TLS mode ServerOnly and ClientAndServer properties: clientCertificateRef: description: |- @@ -182,7 +340,12 @@ spec: - name type: object mode: - description: Mode defines the TLS mode for the backend connection. + description: |- + Mode defines the TLS mode for the backend connection. + + Support: Core - None + + Support: Extended - ServerOnly, ClientAndServer enum: - None - ServerOnly @@ -229,6 +392,14 @@ spec: ensure the `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason `NoValidCACertificate`. + + References to cluster-scoped resources (such as ClusterTrustBundle) + are supported: the implementation resolves the scope based on the kind. + A single CACertificateRef to a ClusterTrustBundle uses the cluster-scoped + resource by name. A reference to a namespaced resource (such as ConfigMap + or Secret) uses the local namespace. + + A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific. @@ -236,6 +407,10 @@ spec: Support: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. + + Support: Extended - A single reference to a ClusterTrustBundle (certificates.k8s.io). + + Support: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates. items: @@ -274,6 +449,7 @@ spec: - name type: object maxItems: 8 + minItems: 1 type: array x-kubernetes-list-type: atomic hostname: @@ -387,14 +563,10 @@ spec: - hostname type: object x-kubernetes-validations: - - message: must not contain both CACertificateRefs and WellKnownCACertificates - rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs) - > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates - != "")' - - message: must specify either CACertificateRefs or WellKnownCACertificates - rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs) - > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates - != "") + - message: exactly one of the fields in [caCertificateRefs + wellKnownCACertificates] must be set + rule: (has(self.caCertificateRefs)?1:0)+(has(self.wellKnownCACertificates)?1:0) + == 1 required: - mode type: object @@ -403,10 +575,14 @@ spec: is ClientAndServer rule: 'self.mode == ''ClientAndServer'' ? has(self.clientCertificateRef) : !has(self.clientCertificateRef)' + - message: validation must be set if and only if mode is either + ClientAndServer or ServerOnly + rule: 'self.mode == ''None'' ? !has(self.validation) : has(self.validation)' type: description: Type defines the backend type. enum: - ExternalHostname + - EndpointSelector type: string required: - port @@ -417,108 +593,44 @@ spec: and must be unset otherwise rule: 'self.type == ''ExternalHostname'' ? has(self.externalHostname) : !has(self.externalHostname)' + - message: endpointSelector must be set when type is EndpointSelector + and must be unset otherwise + rule: 'self.type == ''EndpointSelector'' ? has(self.endpointSelector) + : !has(self.endpointSelector)' + - message: tls must be disabled when protocol is H2C, use protocol + HTTP2 for HTTP/2 with tls + rule: '!has(self.protocol) || self.protocol != ''H2C'' || !has(self.tls) + || self.tls.mode == ''None''' + - message: tls must be enabled when protocol is HTTP2, use protocol + H2C for HTTP/2 without tls + rule: '!has(self.protocol) || self.protocol != ''HTTP2'' || (has(self.tls) + && self.tls.mode != ''None'')' + - message: tls must be enabled when protocol is WSS + rule: '!has(self.protocol) || self.protocol != ''WSS'' || (has(self.tls) + && self.tls.mode != ''None'')' + - message: sessionPersistence can only be set when type is EndpointSelector + rule: 'has(self.sessionPersistence) ? self.type == ''EndpointSelector'' + : true' status: description: Status defines the current state of XBackend. properties: - parents: + ancestors: description: |- - Ancestors is a list of parent resources associated with this Backend, - and the status of the Backend with respect to each parent. + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with this Backend, and the status of the Backend with respect + to each ancestor. - A maximum of 32 parents will be represented in this list. An empty list - indicates that the Backend is not associated with any parents. + A maximum of 32 ancestors will be represented in this list. An empty list + indicates that the Backend is not associated with any ancestors. items: description: |- BackendAncestorStatus describes the status of a Backend with respect to a - specific parent resource (typically a Gateway). + specific ancestor resource (typically a Gateway). properties: - conditions: + ancestorRef: description: |- - For Kubernetes API conventions, see: - https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties - conditions represent the current state of the Backend resource. - Each condition has a unique type and reflects the status of a specific aspect of the resource. - - Defined condition types include: - - "Accepted": the resource has been acknowledged and accepteed by the controller - - The status of each condition is one of True, False, or Unknown. - items: - description: Condition contains details for one aspect of - the current state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: |- - ControllerName is a domain/path string that indicates the name of the - controller that manages the Backend. - - Example: "example.net/gateway-controller". - - The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are - valid Kubernetes names - (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - parentRef: - description: AncestorRef identifies the parent resource that - this status is associated with. + AncestorRef identifies the ancestor resource that this status is + associated with. properties: group: default: gateway.networking.k8s.io @@ -652,9 +764,93 @@ spec: required: - name type: object + conditions: + description: |- + For Kubernetes API conventions, see: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + conditions represent the current state of the Backend resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Defined condition types include: + - "Accepted": the resource has been acknowledged and accepted by the controller + + The status of each condition is one of True, False, or Unknown. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - 'True' + - 'False' + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that manages the Backend. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string required: + - ancestorRef - controllerName - - parentRef type: object maxItems: 32 type: array diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackendtrafficpolicies.gateway.networking.x-k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackendtrafficpolicies.gateway.networking.x-k8s.io.yaml index ee05417..9c3f7dc 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackendtrafficpolicies.gateway.networking.x-k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xbackendtrafficpolicies.gateway.networking.x-k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental labels: gateway.networking.k8s.io/policy: Direct @@ -157,6 +157,8 @@ spec: type: object sessionPersistence: description: |- + Deprecated: use the Backend resource for session persistence (GEP-4894). + SessionPersistence defines and configures session persistence for the backend. @@ -171,9 +173,9 @@ spec: Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string - cookieConfig: + cookie: description: |- - CookieConfig provides configuration settings that are specific + Cookie provides configuration settings that are specific to cookie-based session persistence. Support: Core @@ -204,17 +206,51 @@ spec: - Permanent - Session type: string + name: + description: |- + Name defines the name of the cookie used for session persistence. + If not specified, a unique cookie name SHOULD be generated. + Users should avoid reusing cookie names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Extended + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + path: + default: / + description: |- + Path defines the cookie Path attribute. When not specified, + implementations MUST default the cookie path to "/". + + + Support: Extended + maxLength: 1024 + type: string type: object - sessionName: + header: description: |- - SessionName defines the name of the persistent session token - which may be reflected in the cookie or the header. Users - should avoid reusing session names to prevent unintended - consequences, such as rejection or unpredictable behavior. + Header provides configuration settings that are specific + to header-based session persistence. - Support: Implementation-specific - maxLength: 128 - type: string + Support: Extended + properties: + name: + description: |- + Name defines the name of the header used for session persistence. + The client must include this header in subsequent requests to + maintain the session. + + Support: Core + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + required: + - name + type: object type: default: Cookie description: |- @@ -233,10 +269,16 @@ spec: x-kubernetes-validations: - message: AbsoluteTimeout must be specified when cookie lifetimeType is Permanent - rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) - || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)' - - message: cookieConfig can only be set with type Cookie - rule: '!has(self.cookieConfig) || self.type == ''Cookie''' + rule: '!has(self.cookie) || !has(self.cookie.lifetimeType) || + self.cookie.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)' + - message: cookie must be nil if type is not Cookie + rule: '!has(self.cookie) || self.type == ''Cookie''' + - message: cookie must be specified for Cookie type + rule: self.type != 'Cookie' || has(self.cookie) + - message: header must be nil if type is not Header + rule: '!has(self.header) || self.type == ''Header''' + - message: header must be specified for Header type + rule: self.type != 'Header' || has(self.header) targetRefs: description: |- TargetRefs identifies API object(s) to apply this policy to. diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xmeshes.gateway.networking.x-k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xmeshes.gateway.networking.x-k8s.io.yaml index 345a049..1d1186e 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xmeshes.gateway.networking.x-k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xmeshes.gateway.networking.x-k8s.io.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/4530 - gateway.networking.k8s.io/bundle-version: v1.6.1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: experimental name: xmeshes.gateway.networking.x-k8s.io spec: @@ -68,7 +68,7 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string x-kubernetes-validations: - - message: Value is immutable + - message: field is immutable rule: self == oldSelf description: description: Description optionally provides a human-readable description diff --git a/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xtelemetrypolicies.gateway.networking.x-k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xtelemetrypolicies.gateway.networking.x-k8s.io.yaml new file mode 100644 index 0000000..9bc9771 --- /dev/null +++ b/tests/golden/experimental/gateway-api/gateway-api/10_gateway_api_crds/xtelemetrypolicies.gateway.networking.x-k8s.io.yaml @@ -0,0 +1,830 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/5371 + gateway.networking.k8s.io/bundle-version: v1.7.0 + gateway.networking.k8s.io/channel: experimental + labels: + gateway.networking.k8s.io/policy: Direct + name: xtelemetrypolicies.gateway.networking.x-k8s.io +spec: + group: gateway.networking.x-k8s.io + names: + categories: + - gateway-api + kind: XTelemetryPolicy + listKind: XTelemetryPolicyList + plural: xtelemetrypolicies + shortNames: + - xtelemetrypolicy + singular: xtelemetrypolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + TelemetryPolicy defines a Direct Attached Policy to configure + telemetry/observability signals for Gateways. + + By applying a TelemetryPolicy, platform operators and developers can ensure + consistent collection, formatting, and export of observability signals. + + + Notes for implementors: + + TelemetryPolicy is a Direct Attached Policy. Implementing controllers MUST + adhere to the Policy Attachment guidelines (GEP-713). + + Precedence and Conflict Resolution: + - To prevent complex merging semantics, only a single TelemetryPolicy is + permitted to apply to a specific Gateway resource at any given time. + - If multiple TelemetryPolicy resources target the same Gateway, precedence + MUST be determined using the following criteria, continuing on ties: + 1. The older policy by creation timestamp takes precedence. + 2. The policy appearing first in alphabetical order by {namespace}/{name}. + - For any TelemetryPolicy that does not take precedence, the controller + MUST set the `Accepted` condition on the policy status to `status: False` with + Reason `Conflicted`. + + Conformance: + Implementations MUST support the core resource structure and `targetRefs`. + Support for the tracing block is Extended, but if supported, + its respective conformance profile must be met. + + + Support: Extended + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of TelemetryPolicy. + properties: + targetRefs: + description: |- + TargetRefs identifies the gateways to which this policy applies (GEP-713). + + When configured, the telemetry settings defined in this policy are applied + uniformly to the referenced resources. In the absence of targetRefs, the policy is + invalid and will not be accepted. + + TargetRefs must be distinct. + + Support: Core for Gateway + items: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example "HTTPRoute" + or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + tracing: + description: |- + Tracing defines the configuration for distributed tracing. + + When configured, distributed tracing spans are generated and exported. In the + absence of this configuration, tracing behavior is determined by implementation + defaults. + + Support: Extended + + Feature Name: TelemetryPolicyTracing + properties: + attributes: + description: |- + Attributes is a list of custom key-value pairs (or variables) attached to every span. + + When configured, these attributes are injected into every generated tracing span. + In the absence of attributes, only standard proxy-defined attributes are emitted. + + Support: Extended + items: + description: |- + Attribute defines a single flat key-value pair to attach to traces. + + This allows users to enrich spans with context like HTTP headers + (e.g., "X-User-ID"), static tags, or built-in variables. + + Support: Core + properties: + attributeKey: + description: |- + AttributeKey refers to a standard OpenTelemetry attribute. + For example: "http.response.status_code" or "http.request.method". + This is required if SourceType is "Attribute". + See: https://opentelemetry.io/docs/specs/semconv/ + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9_.-]+$ + type: string + headerName: + description: |- + HeaderName specifies the HTTP header to extract the value from. + This is required if SourceType is "Header". + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + literalValue: + description: |- + LiteralValue specifies a static string value to attach. + This is required if SourceType is "Literal". + maxLength: 1024 + minLength: 1 + type: string + name: + description: |- + Name is the key of the attribute as it will appear in the output + (i.e., as a span tag). + maxLength: 256 + minLength: 1 + pattern: ^[a-zA-Z0-9_.:/-]+$ + type: string + sourceType: + description: |- + SourceType specifies where the attribute value comes from. + Valid values are "Header", "Literal", or "Attribute". + enum: + - Header + - Literal + - Attribute + type: string + required: + - name + - sourceType + type: object + x-kubernetes-validations: + - message: headerName is required when sourceType is Header, + and must be empty otherwise + rule: 'self.sourceType == ''Header'' ? has(self.headerName) + : !has(self.headerName)' + - message: literalValue is required when sourceType is Literal, + and must be empty otherwise + rule: 'self.sourceType == ''Literal'' ? has(self.literalValue) + : !has(self.literalValue)' + - message: attributeKey is required when sourceType is Attribute, + and must be empty otherwise + rule: 'self.sourceType == ''Attribute'' ? has(self.attributeKey) + : !has(self.attributeKey)' + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + mode: + default: ImplementationDefault + description: |- + Mode explicitly controls if tracing is enabled. Valid values are "Enabled", "Disabled", + "ImplementationDefault". + + In the absence of this field, it defaults to "ImplementationDefault". + + Support: Core (within TelemetryPolicy feature) + enum: + - Enabled + - Disabled + - ImplementationDefault + type: string + parentBasedSampling: + description: |- + ParentBasedSampling configures whether to respect the sampling decision of the parent span. + + * When Mode is "Enabled", the proxy will respect the upstream trace parent's sampling + decision. + * When Mode is "Disabled", the proxy ignores the upstream trace parent's sampling + decision and applies its own local sampling rate decision. + * When Mode is "ImplementationDefault" or absent, the implementation's default behavior + is used. + + Support: Extended + + Feature Name: TelemetryPolicyParentBasedSampling + properties: + mode: + default: ImplementationDefault + description: |- + Mode explicitly controls if parent-based sampling is enabled. Valid values are "Enabled", + "Disabled", "ImplementationDefault". + + In the absence of this field, it defaults to "ImplementationDefault". + + Support: Extended + enum: + - Enabled + - Disabled + - ImplementationDefault + type: string + samplingRate: + description: |- + SamplingRate is the sampling rate to apply when parent-based sampling is active. + + This acts as a downsampling governor. It allows an operator to say: "I want to + respect the parent's decision, but only for 50% of those requests". Even if a + parent is already marked as "Sampled", this allows the Gateway to apply a secondary + filter so that it can respect the parent's intent while still controlling the volume + of spans reported. + + When Mode is "Enabled" and this field is absent, a 100% sampling rate + ({numerator: 100, denominator: 100}) is used. + + Support: Extended + properties: + denominator: + default: 100 + format: int32 + minimum: 1 + type: integer + numerator: + format: int32 + minimum: 0 + type: integer + required: + - numerator + type: object + x-kubernetes-validations: + - message: numerator must be less than or equal to denominator + rule: self.numerator <= self.denominator + type: object + x-kubernetes-validations: + - message: samplingRate can only be set when mode is Enabled + rule: 'has(self.samplingRate) ? self.mode == ''Enabled'' + : true' + provider: + description: |- + Provider specifies the tracing collector or backend endpoint receiving OTLP spans. + + When configured, spans generated by the Gateway proxy are exported to this destination. + This field is required when Mode is "Enabled", and must not be set otherwise. + + Support: Core (within Tracing feature) + properties: + backendRef: + description: |- + BackendRef is a reference to a Kubernetes Service or other supported + backend that receives OTLP traces. + + When configured, tracing data is exported to the referenced backend. + + Cross-namespace references are only valid if they are explicitly allowed + by ReferenceGrant in the target namespace. + + If the reference is invalid (e.g., the Service does not exist, has an + unsupported Group or Kind, or is a cross-namespace reference not permitted + by a ReferenceGrant), the implementation MUST set the "ResolvedRefs" + condition on the Policy status to "status: False", with Reason + "BackendNotFound", "InvalidKind", or "RefNotPermitted" as appropriate. + + TLS configuration for the connection to the backend is managed by the referenced + object. For example, if the BackendRef points to a Service, a BackendTLSPolicy + can be attached to configure TLS. Alternatively, the referenced backend could be a + custom resource (e.g., XBackend) that natively manages TLS. + + Support: Core + properties: + group: + default: '' + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + - message: Must not have port for Backend reference + rule: '(self.group == ''gateway.networking.x-k8s.io'' + && self.kind == ''XBackend'') ? !has(self.port) : + true' + headers: + description: |- + Headers specifies a list of custom headers to be added to the telemetry + export requests (e.g., for authentication). + + Support: Extended + items: + description: HTTPHeader represents an HTTP Header name + and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: |- + Value is the value of HTTP Header to be matched. + + Must consist of printable US-ASCII characters, optionally separated + by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + maxLength: 4096 + minLength: 1 + pattern: ^[!-~]+([\t ]?[!-~]+)*$ + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - backendRef + type: object + samplingRate: + description: |- + SamplingRate specifies the base probability of sampling new traces. + + The sampling probability is represented as a fraction. + + For example, a Numerator of 5 and Denominator of 100 represents a 5% sampling rate. + * If configured, only the specified percentage of new traces will be initiated. + * In the absence of this field, an implementation-defined default is used. + + + Support: Extended + properties: + denominator: + default: 100 + format: int32 + minimum: 1 + type: integer + numerator: + format: int32 + minimum: 0 + type: integer + required: + - numerator + type: object + x-kubernetes-validations: + - message: numerator must be less than or equal to denominator + rule: self.numerator <= self.denominator + serviceName: + description: |- + ServiceName is the "service.name" attribute of the OpenTelemetry resource. + If absent, the implementation's default service name will be used. + + Support: Extended + + Feature Name: TelemetryPolicyTracing + maxLength: 253 + minLength: 1 + pattern: ^[a-zA-Z0-9_.:/-]+$ + type: string + spanName: + description: |- + SpanName defines a custom name for the OTel span. By default, the name + is implementation-specific. + + Support: Extended + + Feature Name: TelemetryPolicyTracing + maxLength: 256 + minLength: 1 + pattern: ^[a-zA-Z0-9_.:/-]+( [a-zA-Z0-9_.:/-]+)*$ + type: string + type: object + x-kubernetes-validations: + - message: provider is required when mode is Enabled, and must + be empty otherwise + rule: 'self.mode == ''Enabled'' ? has(self.provider) : !has(self.provider)' + - message: samplingRate can only be set when mode is Enabled + rule: 'has(self.samplingRate) ? self.mode == ''Enabled'' : true' + - message: parentBasedSampling can only be set when mode is Enabled + rule: 'has(self.parentBasedSampling) ? self.mode == ''Enabled'' + : true' + - message: serviceName can only be set when mode is Enabled + rule: 'has(self.serviceName) ? self.mode == ''Enabled'' : true' + - message: spanName can only be set when mode is Enabled + rule: 'has(self.spanName) ? self.mode == ''Enabled'' : true' + - message: attributes can only be set when mode is Enabled + rule: 'has(self.attributes) ? self.mode == ''Enabled'' : true' + required: + - targetRefs + type: object + x-kubernetes-validations: + - message: at least one of the fields in [tracing] must be set + rule: has(self.tracing) + status: + description: Status defines the observed state of TelemetryPolicy. + properties: + ancestors: + description: |- + For Policy Status API conventions, see: + https://gateway-api.sigs.k8s.io/geps/gep-713/#the-status-stanza-of-policy-objects + + Ancestors is a list of ancestor resources (specifically Gateway resources) + that are associated with the policy, and the status of the policy with + respect to each ancestor. When this policy attaches to a parent, the + controller that manages the parent and the ancestors MUST add an entry + to this list when the controller first sees the policy and SHOULD update + the entry as appropriate when the relevant ancestor is modified. + + For TelemetryPolicy, the ancestor MUST be the Gateway resource + referenced in spec.targetRefs. + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy + with respect to the given Ancestor. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - 'True' + - 'False' + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - conditions + - controllerName + type: object + maxItems: 16 + type: array + x-kubernetes-list-type: atomic + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml index dd6da09..6a1385f 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicy_safe-upgrades.gateway.networking.k8s.io.yaml @@ -2,7 +2,7 @@ apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: annotations: - gateway.networking.k8s.io/bundle-version: v1.6.1 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: safe-upgrades.gateway.networking.k8s.io spec: diff --git a/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml b/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml index e4d75f6..49201a7 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/20_gateway_api_policies/validatingadmissionpolicybinding_safe-upgrades.gateway.networking.k8s.io.yaml @@ -2,7 +2,7 @@ apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: annotations: - gateway.networking.k8s.io/bundle-version: v1.6.1 + gateway.networking.k8s.io/bundle-version: v1.7.0 gateway.networking.k8s.io/channel: standard name: safe-upgrades.gateway.networking.k8s.io spec: diff --git a/tests/golden/experimental/gateway-api/gateway-api/30_aggregated_rbac.yaml b/tests/golden/experimental/gateway-api/gateway-api/30_aggregated_rbac.yaml index aaa2bb4..c4267c7 100644 --- a/tests/golden/experimental/gateway-api/gateway-api/30_aggregated_rbac.yaml +++ b/tests/golden/experimental/gateway-api/gateway-api/30_aggregated_rbac.yaml @@ -43,6 +43,7 @@ rules: resources: - xbackends - xbackendtrafficpolicies + - xtelemetrypolicies verbs: - get - list @@ -90,6 +91,7 @@ rules: resources: - xbackends - xbackendtrafficpolicies + - xtelemetrypolicies verbs: - '*' --- @@ -135,5 +137,6 @@ rules: resources: - xbackends - xbackendtrafficpolicies + - xtelemetrypolicies verbs: - '*'