From e1c73452d68525b871fb29ab65ce3948d7c3b0cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 13:42:12 -0700 Subject: [PATCH 01/17] build(deps): bump google.golang.org/protobuf from 1.33.0 to 1.34.0 (#3328) Bumps google.golang.org/protobuf from 1.33.0 to 1.34.0. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e391fe13457..84a2f5747ce 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 golang.org/x/sys v0.20.0 google.golang.org/grpc v1.63.2 - google.golang.org/protobuf v1.33.0 + google.golang.org/protobuf v1.34.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.14.4 k8s.io/api v0.30.0 diff --git a/go.sum b/go.sum index accd029e8e3..e690d0f7d30 100644 --- a/go.sum +++ b/go.sum @@ -904,8 +904,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= +google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From f0bd208587510417d70af17fcbe6f46f29454363 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 16:48:57 -0500 Subject: [PATCH 02/17] build(deps): bump actions/setup-go from 5.0.0 to 5.0.1 in /tools/github-actions/setup-deps (#3329) build(deps): bump actions/setup-go in /tools/github-actions/setup-deps Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/0c52d547c9bc32b1aa3301fd7a9cb496313a4491...cdcb36043654635271a94b9a6d1392de5bb323a7) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tools/github-actions/setup-deps/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/github-actions/setup-deps/action.yaml b/tools/github-actions/setup-deps/action.yaml index 730b5c73a91..d69c611ab6e 100644 --- a/tools/github-actions/setup-deps/action.yaml +++ b/tools/github-actions/setup-deps/action.yaml @@ -4,7 +4,7 @@ description: Install host system dependencies runs: using: composite steps: - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: go-version: 1.22.x cache: true From ce0d8b5e5c05a9a8cae6dbbf5b00015fe4659ca8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 16:49:34 -0500 Subject: [PATCH 03/17] build(deps): bump sigs.k8s.io/controller-runtime from 0.18.0 to 0.18.1 (#3327) Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.18.0 to 0.18.1. - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.18.0...v0.18.1) --- updated-dependencies: - dependency-name: sigs.k8s.io/controller-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 84a2f5747ce..3a7ed2669f3 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( k8s.io/client-go v0.30.0 k8s.io/kubectl v0.30.0 k8s.io/utils v0.0.0-20230726121419-3b25d923346b - sigs.k8s.io/controller-runtime v0.18.0 + sigs.k8s.io/controller-runtime v0.18.1 sigs.k8s.io/gateway-api v1.0.0 sigs.k8s.io/mcs-api v0.1.0 sigs.k8s.io/yaml v1.4.0 diff --git a/go.sum b/go.sum index e690d0f7d30..24a61ef34a5 100644 --- a/go.sum +++ b/go.sum @@ -992,8 +992,8 @@ oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY= oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A= -sigs.k8s.io/controller-runtime v0.18.0 h1:Z7jKuX784TQSUL1TIyeuF7j8KXZ4RtSX0YgtjKcSTME= -sigs.k8s.io/controller-runtime v0.18.0/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +sigs.k8s.io/controller-runtime v0.18.1 h1:RpWbigmuiylbxOCLy0tGnq1cU1qWPwNIQzoJk+QeJx4= +sigs.k8s.io/controller-runtime v0.18.1/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs= sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c= From decefccae531692b2e9b99929bf868deeb71b0e5 Mon Sep 17 00:00:00 2001 From: sh2 Date: Tue, 7 May 2024 05:51:22 +0800 Subject: [PATCH 04/17] e2e: fix flaky merge-gateways test (#3331) * manually create conflicted gateways for merge-gateways e2e test Signed-off-by: shawnh2 * keep skipTest field Signed-off-by: shawnh2 --------- Signed-off-by: shawnh2 --- .../e2e/merge_gateways/merge_gateways_test.go | 4 +- test/e2e/testdata/basic-merge-gateways.yaml | 37 ------ test/e2e/tests/merge_gateways.go | 120 +++++++++++++++++- 3 files changed, 118 insertions(+), 43 deletions(-) diff --git a/test/e2e/merge_gateways/merge_gateways_test.go b/test/e2e/merge_gateways/merge_gateways_test.go index 9c056875c32..6bfbb3a9539 100644 --- a/test/e2e/merge_gateways/merge_gateways_test.go +++ b/test/e2e/merge_gateways/merge_gateways_test.go @@ -52,9 +52,7 @@ func TestMergeGateways(t *testing.T) { Debug: *flags.ShowDebug, CleanupBaseResources: *flags.CleanupBaseResources, RunTest: *flags.RunTest, - SkipTests: []string{ - tests.MergeGatewaysTest.ShortName, // https://github.com/envoyproxy/gateway/issues/3290 - }, + SkipTests: []string{}, }) // Setting up the necessary arguments for the suite instead of calling Suite.Setup method again, diff --git a/test/e2e/testdata/basic-merge-gateways.yaml b/test/e2e/testdata/basic-merge-gateways.yaml index f32fddb29ee..502eb2092b0 100644 --- a/test/e2e/testdata/basic-merge-gateways.yaml +++ b/test/e2e/testdata/basic-merge-gateways.yaml @@ -44,21 +44,6 @@ spec: protocol: HTTP --- apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: merged-gateway-4 - namespace: gateway-conformance-infra -spec: - gatewayClassName: merge-gateways - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http3 - port: 8082 - protocol: HTTP ---- -apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: merged-gateway-route-1 @@ -123,25 +108,3 @@ spec: - path: type: PathPrefix value: /merge3 ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: merged-gateway-route-4 - namespace: gateway-conformance-infra -spec: - parentRefs: - - name: merged-gateway-4 - hostnames: - - "www.example4.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: infra-backend-v3 - port: 8080 - weight: 1 - matches: - - path: - type: PathPrefix - value: /merge4 diff --git a/test/e2e/tests/merge_gateways.go b/test/e2e/tests/merge_gateways.go index abcd809f70d..ae170e6039b 100644 --- a/test/e2e/tests/merge_gateways.go +++ b/test/e2e/tests/merge_gateways.go @@ -9,11 +9,13 @@ package tests import ( + "context" "net" "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/conformance/utils/http" "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" @@ -31,6 +33,7 @@ var MergeGatewaysTest = suite.ConformanceTest{ Description: "Basic test for MergeGateways feature", Manifests: []string{"testdata/basic-merge-gateways.yaml"}, Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + ctx := context.Background() ns := "gateway-conformance-infra" route1NN := types.NamespacedName{Name: "merged-gateway-route-1", Namespace: ns} @@ -45,6 +48,10 @@ var MergeGatewaysTest = suite.ConformanceTest{ gw3NN := types.NamespacedName{Name: "merged-gateway-3", Namespace: ns} gw3HostPort := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gw3NN), route3NN) + // Conflicted Gateway and HTTPRoute name + route4NN := types.NamespacedName{Name: "merged-gateway-route-4", Namespace: ns} + gw4NN := types.NamespacedName{Name: "merged-gateway-4", Namespace: ns} + gw1Addr, _, err := net.SplitHostPort(gw1HostPort) if err != nil { t.Errorf("failed to split hostport %s of gateway %s: %v", gw1HostPort, gw1NN.String(), err) @@ -89,10 +96,96 @@ var MergeGatewaysTest = suite.ConformanceTest{ }) }) - t.Run("gateway with conflicted listener cannot be merged", func(t *testing.T) { - route4NN := types.NamespacedName{Name: "merged-gateway-route-4", Namespace: ns} - gw4NN := types.NamespacedName{Name: "merged-gateway-4", Namespace: ns} + t.Run("apply a gateway with conflicted listener", func(t *testing.T) { + // Manually create the conflicted Gateway and HTTPRoute resources, + // in order to make sure the conflicted status will certainly surface for them. + + conflictedGateway := gwapiv1.Gateway{ + TypeMeta: metav1.TypeMeta{ + Kind: gatewayapi.KindGateway, + APIVersion: gwapiv1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: gw4NN.Name, + Namespace: gw4NN.Namespace, + }, + Spec: gwapiv1.GatewaySpec{ + GatewayClassName: gwapiv1.ObjectName(suite.GatewayClassName), + Listeners: []gwapiv1.Listener{ + { + AllowedRoutes: &gwapiv1.AllowedRoutes{ + Namespaces: &gwapiv1.RouteNamespaces{ + From: gatewayapi.FromNamespacesPtr(gwapiv1.NamespacesFromSame), + }, + }, + Name: "http3", + Port: 8082, + Protocol: gwapiv1.HTTPProtocolType, + }, + }, + }, + } + + conflictedHTTPRoute := gwapiv1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: gatewayapi.KindHTTPRoute, + APIVersion: gwapiv1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: route4NN.Name, + Namespace: route4NN.Namespace, + }, + Spec: gwapiv1.HTTPRouteSpec{ + CommonRouteSpec: gwapiv1.CommonRouteSpec{ + ParentRefs: []gwapiv1.ParentReference{ + { + Name: gwapiv1.ObjectName(gw4NN.Name), + }, + }, + }, + Hostnames: []gwapiv1.Hostname{ + "www.example4.com", + }, + Rules: []gwapiv1.HTTPRouteRule{ + { + BackendRefs: []gwapiv1.HTTPBackendRef{ + { + BackendRef: gwapiv1.BackendRef{ + BackendObjectReference: gwapiv1.BackendObjectReference{ + Group: gatewayapi.GroupPtr(""), + Kind: gatewayapi.KindPtr(gatewayapi.KindService), + Name: "infra-backend-v3", + Port: gatewayapi.PortNumPtr(8080), + }, + Weight: ptr.To[int32](1), + }, + }, + }, + Matches: []gwapiv1.HTTPRouteMatch{ + { + Path: &gwapiv1.HTTPPathMatch{ + Type: ptr.To(gwapiv1.PathMatchPathPrefix), + Value: ptr.To("/merge4"), + }, + }, + }, + }, + }, + }, + } + + if err := suite.Client.Create(ctx, &conflictedGateway); err != nil { + t.Errorf("failed to create conflicted gateway: %v", err) + t.FailNow() + } + if err := suite.Client.Create(ctx, &conflictedHTTPRoute); err != nil { + t.Errorf("failed to create conflicted httproute: %v", err) + t.FailNow() + } + }) + + t.Run("gateway with conflicted listener cannot be merged", func(t *testing.T) { gw4HostPort, err := kubernetes.WaitForGatewayAddress(t, suite.Client, suite.TimeoutConfig, gw4NN) if err != nil { t.Errorf("failed to get the address of gateway %s", gw4NN.String()) @@ -146,5 +239,26 @@ var MergeGatewaysTest = suite.ConformanceTest{ Namespace: ns, }) }) + + t.Run("clean-up conflicted gateway", func(t *testing.T) { + conflictedGateway := new(gwapiv1.Gateway) + conflictedHTTPRoute := new(gwapiv1.HTTPRoute) + + if err := suite.Client.Get(ctx, gw4NN, conflictedGateway); err != nil { + t.Errorf("failed to get conflicted gateway: %v", err) + t.FailNow() + } + if err := suite.Client.Delete(ctx, conflictedGateway); err != nil { + t.Errorf("failed to delete conflicted gateway: %v", err) + } + + if err := suite.Client.Get(ctx, route4NN, conflictedHTTPRoute); err != nil { + t.Errorf("failed to get conflicted httproute: %v", err) + t.FailNow() + } + if err := suite.Client.Delete(ctx, conflictedHTTPRoute); err != nil { + t.Errorf("failed to delete conflicted httproute: %v", err) + } + }) }, } From 6d8f2dce78381a9e3480cb174ee7ed3fbe390991 Mon Sep 17 00:00:00 2001 From: Jesse Haka Date: Tue, 7 May 2024 00:52:09 +0300 Subject: [PATCH 05/17] fix: add proxy protocol always as first listenerFilter (#3332) * add proxy protocol always as first listenerFilter Signed-off-by: Jesse Haka * add test Signed-off-by: Jesse Haka --------- Signed-off-by: Jesse Haka --- internal/xds/translator/proxy_protocol.go | 3 +- .../xds/translator/proxy_protocol_test.go | 58 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 internal/xds/translator/proxy_protocol_test.go diff --git a/internal/xds/translator/proxy_protocol.go b/internal/xds/translator/proxy_protocol.go index 9c0dcb2bd16..a36673dc7fa 100644 --- a/internal/xds/translator/proxy_protocol.go +++ b/internal/xds/translator/proxy_protocol.go @@ -32,7 +32,8 @@ func patchProxyProtocolFilter(xdsListener *listenerv3.Listener, irListener *ir.H proxyProtocolFilter := buildProxyProtocolFilter() if proxyProtocolFilter != nil { - xdsListener.ListenerFilters = append(xdsListener.ListenerFilters, proxyProtocolFilter) + // Add the Proxy Protocol filter as first to listeners. + xdsListener.ListenerFilters = append([]*listenerv3.ListenerFilter{proxyProtocolFilter}, xdsListener.ListenerFilters...) } } diff --git a/internal/xds/translator/proxy_protocol_test.go b/internal/xds/translator/proxy_protocol_test.go new file mode 100644 index 00000000000..b4b5ac51aff --- /dev/null +++ b/internal/xds/translator/proxy_protocol_test.go @@ -0,0 +1,58 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package translator + +import ( + "testing" + + listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" + "github.com/envoyproxy/go-control-plane/pkg/wellknown" + "github.com/stretchr/testify/require" + + "github.com/envoyproxy/gateway/internal/ir" +) + +func TestPatchProxyProtocolFilter(t *testing.T) { + type testCase struct { + name string + listener *listenerv3.Listener + } + + irListener := &ir.HTTPListener{ + EnableProxyProtocol: true, + } + + testCases := []testCase{ + { + name: "listener with proxy proto available already", + listener: &listenerv3.Listener{ + ListenerFilters: []*listenerv3.ListenerFilter{ + { + Name: wellknown.ProxyProtocol, + }, + }, + }, + }, + { + name: "listener with tls, append proxy proto", + listener: &listenerv3.Listener{ + ListenerFilters: []*listenerv3.ListenerFilter{ + { + Name: wellknown.TLSInspector, + }, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + patchProxyProtocolFilter(tc.listener, irListener) + // proxy proto filter should be added always as first + require.Equal(t, wellknown.ProxyProtocol, tc.listener.ListenerFilters[0].Name) + }) + } +} From 3ea7acdd2d345e93317962380395520008dd6367 Mon Sep 17 00:00:00 2001 From: Dingkang Li Date: Tue, 7 May 2024 07:34:31 +0800 Subject: [PATCH 06/17] refactor: refactor TCP IR (#3271) * Refactor IR creation for TLSRoute Takes forward PR https://github.com/envoyproxy/gateway/pull/1798 Fixes: https://github.com/envoyproxy/gateway/issues/1635 Signed-off-by: Arko Dasgupta * pass lint Signed-off-by: Dingkang Li --------- Signed-off-by: Arko Dasgupta Signed-off-by: Dingkang Li Co-authored-by: Arko Dasgupta --- .../translate/out/default-resources.all.yaml | 50 +++---- .../out/from-gateway-api-to-xds.all.json | 58 ++++----- .../out/from-gateway-api-to-xds.all.yaml | 50 +++---- .../out/from-gateway-api-to-xds.cluster.yaml | 8 +- .../out/from-gateway-api-to-xds.endpoint.yaml | 8 +- .../out/from-gateway-api-to-xds.listener.yaml | 34 ++--- internal/gatewayapi/backendtrafficpolicy.go | 44 ++++--- internal/gatewayapi/clienttrafficpolicy.go | 4 +- internal/gatewayapi/helpers.go | 14 +- internal/gatewayapi/listener.go | 11 +- internal/gatewayapi/route.go | 60 +++++---- ...ndtrafficpolicy-status-conditions.out.yaml | 4 + ...cp-udp-listeners-apply-on-gateway.out.yaml | 112 ++++++++-------- ...-tcp-udp-listeners-apply-on-route.out.yaml | 112 ++++++++-------- ...nttrafficpolicy-status-conditions.out.yaml | 4 + ...extensionpolicy-status-conditions.out.yaml | 4 + ...way-with-addresses-with-ipaddress.out.yaml | 4 + ...route-with-mismatch-port-protocol.out.yaml | 4 + ...h-tcproute-with-multiple-backends.out.yaml | 4 + ...with-tcproute-with-multiple-rules.out.yaml | 4 + ...ith-tls-terminate-and-passthrough.out.yaml | 30 +++-- ...-listener-with-unmatched-tcproute.out.yaml | 4 + ...-listener-with-multiple-tcproutes.out.yaml | 24 ++-- ...listeners-on-same-tcp-or-tls-port.out.yaml | 24 ++-- ...-with-same-port-http-tcp-protocol.out.yaml | 24 ++-- ...s-with-tcproutes-with-sectionname.out.yaml | 48 +++---- ...ith-tcproutes-without-sectionname.out.yaml | 48 +++---- .../securitypolicy-status-conditions.out.yaml | 4 + ...teway-with-listener-tls-terminate.out.yaml | 34 ++--- .../tlsroute-attaching-to-gateway.out.yaml | 30 +++-- .../testdata/tlsroute-multiple.out.yaml | 60 ++++----- ...her-namespace-allowed-by-refgrant.out.yaml | 30 +++-- .../tlsroute-with-empty-hostname.out.yaml | 30 +++-- ...oute-with-empty-listener-hostname.out.yaml | 30 +++-- internal/ir/xds.go | 72 ++++++++--- internal/ir/xds_test.go | 122 +++++++++++++----- internal/ir/zz_generated.deepcopy.go | 47 +++++-- internal/xds/translator/listener.go | 14 +- .../xds-ir/multiple-listeners-same-port.yaml | 44 ++++--- .../multiple-simple-tcp-route-same-port.yaml | 98 +++++++------- .../testdata/in/xds-ir/tcp-route-complex.yaml | 32 ++--- .../in/xds-ir/tcp-route-invalid-endpoint.yaml | 18 +-- .../testdata/in/xds-ir/tcp-route-invalid.yaml | 20 +-- .../testdata/in/xds-ir/tcp-route-simple.yaml | 20 +-- .../in/xds-ir/tcp-route-tls-terminate.yaml | 32 ++--- .../in/xds-ir/tcp-route-weighted-backend.yaml | 54 ++++---- .../in/xds-ir/tls-route-passthrough.yaml | 50 +++---- .../listener-connection-limit.clusters.yaml | 34 ----- .../listener-connection-limit.endpoints.yaml | 24 ---- .../listener-connection-limit.listeners.yaml | 32 ----- .../listener-tcp-keepalive.clusters.yaml | 39 ------ .../listener-tcp-keepalive.endpoints.yaml | 24 ---- .../listener-tcp-keepalive.listeners.yaml | 21 --- ...-simple-tcp-route-same-port.endpoints.yaml | 2 +- ...-simple-tcp-route-same-port.listeners.yaml | 2 +- .../xds-ir/tcp-endpoint-stats.clusters.yaml | 20 +-- .../xds-ir/tcp-endpoint-stats.endpoints.yaml | 19 +-- .../xds-ir/tcp-endpoint-stats.listeners.yaml | 7 - .../xds-ir/tcp-route-complex.listeners.yaml | 2 +- .../xds-ir/tcp-route-simple.listeners.yaml | 2 +- .../tcp-route-tls-terminate.listeners.yaml | 2 +- .../tcp-route-weighted-backend.listeners.yaml | 2 +- internal/xds/translator/translator.go | 59 +++++---- 63 files changed, 971 insertions(+), 956 deletions(-) diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml index ffd2abb31b7..7b8319b6376 100644 --- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml @@ -644,7 +644,7 @@ xds: region: grpcroute/default/backend/rule/0/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment - clusterName: tlsroute/default/backend/rule/-1 + clusterName: tcproute/default/backend/rule/-1 endpoints: - lbEndpoints: - endpoint: @@ -655,10 +655,10 @@ xds: loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tlsroute/default/backend/rule/-1/backend/0 + region: tcproute/default/backend/rule/-1/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment - clusterName: tcproute/default/backend/rule/-1 + clusterName: tlsroute/default/backend/rule/-1 endpoints: - lbEndpoints: - endpoint: @@ -669,7 +669,7 @@ xds: loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tcproute/default/backend/rule/-1/backend/0 + region: tlsroute/default/backend/rule/-1/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment clusterName: udproute/default/backend/rule/-1 @@ -742,9 +742,9 @@ xds: edsConfig: ads: {} resourceApiVersion: V3 - serviceName: tlsroute/default/backend/rule/-1 + serviceName: tcproute/default/backend/rule/-1 lbPolicy: LEAST_REQUEST - name: tlsroute/default/backend/rule/-1 + name: tcproute/default/backend/rule/-1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -761,9 +761,9 @@ xds: edsConfig: ads: {} resourceApiVersion: V3 - serviceName: tcproute/default/backend/rule/-1 + serviceName: tlsroute/default/backend/rule/-1 lbPolicy: LEAST_REQUEST - name: tcproute/default/backend/rule/-1 + name: tlsroute/default/backend/rule/-1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -933,13 +933,10 @@ xds: address: socketAddress: address: 0.0.0.0 - portValue: 8443 + portValue: 1234 drainType: MODIFY_ONLY filterChains: - - filterChainMatch: - serverNames: - - foo.com - filters: + - filters: - name: envoy.filters.network.tcp_proxy typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -952,13 +949,9 @@ xds: inlineString: | {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"} path: /dev/stdout - cluster: tlsroute/default/backend/rule/-1 - statPrefix: passthrough - listenerFilters: - - name: envoy.filters.listener.tls_inspector - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector - name: default/eg/tls-passthrough/backend + cluster: tcproute/default/backend/rule/-1 + statPrefix: tcp + name: default/eg/tcp perConnectionBufferLimitBytes: 32768 - activeState: listener: @@ -979,10 +972,13 @@ xds: address: socketAddress: address: 0.0.0.0 - portValue: 1234 + portValue: 8443 drainType: MODIFY_ONLY filterChains: - - filters: + - filterChainMatch: + serverNames: + - foo.com + filters: - name: envoy.filters.network.tcp_proxy typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -995,9 +991,13 @@ xds: inlineString: | {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"} path: /dev/stdout - cluster: tcproute/default/backend/rule/-1 - statPrefix: tcp - name: default/eg/tcp/backend + cluster: tlsroute/default/backend/rule/-1 + statPrefix: passthrough + listenerFilters: + - name: envoy.filters.listener.tls_inspector + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector + name: default/eg/tls-passthrough perConnectionBufferLimitBytes: 32768 - activeState: listener: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json index 1f1b83da3dd..80be0dae629 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json @@ -296,7 +296,7 @@ { "endpointConfig": { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tlsroute/default/backend/rule/-1", + "clusterName": "tcproute/default/backend/rule/-1", "endpoints": [ { "lbEndpoints": [ @@ -314,7 +314,7 @@ ], "loadBalancingWeight": 1, "locality": { - "region": "tlsroute/default/backend/rule/-1/backend/0" + "region": "tcproute/default/backend/rule/-1/backend/0" } } ] @@ -323,7 +323,7 @@ { "endpointConfig": { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcproute/default/backend/rule/-1", + "clusterName": "tlsroute/default/backend/rule/-1", "endpoints": [ { "lbEndpoints": [ @@ -341,7 +341,7 @@ ], "loadBalancingWeight": 1, "locality": { - "region": "tcproute/default/backend/rule/-1/backend/0" + "region": "tlsroute/default/backend/rule/-1/backend/0" } } ] @@ -465,10 +465,10 @@ "ads": {}, "resourceApiVersion": "V3" }, - "serviceName": "tlsroute/default/backend/rule/-1" + "serviceName": "tcproute/default/backend/rule/-1" }, "lbPolicy": "LEAST_REQUEST", - "name": "tlsroute/default/backend/rule/-1", + "name": "tcproute/default/backend/rule/-1", "outlierDetection": {}, "perConnectionBufferLimitBytes": 32768, "type": "EDS" @@ -494,10 +494,10 @@ "ads": {}, "resourceApiVersion": "V3" }, - "serviceName": "tcproute/default/backend/rule/-1" + "serviceName": "tlsroute/default/backend/rule/-1" }, "lbPolicy": "LEAST_REQUEST", - "name": "tcproute/default/backend/rule/-1", + "name": "tlsroute/default/backend/rule/-1", "outlierDetection": {}, "perConnectionBufferLimitBytes": 32768, "type": "EDS" @@ -761,17 +761,12 @@ "address": { "socketAddress": { "address": "0.0.0.0", - "portValue": 8443 + "portValue": 1234 } }, "drainType": "MODIFY_ONLY", "filterChains": [ { - "filterChainMatch": { - "serverNames": [ - "foo.com" - ] - }, "filters": [ { "name": "envoy.filters.network.tcp_proxy", @@ -791,22 +786,14 @@ } } ], - "cluster": "tlsroute/default/backend/rule/-1", - "statPrefix": "passthrough" + "cluster": "tcproute/default/backend/rule/-1", + "statPrefix": "tcp" } } ] } ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "name": "default/eg/tls-passthrough/backend", + "name": "default/eg/tcp", "perConnectionBufferLimitBytes": 32768 } } @@ -839,12 +826,17 @@ "address": { "socketAddress": { "address": "0.0.0.0", - "portValue": 1234 + "portValue": 8443 } }, "drainType": "MODIFY_ONLY", "filterChains": [ { + "filterChainMatch": { + "serverNames": [ + "foo.com" + ] + }, "filters": [ { "name": "envoy.filters.network.tcp_proxy", @@ -864,14 +856,22 @@ } } ], - "cluster": "tcproute/default/backend/rule/-1", - "statPrefix": "tcp" + "cluster": "tlsroute/default/backend/rule/-1", + "statPrefix": "passthrough" } } ] } ], - "name": "default/eg/tcp/backend", + "listenerFilters": [ + { + "name": "envoy.filters.listener.tls_inspector", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" + } + } + ], + "name": "default/eg/tls-passthrough", "perConnectionBufferLimitBytes": 32768 } } diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml index 7e672876739..05c22f5ab88 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml @@ -163,7 +163,7 @@ xds: region: grpcroute/default/backend/rule/0/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment - clusterName: tlsroute/default/backend/rule/-1 + clusterName: tcproute/default/backend/rule/-1 endpoints: - lbEndpoints: - endpoint: @@ -174,10 +174,10 @@ xds: loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tlsroute/default/backend/rule/-1/backend/0 + region: tcproute/default/backend/rule/-1/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment - clusterName: tcproute/default/backend/rule/-1 + clusterName: tlsroute/default/backend/rule/-1 endpoints: - lbEndpoints: - endpoint: @@ -188,7 +188,7 @@ xds: loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tcproute/default/backend/rule/-1/backend/0 + region: tlsroute/default/backend/rule/-1/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment clusterName: udproute/default/backend/rule/-1 @@ -261,9 +261,9 @@ xds: edsConfig: ads: {} resourceApiVersion: V3 - serviceName: tlsroute/default/backend/rule/-1 + serviceName: tcproute/default/backend/rule/-1 lbPolicy: LEAST_REQUEST - name: tlsroute/default/backend/rule/-1 + name: tcproute/default/backend/rule/-1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -280,9 +280,9 @@ xds: edsConfig: ads: {} resourceApiVersion: V3 - serviceName: tcproute/default/backend/rule/-1 + serviceName: tlsroute/default/backend/rule/-1 lbPolicy: LEAST_REQUEST - name: tcproute/default/backend/rule/-1 + name: tlsroute/default/backend/rule/-1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -452,13 +452,10 @@ xds: address: socketAddress: address: 0.0.0.0 - portValue: 8443 + portValue: 1234 drainType: MODIFY_ONLY filterChains: - - filterChainMatch: - serverNames: - - foo.com - filters: + - filters: - name: envoy.filters.network.tcp_proxy typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -471,13 +468,9 @@ xds: inlineString: | {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"} path: /dev/stdout - cluster: tlsroute/default/backend/rule/-1 - statPrefix: passthrough - listenerFilters: - - name: envoy.filters.listener.tls_inspector - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector - name: default/eg/tls-passthrough/backend + cluster: tcproute/default/backend/rule/-1 + statPrefix: tcp + name: default/eg/tcp perConnectionBufferLimitBytes: 32768 - activeState: listener: @@ -498,10 +491,13 @@ xds: address: socketAddress: address: 0.0.0.0 - portValue: 1234 + portValue: 8443 drainType: MODIFY_ONLY filterChains: - - filters: + - filterChainMatch: + serverNames: + - foo.com + filters: - name: envoy.filters.network.tcp_proxy typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -514,9 +510,13 @@ xds: inlineString: | {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"} path: /dev/stdout - cluster: tcproute/default/backend/rule/-1 - statPrefix: tcp - name: default/eg/tcp/backend + cluster: tlsroute/default/backend/rule/-1 + statPrefix: passthrough + listenerFilters: + - name: envoy.filters.listener.tls_inspector + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector + name: default/eg/tls-passthrough perConnectionBufferLimitBytes: 32768 - activeState: listener: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml index efdb106b143..3d9bce8ad21 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml @@ -58,9 +58,9 @@ xds: edsConfig: ads: {} resourceApiVersion: V3 - serviceName: tlsroute/default/backend/rule/-1 + serviceName: tcproute/default/backend/rule/-1 lbPolicy: LEAST_REQUEST - name: tlsroute/default/backend/rule/-1 + name: tcproute/default/backend/rule/-1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -77,9 +77,9 @@ xds: edsConfig: ads: {} resourceApiVersion: V3 - serviceName: tcproute/default/backend/rule/-1 + serviceName: tlsroute/default/backend/rule/-1 lbPolicy: LEAST_REQUEST - name: tcproute/default/backend/rule/-1 + name: tlsroute/default/backend/rule/-1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.endpoint.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.endpoint.yaml index 76b49b6fa24..04b9540b977 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.endpoint.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.endpoint.yaml @@ -32,7 +32,7 @@ xds: region: grpcroute/default/backend/rule/0/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment - clusterName: tlsroute/default/backend/rule/-1 + clusterName: tcproute/default/backend/rule/-1 endpoints: - lbEndpoints: - endpoint: @@ -43,10 +43,10 @@ xds: loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tlsroute/default/backend/rule/-1/backend/0 + region: tcproute/default/backend/rule/-1/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment - clusterName: tcproute/default/backend/rule/-1 + clusterName: tlsroute/default/backend/rule/-1 endpoints: - lbEndpoints: - endpoint: @@ -57,7 +57,7 @@ xds: loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tcproute/default/backend/rule/-1/backend/0 + region: tlsroute/default/backend/rule/-1/backend/0 - endpointConfig: '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment clusterName: udproute/default/backend/rule/-1 diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml index fee6abd4f5a..61288c6e130 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml @@ -147,13 +147,10 @@ xds: address: socketAddress: address: 0.0.0.0 - portValue: 8443 + portValue: 1234 drainType: MODIFY_ONLY filterChains: - - filterChainMatch: - serverNames: - - foo.com - filters: + - filters: - name: envoy.filters.network.tcp_proxy typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -166,13 +163,9 @@ xds: inlineString: | {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"} path: /dev/stdout - cluster: tlsroute/default/backend/rule/-1 - statPrefix: passthrough - listenerFilters: - - name: envoy.filters.listener.tls_inspector - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector - name: default/eg/tls-passthrough/backend + cluster: tcproute/default/backend/rule/-1 + statPrefix: tcp + name: default/eg/tcp perConnectionBufferLimitBytes: 32768 - activeState: listener: @@ -193,10 +186,13 @@ xds: address: socketAddress: address: 0.0.0.0 - portValue: 1234 + portValue: 8443 drainType: MODIFY_ONLY filterChains: - - filters: + - filterChainMatch: + serverNames: + - foo.com + filters: - name: envoy.filters.network.tcp_proxy typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -209,9 +205,13 @@ xds: inlineString: | {"start_time":"%START_TIME%","method":"%REQ(:METHOD)%","x-envoy-origin-path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","response_code_details":"%RESPONSE_CODE_DETAILS%","connection_termination_details":"%CONNECTION_TERMINATION_DETAILS%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","duration":"%DURATION%","x-envoy-upstream-service-time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","x-forwarded-for":"%REQ(X-FORWARDED-FOR)%","user-agent":"%REQ(USER-AGENT)%","x-request-id":"%REQ(X-REQUEST-ID)%",":authority":"%REQ(:AUTHORITY)%","upstream_host":"%UPSTREAM_HOST%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","requested_server_name":"%REQUESTED_SERVER_NAME%","route_name":"%ROUTE_NAME%"} path: /dev/stdout - cluster: tcproute/default/backend/rule/-1 - statPrefix: tcp - name: default/eg/tcp/backend + cluster: tlsroute/default/backend/rule/-1 + statPrefix: passthrough + listenerFilters: + - name: envoy.filters.listener.tls_inspector + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector + name: default/eg/tls-passthrough perConnectionBufferLimitBytes: 32768 - activeState: listener: diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index b77a551d439..65d9607bb08 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -351,13 +351,15 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen for _, ir := range xdsIR { for _, tcp := range ir.TCP { - if strings.HasPrefix(tcp.Destination.Name, prefix) { - tcp.LoadBalancer = lb - tcp.ProxyProtocol = pp - tcp.HealthCheck = hc - tcp.CircuitBreaker = cb - tcp.TCPKeepalive = ka - tcp.Timeout = to + for _, r := range tcp.Routes { + if strings.HasPrefix(r.Destination.Name, prefix) { + r.LoadBalancer = lb + r.ProxyProtocol = pp + r.HealthCheck = hc + r.CircuitBreaker = cb + r.TCPKeepalive = ka + r.Timeout = to + } } } @@ -472,21 +474,23 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back continue } - // policy(targeting xRoute) has already set it, so we skip it. - if tcp.LoadBalancer != nil || tcp.ProxyProtocol != nil || - tcp.HealthCheck != nil || tcp.CircuitBreaker != nil || - tcp.TCPKeepalive != nil || tcp.Timeout != nil { - continue - } + for _, r := range tcp.Routes { + // policy(targeting xRoute) has already set it, so we skip it. + if r.LoadBalancer != nil || r.ProxyProtocol != nil || + r.HealthCheck != nil || r.CircuitBreaker != nil || + r.TCPKeepalive != nil || r.Timeout != nil { + continue + } - tcp.LoadBalancer = lb - tcp.ProxyProtocol = pp - tcp.HealthCheck = hc - tcp.CircuitBreaker = cb - tcp.TCPKeepalive = ka + r.LoadBalancer = lb + r.ProxyProtocol = pp + r.HealthCheck = hc + r.CircuitBreaker = cb + r.TCPKeepalive = ka - if tcp.Timeout == nil { - tcp.Timeout = ct + if r.Timeout == nil { + r.Timeout = ct + } } } diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index d4d059dc462..bc04f7c3b2d 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -323,7 +323,7 @@ func validatePortOverlapForClientTrafficPolicy(l *ListenerContext, xds *ir.Xds, // TODO: Support TLSRoute and TCPRoute once // https://github.com/envoyproxy/gateway/issues/1635 is completed - irListenerName := irHTTPListenerName(l) + irListenerName := irListenerName(l) var httpIR *ir.HTTPListener for _, http := range xds.HTTP { if http.Name == irListenerName { @@ -374,7 +374,7 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie // TODO: Support TLSRoute and TCPRoute once // https://github.com/envoyproxy/gateway/issues/1635 is completed - irListenerName := irHTTPListenerName(l) + irListenerName := irListenerName(l) var httpIR *ir.HTTPListener for _, http := range gwXdsIR.HTTP { if http.Name == irListenerName { diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 269ea9b4147..e17e595fc9f 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -343,18 +343,10 @@ func irStringKey(gatewayNs, gatewayName string) string { return fmt.Sprintf("%s/%s", gatewayNs, gatewayName) } -func irHTTPListenerName(listener *ListenerContext) string { +func irListenerName(listener *ListenerContext) string { return fmt.Sprintf("%s/%s/%s", listener.gateway.Namespace, listener.gateway.Name, listener.Name) } -func irTLSListenerName(listener *ListenerContext, tlsRoute *TLSRouteContext) string { - return fmt.Sprintf("%s/%s/%s/%s", listener.gateway.Namespace, listener.gateway.Name, listener.Name, tlsRoute.Name) -} - -func irTCPListenerName(listener *ListenerContext, tcpRoute *TCPRouteContext) string { - return fmt.Sprintf("%s/%s/%s/%s", listener.gateway.Namespace, listener.gateway.Name, listener.Name, tcpRoute.Name) -} - func irUDPListenerName(listener *ListenerContext, udpRoute *UDPRouteContext) string { return fmt.Sprintf("%s/%s/%s/%s", listener.gateway.Namespace, listener.gateway.Name, listener.Name, udpRoute.Name) } @@ -373,6 +365,10 @@ func irRouteName(route RouteContext, ruleIdx, matchIdx int) string { return fmt.Sprintf("%srule/%d/match/%d", irRoutePrefix(route), ruleIdx, matchIdx) } +func irTCPRouteName(route RouteContext) string { + return fmt.Sprintf("%s/%s/%s", strings.ToLower(string(GetRouteType(route))), route.GetNamespace(), route.GetName()) +} + func irRouteDestinationName(route RouteContext, ruleIdx int) string { return fmt.Sprintf("%srule/%d", irRoutePrefix(route), ruleIdx) } diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index bab7c4c17c2..a5ca14da600 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -97,7 +97,7 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap switch listener.Protocol { case gwapiv1.HTTPProtocolType, gwapiv1.HTTPSProtocolType: irListener := &ir.HTTPListener{ - Name: irHTTPListenerName(listener), + Name: irListenerName(listener), Address: "0.0.0.0", Port: uint32(containerPort), TLS: irTLSConfigs(listener.tlsSecrets), @@ -115,6 +115,13 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap irListener.Hostnames = append(irListener.Hostnames, "*") } xdsIR[irKey].HTTP = append(xdsIR[irKey].HTTP, irListener) + case gwapiv1.TCPProtocolType, gwapiv1.TLSProtocolType: + irListener := &ir.TCPListener{ + Name: irListenerName(listener), + Address: "0.0.0.0", + Port: uint32(containerPort), + } + xdsIR[irKey].TCP = append(xdsIR[irKey].TCP, irListener) } // Add the listener to the Infra IR. Infra IR ports must have a unique port number per layer-4 protocol @@ -156,7 +163,7 @@ func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR I } proxyListener := &ir.ProxyListener{ - Name: irHTTPListenerName(listener), + Name: irListenerName(listener), Ports: []ir.ListenerPort{infraPort}, } diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index ce2efc55be6..4a7dc8dc2d4 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -666,7 +666,8 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route } } irKey := t.getIRKey(listener.gateway) - irListener := xdsIR[irKey].GetHTTPListener(irHTTPListenerName(listener)) + irListener := xdsIR[irKey].GetHTTPListener(irListenerName(listener)) + if irListener != nil { if GetRouteType(route) == KindGRPCRoute { irListener.IsHTTP2 = true @@ -757,24 +758,22 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour irKey := t.getIRKey(listener.gateway) - containerPort := servicePortToContainerPort(int32(listener.Port)) - // Create the TCP Listener while parsing the TLSRoute since - // the listener directly links to a routeDestination. - irListener := &ir.TCPListener{ - Name: irTLSListenerName(listener, tlsRoute), - Address: "0.0.0.0", - Port: uint32(containerPort), - TLS: &ir.TLS{Passthrough: &ir.TLSInspectorConfig{ - SNIs: hosts, - }}, - Destination: &ir.RouteDestination{ - Name: irRouteDestinationName(tlsRoute, -1 /*rule index*/), - Settings: destSettings, - }, - } gwXdsIR := xdsIR[irKey] - gwXdsIR.TCP = append(gwXdsIR.TCP, irListener) + irListener := gwXdsIR.GetTCPListener(irListenerName(listener)) + if irListener != nil { + irRoute := &ir.TCPRoute{ + Name: irTCPRouteName(tlsRoute), + TLS: &ir.TLS{Passthrough: &ir.TLSInspectorConfig{ + SNIs: hosts, + }}, + Destination: &ir.RouteDestination{ + Name: irRouteDestinationName(tlsRoute, -1 /*rule index*/), + Settings: destSettings, + }, + } + irListener.Routes = append(irListener.Routes, irRoute) + } } if !hasHostnameIntersection { @@ -1023,21 +1022,20 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour accepted = true irKey := t.getIRKey(listener.gateway) - containerPort := servicePortToContainerPort(int32(listener.Port)) - // Create the TCP Listener while parsing the TCPRoute since - // the listener directly links to a routeDestination. - irListener := &ir.TCPListener{ - Name: irTCPListenerName(listener, tcpRoute), - Address: "0.0.0.0", - Port: uint32(containerPort), - Destination: &ir.RouteDestination{ - Name: irRouteDestinationName(tcpRoute, -1 /*rule index*/), - Settings: destSettings, - }, - TLS: &ir.TLS{Terminate: irTLSConfigs(listener.tlsSecrets)}, - } gwXdsIR := xdsIR[irKey] - gwXdsIR.TCP = append(gwXdsIR.TCP, irListener) + irListener := gwXdsIR.GetTCPListener(irListenerName(listener)) + if irListener != nil { + irRoute := &ir.TCPRoute{ + Name: irTCPRouteName(tcpRoute), + Destination: &ir.RouteDestination{ + Name: irRouteDestinationName(tcpRoute, -1 /*rule index*/), + Settings: destSettings, + }, + TLS: &ir.TLS{Terminate: irTLSConfigs(listener.tlsSecrets)}, + } + irListener.Routes = append(irListener.Routes, irRoute) + + } } diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml index 64c6932c2a3..b223f3990f4 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml @@ -619,3 +619,7 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/envoy-gateway/grpcroute-1/rule/0/match/0/* + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-2/tcp + port: 10053 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml index 99e076b98ab..e61c3b211a4 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml @@ -234,62 +234,64 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - circuitBreaker: - maxConnections: 2048 - maxParallelRequests: 4294967295 - maxParallelRetries: 1024 - maxPendingRequests: 1 - maxRequestsPerConnection: 1 - destination: - name: tcproute/default/tls-app-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - healthCheck: - active: - healthyThreshold: 1 - http: - expectedResponse: - binary: RXZlcnl0aGluZyBPSw== - expectedStatuses: - - 200 - - 300 - host: "" - method: GET - path: /healthz - interval: 3s - timeout: 500ms - unhealthyThreshold: 3 - passive: - baseEjectionTime: 2m40s - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - interval: 2s - maxEjectionPercent: 100 - splitExternalLocalOriginErrors: false - loadBalancer: - consistentHash: - sourceIP: true - name: default/tcp-gateway/bar/tls-app-1 + name: default/tcp-gateway/bar port: 8089 - proxyProtocol: - version: V2 - tcpKeepalive: - idleTime: 1200 - interval: 60 - probes: 3 - timeout: - http: - connectionIdleTimeout: 16s - maxConnectionDuration: 17s - tcp: - connectTimeout: 15s - tls: {} + routes: + - circuitBreaker: + maxConnections: 2048 + maxParallelRequests: 4294967295 + maxParallelRetries: 1024 + maxPendingRequests: 1 + maxRequestsPerConnection: 1 + destination: + name: tcproute/default/tls-app-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + healthCheck: + active: + healthyThreshold: 1 + http: + expectedResponse: + binary: RXZlcnl0aGluZyBPSw== + expectedStatuses: + - 200 + - 300 + host: "" + method: GET + path: /healthz + interval: 3s + timeout: 500ms + unhealthyThreshold: 3 + passive: + baseEjectionTime: 2m40s + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + interval: 2s + maxEjectionPercent: 100 + splitExternalLocalOriginErrors: false + loadBalancer: + consistentHash: + sourceIP: true + name: tcproute/default/tls-app-1 + proxyProtocol: + version: V2 + tcpKeepalive: + idleTime: 1200 + interval: 60 + probes: 3 + timeout: + http: + connectionIdleTimeout: 16s + maxConnectionDuration: 17s + tcp: + connectTimeout: 15s + tls: {} udp: - address: 0.0.0.0 destination: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml index 14eea34c492..75c5d4cd01d 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml @@ -309,62 +309,64 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - circuitBreaker: - maxConnections: 2048 - maxParallelRequests: 4294967295 - maxParallelRetries: 1024 - maxPendingRequests: 1 - maxRequestsPerConnection: 1 - destination: - name: tcproute/default/tcp-app-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - healthCheck: - active: - healthyThreshold: 1 - http: - expectedResponse: - binary: RXZlcnl0aGluZyBPSw== - expectedStatuses: - - 200 - - 300 - host: "" - method: GET - path: /healthz - interval: 3s - timeout: 500ms - unhealthyThreshold: 3 - passive: - baseEjectionTime: 2m40s - consecutive5XxErrors: 5 - consecutiveGatewayErrors: 0 - consecutiveLocalOriginFailures: 5 - interval: 2s - maxEjectionPercent: 100 - splitExternalLocalOriginErrors: false - loadBalancer: - consistentHash: - sourceIP: true - name: default/tcp-gateway/bar/tcp-app-1 + name: default/tcp-gateway/bar port: 8089 - proxyProtocol: - version: V2 - tcpKeepalive: - idleTime: 1200 - interval: 60 - probes: 3 - timeout: - http: - connectionIdleTimeout: 16s - maxConnectionDuration: 17s - tcp: - connectTimeout: 15s - tls: {} + routes: + - circuitBreaker: + maxConnections: 2048 + maxParallelRequests: 4294967295 + maxParallelRetries: 1024 + maxPendingRequests: 1 + maxRequestsPerConnection: 1 + destination: + name: tcproute/default/tcp-app-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + healthCheck: + active: + healthyThreshold: 1 + http: + expectedResponse: + binary: RXZlcnl0aGluZyBPSw== + expectedStatuses: + - 200 + - 300 + host: "" + method: GET + path: /healthz + interval: 3s + timeout: 500ms + unhealthyThreshold: 3 + passive: + baseEjectionTime: 2m40s + consecutive5XxErrors: 5 + consecutiveGatewayErrors: 0 + consecutiveLocalOriginFailures: 5 + interval: 2s + maxEjectionPercent: 100 + splitExternalLocalOriginErrors: false + loadBalancer: + consistentHash: + sourceIP: true + name: tcproute/default/tcp-app-1 + proxyProtocol: + version: V2 + tcpKeepalive: + idleTime: 1200 + interval: 60 + probes: 3 + timeout: + http: + connectionIdleTimeout: 16s + maxConnectionDuration: 17s + tcp: + connectTimeout: 15s + tls: {} udp: - address: 0.0.0.0 destination: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml index fddae6e6c9e..84ec9e07658 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml @@ -547,6 +547,10 @@ xdsIR: escapedSlashesAction: UnescapeAndRedirect mergeSlashes: true port: 10080 + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-2/tcp + port: 10053 envoy-gateway/gateway-3: accessLog: text: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml index b2abfba7c21..d1978c3ef4c 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml @@ -619,3 +619,7 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/envoy-gateway/grpcroute-1/rule/0/match/0/* + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-2/tcp + port: 10053 diff --git a/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml b/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml index 1001026c2be..798641857cd 100644 --- a/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml @@ -65,3 +65,7 @@ xdsIR: accessLog: text: - path: /dev/stdout + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-1/tcp + port: 10080 diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml index 00a01a90dfe..78d9c5cf752 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml @@ -90,3 +90,7 @@ xdsIR: accessLog: text: - path: /dev/stdout + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-1/tcp + port: 10162 diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml index d87a590cc69..417b1a5d68a 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml @@ -94,3 +94,7 @@ xdsIR: accessLog: text: - path: /dev/stdout + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-1/tcp + port: 10080 diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml index 0298d8e8bc7..7e583a73bda 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml @@ -95,3 +95,7 @@ xdsIR: accessLog: text: - path: /dev/stdout + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-1/tcp + port: 10080 diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml index bb6c6d082bb..8b6f602c543 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml @@ -208,18 +208,20 @@ xdsIR: serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= tcp: - address: 0.0.0.0 - destination: - name: tlsroute/default/tlsroute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: HTTPS - weight: 1 - name: envoy-gateway/gateway-1/tls-passthrough/tlsroute-1 + name: envoy-gateway/gateway-1/tls-passthrough port: 10090 - tls: - passthrough: - snis: - - foo.bar.com + routes: + - destination: + name: tlsroute/default/tlsroute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTPS + weight: 1 + name: tlsroute/default/tlsroute-1 + tls: + passthrough: + snis: + - foo.bar.com diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml index dd31bd501ea..79295aded7b 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml @@ -58,3 +58,7 @@ xdsIR: accessLog: text: - path: /dev/stdout + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-1/tcp + port: 10080 diff --git a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml index 0bd36bdaac1..6441a614d07 100644 --- a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml @@ -123,15 +123,17 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tcp/tcproute-1 + name: envoy-gateway/gateway-1/tcp port: 10162 - tls: {} + routes: + - destination: + name: tcproute/default/tcproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-1 + tls: {} diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml index 0e65142eb85..3422f943b02 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml @@ -121,15 +121,17 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tcp1/tcproute-1 + name: envoy-gateway/gateway-1/tcp1 port: 10162 - tls: {} + routes: + - destination: + name: tcproute/default/tcproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-1 + tls: {} diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml index 0233225bb98..3dc939e6f55 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml @@ -194,15 +194,17 @@ xdsIR: prefix: / tcp: - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tcp/tcproute-1 + name: envoy-gateway/gateway-1/tcp port: 10080 - tls: {} + routes: + - destination: + name: tcproute/default/tcproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-1 + tls: {} diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml index bf49b0dafaa..b667e4243a1 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml @@ -161,28 +161,32 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tcp1/tcproute-1 + name: envoy-gateway/gateway-1/tcp1 port: 10162 - tls: {} + routes: + - destination: + name: tcproute/default/tcproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-1 + tls: {} - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-2/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tcp2/tcproute-2 + name: envoy-gateway/gateway-1/tcp2 port: 10163 - tls: {} + routes: + - destination: + name: tcproute/default/tcproute-2/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-2 + tls: {} diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml index 733f4e76b16..f39d2f4bedb 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml @@ -157,28 +157,32 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tcp1/tcproute-1 + name: envoy-gateway/gateway-1/tcp1 port: 10161 - tls: {} + routes: + - destination: + name: tcproute/default/tcproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-1 + tls: {} - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8163 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tcp2/tcproute-1 + name: envoy-gateway/gateway-1/tcp2 port: 10162 - tls: {} + routes: + - destination: + name: tcproute/default/tcproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8163 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-1 + tls: {} diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml index 026f00b4317..01db3ebbdec 100755 --- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml @@ -464,3 +464,7 @@ xdsIR: isHTTP2: true name: grpcroute/envoy-gateway/grpcroute-1/rule/0/match/0/* security: {} + tcp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-2/tcp + port: 10053 diff --git a/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml b/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml index 44fe206db9b..cb2e63a0170 100644 --- a/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml +++ b/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml @@ -98,20 +98,22 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tcproute/default/tcproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: TCP - weight: 1 - name: envoy-gateway/gateway-1/tls/tcproute-1 + name: envoy-gateway/gateway-1/tls port: 10090 - tls: - terminate: - certificates: - - name: envoy-gateway/tls-secret-1 - privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K - serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + routes: + - destination: + name: tcproute/default/tcproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: TCP + weight: 1 + name: tcproute/default/tcproute-1 + tls: + terminate: + certificates: + - name: envoy-gateway/tls-secret-1 + privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= diff --git a/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml b/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml index 7438edad63a..90c2adb3124 100644 --- a/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml @@ -95,18 +95,20 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tlsroute/default/tlsroute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: HTTPS - weight: 1 - name: envoy-gateway/gateway-1/tls/tlsroute-1 + name: envoy-gateway/gateway-1/tls port: 10090 - tls: - passthrough: - snis: - - foo.com + routes: + - destination: + name: tlsroute/default/tlsroute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTPS + weight: 1 + name: tlsroute/default/tlsroute-1 + tls: + passthrough: + snis: + - foo.com diff --git a/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml b/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml index 4b53cc38e3c..10af5aaf19e 100644 --- a/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml @@ -129,34 +129,34 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tlsroute/default/tlsroute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: HTTPS - weight: 1 - name: envoy-gateway/gateway-1/tls/tlsroute-1 + name: envoy-gateway/gateway-1/tls port: 10091 - tls: - passthrough: - snis: - - foo.com - - address: 0.0.0.0 - destination: - name: tlsroute/default/tlsroute-2/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: HTTPS - weight: 1 - name: envoy-gateway/gateway-1/tls/tlsroute-2 - port: 10091 - tls: - passthrough: - snis: - - bar.com + routes: + - destination: + name: tlsroute/default/tlsroute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTPS + weight: 1 + name: tlsroute/default/tlsroute-1 + tls: + passthrough: + snis: + - foo.com + - destination: + name: tlsroute/default/tlsroute-2/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTPS + weight: 1 + name: tlsroute/default/tlsroute-2 + tls: + passthrough: + snis: + - bar.com diff --git a/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml index f7839533321..2612b521b34 100644 --- a/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml @@ -96,18 +96,20 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tlsroute/default/tlsroute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: HTTPS - weight: 1 - name: envoy-gateway/gateway-1/tls/tlsroute-1 + name: envoy-gateway/gateway-1/tls port: 10090 - tls: - passthrough: - snis: - - foo.com + routes: + - destination: + name: tlsroute/default/tlsroute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTPS + weight: 1 + name: tlsroute/default/tlsroute-1 + tls: + passthrough: + snis: + - foo.com diff --git a/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml index 7444d808de3..8a910c00e81 100644 --- a/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml @@ -94,18 +94,20 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tlsroute/default/tlsroute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: HTTPS - weight: 1 - name: envoy-gateway/gateway-1/tls/tlsroute-1 + name: envoy-gateway/gateway-1/tls port: 10091 - tls: - passthrough: - snis: - - '*' + routes: + - destination: + name: tlsroute/default/tlsroute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTPS + weight: 1 + name: tlsroute/default/tlsroute-1 + tls: + passthrough: + snis: + - '*' diff --git a/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml index 1a45b65bb80..57f27028b74 100644 --- a/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml @@ -96,18 +96,20 @@ xdsIR: - path: /dev/stdout tcp: - address: 0.0.0.0 - destination: - name: tlsroute/default/tlsroute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: HTTPS - weight: 1 - name: envoy-gateway/gateway-1/tls/tlsroute-1 + name: envoy-gateway/gateway-1/tls port: 10091 - tls: - passthrough: - snis: - - foo.com + routes: + - destination: + name: tlsroute/default/tlsroute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTPS + weight: 1 + name: tlsroute/default/tlsroute-1 + tls: + passthrough: + snis: + - foo.com diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 337720f7fb0..9f17d04fcf0 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -30,10 +30,10 @@ var ( ErrListenerAddressInvalid = errors.New("field Address must be a valid IP address") ErrListenerPortInvalid = errors.New("field Port specified is invalid") ErrHTTPListenerHostnamesEmpty = errors.New("field Hostnames must be specified with at least a single hostname entry") - ErrTCPListenerSNIsEmpty = errors.New("field SNIs must be specified with at least a single server name entry") + ErrTCPRouteSNIsEmpty = errors.New("field SNIs must be specified with at least a single server name entry") ErrTLSServerCertEmpty = errors.New("field ServerCertificate must be specified") ErrTLSPrivateKey = errors.New("field PrivateKey must be specified") - ErrHTTPRouteNameEmpty = errors.New("field Name must be specified") + ErrRouteNameEmpty = errors.New("field Name must be specified") ErrHTTPRouteHostnameEmpty = errors.New("field Hostname must be specified") ErrDestinationNameEmpty = errors.New("field Name must be specified") ErrDestEndpointHostInvalid = errors.New("field Address must be a valid IP or FQDN address") @@ -777,7 +777,7 @@ type FaultInjectionAbort struct { func (h HTTPRoute) Validate() error { var errs error if h.Name == "" { - errs = errors.Join(errs, ErrHTTPRouteNameEmpty) + errs = errors.Join(errs, ErrRouteNameEmpty) } if h.Hostname == "" { errs = errors.Join(errs, ErrHTTPRouteHostnameEmpty) @@ -1177,14 +1177,25 @@ type TCPListener struct { Address string `json:"address" yaml:"address"` // Port on which the service can be expected to be accessed by clients. Port uint32 `json:"port" yaml:"port"` + // TCPKeepalive configuration for the listener + TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"` + // Connection settings for clients + Connection *Connection `json:"connection,omitempty" yaml:"connection,omitempty"` + // Routes associated with TCP traffic to the listener. + Routes []*TCPRoute `json:"routes,omitempty" yaml:"routes,omitempty"` +} + +// TCPRoute holds the route information associated with the TCP Route +// +k8s:deepcopy-gen=true +type TCPRoute struct { + // Name of the TCPRoute. + Name string `json:"name" yaml:"name"` // TLS holds information for configuring TLS on a listener TLS *TLS `json:"tls,omitempty" yaml:"tls,omitempty"` // Destinations associated with TCP traffic to the service. Destination *RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"` - // TCPKeepalive configuration for the listener + // TCPKeepalive settings associated with the upstream client connection. TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"` - // Connection settings for clients - Connection *Connection `json:"connection,omitempty" yaml:"connection,omitempty"` // load balancer policy to use when routing to the backend endpoints. LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` // Request and connection timeout settings @@ -1208,34 +1219,61 @@ type TLS struct { } // Validate the fields within the TCPListener structure -func (h TCPListener) Validate() error { +func (t TCPListener) Validate() error { var errs error - if h.Name == "" { + if t.Name == "" { errs = errors.Join(errs, ErrListenerNameEmpty) } - if _, err := netip.ParseAddr(h.Address); err != nil { + if _, err := netip.ParseAddr(t.Address); err != nil { errs = errors.Join(errs, ErrListenerAddressInvalid) } - if h.Port == 0 { + if t.Port == 0 { errs = errors.Join(errs, ErrListenerPortInvalid) } - if h.TLS != nil && h.TLS.Passthrough != nil { - if err := h.TLS.Passthrough.Validate(); err != nil { + for _, route := range t.Routes { + if err := route.Validate(); err != nil { errs = errors.Join(errs, err) } } + return errs +} - if h.TLS != nil && h.TLS.Terminate != nil { - if err := h.TLS.Terminate.Validate(); err != nil { +func (t TCPRoute) Validate() error { + var errs error + if t.Name == "" { + errs = errors.Join(errs, ErrRouteNameEmpty) + } + + if t.TLS != nil && t.TLS.Passthrough != nil { + if err := t.TLS.Passthrough.Validate(); err != nil { errs = errors.Join(errs, err) } } - if h.Destination != nil { - if err := h.Destination.Validate(); err != nil { + if t.TLS != nil && t.TLS.Terminate != nil { + if err := t.TLS.Terminate.Validate(); err != nil { errs = errors.Join(errs, err) } } + + if t.Destination != nil { + if err := t.Destination.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + + if t.LoadBalancer != nil { + if err := t.LoadBalancer.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + + if t.HealthCheck != nil { + if err := t.HealthCheck.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + return errs } @@ -1253,7 +1291,7 @@ type TLSInspectorConfig struct { func (t TLSInspectorConfig) Validate() error { var errs error if len(t.SNIs) == 0 { - errs = errors.Join(errs, ErrTCPListenerSNIsEmpty) + errs = errors.Join(errs, ErrTCPRouteSNIsEmpty) } return errs } diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go index 30c07a70001..ab42d763711 100644 --- a/internal/ir/xds_test.go +++ b/internal/ir/xds_test.go @@ -80,49 +80,64 @@ var ( // TCPListener happyTCPListenerTLSPassthrough = TCPListener{ - Name: "happy", - Address: "0.0.0.0", - Port: 80, - TLS: &TLS{Passthrough: &TLSInspectorConfig{SNIs: []string{"example.com"}}}, - Destination: &happyRouteDestination, + Name: "happy", + Address: "0.0.0.0", + Port: 80, + Routes: []*TCPRoute{&happyTCPRouteTLSPassthrough}, } happyTCPListenerTLSTerminate = TCPListener{ Name: "happy", Address: "0.0.0.0", Port: 80, - TLS: &TLS{Terminate: &TLSConfig{ - Certificates: []TLSCertificate{{ - Name: "happy", - ServerCertificate: []byte("server-cert"), - PrivateKey: []byte("priv-key"), - }}, - }}, - Destination: &happyRouteDestination, + Routes: []*TCPRoute{&happyTCPRouteTLSTermination}, } emptySNITCPListenerTLSPassthrough = TCPListener{ - Name: "empty-sni", - Address: "0.0.0.0", - Port: 80, - Destination: &happyRouteDestination, + Name: "empty-sni", + Address: "0.0.0.0", + Port: 80, + Routes: []*TCPRoute{&emptySNITCPRoute}, } invalidNameTCPListenerTLSPassthrough = TCPListener{ - Address: "0.0.0.0", - Port: 80, - TLS: &TLS{Passthrough: &TLSInspectorConfig{SNIs: []string{"example.com"}}}, - Destination: &happyRouteDestination, + Address: "0.0.0.0", + Port: 80, + Routes: []*TCPRoute{&happyTCPRouteTLSPassthrough}, } invalidAddrTCPListenerTLSPassthrough = TCPListener{ - Name: "invalid-addr", - Address: "1.0.0", - Port: 80, + Name: "invalid-addr", + Address: "1.0.0", + Port: 80, + Routes: []*TCPRoute{&happyTCPRouteTLSPassthrough}, + } + invalidSNITCPListenerTLSPassthrough = TCPListener{ + Address: "0.0.0.0", + Port: 80, + Routes: []*TCPRoute{&invalidSNITCPRoute}, + } + + // TCPRoute + happyTCPRouteTLSPassthrough = TCPRoute{ + Name: "happy-tls-passthrough", TLS: &TLS{Passthrough: &TLSInspectorConfig{SNIs: []string{"example.com"}}}, Destination: &happyRouteDestination, } - invalidSNITCPListenerTLSPassthrough = TCPListener{ - Address: "0.0.0.0", - Port: 80, + happyTCPRouteTLSTermination = TCPRoute{ + Name: "happy-tls-termination", + TLS: &TLS{Terminate: &TLSConfig{Certificates: []TLSCertificate{{ + Name: "happy", + ServerCertificate: []byte("server-cert"), + PrivateKey: []byte("priv-key"), + }}}}, + Destination: &happyRouteDestination, + } + emptySNITCPRoute = TCPRoute{ + Name: "empty-sni", + Destination: &happyRouteDestination, + } + + invalidSNITCPRoute = TCPRoute{ + Name: "invalid-sni", TLS: &TLS{Passthrough: &TLSInspectorConfig{SNIs: []string{}}}, Destination: &happyRouteDestination, } @@ -611,6 +626,11 @@ func TestValidateTCPListener(t *testing.T) { input: happyTCPListenerTLSPassthrough, want: nil, }, + { + name: "tls terminate happy", + input: happyTCPListenerTLSTerminate, + want: nil, + }, { name: "tcp empty SNIs", input: emptySNITCPListenerTLSPassthrough, @@ -629,7 +649,7 @@ func TestValidateTCPListener(t *testing.T) { { name: "tls passthrough empty SNIs", input: invalidSNITCPListenerTLSPassthrough, - want: []error{ErrTCPListenerSNIsEmpty}, + want: []error{ErrTCPRouteSNIsEmpty}, }, } for _, test := range tests { @@ -830,7 +850,7 @@ func TestValidateHTTPRoute(t *testing.T) { }, Destination: &happyRouteDestination, }, - want: []error{ErrHTTPRouteNameEmpty}, + want: []error{ErrRouteNameEmpty}, }, { name: "invalid hostname", @@ -860,7 +880,7 @@ func TestValidateHTTPRoute(t *testing.T) { HeaderMatches: []*StringMatch{ptr.To(StringMatch{})}, Destination: &happyRouteDestination, }, - want: []error{ErrHTTPRouteNameEmpty, ErrStringMatchConditionInvalid}, + want: []error{ErrRouteNameEmpty, ErrStringMatchConditionInvalid}, }, { name: "redirect-httproute", @@ -962,6 +982,48 @@ func TestValidateHTTPRoute(t *testing.T) { } } +func TestValidateTCPRoute(t *testing.T) { + tests := []struct { + name string + input TCPRoute + want []error + }{ + { + name: "tls passthrough happy", + input: happyTCPRouteTLSPassthrough, + want: nil, + }, + { + name: "tls terminatation happy", + input: happyTCPRouteTLSTermination, + want: nil, + }, + { + name: "empty sni", + input: emptySNITCPRoute, + want: nil, + }, + { + name: "invalid sni", + input: invalidSNITCPRoute, + want: []error{ErrTCPRouteSNIsEmpty}, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + if test.want == nil { + require.NoError(t, test.input.Validate()) + } else { + got := test.input.Validate() + for _, w := range test.want { + assert.ErrorContains(t, got, w.Error()) + } + } + }) + } +} + func TestValidateRouteDestination(t *testing.T) { tests := []struct { name string diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 5430ef9ce6b..26c713f28bc 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2075,6 +2075,42 @@ func (in *TCPKeepalive) DeepCopy() *TCPKeepalive { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TCPListener) DeepCopyInto(out *TCPListener) { + *out = *in + if in.TCPKeepalive != nil { + in, out := &in.TCPKeepalive, &out.TCPKeepalive + *out = new(TCPKeepalive) + (*in).DeepCopyInto(*out) + } + if in.Connection != nil { + in, out := &in.Connection, &out.Connection + *out = new(Connection) + (*in).DeepCopyInto(*out) + } + if in.Routes != nil { + in, out := &in.Routes, &out.Routes + *out = make([]*TCPRoute, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(TCPRoute) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPListener. +func (in *TCPListener) DeepCopy() *TCPListener { + if in == nil { + return nil + } + out := new(TCPListener) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TCPRoute) DeepCopyInto(out *TCPRoute) { *out = *in if in.TLS != nil { in, out := &in.TLS, &out.TLS @@ -2091,11 +2127,6 @@ func (in *TCPListener) DeepCopyInto(out *TCPListener) { *out = new(TCPKeepalive) (*in).DeepCopyInto(*out) } - if in.Connection != nil { - in, out := &in.Connection, &out.Connection - *out = new(Connection) - (*in).DeepCopyInto(*out) - } if in.LoadBalancer != nil { in, out := &in.LoadBalancer, &out.LoadBalancer *out = new(LoadBalancer) @@ -2123,12 +2154,12 @@ func (in *TCPListener) DeepCopyInto(out *TCPListener) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPListener. -func (in *TCPListener) DeepCopy() *TCPListener { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPRoute. +func (in *TCPRoute) DeepCopy() *TCPRoute { if in == nil { return nil } - out := new(TCPListener) + out := new(TCPRoute) in.DeepCopyInto(out) return out } diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 64004c9460b..e7ee0e4fbfb 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -383,13 +383,13 @@ func findXdsHTTPRouteConfigName(xdsListener *listenerv3.Listener) string { return "" } -func addXdsTCPFilterChain(xdsListener *listenerv3.Listener, irListener *ir.TCPListener, clusterName string, accesslog *ir.AccessLog, connection *ir.Connection) error { - if irListener == nil { +func addXdsTCPFilterChain(xdsListener *listenerv3.Listener, irRoute *ir.TCPRoute, clusterName string, accesslog *ir.AccessLog, connection *ir.Connection) error { + if irRoute == nil { return errors.New("tcp listener is nil") } - isTLSPassthrough := irListener.TLS != nil && irListener.TLS.Passthrough != nil - isTLSTerminate := irListener.TLS != nil && irListener.TLS.Terminate != nil + isTLSPassthrough := irRoute.TLS != nil && irRoute.TLS.Passthrough != nil + isTLSTerminate := irRoute.TLS != nil && irRoute.TLS.Terminate != nil statPrefix := "tcp" if isTLSPassthrough { statPrefix = "passthrough" @@ -405,7 +405,7 @@ func addXdsTCPFilterChain(xdsListener *listenerv3.Listener, irListener *ir.TCPLi ClusterSpecifier: &tcpv3.TcpProxy_Cluster{ Cluster: clusterName, }, - HashPolicy: buildTCPProxyHashPolicy(irListener.LoadBalancer), + HashPolicy: buildTCPProxyHashPolicy(irRoute.LoadBalancer), } var filters []*listenerv3.Filter @@ -430,13 +430,13 @@ func addXdsTCPFilterChain(xdsListener *listenerv3.Listener, irListener *ir.TCPLi } if isTLSPassthrough { - if err := addServerNamesMatch(xdsListener, filterChain, irListener.TLS.Passthrough.SNIs); err != nil { + if err := addServerNamesMatch(xdsListener, filterChain, irRoute.TLS.Passthrough.SNIs); err != nil { return err } } if isTLSTerminate { - tSocket, err := buildXdsDownstreamTLSSocket(irListener.TLS.Terminate) + tSocket, err := buildXdsDownstreamTLSSocket(irRoute.TLS.Terminate) if err != nil { return err } diff --git a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml index fccf73d51fb..0fd5727987d 100644 --- a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port.yaml @@ -91,26 +91,30 @@ tcp: - name: "fifth-listener" address: "0.0.0.0" port: 10080 - tls: - passthrough: - snis: - - bar.com - destination: - name: "tcp-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 + routes: + - name: "fifth-route" + tls: + passthrough: + snis: + - bar.com + destination: + name: "tcp-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 - name: "sixth-listener" address: "0.0.0.0" port: 10080 - tls: - passthrough: - snis: - - bar.net - destination: - name: "tls-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 + routes: + - name: "sixth-route" + tls: + passthrough: + snis: + - bar.net + destination: + name: "tls-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml b/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml index fca8012cd10..19ad6357e9a 100644 --- a/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml @@ -1,56 +1,66 @@ tcp: -- name: "tcp-route-simple" +- name: "tcp-listener-simple" address: "0.0.0.0" port: 10080 - destination: - name: "tcp-route-simple-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 -- name: "tcp-route-simple-1" + routes: + - name: "tcp-route-simple" + destination: + name: "tcp-route-simple-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-listener-simple-1" address: "0.0.0.0" port: 10080 - destination: - name: "tcp-route-simple-1-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 -- name: "tcp-route-simple-2" + routes: + - name: "tcp-route-simple-1" + destination: + name: "tcp-route-simple-1-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-listener-simple-2" address: "0.0.0.0" port: 10080 - destination: - name: "tcp-route-simple-2-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 -- name: "tcp-route-simple-3" + routes: + - name: "tcp-route-simple-2" + destination: + name: "tcp-route-simple-2-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-listener-simple-3" address: "0.0.0.0" port: 10080 - destination: - name: "tcp-route-simple-3-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 -- name: "tcp-route-simple-4" + routes: + - name: "tcp-route-simple-3" + destination: + name: "tcp-route-simple-3-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-listener-simple-4" address: "0.0.0.0" port: 10080 - destination: - name: "tcp-route-simple-4-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" + routes: + - name: "tcp-route-simple-4" + destination: + name: "tcp-route-simple-4-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml index 05ac886693e..ddae185afcd 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml @@ -1,18 +1,20 @@ tcp: -- name: "tcp-route-complex" +- name: "tcp-listener-complex" address: "0.0.0.0" port: 10080 - tls: - passthrough: - snis: - - foo.com - - bar.com - - example.com - destination: - name: "tcp-route-complex-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 + routes: + - name: "tcp-route-complex" + tls: + passthrough: + snis: + - foo.com + - bar.com + - example.com + destination: + name: "tcp-route-complex-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml index 3885afa4fd9..427472d6832 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid-endpoint.yaml @@ -1,11 +1,13 @@ tcp: -- name: "tcp-route-simple" +- name: "tcp-listener-simple" address: "0.0.0.0" port: 10080 - destination: - name: "tcp-route-simple-dest" - settings: - - endpoints: - - port: 50000 - - host: "5.6.7.8" - port: 50001 + routes: + - name: "tcp-route-simple" + destination: + name: "tcp-route-simple-dest" + settings: + - endpoints: + - port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid.yaml index d14b325d3dc..d694b2c7e48 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-invalid.yaml @@ -1,12 +1,14 @@ tcp: -- name: "tcp-route-invalid" +- name: "tcp-listener-invalid" address: "" port: 10080 - destination: - name: "tcp-route-invalid-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 + routes: + - name: "tcp-route-invalid" + destination: + name: "tcp-route-invalid-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml index f79cebf3e67..58f1ec03892 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml @@ -1,12 +1,14 @@ tcp: -- name: "tcp-route-simple" +- name: "tcp-listener-simple" address: "0.0.0.0" port: 10080 - destination: - name: "tcp-route-simple-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 + routes: + - name: "tcp-route-simple" + destination: + name: "tcp-route-simple-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml index 0bd68608bdb..35c7f7e03a1 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-tls-terminate.yaml @@ -1,18 +1,20 @@ tcp: -- name: "tls-terminate" +- name: "tls-listener-terminate" address: "0.0.0.0" port: 10080 - tls: - terminate: - certificates: - - Name: envoy-gateway-tls-secret-1 - PrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K - ServerCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNxRENDQVpBQ0NRREVNZ1lZblFyQ29EQU5CZ2txaGtpRzl3MEJBUXNGQURBV01SUXdFZ1lEVlFRRERBdG0KYjI4dVltRnlMbU52YlRBZUZ3MHlNekF4TURVeE16UXpNalJhRncweU5EQXhNRFV4TXpRek1qUmFNQll4RkRBUwpCZ05WQkFNTUMyWnZieTVpWVhJdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUFuZEh6d21wS2NUSUViamhGZ2RXd1RSTjc1Y3A4b3VsWnhMMUdydlI2SXc3ejdqaTBSNFcvTm85bkdmOU0KWVAyQ1JqaXN6NTFtd3hTeGVCcm9jTGVBK21reGkxK2lEdk5kQytyU0x4MTN6RUxTQ25xYnVzUHM3bUdmSlpxOAo5TGhlbmx5bzQzaDVjYTZINUxqTXd1L1JHVWlGMzFYck5yaVlGQlB2RTJyQitkd24vTkVrUTRoOFJxcXlwcmtuCkYvcWM5Sk1ZQVlGRld1VkNwa0lFbmRYMUN5dlFOT2FkZmN2cmd6dDV2SmwwT2kxQWdyaU5hWGJFUEdudWY3STQKcXBCSEdVWE5lMVdsOVdlVklxS1g0T2FFWERWQzZGQzdHOHptZWVMVzFBa1lFVm5pcFg2b1NCK0JjL1NIVlZOaApzQkxSbXRuc3pmTnRUMlFyZCttcGt4ODBaUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1VKOElDCkJveUVqT3V3enBHYVJoR044QjRqT1B6aHVDT0V0ZDM3UzAybHUwN09IenlCdmJzVEd6S3dCZ0x5bVdmR2tINEIKajdDTHNwOEZ6TkhLWnVhQmdwblo5SjZETE9Od2ZXZTJBWXA3TGRmT0tWQlVkTVhRaU9tN2pKOUhob0Ntdk1ONwpic2pjaFdKb013ckZmK3dkQUthdHowcUFQeWhMeWUvRnFtaVZ4a09SWmF3K1Q5bURaK0g0OXVBU2d1SnVOTXlRClY2RXlYNmd0Z1dxMzc2SHZhWE1TLzNoYW1Zb1ZXWEk1TXhpUE9ZeG5BQmtKQjRTQ2dJUmVqYkpmVmFRdG9RNGEKejAyaVVMZW5ESUllUU9Zb2JLY01CWGYxQjRQQVFtc2VocVZJYnpzUUNHaTU0VkRyczZiWmQvN0pzMXpDcHBncwpKaUQ1SXFNaktXRHdxN2FLCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - destination: - name: "tls-terminate-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 + routes: + - name: "tls-route-terminate" + tls: + terminate: + certificates: + - Name: envoy-gateway-tls-secret-1 + PrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + ServerCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNxRENDQVpBQ0NRREVNZ1lZblFyQ29EQU5CZ2txaGtpRzl3MEJBUXNGQURBV01SUXdFZ1lEVlFRRERBdG0KYjI4dVltRnlMbU52YlRBZUZ3MHlNekF4TURVeE16UXpNalJhRncweU5EQXhNRFV4TXpRek1qUmFNQll4RkRBUwpCZ05WQkFNTUMyWnZieTVpWVhJdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUFuZEh6d21wS2NUSUViamhGZ2RXd1RSTjc1Y3A4b3VsWnhMMUdydlI2SXc3ejdqaTBSNFcvTm85bkdmOU0KWVAyQ1JqaXN6NTFtd3hTeGVCcm9jTGVBK21reGkxK2lEdk5kQytyU0x4MTN6RUxTQ25xYnVzUHM3bUdmSlpxOAo5TGhlbmx5bzQzaDVjYTZINUxqTXd1L1JHVWlGMzFYck5yaVlGQlB2RTJyQitkd24vTkVrUTRoOFJxcXlwcmtuCkYvcWM5Sk1ZQVlGRld1VkNwa0lFbmRYMUN5dlFOT2FkZmN2cmd6dDV2SmwwT2kxQWdyaU5hWGJFUEdudWY3STQKcXBCSEdVWE5lMVdsOVdlVklxS1g0T2FFWERWQzZGQzdHOHptZWVMVzFBa1lFVm5pcFg2b1NCK0JjL1NIVlZOaApzQkxSbXRuc3pmTnRUMlFyZCttcGt4ODBaUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1VKOElDCkJveUVqT3V3enBHYVJoR044QjRqT1B6aHVDT0V0ZDM3UzAybHUwN09IenlCdmJzVEd6S3dCZ0x5bVdmR2tINEIKajdDTHNwOEZ6TkhLWnVhQmdwblo5SjZETE9Od2ZXZTJBWXA3TGRmT0tWQlVkTVhRaU9tN2pKOUhob0Ntdk1ONwpic2pjaFdKb013ckZmK3dkQUthdHowcUFQeWhMeWUvRnFtaVZ4a09SWmF3K1Q5bURaK0g0OXVBU2d1SnVOTXlRClY2RXlYNmd0Z1dxMzc2SHZhWE1TLzNoYW1Zb1ZXWEk1TXhpUE9ZeG5BQmtKQjRTQ2dJUmVqYkpmVmFRdG9RNGEKejAyaVVMZW5ESUllUU9Zb2JLY01CWGYxQjRQQVFtc2VocVZJYnpzUUNHaTU0VkRyczZiWmQvN0pzMXpDcHBncwpKaUQ1SXFNaktXRHdxN2FLCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + destination: + name: "tls-terminate-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml index 0bd5ac621a9..4b291fb1780 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml @@ -1,29 +1,31 @@ tcp: -- name: "tcp-route-weighted-backend" +- name: "tcp-listener-weighted-backend" address: "0.0.0.0" port: 10080 - tls: - passthrough: - snis: - - foo.com - - bar.com - - example.com - destination: - name: "tcp-route-weighted-backend-dest" - settings: - - endpoints: - - host: "1.1.1.1" - port: 50001 - weight: 20 - - endpoints: - - host: "2.2.2.2" - port: 50002 - weight: 40 - - endpoints: - - host: "3.3.3.3" - port: 50003 - weight: 20 - - endpoints: - - host: "4.4.4.4" - port: 50004 - weight: 20 + routes: + - name: "tcp-route-weighted-backend" + tls: + passthrough: + snis: + - foo.com + - bar.com + - example.com + destination: + name: "tcp-route-weighted-backend-dest" + settings: + - endpoints: + - host: "1.1.1.1" + port: 50001 + weight: 20 + - endpoints: + - host: "2.2.2.2" + port: 50002 + weight: 40 + - endpoints: + - host: "3.3.3.3" + port: 50003 + weight: 20 + - endpoints: + - host: "4.4.4.4" + port: 50004 + weight: 20 diff --git a/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml b/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml index a798d00b8fd..6227dd0feda 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tls-route-passthrough.yaml @@ -2,29 +2,33 @@ tcp: - name: "tls-passthrough-foo" address: "0.0.0.0" port: 10080 - tls: - passthrough: - snis: - - foo.com - destination: - name: "tls-passthrough-foo-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 + routes: + - name: "tls-route-passthrough-foo" + tls: + passthrough: + snis: + - foo.com + destination: + name: "tls-passthrough-foo-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 - name: "tls-passthrough-bar" address: "0.0.0.0" port: 10081 - tls: - passthrough: - snis: - - bar.com - destination: - name: "tls-passthrough-bar-dest" - settings: - - endpoints: - - host: "bar" - port: 50000 - addressType: FQDN + routes: + - name: "tls-route-passthrough-bar" + tls: + passthrough: + snis: + - bar.com + destination: + name: "tls-passthrough-bar-dest" + settings: + - endpoints: + - host: "bar" + port: 50000 + addressType: FQDN diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml index a52251e32bf..d65e267ad7d 100644 --- a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.clusters.yaml @@ -32,37 +32,3 @@ outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS -- circuitBreakers: - thresholds: - - maxRetries: 1024 - commonLbConfig: - localityWeightedLbConfig: {} - connectTimeout: 10s - dnsLookupFamily: V4_ONLY - edsClusterConfig: - edsConfig: - ads: {} - resourceApiVersion: V3 - serviceName: tls-route-dest - lbPolicy: LEAST_REQUEST - name: tls-route-dest - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 - type: EDS -- circuitBreakers: - thresholds: - - maxRetries: 1024 - commonLbConfig: - localityWeightedLbConfig: {} - connectTimeout: 10s - dnsLookupFamily: V4_ONLY - edsClusterConfig: - edsConfig: - ads: {} - resourceApiVersion: V3 - serviceName: tcp-route-dest - lbPolicy: LEAST_REQUEST - name: tcp-route-dest - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 - type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml index 5b4fe89e58c..de95bf555b9 100644 --- a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.endpoints.yaml @@ -22,27 +22,3 @@ loadBalancingWeight: 1 locality: region: second-route-dest/backend/0 -- clusterName: tls-route-dest - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: 1.2.3.4 - portValue: 50000 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: - region: tls-route-dest/backend/0 -- clusterName: tcp-route-dest - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: 1.2.3.4 - portValue: 50000 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: - region: tcp-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml index a7500a6bb76..d447062d4f7 100644 --- a/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/listener-connection-limit.listeners.yaml @@ -76,25 +76,6 @@ address: 0.0.0.0 portValue: 10082 drainType: MODIFY_ONLY - filterChains: - - filterChainMatch: - serverNames: - - bar.com - filters: - - name: envoy.filters.network.connection_limit - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit - maxConnections: "3" - statPrefix: passthrough - - name: envoy.filters.network.tcp_proxy - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy - cluster: tls-route-dest - statPrefix: passthrough - listenerFilters: - - name: envoy.filters.listener.tls_inspector - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector name: third-listener perConnectionBufferLimitBytes: 32768 - address: @@ -102,18 +83,5 @@ address: 0.0.0.0 portValue: 10083 drainType: MODIFY_ONLY - filterChains: - - filters: - - name: envoy.filters.network.connection_limit - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit - delay: 3s - maxConnections: "10" - statPrefix: tcp - - name: envoy.filters.network.tcp_proxy - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy - cluster: tcp-route-dest - statPrefix: tcp name: fourth-listener perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml index 70597002c88..d65e267ad7d 100644 --- a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.clusters.yaml @@ -32,42 +32,3 @@ outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS -- circuitBreakers: - thresholds: - - maxRetries: 1024 - commonLbConfig: - localityWeightedLbConfig: {} - connectTimeout: 10s - dnsLookupFamily: V4_ONLY - edsClusterConfig: - edsConfig: - ads: {} - resourceApiVersion: V3 - serviceName: tls-route-dest - lbPolicy: LEAST_REQUEST - name: tls-route-dest - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 - type: EDS - upstreamConnectionOptions: - tcpKeepalive: {} -- circuitBreakers: - thresholds: - - maxRetries: 1024 - commonLbConfig: - localityWeightedLbConfig: {} - connectTimeout: 10s - dnsLookupFamily: V4_ONLY - edsClusterConfig: - edsConfig: - ads: {} - resourceApiVersion: V3 - serviceName: tcp-route-dest - lbPolicy: LEAST_REQUEST - name: tcp-route-dest - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 - type: EDS - upstreamConnectionOptions: - tcpKeepalive: - keepaliveProbes: 10 diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml index 5b4fe89e58c..de95bf555b9 100644 --- a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.endpoints.yaml @@ -22,27 +22,3 @@ loadBalancingWeight: 1 locality: region: second-route-dest/backend/0 -- clusterName: tls-route-dest - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: 1.2.3.4 - portValue: 50000 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: - region: tls-route-dest/backend/0 -- clusterName: tcp-route-dest - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: 1.2.3.4 - portValue: 50000 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: - region: tcp-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml index df60e562394..b4d5ae66f5b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/listener-tcp-keepalive.listeners.yaml @@ -93,20 +93,6 @@ address: 0.0.0.0 portValue: 10082 drainType: MODIFY_ONLY - filterChains: - - filterChainMatch: - serverNames: - - bar.com - filters: - - name: envoy.filters.network.tcp_proxy - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy - cluster: tls-route-dest - statPrefix: passthrough - listenerFilters: - - name: envoy.filters.listener.tls_inspector - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector name: third-listener perConnectionBufferLimitBytes: 32768 socketOptions: @@ -119,13 +105,6 @@ address: 0.0.0.0 portValue: 10083 drainType: MODIFY_ONLY - filterChains: - - filters: - - name: envoy.filters.network.tcp_proxy - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy - cluster: tcp-route-dest - statPrefix: tcp name: fourth-listener perConnectionBufferLimitBytes: 32768 socketOptions: diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.endpoints.yaml index 8d9b5f2277d..4faf21420c2 100644 --- a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.endpoints.yaml @@ -83,7 +83,7 @@ address: socketAddress: address: 5.6.7.8 - portValue: 50001 + portValue: 0 loadBalancingWeight: 1 loadBalancingWeight: 1 locality: diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml index 33e4073d897..44f04718c2a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml @@ -34,5 +34,5 @@ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy cluster: tcp-route-simple-4-dest statPrefix: tcp - name: tcp-route-simple + name: tcp-listener-simple perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml index 4387d9b31e0..fe51488c706 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml @@ -1,19 +1 @@ -- circuitBreakers: - thresholds: - - maxRetries: 1024 - commonLbConfig: - localityWeightedLbConfig: {} - connectTimeout: 10s - dnsLookupFamily: V4_ONLY - edsClusterConfig: - edsConfig: - ads: {} - resourceApiVersion: V3 - serviceName: tcp-route-simple-dest - lbPolicy: LEAST_REQUEST - name: tcp-route-simple-dest - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 - trackClusterStats: - perEndpointStats: true - type: EDS +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml index 7eb06a08f40..fe51488c706 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml @@ -1,18 +1 @@ -- clusterName: tcp-route-simple-dest - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: 1.2.3.4 - portValue: 50000 - loadBalancingWeight: 1 - - endpoint: - address: - socketAddress: - address: 5.6.7.8 - portValue: 50001 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: - region: tcp-route-simple-dest/backend/0 +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml index 7cf2660fa72..f0aad4ff2da 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml @@ -3,12 +3,5 @@ address: 0.0.0.0 portValue: 10080 drainType: MODIFY_ONLY - filterChains: - - filters: - - name: envoy.filters.network.tcp_proxy - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy - cluster: tcp-route-simple-dest - statPrefix: tcp name: tcp-route-enable-endpoint-stats perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml index 0c343d46e19..baf73e96051 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml @@ -19,5 +19,5 @@ - name: envoy.filters.listener.tls_inspector typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector - name: tcp-route-complex + name: tcp-listener-complex perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml index 7fb5696df18..85f1194080a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml @@ -10,5 +10,5 @@ '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy cluster: tcp-route-simple-dest statPrefix: tcp - name: tcp-route-simple + name: tcp-listener-simple perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml index 34bc646e4db..e504c79c007 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.listeners.yaml @@ -23,5 +23,5 @@ sdsConfig: ads: {} resourceApiVersion: V3 - name: tls-terminate + name: tls-listener-terminate perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml index 74cd0effc0a..bcf916a9f54 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml @@ -19,5 +19,5 @@ - name: envoy.filters.listener.tls_inspector typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector - name: tcp-route-weighted-backend + name: tcp-listener-weighted-backend perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index eaef03e97b5..6754feaada5 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -480,39 +480,38 @@ func processTCPListenerXdsTranslation(tCtx *types.ResourceVersionTable, tcpListe } } - if err := addXdsTCPFilterChain(xdsListener, tcpListener, tcpListener.Destination.Name, accesslog, tcpListener.Connection); err != nil { - errs = errors.Join(errs, err) - } - - // 1:1 between IR TCPListener and xDS Cluster - if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: tcpListener.Destination.Name, - settings: tcpListener.Destination.Settings, - loadBalancer: tcpListener.LoadBalancer, - proxyProtocol: tcpListener.ProxyProtocol, - circuitBreaker: tcpListener.CircuitBreaker, - tcpkeepalive: tcpListener.TCPKeepalive, - healthCheck: tcpListener.HealthCheck, - timeout: tcpListener.Timeout, - endpointType: buildEndpointType(tcpListener.Destination.Settings), - metrics: metrics, - }); err != nil && !errors.Is(err, ErrXdsClusterExists) { - errs = errors.Join(errs, err) - } - - if tcpListener.TLS != nil && tcpListener.TLS.Terminate != nil { - for _, s := range tcpListener.TLS.Terminate.Certificates { - secret := buildXdsTLSCertSecret(s) - if err := tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil { - errs = errors.Join(errs, err) - } + for _, route := range tcpListener.Routes { + if err := addXdsCluster(tCtx, &xdsClusterArgs{ + name: route.Destination.Name, + settings: route.Destination.Settings, + loadBalancer: route.LoadBalancer, + proxyProtocol: route.ProxyProtocol, + circuitBreaker: route.CircuitBreaker, + tcpkeepalive: route.TCPKeepalive, + healthCheck: route.HealthCheck, + timeout: route.Timeout, + endpointType: buildEndpointType(route.Destination.Settings), + metrics: metrics, + }); err != nil && !errors.Is(err, ErrXdsClusterExists) { + errs = errors.Join(errs, err) } - if tcpListener.TLS.Terminate.CACertificate != nil { - caSecret := buildXdsTLSCaCertSecret(tcpListener.TLS.Terminate.CACertificate) - if err := tCtx.AddXdsResource(resourcev3.SecretType, caSecret); err != nil { - errs = errors.Join(errs, err) + if route.TLS != nil && route.TLS.Terminate != nil { + for _, s := range route.TLS.Terminate.Certificates { + secret := buildXdsTLSCertSecret(s) + if err := tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil { + errs = errors.Join(errs, err) + } + } + if route.TLS.Terminate.CACertificate != nil { + caSecret := buildXdsTLSCaCertSecret(route.TLS.Terminate.CACertificate) + if err := tCtx.AddXdsResource(resourcev3.SecretType, caSecret); err != nil { + errs = errors.Join(errs, err) + } } } + if err := addXdsTCPFilterChain(xdsListener, route, route.Destination.Name, accesslog, tcpListener.Connection); err != nil { + errs = errors.Join(errs, err) + } } } return errs From 4c52f100cf8748120652f1c5fc452bed4b7178ae Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Tue, 7 May 2024 08:21:15 +0800 Subject: [PATCH 07/17] docs(zh): translate contributing doc into Chinese (#3308) * docs(zh): translate contributing doc into Chinese Signed-off-by: Wilson Wu * Update site/content/zh/contributions/CONTRIBUTING.md Co-authored-by: sh2 Signed-off-by: Wilson Wu --------- Signed-off-by: Wilson Wu Co-authored-by: zirain Co-authored-by: sh2 --- site/content/zh/contributions/CONTRIBUTING.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 site/content/zh/contributions/CONTRIBUTING.md diff --git a/site/content/zh/contributions/CONTRIBUTING.md b/site/content/zh/contributions/CONTRIBUTING.md new file mode 100644 index 00000000000..b956084d7dc --- /dev/null +++ b/site/content/zh/contributions/CONTRIBUTING.md @@ -0,0 +1,167 @@ +--- +title: "贡献" +description: "本节介绍如何为 Envoy Gateway 做出贡献。" +weight: 3 +--- + +我们欢迎来自社区的贡献。请仔细查看[项目目标](/zh/about)和以下指南,以简化您的贡献流程。 + +## 沟通 {#communication} + +* 在开始开发主要功能之前,请通过 GitHub 或 Slack 联系我们。 + 我们将确保没有其他人正在处理此问题,并要求您创建 GitHub Issue。 +* “主要功能”定义为超过 100 个 LOC 的任意更改(不包括测试), + 或更改任何面向用户的行为。我们将使用 GitHub Issue 来讨论该功能并达成一致。 + 这是为了防止浪费您和我们的时间。主要功能的 GitHub 审核流程也很重要, + 以便[与提交权限的干系者](../codeowners)可以就设计达成一致。 + 如果适合编写设计文档,则该文档必须托管在 GitHub Issue 中,或者托管在公开可读的位置并链接到 Issue 中。 +* 小补丁和错误修复不需要事先沟通。 + +## 包容性 {#inclusivity} + +Envoy Gateway 社区的一个明确的目标是完全包容性。 +因此,所有 PR 的所有代码、API 和文档都必须遵守以下准则: + +* 不允许使用以下单词和短语: + * **Whitelist**:使用 allowlist 代替。 + * **Blacklist**:使用 denylist 或 blocklist 代替。 + * **Master**:使用 primary 代替。 + * **Slave**:使用 secondary 或 replica 代替。 +* 文档应该以包容的风格编写。 + [Google 开发人员文档](https://developers.google.com/style/inclusive-documentation)包含有关此主题的出色参考。 +* 上述政策并非最终政策,未来可能会随着行业最佳实践的发展而进行修改。 + 维护人员在代码审查期间可能会提供有关此主题的其他评论。 + +## 提交一个 PR {#submitting-a-pr} + +* Fork 该仓库。 +* 修改。 +* 对每次提交都进行 DCO 签署。这可以通过 `git commit -s` 来完成。 +* 提交您的 PR。 +* 将为您自动运行测试。 +* 我们**不会**合并任何未通过测试的 PR。 +* PR 预计对添加的代码具有 100% 的测试覆盖率。这可以通过覆盖范围构建来验证。 + 如果您的 PR 由于某种原因无法被 100% 覆盖,请在创建时明确解释原因。 +* 任何更改面向用户行为的 PR **必须**在仓库中的 + [docs](https://github.com/envoyproxy/gateway/tree/main/site) 文件夹中具有关联的文档以及[变更日志](./RELEASING)。 +* 所有代码注释和文档均应具有正确的英语语法和标点符号。 + 如果您的英语不流利(或者是一个糟糕的写作者 ;-)),请告诉我们,我们会尽力为您寻求帮助,但不能保证。 +* 您的 PR 标题应该是描述性的,通常以包含子系统名称的类型开头, + 如有必要,带有 `()`,摘要后跟冒号。格式例子如下: + * "docs: fix grammar error" + * "feat(translator): add new feature" + * "fix: fix xx bug" + * "chore: change ci & build tools etc" +* 当您的 PR 被合并时,您的 PR 提交消息将用作其提交消息。 + 如果您的 PR 在审核期间出现分歧,您应该更新此字段。 +* 您的 PR 描述应详细说明 PR 的用途。如果它修复了现有问题,则应以“Fixes #XXX”结尾。 +* 如果您的 PR 是共同创作的或基于其他贡献者的早期 PR, + 请注明 `Co-authored-by: name `。 + 有关更多详细信息,请参阅 GitHub 的[多作者指南](https://docs.github.com/zh/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors)。 +* 当所有测试都通过并且满足本文所述的所有其他条件时,将指派维护人员审查并合并 PR。 +* 一旦您提交了 PR,**请不要对其进行 Rebase**。 + 如果后续提交是新提交和/或合并,则检查起来要容易得多。我们会压缩并合并,因此 PR 中的提交数量并不重要。 +* 我们预计,一旦 PR 被开启,它将被积极处理,直到它被合并或关闭。 + 我们保留关闭没有取得进展的 PR 的权利。这通常定义为 7 天内没有变化。 + 显然,由于缺乏活跃度而被关闭的 PR 可以稍后重新开启。 + 关闭过时的 PR 有助于我们掌控当前正在进行的所有工作。 + +## 维护者 PR 审查策略 {#maintainer-pr-review-policy} + +* 请参阅 [CODEOWNERS.md](./codeowners) 了解当前的维护者列表。 +* 需要由代表与 PR 所有者不同的隶属关系的维护者来审查和批准 PR。 +* 当项目成熟时,预计 PR 涉及代码的“领域专家”应该对 PR 进行审查。 + 此人不需要提交权限,只需要领域知识。 +* 对于仅更新文档或评论, + 或对测试和工具进行细微更改(其中细微更改由相关维护者决定)的 PR,可以免除上述规则。 +* 如果有关于谁应该审查 PR 的问题,请在 Slack 中讨论。 +* 欢迎任何人审查他们想要审查的任何 PR,无论他们是否是维护者。 +* 如果 PR 在审核期间发生重大变化,请确保更新 PR 标题、提交消息和描述。 +* 合并前请**清理标题和正文**。默认情况下,GitHub 使用原始标题填充压缩合并标题, + 并使用 PR 中的每个单独提交填充提交正文。进行合并的维护者应确保标题遵循上述准则, + 并应使用 PR 的原始提交消息覆盖正文(如有必要,请将其清理),同时保留 PR 作者的最终 DCO 签名。 + +## 决策 {#decision-making} + +这是一个新的、复杂的项目,我们需要很快做出很多决定。 +为此,我们确定了做出(可能有争议的)决定的流程: + +* 对于需要记录的决策,我们会创建一个 Issue。 +* 在该 Issue 中,我们讨论想法,然后维护者可以在评论中要求投票。 +* 维护者可以通过在另外的评论中做出反馈或回复来对该评论进行具有约束力的投票。 +* 欢迎非维护者社区成员通过这两种方法进行不具约束力的投票。 +* 投票将通过简单多数达成决定。 +* 如果出现僵局,这个问题将被转移到 Steering 处理。 + +## DCO:签署您的工作 {#dco-sign-your-work} + +签署是补丁说明末尾的一行简单内容,它证明您编写了该补丁或有权将其作为开源补丁传递。 +规则非常简单:如果您可以证明以下内容(来自 [developercertificate.org](https://developercertificate.org/)): + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +然后您只需在每个 git 提交消息中使用您的真实姓名(抱歉,不支持化名或匿名贡献)添加一行: + + Signed-off-by: Joe Smith + +您可以在通过 `git commit -s` 创建 git 提交时添加签署。 + +如果您希望这是自动的,您可以设置一些别名: + +```bash +git config --add alias.amend "commit -s --amend" +git config --add alias.c "commit -s" +``` + +## 修复 DCO {#fixing-dco} + +如果您的 PR 未通过 DCO 检查,则有必要修复 PR 中的整个提交历史记录。 +最佳实践是 [squash](https://docs.github.com/zh/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) +将提交历史记录合并到单个提交中,如上所述附加 DCO 签名, +然后[强制推送](https://git-scm.com/docs/git-push/zh_HANS-CN#git-push---force)。 +例如,如果您的历史记录中有 2 次提交: + +```bash +git rebase -i HEAD^^ +(interactive squash + DCO append) +git push origin -f +``` + +请注意,一般来说,以这种方式重写历史记录会阻碍审核过程,并且只能在纠正 DCO 错误时才这样做。 From d048a9f1b78244bd745557caa32ad90dcf2dca97 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Tue, 7 May 2024 00:10:15 -0700 Subject: [PATCH 08/17] feat: support custom HTTP filter ordering (#3273) * Support custom HTTP filter ordering. Signed-off-by: huabing zhao * address comments Signed-off-by: huabing zhao * address comments Signed-off-by: huabing zhao * add comments Signed-off-by: huabing zhao * add comments Signed-off-by: huabing zhao * minor wording Signed-off-by: huabing zhao --------- Signed-off-by: huabing zhao --- api/v1alpha1/envoyextensionypolicy_types.go | 2 + api/v1alpha1/envoyproxy_types.go | 3 +- .../validation/envoyproxy_validate.go | 41 ++ .../validation/envoyproxy_validate_test.go | 48 +++ ....envoyproxy.io_envoyextensionpolicies.yaml | 2 + .../gateway.envoyproxy.io_envoyproxies.yaml | 5 +- go.mod | 1 + go.sum | 2 + internal/cmd/egctl/translate.go | 3 + .../testdata/custom-filter-order.in.yaml | 130 ++++++ .../testdata/custom-filter-order.out.yaml | 307 ++++++++++++++ internal/gatewayapi/translator.go | 9 + internal/ir/xds.go | 2 + internal/ir/zz_generated.deepcopy.go | 7 + internal/xds/translator/httpfilters.go | 117 +++++- internal/xds/translator/httpfilters_test.go | 379 +++++++++++++++++- internal/xds/translator/runner/runner.go | 4 +- .../in/xds-ir/custom-filter-order.yaml | 84 ++++ .../xds-ir/custom-filter-order.clusters.yaml | 99 +++++ .../xds-ir/custom-filter-order.endpoints.yaml | 1 + .../xds-ir/custom-filter-order.listeners.yaml | 125 ++++++ .../xds-ir/custom-filter-order.routes.yaml | 35 ++ internal/xds/translator/translator.go | 4 + internal/xds/translator/translator_test.go | 1 + site/content/en/latest/api/extension_types.md | 2 +- 25 files changed, 1380 insertions(+), 33 deletions(-) create mode 100644 internal/gatewayapi/testdata/custom-filter-order.in.yaml create mode 100755 internal/gatewayapi/testdata/custom-filter-order.out.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/custom-filter-order.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/custom-filter-order.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml diff --git a/api/v1alpha1/envoyextensionypolicy_types.go b/api/v1alpha1/envoyextensionypolicy_types.go index 76e863ce00d..81015567934 100644 --- a/api/v1alpha1/envoyextensionypolicy_types.go +++ b/api/v1alpha1/envoyextensionypolicy_types.go @@ -48,12 +48,14 @@ type EnvoyExtensionPolicySpec struct { // Order matters, as the extensions will be loaded in the order they are // defined in this list. // + // +kubebuilder:validation:MaxItems=16 // +optional Wasm []Wasm `json:"wasm,omitempty"` // ExtProc is an ordered list of external processing filters // that should added to the envoy filter chain // + // +kubebuilder:validation:MaxItems=16 // +optional ExtProc []ExtProc `json:"extProc,omitempty"` } diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go index bcec1ff5837..efd04149dbe 100644 --- a/api/v1alpha1/envoyproxy_types.go +++ b/api/v1alpha1/envoyproxy_types.go @@ -89,6 +89,7 @@ type EnvoyProxySpec struct { Shutdown *ShutdownConfig `json:"shutdown,omitempty"` // FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. + // The FilterPosition in the list will be applied in the order they are defined. // If unspecified, the default filter order is applied. // Default filter order is: // @@ -138,7 +139,7 @@ type BackendTLSConfig struct { // +kubebuilder:validation:XValidation:rule="(has(self.before) && !has(self.after)) || (!has(self.before) && has(self.after))",message="only one of before or after can be specified" type FilterPosition struct { // Name of the filter. - Name EnvoyFilter `json:"filter"` + Name EnvoyFilter `json:"name"` // Before defines the filter that should come before the filter. // Only one of Before or After must be set. diff --git a/api/v1alpha1/validation/envoyproxy_validate.go b/api/v1alpha1/validation/envoyproxy_validate.go index 0e4f7e22221..9c8eee5731a 100644 --- a/api/v1alpha1/validation/envoyproxy_validate.go +++ b/api/v1alpha1/validation/envoyproxy_validate.go @@ -11,6 +11,7 @@ import ( "net" "net/netip" + "github.com/dominikbraun/graph" bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3" clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" "github.com/google/go-cmp/cmp" @@ -62,6 +63,13 @@ func validateEnvoyProxySpec(spec *egv1a1.EnvoyProxySpec) error { errs = append(errs, validateProxyTelemetryErrs...) } + // validate filter order + if spec != nil && spec.FilterOrder != nil { + if err := validateFilterOrder(spec.FilterOrder); err != nil { + errs = append(errs, err) + } + } + return utilerrors.NewAggregate(errs) } @@ -269,3 +277,36 @@ func validateProxyAccessLog(accessLog *egv1a1.ProxyAccessLog) []error { return errs } + +func validateFilterOrder(filterOrder []egv1a1.FilterPosition) error { + g := graph.New(graph.StringHash, graph.Directed(), graph.PreventCycles()) + + for _, filter := range filterOrder { + // Ignore the error since the same filter can be added multiple times + _ = g.AddVertex(string(filter.Name)) + if filter.Before != nil { + _ = g.AddVertex(string(*filter.Before)) + } + if filter.After != nil { + _ = g.AddVertex(string(*filter.After)) + } + } + + for _, filter := range filterOrder { + var from, to string + if filter.Before != nil { + from = string(filter.Name) + to = string(*filter.Before) + } else { + from = string(*filter.After) + to = string(filter.Name) + } + if err := g.AddEdge(from, to); err != nil { + if errors.Is(err, graph.ErrEdgeCreatesCycle) { + return fmt.Errorf("there is a cycle in the filter order: %s -> %s", from, to) + } + } + } + + return nil +} diff --git a/api/v1alpha1/validation/envoyproxy_validate_test.go b/api/v1alpha1/validation/envoyproxy_validate_test.go index 6619888bdc8..6e1321eeee7 100644 --- a/api/v1alpha1/validation/envoyproxy_validate_test.go +++ b/api/v1alpha1/validation/envoyproxy_validate_test.go @@ -613,6 +613,54 @@ func TestValidateEnvoyProxy(t *testing.T) { }, expected: true, }, + { + name: "valid filter order", + proxy: &egv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "test", + }, + Spec: egv1a1.EnvoyProxySpec{ + FilterOrder: []egv1a1.FilterPosition{ + { + Name: egv1a1.EnvoyFilterOAuth2, + Before: ptr.To(egv1a1.EnvoyFilterJWTAuthn), + }, + { + Name: egv1a1.EnvoyFilterExtProc, + After: ptr.To(egv1a1.EnvoyFilterJWTAuthn), + }, + }, + }, + }, + expected: true, + }, + { + name: "invalid filter order with circular dependency", + proxy: &egv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "test", + }, + Spec: egv1a1.EnvoyProxySpec{ + FilterOrder: []egv1a1.FilterPosition{ + { + Name: egv1a1.EnvoyFilterOAuth2, + Before: ptr.To(egv1a1.EnvoyFilterJWTAuthn), + }, + { + Name: egv1a1.EnvoyFilterJWTAuthn, + Before: ptr.To(egv1a1.EnvoyFilterExtProc), + }, + { + Name: egv1a1.EnvoyFilterExtProc, + Before: ptr.To(egv1a1.EnvoyFilterOAuth2), + }, + }, + }, + }, + expected: false, + }, } for i := range testCases { diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index f8c0135411b..6e8c04b96b5 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -189,6 +189,7 @@ spec: required: - backendRefs type: object + maxItems: 16 type: array targetRef: description: |- @@ -398,6 +399,7 @@ spec: - code - name type: object + maxItems: 16 type: array required: - targetRef diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml index 79328d5b80d..0282aed70d0 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -224,6 +224,7 @@ spec: filterOrder: description: |- FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. + The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is: @@ -295,7 +296,7 @@ spec: - envoy.filters.http.wasm - envoy.filters.http.ext_proc type: string - filter: + name: description: Name of the filter. enum: - envoy.filters.http.cors @@ -310,7 +311,7 @@ spec: - envoy.filters.http.ext_proc type: string required: - - filter + - name type: object x-kubernetes-validations: - message: one of before or after must be specified diff --git a/go.mod b/go.mod index 3a7ed2669f3..114fcdce2a3 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b github.com/davecgh/go-spew v1.1.1 + github.com/dominikbraun/graph v0.23.0 github.com/envoyproxy/go-control-plane v0.12.1-0.20240425230418-212e93054f1a github.com/envoyproxy/ratelimit v1.4.1-0.20230427142404-e2a87f41d3a7 github.com/evanphx/json-patch/v5 v5.9.0 diff --git a/go.sum b/go.sum index 24a61ef34a5..185c5f15525 100644 --- a/go.sum +++ b/go.sum @@ -161,6 +161,8 @@ github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arX github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= +github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go index 9d21b20105e..056dc47ac54 100644 --- a/internal/cmd/egctl/translate.go +++ b/internal/cmd/egctl/translate.go @@ -362,6 +362,9 @@ func translateGatewayAPIToXds(dnsDomain string, resourceType string, resources * ServiceURL: ratelimit.GetServiceURL("envoy-gateway", dnsDomain), }, } + if resources.EnvoyProxy != nil { + xTranslator.FilterOrder = resources.EnvoyProxy.Spec.FilterOrder + } xRes, err := xTranslator.Translate(val) if err != nil { return nil, fmt.Errorf("failed to translate xds ir for key %s value %+v, error:%w", key, val, err) diff --git a/internal/gatewayapi/testdata/custom-filter-order.in.yaml b/internal/gatewayapi/testdata/custom-filter-order.in.yaml new file mode 100644 index 00000000000..d0a4bedc2e1 --- /dev/null +++ b/internal/gatewayapi/testdata/custom-filter-order.in.yaml @@ -0,0 +1,130 @@ +secrets: + - apiVersion: v1 + kind: Secret + metadata: + namespace: envoy-gateway + name: users-secret1 + data: + .htpasswd: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" +envoyproxy: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + name: custom-proxy-config + namespace: envoy-gateway-system + spec: + filterOrder: + - name: envoy.filters.http.wasm + before: envoy.filters.http.jwt_authn + - name: envoy.filters.http.cors + after: envoy.filters.http.basic_authn +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: envoy-gateway + name: httproute-1 + spec: + hostnames: + - www.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 +securityPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + cors: + allowOrigins: + - "https://*.test.com:8080" + - "https://www.test.org:8080" + allowMethods: + - GET + - POST + basicAuth: + users: + name: "users-secret1" + jwt: + providers: + - name: example1 + issuer: https://one.example.com + audiences: + - one.foo.com + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + claimToHeaders: + - header: one-route-example-key + claim: claim1 + - name: example2 + issuer: http://two.example.com + audiences: + - two.foo.com + remoteJWKS: + uri: http://two.example.com/jwt/public-key/jwks.json + claimToHeaders: + - header: two-route-example-key + claim: claim2 +envoyextensionpolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway # This policy should attach httproute-2 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + wasm: + - name: wasm-filter-1 + code: + type: HTTP + http: + url: https://www.example.com/wasm-filter-1.wasm + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + - name: wasm-filter-2 + code: + type: HTTP + http: + url: https://www.example.com/wasm-filter-2.wasm + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + config: + parameter1: value1 + parameter2: value2 diff --git a/internal/gatewayapi/testdata/custom-filter-order.out.yaml b/internal/gatewayapi/testdata/custom-filter-order.out.yaml new file mode 100755 index 00000000000..eea919c09fe --- /dev/null +++ b/internal/gatewayapi/testdata/custom-filter-order.out.yaml @@ -0,0 +1,307 @@ +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + wasm: + - code: + http: + url: https://www.example.com/wasm-filter-1.wasm + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + type: HTTP + config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + name: wasm-filter-1 + - code: + http: + url: https://www.example.com/wasm-filter-2.wasm + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + type: HTTP + config: + parameter1: value1 + parameter2: value2 + name: wasm-filter-2 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: envoy-gateway + spec: + hostnames: + - www.example.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Service envoy-gateway/service-1 not found + reason: BackendNotFound + status: "False" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: custom-proxy-config + namespace: envoy-gateway-system + spec: + filterOrder: + - before: envoy.filters.http.jwt_authn + name: envoy.filters.http.wasm + - after: envoy.filters.http.basic_authn + name: envoy.filters.http.cors + logging: {} + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + spec: + basicAuth: + users: + group: null + kind: null + name: users-secret1 + cors: + allowMethods: + - GET + - POST + allowOrigins: + - https://*.test.com:8080 + - https://www.test.org:8080 + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: http://two.example.com + name: example2 + remoteJWKS: + uri: http://two.example.com/jwt/public-key/jwks.json + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + filterOrder: + - before: envoy.filters.http.jwt_authn + name: envoy.filters.http.wasm + - after: envoy.filters.http.basic_authn + name: envoy.filters.http.cors + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 1 + valid: 0 + directResponse: + statusCode: 500 + hostname: www.example.com + isHTTP2: false + name: httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + security: + basicAuth: + name: securitypolicy/envoy-gateway/policy-for-gateway + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + cors: + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: https://.*\.test\.com:8080 + - distinct: false + exact: https://www.test.org:8080 + name: "" + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: http://two.example.com + name: example2 + remoteJWKS: + uri: http://two.example.com/jwt/public-key/jwks.json + wasm: + - config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + failOpen: false + httpWasmCode: + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + url: https://www.example.com/wasm-filter-1.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + wasmName: wasm-filter-1 + - config: + parameter1: value1 + parameter2: value2 + failOpen: false + httpWasmCode: + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + url: https://www.example.com/wasm-filter-2.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + wasmName: wasm-filter-2 diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 1827d962d57..c0764e583ab 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -217,6 +217,15 @@ func (t *Translator) Translate(resources *Resources) *TranslateResult { // Sort xdsIR based on the Gateway API spec sortXdsIRMap(xdsIR) + // Set custom filter order if EnvoyProxy is set + // The custom filter order will be applied when generating the HTTP filter chain. + if resources.EnvoyProxy != nil { + for _, gateway := range gateways { + irKey := t.getIRKey(gateway.Gateway) + xdsIR[irKey].FilterOrder = resources.EnvoyProxy.Spec.FilterOrder + } + } + return newTranslateResult(gateways, httpRoutes, grpcRoutes, tlsRoutes, tcpRoutes, udpRoutes, clientTrafficPolicies, backendTrafficPolicies, securityPolicies, resources.BackendTLSPolicies, envoyExtensionPolicies, diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 9f17d04fcf0..02f3f448aee 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -84,6 +84,8 @@ type Xds struct { UDP []*UDPListener `json:"udp,omitempty" yaml:"udp,omitempty"` // EnvoyPatchPolicies is the intermediate representation of the EnvoyPatchPolicy resource EnvoyPatchPolicies []*EnvoyPatchPolicy `json:"envoyPatchPolicies,omitempty" yaml:"envoyPatchPolicies,omitempty"` + // FilterOrder holds the custom order of the HTTP filters + FilterOrder []egv1a1.FilterPosition `json:"filterOrder,omitempty" yaml:"filterOrder,omitempty"` } // Equal implements the Comparable interface used by watchable.DeepEqual to skip unnecessary updates. diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 26c713f28bc..f400de7019c 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2585,6 +2585,13 @@ func (in *Xds) DeepCopyInto(out *Xds) { } } } + if in.FilterOrder != nil { + in, out := &in.FilterOrder, &out.FilterOrder + *out = make([]v1alpha1.FilterPosition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Xds. diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index 0b8f6dbeff9..5738d621eb8 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -6,7 +6,10 @@ package translator import ( + "container/list" + "fmt" "sort" + "strconv" "strings" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" @@ -14,6 +17,7 @@ import ( "github.com/envoyproxy/go-control-plane/pkg/wellknown" "k8s.io/utils/ptr" + "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/xds/filters" "github.com/envoyproxy/gateway/internal/xds/types" @@ -91,28 +95,28 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { // When the fault filter is configured to be at the first, the computation of // the remaining filters is skipped when rejected early switch { - case filter.Name == wellknown.Fault: + case isFilterType(filter, wellknown.Fault): order = 1 - case filter.Name == wellknown.CORS: + case isFilterType(filter, wellknown.CORS): order = 2 case isFilterType(filter, extAuthFilter): order = 3 - case filter.Name == basicAuthFilter: + case isFilterType(filter, basicAuthFilter): order = 4 case isFilterType(filter, oauth2Filter): order = 5 - case filter.Name == jwtAuthn: + case isFilterType(filter, jwtAuthn): order = 6 case isFilterType(filter, extProcFilter): - order = 7 + order = 7 + mustGetFilterIndex(filter.Name) case isFilterType(filter, wasmFilter): - order = 8 - case filter.Name == localRateLimitFilter: - order = 9 - case filter.Name == wellknown.HTTPRateLimit: - order = 10 - case filter.Name == wellknown.Router: - order = 100 + order = 100 + mustGetFilterIndex(filter.Name) + case isFilterType(filter, localRateLimitFilter): + order = 201 + case isFilterType(filter, wellknown.HTTPRateLimit): + order = 202 + case isFilterType(filter, wellknown.Router): + order = 203 } return &OrderedHTTPFilter{ @@ -140,16 +144,87 @@ func (o OrderedHTTPFilters) Swap(i, j int) { // For example, the cors filter should be put at the first to avoid unnecessary // processing of other filters for unauthorized cross-region access. // The router filter must be the last one since it's a terminal filter. -func sortHTTPFilters(filters []*hcmv3.HttpFilter) []*hcmv3.HttpFilter { +func sortHTTPFilters(filters []*hcmv3.HttpFilter, filterOrder []v1alpha1.FilterPosition) []*hcmv3.HttpFilter { + // Sort the filters in the default order. orderedFilters := make(OrderedHTTPFilters, len(filters)) for i := 0; i < len(filters); i++ { orderedFilters[i] = newOrderedHTTPFilter(filters[i]) } sort.Sort(orderedFilters) - for i := 0; i < len(filters); i++ { - filters[i] = orderedFilters[i].filter + // Use a linked list to sort the filters in the custom order. + l := list.New() + for i := 0; i < len(orderedFilters); i++ { + l.PushBack(orderedFilters[i].filter) } + + // Sort the filters in the custom order. + for i := 0; i < len(filterOrder); i++ { + var ( + // The filter name in the filterOrder is the filter type. + // For example, "envoy.filters.http.oauth2". + filterType = string(filterOrder[i].Name) + // currentFilters holds all the filters of the specified filter type + // in the custom FilterOrder that we are currently processing. + // + // We need an array to store the filters because there may be multiple + // filters of the same filter type for a specific HTTPRoute. + // For example, there may be multiple wasm filters or extProc filters, for + // different custom extensions. + currentFilters []*list.Element + ) + + // Find all the filters for the current filter type in the custom FilterOrder. + // + // The real filter name is a generated name prefixed with the filter type, + // for example,"envoy.filters.http.oauth2/securitypolicy/default/policy-for-http-route-1". + for element := l.Front(); element != nil; element = element.Next() { + if isFilterType(element.Value.(*hcmv3.HttpFilter), filterType) { + currentFilters = append(currentFilters, element) + } + } + + // Skip if there are no filters found for the filter type in a custom order. + if len(currentFilters) == 0 { + continue + } + + switch { + // Move all the current filters before the first filter of the filter type + // specified in the `FilterOrder.Before` field. + case filterOrder[i].Before != nil: + for element := l.Front(); element != nil; element = element.Next() { + if isFilterType(element.Value.(*hcmv3.HttpFilter), string(*filterOrder[i].Before)) { + for _, filter := range currentFilters { + l.MoveBefore(filter, element) + } + break + } + } + // Move all the current filters after the last filter of the filter type + // specified in the `FilterOrder.After` field. + case filterOrder[i].After != nil: + var afterFilter *list.Element + for element := l.Front(); element != nil; element = element.Next() { + if isFilterType(element.Value.(*hcmv3.HttpFilter), string(*filterOrder[i].After)) { + afterFilter = element + } + } + if afterFilter != nil { + for i := range currentFilters { + l.MoveAfter(currentFilters[len(currentFilters)-1-i], afterFilter) + } + } + } + } + + // Collect the sorted filters. + i := 0 + for element := l.Front(); element != nil; element = element.Next() { + filters[i] = element.Value.(*hcmv3.HttpFilter) + i++ + } + return filters } @@ -190,7 +265,7 @@ func (t *Translator) patchHCMWithFilters( } // Sort the filters in the correct order. - mgr.HttpFilters = sortHTTPFilters(mgr.HttpFilters) + mgr.HttpFilters = sortHTTPFilters(mgr.HttpFilters, t.FilterOrder) return nil } @@ -223,6 +298,16 @@ func isFilterType(filter *hcmv3.HttpFilter, filterType string) bool { return strings.HasPrefix(filter.Name, filterType) } +// mustGetFilterIndex returns the index of the filter in its filter type. +func mustGetFilterIndex(filterName string) int { + a := strings.Split(filterName, "/") + index, err := strconv.Atoi(a[len(a)-1]) + if err != nil { + panic(fmt.Errorf("cannot get filter index from %s :%w", filterName, err)) + } + return index +} + // patchResources adds all the other needed resources referenced by this // filter to the resource version table. // for example: diff --git a/internal/xds/translator/httpfilters_test.go b/internal/xds/translator/httpfilters_test.go index 90773ce6a36..2f277aa969a 100644 --- a/internal/xds/translator/httpfilters_test.go +++ b/internal/xds/translator/httpfilters_test.go @@ -11,13 +11,17 @@ import ( hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" "github.com/stretchr/testify/assert" + "k8s.io/utils/ptr" + + "github.com/envoyproxy/gateway/api/v1alpha1" ) func Test_sortHTTPFilters(t *testing.T) { tests := []struct { - name string - filters []*hcmv3.HttpFilter - want []*hcmv3.HttpFilter + name string + filters []*hcmv3.HttpFilter + filterOrder []v1alpha1.FilterPosition + want []*hcmv3.HttpFilter }{ { name: "sort filters", @@ -25,33 +29,384 @@ func Test_sortHTTPFilters(t *testing.T) { httpFilterForTest(wellknown.Router), httpFilterForTest(wellknown.CORS), httpFilterForTest(jwtAuthn), - httpFilterForTest(oauth2Filter + "-route1"), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Fault), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(jwtAuthn), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(wellknown.Router), + }, + }, + { + name: "custom filter order-singleton filter", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), httpFilterForTest(wellknown.Fault), - httpFilterForTest(extAuthFilter + "-route1"), - httpFilterForTest(wasmFilter + "-route1"), - httpFilterForTest(extProcFilter + "-route1"), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterFault, + After: ptr.To(v1alpha1.EnvoyFilterCORS), + }, + { + Name: v1alpha1.EnvoyFilterRateLimit, + Before: ptr.To(v1alpha1.EnvoyFilterJWTAuthn), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.CORS), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(jwtAuthn), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wellknown.Router), + }, + }, + { + name: "custom filter order-singleton-before-multipleton", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterRateLimit, + Before: ptr.To(v1alpha1.EnvoyFilterWasm), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Fault), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(jwtAuthn), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wellknown.Router), + }, + }, + { + name: "custom filter order-singleton-after-multipleton", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterJWTAuthn, + After: ptr.To(v1alpha1.EnvoyFilterWasm), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Fault), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(jwtAuthn), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(wellknown.Router), + }, + }, + { + name: "custom filter order-multipleton-before-singleton", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterWasm, + Before: ptr.To(v1alpha1.EnvoyFilterJWTAuthn), + }, }, want: []*hcmv3.HttpFilter{ httpFilterForTest(wellknown.Fault), httpFilterForTest(wellknown.CORS), - httpFilterForTest(extAuthFilter + "-route1"), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), httpFilterForTest(basicAuthFilter), - httpFilterForTest(oauth2Filter + "-route1"), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), httpFilterForTest(jwtAuthn), - httpFilterForTest(extProcFilter + "-route1"), - httpFilterForTest(wasmFilter + "-route1"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), httpFilterForTest(localRateLimitFilter), httpFilterForTest(wellknown.HTTPRateLimit), httpFilterForTest(wellknown.Router), }, }, + { + name: "custom filter order-multipleton-after-singleton", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterWasm, + After: ptr.To(v1alpha1.EnvoyFilterRateLimit), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Fault), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(jwtAuthn), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.Router), + }, + }, + { + name: "custom filter order-multipleton-before-multipleton", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterWasm, + Before: ptr.To(v1alpha1.EnvoyFilterExtProc), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Fault), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(jwtAuthn), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(wellknown.Router), + }, + }, + { + name: "custom filter order-multipleton-after-multipleton", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterExtProc, + After: ptr.To(v1alpha1.EnvoyFilterWasm), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Fault), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(jwtAuthn), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(wellknown.Router), + }, + }, + { + name: "custom filter order-complex-ordering", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Router), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(jwtAuthn), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wellknown.Fault), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + }, + filterOrder: []v1alpha1.FilterPosition{ + { + Name: v1alpha1.EnvoyFilterLocalRateLimit, + Before: ptr.To(v1alpha1.EnvoyFilterJWTAuthn), + }, + { + Name: v1alpha1.EnvoyFilterLocalRateLimit, + After: ptr.To(v1alpha1.EnvoyFilterCORS), + }, + { + Name: v1alpha1.EnvoyFilterWasm, + Before: ptr.To(v1alpha1.EnvoyFilterOAuth2), + }, + { + Name: v1alpha1.EnvoyFilterExtProc, + Before: ptr.To(v1alpha1.EnvoyFilterWasm), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(wellknown.Fault), + httpFilterForTest(wellknown.CORS), + httpFilterForTest(localRateLimitFilter), + httpFilterForTest(extAuthFilter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(basicAuthFilter), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"), + httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"), + httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(jwtAuthn), + httpFilterForTest(wellknown.HTTPRateLimit), + httpFilterForTest(wellknown.Router), + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, sortHTTPFilters(tt.filters), "sortHTTPFilters(%v)", tt.filters) + result := sortHTTPFilters(tt.filters, tt.filterOrder) + assert.Equalf(t, tt.want, result, "sortHTTPFilters(%v)", tt.filters) }) } } diff --git a/internal/xds/translator/runner/runner.go b/internal/xds/translator/runner/runner.go index 573afc38228..6e2c8ba7880 100644 --- a/internal/xds/translator/runner/runner.go +++ b/internal/xds/translator/runner/runner.go @@ -60,7 +60,9 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { r.Xds.Delete(key) } else { // Translate to xds resources - t := &translator.Translator{} + t := &translator.Translator{ + FilterOrder: val.FilterOrder, + } // Set the extension manager if an extension is loaded if r.ExtensionManager != nil { diff --git a/internal/xds/translator/testdata/in/xds-ir/custom-filter-order.yaml b/internal/xds/translator/testdata/in/xds-ir/custom-filter-order.yaml new file mode 100644 index 00000000000..8dcefc9c880 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/custom-filter-order.yaml @@ -0,0 +1,84 @@ +filterOrder: +- before: envoy.filters.http.jwt_authn + name: envoy.filters.http.wasm +- after: envoy.filters.http.basic_authn + name: envoy.filters.http.cors +http: +- address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 1 + valid: 0 + directResponse: + statusCode: 500 + hostname: www.example.com + isHTTP2: false + name: httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + security: + basicAuth: + name: securitypolicy/envoy-gateway/policy-for-gateway + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + cors: + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: https://.*\.test\.com:8080 + - distinct: false + exact: https://www.test.org:8080 + name: "" + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: http://two.example.com + name: example2 + remoteJWKS: + uri: http://two.example.com/jwt/public-key/jwks.json + wasm: + - config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + failOpen: false + httpWasmCode: + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + url: https://www.example.com/wasm-filter-1.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + wasmName: wasm-filter-1 + - config: + parameter1: value1 + parameter2: value2 + failOpen: false + httpWasmCode: + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + url: https://www.example.com/wasm-filter-2.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + wasmName: wasm-filter-2 diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml new file mode 100644 index 00000000000..ae5259499fd --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.clusters.yaml @@ -0,0 +1,99 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: one_example_com_443 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: one.example.com + portValue: 443 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: one_example_com_443/backend/0 + name: one_example_com_443 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + validationContext: + trustedCa: + filename: /etc/ssl/certs/ca-certificates.crt + sni: one.example.com + type: STRICT_DNS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: two_example_com_80 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: two.example.com + portValue: 80 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: two_example_com_80/backend/0 + name: two_example_com_80 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + type: STRICT_DNS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: www_example_com_443 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: www.example.com + portValue: 443 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: www_example_com_443/backend/0 + name: www_example_com_443 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + validationContext: + trustedCa: + filename: /etc/ssl/certs/ca-certificates.crt + sni: www.example.com + type: STRICT_DNS diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.endpoints.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.endpoints.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml new file mode 100644 index 00000000000..750690af34b --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml @@ -0,0 +1,125 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.cors + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors + - disabled: true + name: envoy.filters.http.basic_auth + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth + users: + inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + - disabled: true + name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":{"key1":"value1","key2":"value2"},"parameter2":"value3"}' + name: wasm-filter-1 + vmConfig: + code: + remote: + httpUri: + cluster: www_example_com_443 + timeout: 10s + uri: https://www.example.com/wasm-filter-1.wasm + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + - disabled: true + name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":"value1","parameter2":"value2"}' + name: wasm-filter-2 + vmConfig: + code: + remote: + httpUri: + cluster: www_example_com_443 + timeout: 10s + uri: https://www.example.com/wasm-filter-2.wasm + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + - name: envoy.filters.http.jwt_authn + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication + providers: + httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com/example1: + audiences: + - one.foo.com + claimToHeaders: + - claimName: claim1 + headerName: one-route-example-key + forward: true + issuer: https://one.example.com + payloadInMetadata: https://one.example.com + remoteJwks: + asyncFetch: {} + cacheDuration: 300s + httpUri: + cluster: one_example_com_443 + timeout: 10s + uri: https://one.example.com/jwt/public-key/jwks.json + retryPolicy: {} + httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com/example2: + audiences: + - two.foo.com + claimToHeaders: + - claimName: claim2 + headerName: two-route-example-key + forward: true + issuer: http://two.example.com + payloadInMetadata: http://two.example.com + remoteJwks: + asyncFetch: {} + cacheDuration: 300s + httpUri: + cluster: two_example_com_80 + timeout: 10s + uri: http://two.example.com/jwt/public-key/jwks.json + retryPolicy: {} + requirementMap: + httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com: + requiresAny: + requirements: + - providerName: httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com/example1 + - providerName: httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com/example2 + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: envoy-gateway/gateway-1/http + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml new file mode 100644 index 00000000000..5299f2ff4fb --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml @@ -0,0 +1,35 @@ +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http + virtualHosts: + - domains: + - www.example.com + name: envoy-gateway/gateway-1/http/www_example_com + routes: + - directResponse: + status: 500 + match: + pathSeparatedPrefix: /foo + name: httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com + typedPerFilterConfig: + envoy.filters.http.basic_auth: + '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuthPerRoute + users: + inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + envoy.filters.http.cors: + '@type': type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy + allowCredentials: false + allowMethods: GET, POST + allowOriginStringMatch: + - safeRegex: + regex: https://.*\.test\.com:8080 + - exact: https://www.test.org:8080 + forwardNotMatchingPreflights: false + envoy.filters.http.jwt_authn: + '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig + requirementName: httproute/envoy-gateway/httproute-1/rule/0/match/0/www_example_com + envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 6754feaada5..a88f4e3fc2d 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -26,6 +26,7 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" "k8s.io/utils/ptr" + "github.com/envoyproxy/gateway/api/v1alpha1" extensionTypes "github.com/envoyproxy/gateway/internal/extension/types" "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/utils/protocov" @@ -48,6 +49,9 @@ type Translator struct { // ExtensionManager holds the config for interacting with extensions when generating xDS // resources. Only required during xds translation. ExtensionManager *extensionTypes.Manager + + // FilterOrder holds the custom order of the HTTP filters + FilterOrder []v1alpha1.FilterPosition } type GlobalRateLimitSettings struct { diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index 28868500b68..60dcf8636c8 100644 --- a/internal/xds/translator/translator_test.go +++ b/internal/xds/translator/translator_test.go @@ -122,6 +122,7 @@ func TestTranslateXds(t *testing.T) { GlobalRateLimit: &GlobalRateLimitSettings{ ServiceURL: ratelimit.GetServiceURL("envoy-gateway-system", dnsDomain), }, + FilterOrder: x.FilterOrder, } tCtx, err := tr.Translate(x) diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index d485100eab3..50adb24c983 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1397,7 +1397,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `filter` | _[EnvoyFilter](#envoyfilter)_ | true | Name of the filter. | +| `name` | _[EnvoyFilter](#envoyfilter)_ | true | Name of the filter. | | `before` | _[EnvoyFilter](#envoyfilter)_ | true | Before defines the filter that should come before the filter.
Only one of Before or After must be set. | | `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter.
Only one of Before or After must be set. | From 019a5e197263e22674f7b9cd84a5dc54a143f9cf Mon Sep 17 00:00:00 2001 From: yaelSchechter <159942322+yaelSchechter@users.noreply.github.com> Date: Tue, 7 May 2024 10:19:42 +0300 Subject: [PATCH 09/17] docs: document client idle timeout (#3325) * docs: document client idle timeout Signed-off-by: Yael Shechter * fix pr comments Signed-off-by: Yael Shechter --------- Signed-off-by: Yael Shechter --- .../tasks/traffic/client-traffic-policy.md | 65 +++++++++++++++++++ .../tasks/traffic/client-traffic-policy.md | 65 +++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/site/content/en/latest/tasks/traffic/client-traffic-policy.md b/site/content/en/latest/tasks/traffic/client-traffic-policy.md index 7132453da38..b1782570796 100644 --- a/site/content/en/latest/tasks/traffic/client-traffic-policy.md +++ b/site/content/en/latest/tasks/traffic/client-traffic-policy.md @@ -573,5 +573,70 @@ curl -v http://$GATEWAY_HOST/get \ request timeout ``` +### Configure Client HTTP Idle Timeout + +The idle timeout is defined as the period in which there are no active requests. When the idle timeout is reached the connection will be closed. +For more details see [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout:~:text=...%7D%0A%7D-,idle_timeout,-(Duration)%20The). + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +Curl the example app through Envoy proxy: + +```shell +openssl s_client -crlf -connect $GATEWAY_HOST:443 +``` + +You should expect the connection to be closed after 5s. + +You can also check the number of connections closed due to idle timeout by using the following query: + +```shell +envoy_http_downstream_cx_idle_timeout{envoy_http_conn_manager_prefix=""} +``` + +The number of connections closed due to idle timeout should be increased by 1. + + [ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy [BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy diff --git a/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md b/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md index 7b37f8d4338..3e75d98e239 100644 --- a/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md +++ b/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md @@ -464,5 +464,70 @@ curl -v http://$GATEWAY_HOST/get \ request timeout ``` +### Configure Client HTTP Idle Timeout + +The idle timeout is defined as the period in which there are no active requests. When the idle timeout is reached the connection will be closed. +For more details see [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout:~:text=...%7D%0A%7D-,idle_timeout,-(Duration)%20The). + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +Curl the example app through Envoy proxy: + +```shell +openssl s_client -crlf -connect $GATEWAY_HOST:443 +``` + +You should expect the connection to be closed after 5s. + +You can also check the number of connections closed due to idle timeout by using the following query: + +```shell +envoy_http_downstream_cx_idle_timeout{envoy_http_conn_manager_prefix=""} +``` + +The number of connections closed due to idle timeout should be increased by 1. + + [ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy [BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy From 2ad24a888b2faaf25380ca30d0ff86e8b545d5c3 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Tue, 7 May 2024 11:19:10 -0700 Subject: [PATCH 10/17] feat: expose shutdownmanager image to EnvoyGageway API (#3269) * expose shutdownmanager image to EnvoyGageway API Signed-off-by: huabing zhao * fix test Signed-off-by: huabing zhao * Update internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml Co-authored-by: Arko Dasgupta Signed-off-by: Huabing Zhao * add comments Signed-off-by: huabing zhao * fix gen Signed-off-by: huabing zhao * set default shutdownmanger image in helm value template Signed-off-by: huabing zhao * set default shutdownmanger image in helm value template Signed-off-by: huabing zhao * fix README Signed-off-by: huabing zhao * use the same Envoy Gateway version for ShutManager Signed-off-by: huabing zhao * fix check Signed-off-by: huabing zhao * fix typo Signed-off-by: huabing zhao * fix gen Signed-off-by: huabing zhao * fix gen Signed-off-by: huabing zhao * fix typo Signed-off-by: huabing zhao --------- Signed-off-by: huabing zhao Signed-off-by: Huabing Zhao Co-authored-by: Arko Dasgupta --- api/v1alpha1/envoygateway_helpers.go | 3 ++ api/v1alpha1/envoygateway_types.go | 10 +++++ api/v1alpha1/zz_generated.deepcopy.go | 25 +++++++++++ charts/gateway-helm/values.tmpl.yaml | 5 ++- internal/cmd/version/version.go | 28 ++++++------ .../kubernetes/proxy/resource.go | 11 +++-- .../kubernetes/proxy/resource_provider.go | 13 +++--- .../proxy/resource_provider_test.go | 43 +++++++++++-------- .../deployments/shutdown-manager.yaml | 2 +- .../kubernetes/proxy_configmap_test.go | 4 +- .../kubernetes/proxy_deployment_test.go | 6 +-- .../infrastructure/kubernetes/proxy_infra.go | 4 +- .../kubernetes/proxy_service_test.go | 2 +- .../kubernetes/proxy_serviceaccount_test.go | 4 +- site/content/en/latest/api/extension_types.md | 15 +++++++ site/content/en/latest/install/api.md | 1 + test/helm/default.yaml | 3 ++ tools/make/golang.mk | 5 +-- tools/make/helm.mk | 2 +- 19 files changed, 126 insertions(+), 60 deletions(-) diff --git a/api/v1alpha1/envoygateway_helpers.go b/api/v1alpha1/envoygateway_helpers.go index 5f36282f5b5..0b1faf7e66a 100644 --- a/api/v1alpha1/envoygateway_helpers.go +++ b/api/v1alpha1/envoygateway_helpers.go @@ -234,6 +234,9 @@ func (r *EnvoyGatewayProvider) GetEnvoyGatewayKubeProvider() *EnvoyGatewayKubern r.Kubernetes.RateLimitDeployment.defaultKubernetesDeploymentSpec(DefaultRateLimitImage) + if r.Kubernetes.ShutdownManager == nil { + r.Kubernetes.ShutdownManager = &ShutdownManager{Image: ptr.To(DefaultShutdownManagerImage)} + } return r.Kubernetes } diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go index 3ae313dc409..b1de1937c61 100644 --- a/api/v1alpha1/envoygateway_types.go +++ b/api/v1alpha1/envoygateway_types.go @@ -213,6 +213,10 @@ type EnvoyGatewayKubernetesProvider struct { // If it's not set up, leader election will be active by default, using Kubernetes' standard settings. // +optional LeaderElection *LeaderElection `json:"leaderElection,omitempty"` + + // ShutdownManager defines the configuration for the shutdown manager. + // +optional + ShutdownManager *ShutdownManager `json:"shutdownManager,omitempty"` } const ( @@ -535,6 +539,12 @@ type EnvoyGatewayAdminAddress struct { Host string `json:"host,omitempty"` } +// ShutdownManager defines the configuration for the shutdown manager. +type ShutdownManager struct { + // Image specifies the ShutdownManager container image to be used, instead of the default image. + Image *string `json:"image,omitempty"` +} + func init() { SchemeBuilder.Register(&EnvoyGateway{}) } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index c3d53f443ba..4e0ebe32dbf 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1082,6 +1082,11 @@ func (in *EnvoyGatewayKubernetesProvider) DeepCopyInto(out *EnvoyGatewayKubernet *out = new(LeaderElection) (*in).DeepCopyInto(*out) } + if in.ShutdownManager != nil { + in, out := &in.ShutdownManager, &out.ShutdownManager + *out = new(ShutdownManager) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyGatewayKubernetesProvider. @@ -3931,6 +3936,26 @@ func (in *ShutdownConfig) DeepCopy() *ShutdownConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ShutdownManager) DeepCopyInto(out *ShutdownManager) { + *out = *in + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShutdownManager. +func (in *ShutdownManager) DeepCopy() *ShutdownManager { + if in == nil { + return nil + } + out := new(ShutdownManager) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SlowStart) DeepCopyInto(out *SlowStart) { *out = *in diff --git a/charts/gateway-helm/values.tmpl.yaml b/charts/gateway-helm/values.tmpl.yaml index c0dbfaa762a..4760f2bb3ee 100644 --- a/charts/gateway-helm/values.tmpl.yaml +++ b/charts/gateway-helm/values.tmpl.yaml @@ -25,7 +25,7 @@ deployment: replicas: 1 pod: affinity: {} - annotations: + annotations: prometheus.io/scrape: 'true' prometheus.io/port: '19001' labels: {} @@ -36,6 +36,9 @@ config: controllerName: gateway.envoyproxy.io/gatewayclass-controller provider: type: Kubernetes + kubernetes: + shutdownManager: + image: ${ImageRepository}:${ImageTag} logging: level: default: info diff --git a/internal/cmd/version/version.go b/internal/cmd/version/version.go index f40eb510413..f1294fcfb45 100644 --- a/internal/cmd/version/version.go +++ b/internal/cmd/version/version.go @@ -18,29 +18,26 @@ import ( ) type Info struct { - EnvoyGatewayVersion string `json:"envoyGatewayVersion"` - GatewayAPIVersion string `json:"gatewayAPIVersion"` - EnvoyProxyVersion string `json:"envoyProxyVersion"` - ShutdownManagerVersion string `json:"shutdownManagerVersion"` - GitCommitID string `json:"gitCommitID"` + EnvoyGatewayVersion string `json:"envoyGatewayVersion"` + GatewayAPIVersion string `json:"gatewayAPIVersion"` + EnvoyProxyVersion string `json:"envoyProxyVersion"` + GitCommitID string `json:"gitCommitID"` } func Get() Info { return Info{ - EnvoyGatewayVersion: envoyGatewayVersion, - GatewayAPIVersion: gatewayAPIVersion, - EnvoyProxyVersion: envoyProxyVersion, - ShutdownManagerVersion: shutdownManagerVersion, - GitCommitID: gitCommitID, + EnvoyGatewayVersion: envoyGatewayVersion, + GatewayAPIVersion: gatewayAPIVersion, + EnvoyProxyVersion: envoyProxyVersion, + GitCommitID: gitCommitID, } } var ( - envoyGatewayVersion string - gatewayAPIVersion string - envoyProxyVersion = strings.Split(*v1alpha1.DefaultKubernetesContainerImage(v1alpha1.DefaultEnvoyProxyImage), ":")[1] - shutdownManagerVersion string - gitCommitID string + envoyGatewayVersion string + gatewayAPIVersion string + envoyProxyVersion = strings.Split(v1alpha1.DefaultEnvoyProxyImage, ":")[1] + gitCommitID string ) func init() { @@ -70,7 +67,6 @@ func Print(w io.Writer, format string) error { _, _ = fmt.Fprintf(w, "ENVOY_GATEWAY_VERSION: %s\n", v.EnvoyGatewayVersion) _, _ = fmt.Fprintf(w, "ENVOY_PROXY_VERSION: %s\n", v.EnvoyProxyVersion) _, _ = fmt.Fprintf(w, "GATEWAYAPI_VERSION: %s\n", v.GatewayAPIVersion) - _, _ = fmt.Fprintf(w, "SHUTDOWN_MANAGER_VERSION: %s\n", v.ShutdownManagerVersion) _, _ = fmt.Fprintf(w, "GIT_COMMIT_ID: %s\n", v.GitCommitID) } diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go index f74481f281b..dd9f7a90ff9 100644 --- a/internal/infrastructure/kubernetes/proxy/resource.go +++ b/internal/infrastructure/kubernetes/proxy/resource.go @@ -7,7 +7,6 @@ package proxy import ( "fmt" - "strings" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -15,7 +14,6 @@ import ( egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/cmd/envoy" - "github.com/envoyproxy/gateway/internal/cmd/version" "github.com/envoyproxy/gateway/internal/envoygateway/config" "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/resource" "github.com/envoyproxy/gateway/internal/ir" @@ -103,6 +101,7 @@ func enablePrometheus(infra *ir.ProxyInfra) bool { func expectedProxyContainers(infra *ir.ProxyInfra, containerSpec *egv1a1.KubernetesContainerSpec, shutdownConfig *egv1a1.ShutdownConfig, + shutdownManager *egv1a1.ShutdownManager, ) ([]corev1.Container, error) { // Define slice to hold container ports var ports []corev1.ContainerPort @@ -230,7 +229,7 @@ func expectedProxyContainers(infra *ir.ProxyInfra, }, { Name: "shutdown-manager", - Image: expectedShutdownManagerImage(), + Image: expectedShutdownManagerImage(shutdownManager), ImagePullPolicy: corev1.PullIfNotPresent, Command: []string{"envoy-gateway"}, Args: expectedShutdownManagerArgs(shutdownConfig), @@ -277,9 +276,9 @@ func expectedProxyContainers(infra *ir.ProxyInfra, return containers, nil } -func expectedShutdownManagerImage() string { - if v := version.Get().ShutdownManagerVersion; v != "" { - return fmt.Sprintf("%s:%s", strings.Split(egv1a1.DefaultShutdownManagerImage, ":")[0], v) +func expectedShutdownManagerImage(shutdownManager *egv1a1.ShutdownManager) string { + if shutdownManager != nil && shutdownManager.Image != nil { + return *shutdownManager.Image } return egv1a1.DefaultShutdownManagerImage } diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go index 607aa117e7b..502620c1cd0 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go @@ -29,12 +29,15 @@ type ResourceRender struct { // Namespace is the Namespace used for managed infra. Namespace string + + ShutdownManager *egv1a1.ShutdownManager } -func NewResourceRender(ns string, infra *ir.ProxyInfra) *ResourceRender { +func NewResourceRender(ns string, infra *ir.ProxyInfra, gateway *egv1a1.EnvoyGateway) *ResourceRender { return &ResourceRender{ - Namespace: ns, - infra: infra, + Namespace: ns, + infra: infra, + ShutdownManager: gateway.GetEnvoyGatewayProvider().GetEnvoyGatewayKubeProvider().ShutdownManager, } } @@ -199,7 +202,7 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { } // Get expected bootstrap configurations rendered ProxyContainers - containers, err := expectedProxyContainers(r.infra, deploymentConfig.Container, proxyConfig.Spec.Shutdown) + containers, err := expectedProxyContainers(r.infra, deploymentConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager) if err != nil { return nil, err } @@ -288,7 +291,7 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) { } // Get expected bootstrap configurations rendered ProxyContainers - containers, err := expectedProxyContainers(r.infra, daemonSetConfig.Container, proxyConfig.Spec.Shutdown) + containers, err := expectedProxyContainers(r.infra, daemonSetConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager) if err != nil { return nil, err } diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go index 0d4a5999368..e32d4953f42 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go @@ -88,15 +88,16 @@ func TestDeployment(t *testing.T) { require.NoError(t, err) cases := []struct { - caseName string - infra *ir.Infra - deploy *egv1a1.KubernetesDeploymentSpec - shutdown *egv1a1.ShutdownConfig - proxyLogging map[egv1a1.ProxyLogComponent]egv1a1.LogLevel - bootstrap string - telemetry *egv1a1.ProxyTelemetry - concurrency *int32 - extraArgs []string + caseName string + infra *ir.Infra + deploy *egv1a1.KubernetesDeploymentSpec + shutdown *egv1a1.ShutdownConfig + shutdownManager *egv1a1.ShutdownManager + proxyLogging map[egv1a1.ProxyLogComponent]egv1a1.LogLevel + bootstrap string + telemetry *egv1a1.ProxyTelemetry + concurrency *int32 + extraArgs []string }{ { caseName: "default", @@ -171,8 +172,7 @@ func TestDeployment(t *testing.T) { "env":[ {"name":"env_a","value":"env_a_value"}, {"name":"env_b","value":"env_b_value"} - ], - "image":"envoyproxy/gateway-dev:v1.2.3" + ] }] } } @@ -189,6 +189,9 @@ func TestDeployment(t *testing.T) { Duration: 15 * time.Second, }, }, + shutdownManager: &egv1a1.ShutdownManager{ + Image: ptr.To("privaterepo/envoyproxy/gateway-dev:v1.2.3"), + }, }, { caseName: "bootstrap", @@ -542,11 +545,17 @@ func TestDeployment(t *testing.T) { tc.infra.Proxy.Config.Spec.Shutdown = tc.shutdown } + if tc.shutdownManager != nil { + cfg.EnvoyGateway.Provider.Kubernetes.ShutdownManager = tc.shutdownManager + } else { + cfg.EnvoyGateway.Provider.Kubernetes.ShutdownManager = nil + } + if len(tc.extraArgs) > 0 { tc.infra.Proxy.Config.Spec.ExtraArgs = tc.extraArgs } - r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra()) + r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway) dp, err := r.Deployment() require.NoError(t, err) @@ -967,7 +976,7 @@ func TestDaemonSet(t *testing.T) { tc.infra.Proxy.Config.Spec.ExtraArgs = tc.extraArgs } - r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra()) + r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway) ds, err := r.DaemonSet() require.NoError(t, err) @@ -1082,7 +1091,7 @@ func TestService(t *testing.T) { provider.EnvoyService = tc.service } - r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra()) + r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway) svc, err := r.Service() require.NoError(t, err) @@ -1125,7 +1134,7 @@ func TestConfigMap(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra()) + r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway) cm, err := r.ConfigMap() require.NoError(t, err) @@ -1168,7 +1177,7 @@ func TestServiceAccount(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra()) + r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway) sa, err := r.ServiceAccount() require.NoError(t, err) @@ -1249,7 +1258,7 @@ func TestHorizontalPodAutoscaler(t *testing.T) { provider.GetEnvoyProxyKubeProvider() - r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra()) + r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra(), cfg.EnvoyGateway) hpa, err := r.HorizontalPodAutoscaler() require.NoError(t, err) diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml index 7bcb064cdee..12c9ad5766f 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml @@ -249,7 +249,7 @@ spec: fieldRef: apiVersion: v1 fieldPath: metadata.name - image: envoyproxy/gateway-dev:v1.2.3 + image: privaterepo/envoyproxy/gateway-dev:v1.2.3 imagePullPolicy: IfNotPresent lifecycle: preStop: diff --git a/internal/infrastructure/kubernetes/proxy_configmap_test.go b/internal/infrastructure/kubernetes/proxy_configmap_test.go index 4df19b223f2..b16a0f61bbf 100644 --- a/internal/infrastructure/kubernetes/proxy_configmap_test.go +++ b/internal/infrastructure/kubernetes/proxy_configmap_test.go @@ -111,7 +111,7 @@ func TestCreateOrUpdateProxyConfigMap(t *testing.T) { Build() } kube := NewInfra(cli, cfg) - r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway) err := kube.createOrUpdateConfigMap(context.Background(), r) require.NoError(t, err) actual := &corev1.ConfigMap{ @@ -170,7 +170,7 @@ func TestDeleteConfigProxyMap(t *testing.T) { infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default" infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name - r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway) cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: kube.Namespace, diff --git a/internal/infrastructure/kubernetes/proxy_deployment_test.go b/internal/infrastructure/kubernetes/proxy_deployment_test.go index 1958dffd559..a1d595b750d 100644 --- a/internal/infrastructure/kubernetes/proxy_deployment_test.go +++ b/internal/infrastructure/kubernetes/proxy_deployment_test.go @@ -47,7 +47,7 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) { infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default" infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name - r := proxy.NewResourceRender(cfg.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(cfg.Namespace, infra.GetProxyInfra(), cfg.EnvoyGateway) deploy, err := r.Deployment() require.NoError(t, err) @@ -119,7 +119,7 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) { } kube := NewInfra(cli, cfg) - r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra()) + r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra(), cfg.EnvoyGateway) err := kube.createOrUpdateDeployment(context.Background(), r) require.NoError(t, err) @@ -162,7 +162,7 @@ func TestDeleteProxyDeployment(t *testing.T) { infra := ir.NewInfra() infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default" infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name - r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway) err := kube.createOrUpdateDeployment(context.Background(), r) require.NoError(t, err) diff --git a/internal/infrastructure/kubernetes/proxy_infra.go b/internal/infrastructure/kubernetes/proxy_infra.go index 203c3fa4ef6..e0b1fc5f9cc 100644 --- a/internal/infrastructure/kubernetes/proxy_infra.go +++ b/internal/infrastructure/kubernetes/proxy_infra.go @@ -23,7 +23,7 @@ func (i *Infra) CreateOrUpdateProxyInfra(ctx context.Context, infra *ir.Infra) e return errors.New("infra proxy ir is nil") } - r := proxy.NewResourceRender(i.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(i.Namespace, infra.GetProxyInfra(), i.EnvoyGateway) return i.createOrUpdate(ctx, r) } @@ -33,6 +33,6 @@ func (i *Infra) DeleteProxyInfra(ctx context.Context, infra *ir.Infra) error { return errors.New("infra ir is nil") } - r := proxy.NewResourceRender(i.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(i.Namespace, infra.GetProxyInfra(), i.EnvoyGateway) return i.delete(ctx, r) } diff --git a/internal/infrastructure/kubernetes/proxy_service_test.go b/internal/infrastructure/kubernetes/proxy_service_test.go index 6aa221a4113..0c1c0cc6b89 100644 --- a/internal/infrastructure/kubernetes/proxy_service_test.go +++ b/internal/infrastructure/kubernetes/proxy_service_test.go @@ -33,7 +33,7 @@ func TestDeleteProxyService(t *testing.T) { infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default" infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name - r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway) err := kube.createOrUpdateService(context.Background(), r) require.NoError(t, err) diff --git a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go index abed92cbccb..2b92fc53417 100644 --- a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go +++ b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go @@ -188,7 +188,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) { kube := NewInfra(cli, cfg) - r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra()) + r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra(), cfg.EnvoyGateway) err = kube.createOrUpdateServiceAccount(context.Background(), r) require.NoError(t, err) @@ -221,7 +221,7 @@ func TestDeleteProxyServiceAccount(t *testing.T) { infra := ir.NewInfra() infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default" infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name - r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra()) + r := proxy.NewResourceRender(kube.Namespace, infra.GetProxyInfra(), kube.EnvoyGateway) err := kube.createOrUpdateServiceAccount(context.Background(), r) require.NoError(t, err) diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 50adb24c983..e5bd11a440e 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -843,6 +843,7 @@ _Appears in:_ | `deploy` | _[KubernetesDeployMode](#kubernetesdeploymode)_ | false | Deploy holds configuration of how output managed resources such as the Envoy Proxy data plane
should be deployed | | `overwriteControlPlaneCerts` | _boolean_ | false | OverwriteControlPlaneCerts updates the secrets containing the control plane certs, when set. | | `leaderElection` | _[LeaderElection](#leaderelection)_ | false | LeaderElection specifies the configuration for leader election.
If it's not set up, leader election will be active by default, using Kubernetes' standard settings. | +| `shutdownManager` | _[ShutdownManager](#shutdownmanager)_ | false | ShutdownManager defines the configuration for the shutdown manager. | #### EnvoyGatewayLogComponent @@ -2966,6 +2967,20 @@ _Appears in:_ | `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 5 seconds. | +#### ShutdownManager + + + +ShutdownManager defines the configuration for the shutdown manager. + +_Appears in:_ +- [EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `image` | _string_ | true | Image specifies the ShutdownManager container image to be used, instead of the default image. | + + #### SlowStart diff --git a/site/content/en/latest/install/api.md b/site/content/en/latest/install/api.md index 36fe24f6e5b..f9c3b35b531 100644 --- a/site/content/en/latest/install/api.md +++ b/site/content/en/latest/install/api.md @@ -31,6 +31,7 @@ The Helm chart for Envoy Gateway | certgen.rbac.labels | object | `{}` | | | config.envoyGateway.gateway.controllerName | string | `"gateway.envoyproxy.io/gatewayclass-controller"` | | | config.envoyGateway.logging.level.default | string | `"info"` | | +| config.envoyGateway.provider.kubernetes.shutdownManager.image | string | `"docker.io/envoyproxy/gateway:latest"` | | | config.envoyGateway.provider.type | string | `"Kubernetes"` | | | createNamespace | bool | `false` | | | deployment.envoyGateway.image.repository | string | `"docker.io/envoyproxy/gateway"` | | diff --git a/test/helm/default.yaml b/test/helm/default.yaml index 5bebac04aad..b4a1b5426af 100644 --- a/test/helm/default.yaml +++ b/test/helm/default.yaml @@ -34,6 +34,9 @@ data: level: default: info provider: + kubernetes: + shutdownManager: + image: docker.io/envoyproxy/gateway-dev:latest type: Kubernetes --- # Source: gateway-helm/templates/envoy-gateway-rbac.yaml diff --git a/tools/make/golang.mk b/tools/make/golang.mk index 9e4937b3df3..f039f7de29d 100644 --- a/tools/make/golang.mk +++ b/tools/make/golang.mk @@ -5,7 +5,6 @@ VERSION_PACKAGE := github.com/envoyproxy/gateway/internal/cmd/version GO_LDFLAGS += -X $(VERSION_PACKAGE).envoyGatewayVersion=$(shell cat VERSION) \ - -X $(VERSION_PACKAGE).shutdownManagerVersion=$(TAG) \ -X $(VERSION_PACKAGE).gitCommitID=$(GIT_COMMIT) GIT_COMMIT:=$(shell git rev-parse HEAD) @@ -19,7 +18,7 @@ GO_VERSION = $(shell grep -oE "^go [[:digit:]]*\.[[:digit:]]*" go.mod | cut -d' # Build the target binary in target platform. # The pattern of build.% is `build.{Platform}.{Command}`. -# If we want to build envoy-gateway in linux amd64 platform, +# If we want to build envoy-gateway in linux amd64 platform, # just execute make go.build.linux_amd64.envoy-gateway. .PHONY: go.build.% go.build.%: @@ -119,4 +118,4 @@ clean: go.clean .PHONY: testdata testdata: ## Override the testdata with new configurations. -testdata: go.testdata.complete \ No newline at end of file +testdata: go.testdata.complete diff --git a/tools/make/helm.mk b/tools/make/helm.mk index 5ca7d1c8612..c664974d133 100644 --- a/tools/make/helm.mk +++ b/tools/make/helm.mk @@ -33,4 +33,4 @@ helm-generate: helm-template: ## Template envoy gateway helm chart. @$(LOG_TARGET) - helm template eg charts/gateway-helm --set deployment.envoyGateway.image.tag=latest > ./test/helm/default.yaml --namespace=envoy-gateway-system + helm template eg charts/gateway-helm --set deployment.envoyGateway.image.tag=latest --set config.envoyGateway.provider.kubernetes.shutdownManager.image="docker.io/envoyproxy/gateway-dev:latest" > ./test/helm/default.yaml --namespace=envoy-gateway-system From ed4222b78124de25d0c7094080567c45047d33c3 Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 8 May 2024 04:22:18 +0800 Subject: [PATCH 11/17] bump gatewayapi to 1.1.0-rc2 (#3336) * bump gatewayapi Signed-off-by: zirain * fix lint and test Signed-off-by: zirain * yaml-lint Signed-off-by: zirain * fix scheme Signed-off-by: zirain * lint Signed-off-by: zirain * fix conformance test Signed-off-by: zirain * add apiextensionsv1 to scheme Signed-off-by: zirain * lint Signed-off-by: zirain * fix test Signed-off-by: zirain * skip GatewayHTTPListenerIsolation Signed-off-by: zirain * fix e2e Signed-off-by: zirain * skip HTTPRouteBackendRequestHeaderModifier Signed-off-by: zirain * fix e2e Signed-off-by: zirain * fix e2e Signed-off-by: zirain * yaml lint Signed-off-by: zirain * update api/extension_types.md Signed-off-by: zirain --------- Signed-off-by: zirain --- api/v1alpha1/backendtrafficpolicy_types.go | 2 +- api/v1alpha1/clienttrafficpolicy_types.go | 2 +- api/v1alpha1/envoyextensionypolicy_types.go | 2 +- api/v1alpha1/envoypatchpolicy_types.go | 4 +- api/v1alpha1/securitypolicy_types.go | 2 +- api/v1alpha1/zz_generated.deepcopy.go | 2 +- charts/gateway-helm/crds/gatewayapi-crds.yaml | 20794 ++++++++++------ ....envoyproxy.io_backendtrafficpolicies.yaml | 28 +- ...y.envoyproxy.io_clienttrafficpolicies.yaml | 28 +- ....envoyproxy.io_envoyextensionpolicies.yaml | 28 +- ...eway.envoyproxy.io_envoypatchpolicies.yaml | 25 +- ...ateway.envoyproxy.io_securitypolicies.yaml | 28 +- go.mod | 29 +- go.sum | 73 +- internal/cmd/egctl/status.go | 5 +- internal/cmd/egctl/status_test.go | 5 +- .../translate/out/default-resources.all.yaml | 2 + .../out/echo-gateway-api.cluster.yaml | 1 + .../translate/out/echo-gateway-api.route.json | 3 +- .../translate/out/invalid-envoyproxy.all.yaml | 2 + .../translate/out/quickstart.all.yaml | 1 + .../out/rejected-http-route.route.yaml | 1 + .../translate/out/valid-envoyproxy.all.yaml | 2 + internal/cmd/egctl/translate.go | 6 +- internal/envoygateway/scheme.go | 30 +- internal/gatewayapi/backendtlspolicy.go | 19 +- internal/gatewayapi/backendtrafficpolicy.go | 31 +- internal/gatewayapi/clienttrafficpolicy.go | 13 +- internal/gatewayapi/contexts.go | 4 +- internal/gatewayapi/envoyextensionpolicy.go | 31 +- internal/gatewayapi/envoypatchpolicy.go | 13 +- internal/gatewayapi/filters.go | 11 +- internal/gatewayapi/helpers.go | 12 +- internal/gatewayapi/helpers_test.go | 29 +- internal/gatewayapi/resource.go | 9 +- internal/gatewayapi/route.go | 25 +- internal/gatewayapi/runner/runner_test.go | 4 +- internal/gatewayapi/securitypolicy.go | 30 +- .../testdata/backendtlspolicy-ca-only.in.yaml | 18 +- .../backendtlspolicy-ca-only.out.yaml | 10 +- .../backendtlspolicy-default-ns.in.yaml | 18 +- .../backendtlspolicy-default-ns.out.yaml | 9 +- .../backendtlspolicy-invalid-ca.in.yaml | 18 +- .../backendtlspolicy-invalid-ca.out.yaml | 10 +- ...backendtlspolicy-system-truststore.in.yaml | 15 +- ...ackendtlspolicy-system-truststore.out.yaml | 9 +- ...ndtlspolicy-without-referencegrant.in.yaml | 18 +- ...dtlspolicy-without-referencegrant.out.yaml | 10 +- ...kendtrafficpolicy-override-replace.in.yaml | 2 - ...endtrafficpolicy-override-replace.out.yaml | 4 +- ...endtrafficpolicy-status-conditions.in.yaml | 9 - ...ndtrafficpolicy-status-conditions.out.yaml | 42 +- ...afficpolicy-status-fault-injection.in.yaml | 3 - ...fficpolicy-status-fault-injection.out.yaml | 6 +- ...dtrafficpolicy-use-client-protocol.in.yaml | 1 - ...trafficpolicy-use-client-protocol.out.yaml | 2 +- ...cpolicy-with-circuitbreakers-error.in.yaml | 3 - ...policy-with-circuitbreakers-error.out.yaml | 6 +- ...trafficpolicy-with-circuitbreakers.in.yaml | 2 - ...rafficpolicy-with-circuitbreakers.out.yaml | 4 +- ...kendtrafficpolicy-with-healthcheck.in.yaml | 4 - ...endtrafficpolicy-with-healthcheck.out.yaml | 8 +- ...endtrafficpolicy-with-loadbalancer.in.yaml | 4 - ...ndtrafficpolicy-with-loadbalancer.out.yaml | 7 +- ...atelimit-default-route-level-limit.in.yaml | 1 - ...telimit-default-route-level-limit.out.yaml | 2 +- ...local-ratelimit-invalid-limit-unit.in.yaml | 1 - ...ocal-ratelimit-invalid-limit-unit.out.yaml | 2 +- ...local-ratelimit-invalid-match-type.in.yaml | 1 - ...ocal-ratelimit-invalid-match-type.out.yaml | 2 +- ...nvalid-multiple-route-level-limits.in.yaml | 1 - ...valid-multiple-route-level-limits.out.yaml | 2 +- ...trafficpolicy-with-local-ratelimit.in.yaml | 1 - ...rafficpolicy-with-local-ratelimit.out.yaml | 2 +- ...ndtrafficpolicy-with-proxyprotocol.in.yaml | 2 - ...dtrafficpolicy-with-proxyprotocol.out.yaml | 4 +- ...olicy-with-ratelimit-invalid-regex.in.yaml | 1 - ...licy-with-ratelimit-invalid-regex.out.yaml | 2 +- ...ackendtrafficpolicy-with-ratelimit.in.yaml | 2 - ...ckendtrafficpolicy-with-ratelimit.out.yaml | 4 +- .../backendtrafficpolicy-with-retries.in.yaml | 2 - ...backendtrafficpolicy-with-retries.out.yaml | 4 +- ...policy-with-same-prefix-httproutes.in.yaml | 1 - ...olicy-with-same-prefix-httproutes.out.yaml | 3 +- ...h-tcp-udp-listeners-apply-on-route.in.yaml | 2 - ...-tcp-udp-listeners-apply-on-route.out.yaml | 2 - ...endtrafficpolicy-with-tcpkeepalive.in.yaml | 2 - ...ndtrafficpolicy-with-tcpkeepalive.out.yaml | 4 +- ...ndtrafficpolicy-with-timeout-error.in.yaml | 1 - ...dtrafficpolicy-with-timeout-error.out.yaml | 2 +- .../backendtrafficpolicy-with-timeout.in.yaml | 2 - ...backendtrafficpolicy-with-timeout.out.yaml | 4 +- ...icy-buffer-limit-with-format-error.in.yaml | 2 - ...cy-buffer-limit-with-format-error.out.yaml | 2 - ...ffer-limit-with-out-of-range-error.in.yaml | 2 - ...fer-limit-with-out-of-range-error.out.yaml | 2 - .../clienttrafficpolicy-buffer-limit.in.yaml | 2 - .../clienttrafficpolicy-buffer-limit.out.yaml | 2 - ...ttrafficpolicy-client-ip-detection.in.yaml | 3 - ...trafficpolicy-client-ip-detection.out.yaml | 3 - ...afficpolicy-connection-limit-error.in.yaml | 2 - ...fficpolicy-connection-limit-error.out.yaml | 2 - ...ienttrafficpolicy-connection-limit.in.yaml | 2 - ...enttrafficpolicy-connection-limit.out.yaml | 2 - .../clienttrafficpolicy-headers.in.yaml | 1 - .../clienttrafficpolicy-headers.out.yaml | 1 - .../clienttrafficpolicy-http10.in.yaml | 3 - .../clienttrafficpolicy-http10.out.yaml | 3 - .../clienttrafficpolicy-http2.in.yaml | 2 - .../clienttrafficpolicy-http2.out.yaml | 2 - .../clienttrafficpolicy-http3.in.yaml | 1 - .../clienttrafficpolicy-http3.out.yaml | 2 +- ...fficpolicy-idle-timeout-with-error.in.yaml | 1 - ...ficpolicy-idle-timeout-with-error.out.yaml | 1 - .../clienttrafficpolicy-idle-timeout.in.yaml | 1 - .../clienttrafficpolicy-idle-timeout.out.yaml | 1 - ...ficpolicy-mtls-client-verification.in.yaml | 2 - ...icpolicy-mtls-client-verification.out.yaml | 2 - .../testdata/clienttrafficpolicy-mtls.in.yaml | 2 - .../clienttrafficpolicy-mtls.out.yaml | 2 - .../clienttrafficpolicy-path-settings.in.yaml | 1 - ...clienttrafficpolicy-path-settings.out.yaml | 1 - .../clienttrafficpolicy-preserve-case.in.yaml | 1 - ...clienttrafficpolicy-preserve-case.out.yaml | 1 - .../clienttrafficpolicy-proxyprotocol.in.yaml | 1 - ...clienttrafficpolicy-proxyprotocol.out.yaml | 1 - ...enttrafficpolicy-status-conditions.in.yaml | 9 - ...nttrafficpolicy-status-conditions.out.yaml | 24 +- .../clienttrafficpolicy-tcp-keepalive.in.yaml | 2 - ...clienttrafficpolicy-tcp-keepalive.out.yaml | 2 - ...nttrafficpolicy-timeout-with-error.in.yaml | 1 - ...ttrafficpolicy-timeout-with-error.out.yaml | 1 - .../clienttrafficpolicy-timeout.in.yaml | 1 - .../clienttrafficpolicy-timeout.out.yaml | 1 - .../clienttrafficpolicy-tls-settings.in.yaml | 1 - .../clienttrafficpolicy-tls-settings.out.yaml | 1 - .../clienttrafficpolicy-trailers.in.yaml | 1 - .../clienttrafficpolicy-trailers.out.yaml | 1 - .../testdata/conflicting-policies.in.yaml | 1 - .../testdata/conflicting-policies.out.yaml | 3 +- .../testdata/custom-filter-order.in.yaml | 2 - .../testdata/custom-filter-order.out.yaml | 3 +- ...tensionpolicy-invalid-cross-ns-ref.in.yaml | 1 - ...ensionpolicy-invalid-cross-ns-ref.out.yaml | 16 +- ...oyextensionpolicy-override-replace.in.yaml | 2 - ...yextensionpolicy-override-replace.out.yaml | 4 +- ...yextensionpolicy-status-conditions.in.yaml | 9 - ...extensionpolicy-status-conditions.out.yaml | 42 +- ...h-extproc-invalid-no-matching-port.in.yaml | 1 - ...-extproc-invalid-no-matching-port.out.yaml | 2 +- ...olicy-with-extproc-invalid-no-port.in.yaml | 1 - ...licy-with-extproc-invalid-no-port.out.yaml | 2 +- ...extproc-invalid-no-reference-grant.in.yaml | 1 - ...xtproc-invalid-no-reference-grant.out.yaml | 2 +- ...cy-with-extproc-invalid-no-service.in.yaml | 1 - ...y-with-extproc-invalid-no-service.out.yaml | 2 +- ...with-extproc-with-backendtlspolicy.in.yaml | 19 +- ...ith-extproc-with-backendtlspolicy.out.yaml | 21 +- ...-extproc-with-multiple-backendrefs.in.yaml | 10 +- ...extproc-with-multiple-backendrefs.out.yaml | 12 +- .../envoyextensionpolicy-with-wasm.in.yaml | 2 - .../envoyextensionpolicy-with-wasm.out.yaml | 4 +- .../envoypatchpolicy-cross-ns-target.in.yaml | 1 - .../envoypatchpolicy-cross-ns-target.out.yaml | 18 - ...tchpolicy-invalid-feature-disabled.in.yaml | 1 - ...invalid-target-kind-merge-gateways.in.yaml | 1 - ...voypatchpolicy-invalid-target-kind.in.yaml | 1 - ...licy-no-status-for-unknown-gateway.in.yaml | 1 - ...oypatchpolicy-valid-merge-gateways.in.yaml | 2 - .../testdata/envoypatchpolicy-valid.in.yaml | 2 - .../testdata/envoyproxy-tls-settings.in.yaml | 12 +- .../testdata/envoyproxy-tls-settings.out.yaml | 9 +- ...th-extension-filter-invalid-group.out.yaml | 1 + ...ith-non-matching-extension-filter.out.yaml | 1 + ...with-unsupported-extension-filter.out.yaml | 1 + ...route-with-valid-extension-filter.out.yaml | 1 + ...-namespace-with-allowed-httproute.out.yaml | 1 + ...mespace-with-disallowed-httproute.out.yaml | 1 + .../testdata/gateway-infrastructure.out.yaml | 1 + ...valid-allowed-namespaces-selector.out.yaml | 1 + ...with-invalid-allowed-routes-group.out.yaml | 1 + ...allowed-routes-kind-and-supported.out.yaml | 1 + ...-with-invalid-allowed-routes-kind.out.yaml | 1 + ...nvalid-multiple-tls-configuration.out.yaml | 1 + ...id-tls-configuration-invalid-mode.out.yaml | 1 + ...configuration-no-certificate-refs.out.yaml | 1 + ...ion-no-valid-certificate-for-fqdn.out.yaml | 1 + ...nfiguration-secret-does-not-exist.out.yaml | 1 + ...uration-secret-in-other-namespace.out.yaml | 1 + ...configuration-secret-is-not-valid.out.yaml | 1 + ...ssing-allowed-namespaces-selector.out.yaml | 1 + ...her-namespace-allowed-by-refgrant.out.yaml | 1 + ...ith-tls-terminate-and-passthrough.out.yaml | 1 + ...istener-with-unsupported-protocol.out.yaml | 1 + ...ith-same-algorithm-different-fqdn.out.yaml | 1 + ...-valid-multiple-tls-configuration.out.yaml | 1 + ...ener-with-valid-tls-configuration.out.yaml | 1 + ...with-preexisting-status-condition.out.yaml | 1 + ...teway-with-stale-status-condition.out.yaml | 1 + ...d-tlsroute-same-hostname-and-port.out.yaml | 1 + ...isteners-with-multiple-httproutes.out.yaml | 2 + ...eners-with-same-port-and-hostname.out.yaml | 1 + ...me-port-and-incompatible-protocol.out.yaml | 1 + ...-with-same-port-http-tcp-protocol.out.yaml | 1 + ...-with-same-port-http-udp-protocol.out.yaml | 1 + .../grpcroute-with-empty-backends.out.yaml | 1 + .../grpcroute-with-header-match.out.yaml | 1 + ...ute-with-method-and-service-match.out.yaml | 1 + .../grpcroute-with-method-match.out.yaml | 1 + ...oute-with-request-header-modifier.out.yaml | 1 + .../grpcroute-with-service-match.out.yaml | 1 + ...ndtrafficpolicy-with-timeout-error.in.yaml | 1 - ...dtrafficpolicy-with-timeout-error.out.yaml | 2 +- ...-backendtrafficpolicy-with-timeout.in.yaml | 2 - ...backendtrafficpolicy-with-timeout.out.yaml | 4 +- ...way-with-more-different-listeners.out.yaml | 1 + ...ng-to-gateway-with-more-listeners.out.yaml | 1 + ...wo-listeners-with-different-ports.out.yaml | 1 + ...ing-to-gateway-with-two-listeners.out.yaml | 1 + .../httproute-attaching-to-gateway.out.yaml | 1 + ...taching-to-listener-matching-port.out.yaml | 1 + ...ner-on-gateway-with-two-listeners.out.yaml | 1 + ...ort-backendrefs-diff-address-type.out.yaml | 1 + ...ort-backendrefs-same-address-type.out.yaml | 1 + ...port-backendref-fqdn-address-type.out.yaml | 1 + ...ort-backendref-mixed-address-type.out.yaml | 1 + ...ner-with-serviceimport-backendref.out.yaml | 1 + .../httproute-attaching-to-listener.out.yaml | 1 + ...httproute-backend-request-timeout.out.yaml | 1 + ...ing-to-listener-non-matching-port.out.yaml | 1 + .../httproute-request-timeout.out.yaml | 1 + ...ith-empty-backends-and-no-filters.out.yaml | 1 + ...-multiple-backends-and-no-weights.out.yaml | 1 + ...ith-multiple-backends-and-weights.out.yaml | 1 + ...her-namespace-allowed-by-refgrant.out.yaml | 1 + ...her-namespace-allowed-by-refgrant.out.yaml | 1 + .../httproute-with-empty-matches.out.yaml | 1 + ...er-duplicate-add-multiple-filters.out.yaml | 1 + ...with-header-filter-duplicate-adds.out.yaml | 1 + ...duplicate-remove-multiple-filters.out.yaml | 1 + ...h-header-filter-duplicate-removes.out.yaml | 1 + ...header-filter-empty-header-values.out.yaml | 1 + ...-with-header-filter-empty-headers.out.yaml | 1 + ...ith-header-filter-invalid-headers.out.yaml | 1 + ...ute-with-header-filter-no-headers.out.yaml | 1 + ...th-header-filter-no-valid-headers.out.yaml | 1 + ...tproute-with-header-filter-remove.out.yaml | 1 + ...with-invalid-backend-ref-bad-port.out.yaml | 1 + ...invalid-backend-ref-invalid-group.out.yaml | 1 + ...-invalid-backend-ref-invalid-kind.out.yaml | 1 + ...-with-invalid-backend-ref-no-port.out.yaml | 1 + ...lid-backend-ref-no-service.import.out.yaml | 1 + ...th-invalid-backend-ref-no-service.out.yaml | 1 + ...id-backend-ref-unsupported-filter.out.yaml | 1 + ...lid-backendref-in-other-namespace.out.yaml | 1 + .../httproute-with-invalid-regex.out.yaml | 1 + ...ute-with-mirror-filter-duplicates.out.yaml | 1 + ...route-with-mirror-filter-multiple.out.yaml | 1 + ...ith-mirror-filter-service-no-port.out.yaml | 1 + ...h-mirror-filter-service-not-found.out.yaml | 1 + .../httproute-with-mirror-filter.out.yaml | 1 + ...to-gateway-with-wildcard-hostname.out.yaml | 1 + ...ct-filter-full-path-replace-https.out.yaml | 1 + ...ute-with-redirect-filter-hostname.out.yaml | 1 + ...direct-filter-invalid-filter-type.out.yaml | 1 + ...th-redirect-filter-invalid-scheme.out.yaml | 1 + ...th-redirect-filter-invalid-status.out.yaml | 1 + ...ter-prefix-replace-with-port-http.out.yaml | 1 + ...-with-response-header-filter-adds.out.yaml | 1 + ...er-duplicate-add-multiple-filters.out.yaml | 1 + ...onse-header-filter-duplicate-adds.out.yaml | 1 + ...duplicate-remove-multiple-filters.out.yaml | 1 + ...e-header-filter-duplicate-removes.out.yaml | 1 + ...header-filter-empty-header-values.out.yaml | 1 + ...ponse-header-filter-empty-headers.out.yaml | 1 + ...nse-header-filter-invalid-headers.out.yaml | 1 + ...response-header-filter-no-headers.out.yaml | 1 + ...se-header-filter-no-valid-headers.out.yaml | 1 + ...ith-response-header-filter-remove.out.yaml | 1 + ...single-rule-with-exact-path-match.out.yaml | 1 + ...ingle-rule-with-http-method-match.out.yaml | 1 + ...h-single-rule-with-multiple-rules.out.yaml | 3 + ...h-prefix-and-exact-header-matches.out.yaml | 1 + ...e-invalid-backend-refs-no-service.out.yaml | 1 + ...to-gateway-with-wildcard-hostname.out.yaml | 1 + ...to-gateway-with-wildcard-hostname.out.yaml | 1 + ...ite-filter-full-path-replace-http.out.yaml | 1 + ...te-filter-hostname-prefix-replace.out.yaml | 1 + ...e-with-urlrewrite-filter-hostname.out.yaml | 1 + ...ewrite-filter-invalid-filter-type.out.yaml | 1 + ...rlrewrite-filter-invalid-hostname.out.yaml | 1 + ...e-filter-invalid-multiple-filters.out.yaml | 1 + ...lrewrite-filter-invalid-path-type.out.yaml | 1 + ...th-urlrewrite-filter-invalid-path.out.yaml | 1 + ...th-urlrewrite-filter-missing-path.out.yaml | 1 + ...ewrite-filter-prefix-replace-http.out.yaml | 1 + ...ng-to-gateway-with-unset-hostname.out.yaml | 1 + .../httproutes-with-multiple-matches.out.yaml | 6 + ...multiple-gateways-multiple-routes.out.yaml | 2 + .../merge-with-isolated-policies-2.in.yaml | 5 - .../merge-with-isolated-policies-2.out.yaml | 9 +- .../merge-with-isolated-policies.in.yaml | 3 - .../merge-with-isolated-policies.out.yaml | 5 +- ...ecuritypolicy-invalid-cross-ns-ref.in.yaml | 1 - ...curitypolicy-invalid-cross-ns-ref.out.yaml | 16 +- .../securitypolicy-override-replace.in.yaml | 2 - .../securitypolicy-override-replace.out.yaml | 4 +- .../securitypolicy-status-conditions.in.yaml | 7 - .../securitypolicy-status-conditions.out.yaml | 9 +- .../securitypolicy-with-basic-auth.in.yaml | 2 - .../securitypolicy-with-basic-auth.out.yaml | 5 +- .../testdata/securitypolicy-with-cors.in.yaml | 3 - .../securitypolicy-with-cors.out.yaml | 6 +- ...h-extauth-invalid-no-matching-port.in.yaml | 1 - ...-extauth-invalid-no-matching-port.out.yaml | 2 +- ...olicy-with-extauth-invalid-no-port.in.yaml | 1 - ...licy-with-extauth-invalid-no-port.out.yaml | 2 +- ...extauth-invalid-no-reference-grant.in.yaml | 1 - ...xtauth-invalid-no-reference-grant.out.yaml | 2 +- ...cy-with-extauth-invalid-no-service.in.yaml | 1 - ...y-with-extauth-invalid-no-service.out.yaml | 2 +- ...with-extauth-with-backendtlspolicy.in.yaml | 37 +- ...ith-extauth-with-backendtlspolicy.out.yaml | 21 +- .../securitypolicy-with-extauth.in.yaml | 2 - .../securitypolicy-with-extauth.out.yaml | 5 +- ...typolicy-with-jwt-and-invalid-oidc.in.yaml | 2 - ...ypolicy-with-jwt-and-invalid-oidc.out.yaml | 4 +- .../securitypolicy-with-jwt-optional.in.yaml | 2 - .../securitypolicy-with-jwt-optional.out.yaml | 4 +- ...icy-with-jwt-with-custom-extractor.in.yaml | 2 - ...cy-with-jwt-with-custom-extractor.out.yaml | 4 +- .../testdata/securitypolicy-with-jwt.in.yaml | 2 - .../testdata/securitypolicy-with-jwt.out.yaml | 4 +- .../testdata/securitypolicy-with-oidc.in.yaml | 2 - .../securitypolicy-with-oidc.out.yaml | 4 +- .../tracing-merged-multiple-routes.out.yaml | 2 + .../testdata/tracing-multiple-routes.out.yaml | 2 + internal/gatewayapi/translator.go | 4 +- internal/gatewayapi/validate.go | 2 +- internal/gatewayapi/zz_generated.deepcopy.go | 9 +- internal/message/types.go | 2 +- internal/provider/kubernetes/controller.go | 29 +- internal/provider/kubernetes/indexers.go | 17 +- internal/provider/kubernetes/predicates.go | 5 +- .../provider/kubernetes/predicates_test.go | 24 +- internal/provider/kubernetes/routes.go | 6 +- internal/provider/kubernetes/routes_test.go | 17 +- internal/provider/kubernetes/status.go | 11 +- internal/provider/kubernetes/test/utils.go | 10 +- internal/status/status.go | 9 +- site/content/en/latest/api/extension_types.md | 10 +- .../backendtrafficpolicy_test.go | 140 +- .../clienttrafficpolicy_test.go | 56 +- .../envoyextensionpolicy_test.go | 40 +- test/cel-validation/securitypolicy_test.go | 108 +- test/conformance/conformance_test.go | 60 +- .../experimental_conformance_test.go | 108 +- test/e2e/e2e_test.go | 25 +- .../e2e/merge_gateways/merge_gateways_test.go | 22 +- test/e2e/testdata/backend-tls.yaml | 18 +- .../ext-auth-grpc-securitypolicy.yaml | 10 +- .../ext-proc-envoyextensionpolicy.yaml | 10 +- test/e2e/tests/gateway_infra_resource.go | 4 +- test/e2e/tests/merge_gateways.go | 2 +- test/e2e/tests/udproute.go | 4 +- test/e2e/upgrade/eg_upgrade_test.go | 23 +- tools/crd-ref-docs/config.yaml | 4 +- tools/linter/yamllint/.yamllint | 1 + tools/make/lint.mk | 2 +- 369 files changed, 14623 insertions(+), 8450 deletions(-) diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index 4689fdfeea9..4dd71d945da 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -43,7 +43,7 @@ type BackendTrafficPolicySpec struct { // is being attached to. // This Policy and the TargetRef MUST be in the same namespace // for this Policy to have effect and be applied to the Gateway. - TargetRef gwapiv1a2.PolicyTargetReferenceWithSectionName `json:"targetRef"` + TargetRef gwapiv1a2.LocalPolicyTargetReferenceWithSectionName `json:"targetRef"` // RateLimit allows the user to limit the number of incoming requests // to a predefined value based on attributes within the traffic flow. diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index 8f85d0617c7..b84d7a9698e 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -45,7 +45,7 @@ type ClientTrafficPolicySpec struct { // This Policy and the TargetRef MUST be in the same namespace // for this Policy to have effect and be applied to the Gateway. // TargetRef - TargetRef gwapiv1a2.PolicyTargetReferenceWithSectionName `json:"targetRef"` + TargetRef gwapiv1a2.LocalPolicyTargetReferenceWithSectionName `json:"targetRef"` // TcpKeepalive settings associated with the downstream client connection. // If defined, sets SO_KEEPALIVE on the listener socket to enable TCP Keepalives. // Disabled by default. diff --git a/api/v1alpha1/envoyextensionypolicy_types.go b/api/v1alpha1/envoyextensionypolicy_types.go index 81015567934..de2bb14595f 100644 --- a/api/v1alpha1/envoyextensionypolicy_types.go +++ b/api/v1alpha1/envoyextensionypolicy_types.go @@ -42,7 +42,7 @@ type EnvoyExtensionPolicySpec struct { // is being attached to. // This Policy and the TargetRef MUST be in the same namespace // for this Policy to have effect and be applied to the Gateway or xRoute. - TargetRef gwapiv1a2.PolicyTargetReferenceWithSectionName `json:"targetRef"` + TargetRef gwapiv1a2.LocalPolicyTargetReferenceWithSectionName `json:"targetRef"` // Wasm is a list of Wasm extensions to be loaded by the Gateway. // Order matters, as the extensions will be loaded in the order they are diff --git a/api/v1alpha1/envoypatchpolicy_types.go b/api/v1alpha1/envoypatchpolicy_types.go index a6ae7b9db3b..22effb69756 100644 --- a/api/v1alpha1/envoypatchpolicy_types.go +++ b/api/v1alpha1/envoypatchpolicy_types.go @@ -49,12 +49,12 @@ type EnvoyPatchPolicySpec struct { JSONPatches []EnvoyJSONPatchConfig `json:"jsonPatches,omitempty"` // TargetRef is the name of the Gateway API resource this policy // is being attached to. - // By default attaching to Gateway is supported and + // By default, attaching to Gateway is supported and // when mergeGateways is enabled it should attach to GatewayClass. // This Policy and the TargetRef MUST be in the same namespace // for this Policy to have effect and be applied to the Gateway // TargetRef - TargetRef gwapiv1a2.PolicyTargetReference `json:"targetRef"` + TargetRef gwapiv1a2.LocalPolicyTargetReference `json:"targetRef"` // Priority of the EnvoyPatchPolicy. // If multiple EnvoyPatchPolicies are applied to the same // TargetRef, they will be applied in the ascending order of diff --git a/api/v1alpha1/securitypolicy_types.go b/api/v1alpha1/securitypolicy_types.go index 85c0b21892d..bbc86072324 100644 --- a/api/v1alpha1/securitypolicy_types.go +++ b/api/v1alpha1/securitypolicy_types.go @@ -43,7 +43,7 @@ type SecurityPolicySpec struct { // is being attached to. // This Policy and the TargetRef MUST be in the same namespace // for this Policy to have effect and be applied to the Gateway. - TargetRef gwapiv1a2.PolicyTargetReferenceWithSectionName `json:"targetRef"` + TargetRef gwapiv1a2.LocalPolicyTargetReferenceWithSectionName `json:"targetRef"` // CORS defines the configuration for Cross-Origin Resource Sharing (CORS). // diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 4e0ebe32dbf..8ebd4453c5c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1403,7 +1403,7 @@ func (in *EnvoyPatchPolicySpec) DeepCopyInto(out *EnvoyPatchPolicySpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - in.TargetRef.DeepCopyInto(&out.TargetRef) + out.TargetRef = in.TargetRef } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyPatchPolicySpec. diff --git a/charts/gateway-helm/crds/gatewayapi-crds.yaml b/charts/gateway-helm/crds/gatewayapi-crds.yaml index bbb71f11f65..8d327884535 100644 --- a/charts/gateway-helm/crds/gatewayapi-crds.yaml +++ b/charts/gateway-helm/crds/gatewayapi-crds.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 The Kubernetes Authors. +# Copyright 2024 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,30 +17,28 @@ # --- # -# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendlbpolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - labels: - gateway.networking.k8s.io/policy: Direct - name: backendtlspolicies.gateway.networking.k8s.io + name: backendlbpolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: BackendTLSPolicy - listKind: BackendTLSPolicyList - plural: backendtlspolicies + kind: BackendLBPolicy + listKind: BackendLBPolicyList + plural: backendlbpolicies shortNames: - - btlspolicy - singular: backendtlspolicy + - blbpolicy + singular: backendlbpolicy scope: Namespaced versions: - additionalPrinterColumns: @@ -50,332 +48,400 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: BackendTLSPolicy provides a way to configure how a Gateway connects - to a Backend via TLS. + description: |- + BackendLBPolicy provides a way to define load balancing rules + for a backend. 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' + 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' + 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 BackendTLSPolicy. + description: Spec defines the desired state of BackendLBPolicy. properties: - targetRef: - description: "TargetRef identifies an API object to apply the policy - to. Only Services have Extended support. Implementations MAY support - additional objects, with Implementation Specific support. Note that - this config applies to the entire referenced resource by default, - but this default may change in the future to provide a more granular - application of the policy. \n Support: Extended for Kubernetes Service - \n Support: Implementation-specific for any other resource" + sessionPersistence: + description: |- + SessionPersistence defines and configures session persistence + for the backend. + + + Support: Extended properties: - group: - description: Group is the group of the target resource. - 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 target resource. - 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 target resource. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace is the namespace of the referent. When - unspecified, the local namespace is inferred. Even when policy - targets a resource in a different namespace, it MUST only apply - to traffic originating from the same namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 - sectionName: - description: "SectionName is the name of a section within the - target resource. When unspecified, this targetRef targets the - entire resource. In the following resources, SectionName is - interpreted as the following: \n * Gateway: Listener Name * - Service: Port Name \n If a SectionName is specified, but does - not exist on the targeted object, the Policy must fail to attach, - and the policy implementation should record a `ResolvedRefs` - or similar Condition in the Policy's status." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + cookieConfig: + description: |- + CookieConfig 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. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string - required: - - group - - kind - - name - type: object - tls: - description: TLS contains backend TLS policy configuration. - properties: - caCertRefs: - description: "CACertRefs contains one or more references to Kubernetes - objects that contain a PEM-encoded TLS CA certificate bundle, - which is used to validate a TLS handshake between the Gateway - and backend Pod. \n If CACertRefs is empty or unspecified, then - WellKnownCACerts must be specified. Only one of CACertRefs or - WellKnownCACerts may be specified, not both. If CACertRefs is - empty or unspecified, the configuration for WellKnownCACerts - MUST be honored instead. \n References to a resource in a different - namespace are invalid for the moment, although we will revisit - this in the future. \n A single CACertRef 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. \n Support: Core - An optional single - reference to a Kubernetes ConfigMap, with the CA certificate - in a key named `ca.crt`. \n Support: Implementation-specific - (More than one reference, or other kinds of resources)." - 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. \n 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: 8 - type: array - hostname: - description: "Hostname is used for two purposes in the connection - between Gateways and backends: \n 1. Hostname MUST be used as - the SNI to connect to the backend (RFC 6066). 2. Hostname MUST - be used for authentication and MUST match the certificate served - by the matching backend. \n 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])?)*$ + sessionName: + 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. + + + Support: Implementation-specific + maxLength: 128 type: string - wellKnownCACerts: - description: "WellKnownCACerts specifies whether system CA certificates - may be used in the TLS handshake between the gateway and backend - pod. \n If WellKnownCACerts is unspecified or empty (\"\"), - then CACertRefs must be specified with at least one entry for - a valid configuration. Only one of CACertRefs or WellKnownCACerts - may be specified, not both. \n Support: Core for \"System\"" + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use a header or cookie. Defaults to cookie based session + persistence. + + + Support: Core for "Cookie" type + + + Support: Extended for "Header" type enum: - - System + - Cookie + - Header type: string - required: - - hostname type: object x-kubernetes-validations: - - message: must not contain both CACertRefs and WellKnownCACerts - rule: '!(has(self.caCertRefs) && size(self.caCertRefs) > 0 && has(self.wellKnownCACerts) - && self.wellKnownCACerts != "")' - - message: must specify either CACertRefs or WellKnownCACerts - rule: (has(self.caCertRefs) && size(self.caCertRefs) > 0 || has(self.wellKnownCACerts) - && self.wellKnownCACerts != "") + - message: AbsoluteTimeout must be specified when cookie lifetimeType + is Permanent + rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' + targetRefs: + description: |- + TargetRef identifies an API object to apply policy to. + Currently, Backends (i.e. Service, ServiceImport, or any + implementation-specific backendRef) are the only valid API + target references. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + 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 target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - group + - kind + - name + x-kubernetes-list-type: map required: - - targetRef - - tls + - targetRefs type: object status: - description: Status defines the current state of BackendTLSPolicy. + description: Status defines the current state of BackendLBPolicy. properties: ancestors: - description: "Ancestors is a list of ancestor resources (usually Gateways) - 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. \n Note that choosing the relevant ancestor is left - to the Policy designers; an important part of Policy design is designing - the right object level at which to namespace this status. \n 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. \n 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. \n A maximum of 16 ancestors will be represented - in this list. An empty list means the Policy is not relevant for - any ancestors. \n 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. For example, if this list was full on - BackendTLSPolicy, no additional Gateways would be able to reference - the Service targeted by the BackendTLSPolicy." + description: |- + Ancestors is a list of ancestor resources (usually Gateways) 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. + + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + + 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. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. items: - description: "PolicyAncestorStatus describes the status of a route - with respect to an associated Ancestor. \n 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. \n 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. \n 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. \n 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. \n 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. \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -388,46 +454,45 @@ spec: respect to the given Ancestor. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -441,12 +506,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -464,16 +529,23 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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\/\-._~%!$&'()*+,;=:]+$ @@ -502,490 +574,594 @@ status: storedVersions: null --- # -# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - name: gatewayclasses.gateway.networking.k8s.io + labels: + gateway.networking.k8s.io/policy: Direct + name: backendtlspolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: GatewayClass - listKind: GatewayClassList - plural: gatewayclasses + kind: BackendTLSPolicy + listKind: BackendTLSPolicyList + plural: backendtlspolicies shortNames: - - gc - singular: gatewayclass - scope: Cluster + - btlspolicy + singular: backendtlspolicy + scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1 + name: v1alpha3 schema: openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n It is recommended that this resource - be used as a template for Gateways. This means that a Gateway is based on - the state of the GatewayClass at the time it was created and changes to - the GatewayClass or associated parameters are not propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n Whenever one or more Gateways are using a GatewayClass, - implementations SHOULD add the `gateway-exists-finalizer.gateway.networking.k8s.io` - finalizer on the associated GatewayClass. This ensures that a GatewayClass - associated with a Gateway is not deleted while in use. \n GatewayClass is - a Cluster level resource." + description: |- + BackendTLSPolicy provides a way to configure how a Gateway + connects to a Backend via TLS. 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' + 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' + 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 GatewayClass. + description: Spec defines the desired state of BackendTLSPolicy. properties: - controllerName: - description: "ControllerName is the name of the controller that is - managing Gateways of this class. The value of this field MUST be - a domain prefixed path. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n ParametersRef can reference a standard Kubernetes - resource, i.e. ConfigMap, or an implementation-specific custom resource. - The resource can be cluster-scoped or namespace-scoped. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. - 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. - 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 referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - name - type: object - required: - - controllerName - type: object - status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." - properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + targetRefs: + description: |- + TargetRefs identifies an API object to apply the policy to. + Only Services have Extended support. Implementations MAY support + additional objects, with Implementation Specific support. + Note that this config applies to the entire referenced resource + by default, but this default may change in the future to provide + a more granular application of the policy. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a + direct policy to. This should be used as part of Policy resources that can + target single resources. For more information on how this policy attachment + mode works, and a sample Policy resource, refer to the policy attachment + documentation for Gateway API. + + + Note: This should only be used for direct policy attachment when references + to SectionName are actually needed. In all other cases, + LocalPolicyTargetReference should be used. 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 + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ 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 + kind: + description: Kind is kind of the target resource. + maxLength: 63 minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + 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 + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - 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])$ + sectionName: + description: |- + SectionName is the name of a section within the target resource. When + unspecified, this targetRef targets the entire resource. In the following + resources, SectionName is interpreted as the following: + + + * Gateway: Listener name + * HTTPRoute: HTTPRouteRule name + * Service: Port name + + + If a SectionName is specified, but does not exist on the targeted object, + the Policy must fail to attach, and the policy implementation should record + a `ResolvedRefs` or similar Condition in the Policy's status. + 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: - - lastTransitionTime - - message - - reason - - status - - type + - group + - kind + - name type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 + maxItems: 16 + minItems: 1 type: array - x-kubernetes-list-type: set - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n It is recommended that this resource - be used as a template for Gateways. This means that a Gateway is based on - the state of the GatewayClass at the time it was created and changes to - the GatewayClass or associated parameters are not propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n Whenever one or more Gateways are using a GatewayClass, - implementations SHOULD add the `gateway-exists-finalizer.gateway.networking.k8s.io` - finalizer on the associated GatewayClass. This ensures that a GatewayClass - associated with a Gateway is not deleted while in use. \n GatewayClass is - a Cluster level resource." - 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 GatewayClass. - properties: - controllerName: - description: "ControllerName is the name of the controller that is - managing Gateways of this class. The value of this field MUST be - a domain prefixed path. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n ParametersRef can reference a standard Kubernetes - resource, i.e. ConfigMap, or an implementation-specific custom resource. - The resource can be cluster-scoped or namespace-scoped. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" + validation: + description: Validation contains backend TLS validation configuration. properties: - group: - description: Group is the group of the referent. - 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. - 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. + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to Kubernetes objects that + contain a PEM-encoded TLS CA certificate bundle, which is used to + validate a TLS handshake between the Gateway and backend Pod. + + + If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be + specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified, + not both. If CACertifcateRefs is empty or unspecified, the configuration for + WellKnownCACertificates MUST be honored instead if supported by the implementation. + + + References to a resource in a different namespace are invalid for the + moment, although we will revisit this in the future. + + + 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. + + + Support: Core - An optional single reference to a Kubernetes ConfigMap, + with the CA certificate in a key named `ca.crt`. + + + Support: Implementation-specific (More than one reference, or other kinds + of resources). + 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: 8 + type: array + hostname: + description: |- + Hostname is used for two purposes in the connection between Gateways and + backends: + + + 1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066). + 2. Hostname MUST be used for authentication and MUST match the certificate + served by the matching backend. + + + 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 - namespace: - description: Namespace is the namespace of the referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + wellKnownCACertificates: + description: |- + WellKnownCACertificates specifies whether system CA certificates may be used in + the TLS handshake between the gateway and backend pod. + + + If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs + must be specified with at least one entry for a valid configuration. Only one of + CACertificateRefs or WellKnownCACertificates may be specified, not both. If an + implementation does not support the WellKnownCACertificates field or the value + supplied is not supported, the Status Conditions on the Policy MUST be + updated to include an Accepted: False Condition with Reason: Invalid. + + + Support: Implementation-specific + enum: + - System type: string required: - - group - - kind - - name + - 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 + != "") required: - - controllerName + - targetRefs + - validation type: object status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." + description: Status defines the current state of BackendTLSPolicy. properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) 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. + + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + + 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. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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: - 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 + 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.\n---\nThis struct + is intended for direct use as an array at the field path + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + 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-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. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - 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])$ + 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: - - lastTransitionTime - - message - - reason - - status - - type + - ancestorRef + - controllerName type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 + maxItems: 16 type: array - x-kubernetes-list-type: set + required: + - ancestors type: object required: - spec @@ -1002,723 +1178,236 @@ status: storedVersions: null --- # -# config/crd/experimental/gateway.networking.k8s.io_gateways.yaml +# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - name: gateways.gateway.networking.k8s.io + name: gatewayclasses.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: Gateway - listKind: GatewayList - plural: gateways + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses shortNames: - - gtw - singular: gateway - scope: Namespaced + - gc + singular: gatewayclass + scope: Cluster versions: - additionalPrinterColumns: - - jsonPath: .spec.gatewayClassName - name: Class - type: string - - jsonPath: .status.addresses[*].value - name: Address + - jsonPath: .spec.controllerName + name: Controller type: string - - jsonPath: .status.conditions[?(@.type=="Programmed")].status - name: Programmed + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted type: string - jsonPath: .metadata.creationTimestamp name: Age type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string name: v1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + + GatewayClass is a Cluster level resource. 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' + 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' + 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 Gateway. + description: Spec defines the desired state of GatewayClass. properties: - addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n The Addresses field represents a request - for the address(es) on the \"outside of the Gateway\", that traffic - bound for this Gateway will use. This could be the IP address or - hostname of an external load balancer or other networking infrastructure, - or some other address that traffic will be sent to. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " - items: - description: GatewayAddress describes an address that can be bound - to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: IPAddress values must be unique - rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, - a2.type == a1.type && a2.value == a1.value) : true )' - - message: Hostname values must be unique - rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, - a2.type == a1.type && a2.value == a1.value) : true )' - gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + + Example: "example.net/gateway-controller". + + + This field is not mutable and cannot be empty. + + + 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string - infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + + If the referent cannot be found, the GatewayClass's "InvalidParameters" + status condition will be true. + + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: Implementation-specific properties: - annotations: - additionalProperties: - description: AnnotationValue is the value of an annotation in - Gateway API. This is used for validation of maps such as TLS - options. This roughly matches Kubernetes annotation validation, - although the length validation in that case is based on the - entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n For implementations - creating other Kubernetes objects, this should be the `metadata.annotations` - field on resources. For other implementations, this refers to - any relevant (implementation specific) \"annotations\" concepts. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - labels: - additionalProperties: - description: AnnotationValue is the value of an annotation in - Gateway API. This is used for validation of maps such as TLS - options. This roughly matches Kubernetes annotation validation, - although the length validation in that case is based on the - entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n For implementations creating - other Kubernetes objects, this should be the `metadata.labels` - field on resources. For other implementations, this refers to - any relevant (implementation specific) \"labels\" concepts. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n Each Listener in a set - of Listeners (for example, in a single Gateway) MUST be _distinct_, - in that a traffic flow MUST be able to be assigned to exactly one - listener. (This section uses \"set of Listeners\" rather than \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n The implementation can match inbound - requests to a single distinct Listener. When multiple Listeners - share values for fields (for example, two Listeners with the same - Port value), the implementation can match requests to only one of - the Listeners using other Listener fields. \n For example, the following - Listener scenarios are distinct: \n 1. Multiple Listeners with the - same Port that all use the \"HTTP\" Protocol that all have unique - Hostname values. 2. Multiple Listeners with the same Port that use - either the \"HTTPS\" or \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n Some fields in the Listener struct have possible values that - affect whether the Listener is distinct. Hostname is particularly - relevant for HTTP or HTTPS protocols. \n When using the Hostname - value to select between same-Port, same-Protocol Listeners, the - Hostname value must be different on each Listener for the Listener - to be distinct. \n When the Listeners are distinct based on Hostname, - inbound request hostnames MUST match from the most specific to least - specific Hostname values to choose the correct Listener and its - associated set of Routes. \n Exact matches must be processed before - wildcard matches, and wildcard matches must be processed before - fallback (empty Hostname value) matches. For example, `\"foo.example.com\"` - takes precedence over `\"*.example.com\"`, and `\"*.example.com\"` - takes precedence over `\"\"`. \n Additionally, if there are multiple - wildcard entries, more specific wildcard entries must be processed - before less specific wildcard entries. For example, `\"*.foo.example.com\"` - takes precedence over `\"*.example.com\"`. The precise definition - here is that the higher the number of dots in the hostname to the - right of the wildcard character, the higher the precedence. \n The - wildcard character will match any number of characters _and dots_ - to the left, however, so `\"*.example.com\"` will match both `\"foo.bar.example.com\"` - _and_ `\"bar.example.com\"`. \n If a set of Listeners contains Listeners - that are not distinct, then those Listeners are Conflicted, and - the implementation MUST set the \"Conflicted\" condition in the - Listener Status to \"True\". \n Implementations MAY choose to accept - a Gateway with some Conflicted Listeners only if they only accept - the partial Listener set that contains no Conflicted Listeners. - To put this another way, implementations may accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n The implementation MUST set a \"ListenersNotValid\" - condition on the Gateway Status when the Gateway contains Conflicted - Listeners whether or not they accept the Gateway. That Condition - SHOULD clearly indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 1. They are distinct. 2. The implementation can serve them - in compliance with the Addresses requirement that all Listeners - are available on all assigned addresses. \n Compatible combinations - in Extended support are expected to vary across implementations. - A combination that is compatible for one implementation may not - be compatible for another. \n For example, an implementation that - cannot serve both TCP and UDP listeners on the same address, or - cannot mix HTTPS and generic TLS listens on the same port would - not consider those cases compatible, even though they are distinct. - \n Note that requests SHOULD match at most one Listener. For example, - if Listeners are defined for \"foo.example.com\" and \"*.example.com\", - a request to \"foo.example.com\" SHOULD only be routed using routes - attached to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" - items: - description: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. - properties: - allowedRoutes: - default: - namespaces: - from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n Although a client - request may match multiple route rules, only one rule may - ultimately receive the request. Matching precedence MUST be - determined in order of the following criteria: \n * The most - specific match as defined by the Route type. * The oldest - Route based on creation timestamp. For example, a Route with - a creation timestamp of \"2020-09-08 01:02:03\" is given precedence - over a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - All valid rules within a Route attached to this Listener should - be implemented. Invalid Route rules can be ignored (sometimes - that will mean the full Route). If a Route rule transitions - from valid to invalid, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" - properties: - kinds: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n A RouteGroupKind - MUST correspond to kinds of Routes that are compatible - with the application protocol specified in the Listener's - Protocol field. If an implementation does not support - or recognize this resource type, it MUST set the \"ResolvedRefs\" - condition to False for this Listener with the \"InvalidRouteKinds\" - reason. \n Support: Core" - items: - description: RouteGroupKind indicates the group and kind - of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - namespaces: - default: - from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" - properties: - from: - default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * All: Routes - in all namespaces may be used by this Gateway. * Selector: - Routes in namespaces selected by the selector may - be used by this Gateway. * Same: Only Routes in the - same namespace may be used by this Gateway. \n Support: - Core" - enum: - - All - - Selector - - Same - type: string - selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - type: object - hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * TLS: The Listener Hostname MUST - match the SNI. * HTTP: The Listener Hostname MUST match the - Host header of the request. * HTTPS: The Listener Hostname - SHOULD match at both the TLS and HTTP protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n For HTTPRoute and TLSRoute resources, there - is an interaction with the `spec.hostnames` array. When both - listener and route specify hostnames, there MUST be an intersection - between the values for a Route to be accepted. For more information, - refer to the Route specific Hostnames documentation. \n Hostnames - that are prefixed with a wildcard label (`*.`) are interpreted - as a suffix match. That means that a match for `*.example.com` - would match both `test.example.com`, and `foo.test.example.com`, - but not `example.com`. \n 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 - name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n 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 - port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n Support: Core" - maxLength: 255 - minLength: 1 - pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ - type: string - tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" - properties: - certificateRefs: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n A single CertificateRef to - a Kubernetes Secret has \"Core\" support. Implementations - MAY choose to support attaching multiple certificates - to a Listener, but this behavior is implementation-specific. - \n References to a resource in different namespace are - invalid UNLESS there is a ReferenceGrant in the target - namespace that allows the certificate to be attached. - If a ReferenceGrant does not allow this reference, the - \"ResolvedRefs\" condition MUST be set to False for this - listener with the \"RefNotPermitted\" reason. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" - items: - description: "SecretObjectReference identifies an API - object including its namespace, defaulting to Secret. - \n 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. \n 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: - 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: Secret - description: Kind is kind of the referent. For example - "Secret". - 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 referenced - object. When unspecified, the local namespace is - inferred. \n 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. - \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - name - type: object - maxItems: 64 - type: array - mode: - default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" - enum: - - Terminate - - Passthrough - type: string - options: - additionalProperties: - description: AnnotationValue is the value of an annotation - in Gateway API. This is used for validation of maps - such as TLS options. This roughly matches Kubernetes - annotation validation, although the length validation - in that case is based on the entire size of the annotations - struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Options are a list of key/value pairs to enable - extended TLS configuration for each implementation. For - example, configuring the minimum TLS version or supported - cipher suites. \n A set of common keys MAY be defined - by the API in the future. To avoid any ambiguity, implementation-specific - definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. - Un-prefixed names are reserved for key names defined by - Gateway API. \n Support: Implementation-specific" - maxProperties: 16 - type: object - type: object - x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType - is Terminate - rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' - required: - - name - - port - - protocol - type: object - maxItems: 64 - minItems: 1 - type: array - x-kubernetes-list-map-keys: + group: + description: Group is the group of the referent. + 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. + 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 referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind - name - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - - message: tls must not be specified for protocols ['HTTP', 'TCP', - 'UDP'] - rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? - !has(l.tls) : true)' - - message: hostname must not be specified for protocols ['TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) - || l.hostname == '''') : true)' - - message: Listener name must be unique within the Gateway - rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) - - message: Combination of port, protocol and hostname must be unique - for each listener - rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol - == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname - == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + type: object required: - - gatewayClassName - - listeners + - controllerName type: object status: default: conditions: - lastTransitionTime: "1970-01-01T00:00:00Z" message: Waiting for controller - reason: Pending + reason: Waiting status: Unknown type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: Status defines the current state of Gateway. + description: |- + Status defines the current state of GatewayClass. + + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. properties: - addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * no addresses are - specified, all addresses are dynamically assigned * a combination - of specified and dynamic addresses are assigned * a specified address - was unusable (e.g. already in use) \n " - items: - description: GatewayStatusAddress describes a network address that - is bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n Implementations should prefer to express Gateway conditions using - the `GatewayConditionType` and `GatewayConditionReason` constants - so that operators and tools can converge on a common vocabulary - to describe Gateway state. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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 @@ -1732,11 +1421,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -1752,965 +1442,4907 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map - listeners: - description: Listeners provide status for each unique listener port - defined in the Spec. + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. items: - description: ListenerStatus is the status associated with a Listener. - properties: - attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n Successful attachment of a Route to a Listener is based - solely on the combination of the AllowedRoutes field on the - corresponding Listener and the Route's ParentRefs field. A - Route is successfully attached to a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." - format: int32 - type: integer - conditions: - description: Conditions describe the current condition of this - listener. - items: - description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct - is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" - 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. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) - 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 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - name: - description: Name is the name of the Listener that this status - corresponds to. - 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 - supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n If kinds are specified in Spec that are not supported, - they MUST NOT appear in this list and an implementation MUST - set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" - reason. If both valid and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." - items: - description: RouteGroupKind indicates the group and kind of - a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - required: - - attachedRoutes - - conditions - - name - - supportedKinds - type: object + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string maxItems: 64 type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map + x-kubernetes-list-type: set type: object required: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: - - jsonPath: .spec.gatewayClassName - name: Class - type: string - - jsonPath: .status.addresses[*].value - name: Address + - jsonPath: .spec.controllerName + name: Controller type: string - - jsonPath: .status.conditions[?(@.type=="Programmed")].status - name: Programmed + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted type: string - jsonPath: .metadata.creationTimestamp name: Age type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string name: v1beta1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + + GatewayClass is a Cluster level resource. 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' + 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' + 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 Gateway. + description: Spec defines the desired state of GatewayClass. properties: - addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n The Addresses field represents a request - for the address(es) on the \"outside of the Gateway\", that traffic - bound for this Gateway will use. This could be the IP address or - hostname of an external load balancer or other networking infrastructure, - or some other address that traffic will be sent to. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " - items: - description: GatewayAddress describes an address that can be bound - to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: IPAddress values must be unique - rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, - a2.type == a1.type && a2.value == a1.value) : true )' - - message: Hostname values must be unique - rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, - a2.type == a1.type && a2.value == a1.value) : true )' - gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + + Example: "example.net/gateway-controller". + + + This field is not mutable and cannot be empty. + + + 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string - infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + + If the referent cannot be found, the GatewayClass's "InvalidParameters" + status condition will be true. + + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: Implementation-specific properties: - annotations: - additionalProperties: - description: AnnotationValue is the value of an annotation in - Gateway API. This is used for validation of maps such as TLS - options. This roughly matches Kubernetes annotation validation, - although the length validation in that case is based on the - entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n For implementations - creating other Kubernetes objects, this should be the `metadata.annotations` - field on resources. For other implementations, this refers to - any relevant (implementation specific) \"annotations\" concepts. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - labels: - additionalProperties: - description: AnnotationValue is the value of an annotation in - Gateway API. This is used for validation of maps such as TLS - options. This roughly matches Kubernetes annotation validation, - although the length validation in that case is based on the - entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n For implementations creating - other Kubernetes objects, this should be the `metadata.labels` - field on resources. For other implementations, this refers to - any relevant (implementation specific) \"labels\" concepts. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" - maxProperties: 8 - type: object + group: + description: Group is the group of the referent. + 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. + 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 referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n Each Listener in a set - of Listeners (for example, in a single Gateway) MUST be _distinct_, - in that a traffic flow MUST be able to be assigned to exactly one - listener. (This section uses \"set of Listeners\" rather than \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n The implementation can match inbound - requests to a single distinct Listener. When multiple Listeners - share values for fields (for example, two Listeners with the same - Port value), the implementation can match requests to only one of - the Listeners using other Listener fields. \n For example, the following - Listener scenarios are distinct: \n 1. Multiple Listeners with the - same Port that all use the \"HTTP\" Protocol that all have unique - Hostname values. 2. Multiple Listeners with the same Port that use - either the \"HTTPS\" or \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n Some fields in the Listener struct have possible values that - affect whether the Listener is distinct. Hostname is particularly - relevant for HTTP or HTTPS protocols. \n When using the Hostname - value to select between same-Port, same-Protocol Listeners, the - Hostname value must be different on each Listener for the Listener - to be distinct. \n When the Listeners are distinct based on Hostname, - inbound request hostnames MUST match from the most specific to least - specific Hostname values to choose the correct Listener and its - associated set of Routes. \n Exact matches must be processed before - wildcard matches, and wildcard matches must be processed before - fallback (empty Hostname value) matches. For example, `\"foo.example.com\"` - takes precedence over `\"*.example.com\"`, and `\"*.example.com\"` - takes precedence over `\"\"`. \n Additionally, if there are multiple - wildcard entries, more specific wildcard entries must be processed - before less specific wildcard entries. For example, `\"*.foo.example.com\"` - takes precedence over `\"*.example.com\"`. The precise definition - here is that the higher the number of dots in the hostname to the - right of the wildcard character, the higher the precedence. \n The - wildcard character will match any number of characters _and dots_ - to the left, however, so `\"*.example.com\"` will match both `\"foo.bar.example.com\"` - _and_ `\"bar.example.com\"`. \n If a set of Listeners contains Listeners - that are not distinct, then those Listeners are Conflicted, and - the implementation MUST set the \"Conflicted\" condition in the - Listener Status to \"True\". \n Implementations MAY choose to accept - a Gateway with some Conflicted Listeners only if they only accept - the partial Listener set that contains no Conflicted Listeners. - To put this another way, implementations may accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n The implementation MUST set a \"ListenersNotValid\" - condition on the Gateway Status when the Gateway contains Conflicted - Listeners whether or not they accept the Gateway. That Condition - SHOULD clearly indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 1. They are distinct. 2. The implementation can serve them - in compliance with the Addresses requirement that all Listeners - are available on all assigned addresses. \n Compatible combinations - in Extended support are expected to vary across implementations. - A combination that is compatible for one implementation may not - be compatible for another. \n For example, an implementation that - cannot serve both TCP and UDP listeners on the same address, or - cannot mix HTTPS and generic TLS listens on the same port would - not consider those cases compatible, even though they are distinct. - \n Note that requests SHOULD match at most one Listener. For example, - if Listeners are defined for \"foo.example.com\" and \"*.example.com\", - a request to \"foo.example.com\" SHOULD only be routed using routes - attached to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: |- + Status defines the current state of GatewayClass. + + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. items: - description: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: - allowedRoutes: - default: - namespaces: - from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n Although a client - request may match multiple route rules, only one rule may - ultimately receive the request. Matching precedence MUST be - determined in order of the following criteria: \n * The most - specific match as defined by the Route type. * The oldest - Route based on creation timestamp. For example, a Route with - a creation timestamp of \"2020-09-08 01:02:03\" is given precedence - over a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - All valid rules within a Route attached to this Listener should - be implemented. Invalid Route rules can be ignored (sometimes - that will mean the full Route). If a Route rule transitions - from valid to invalid, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" - properties: - kinds: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n A RouteGroupKind - MUST correspond to kinds of Routes that are compatible - with the application protocol specified in the Listener's - Protocol field. If an implementation does not support - or recognize this resource type, it MUST set the \"ResolvedRefs\" - condition to False for this Listener with the \"InvalidRouteKinds\" - reason. \n Support: Core" - items: - description: RouteGroupKind indicates the group and kind - of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - namespaces: - default: - from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" - properties: - from: - default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * All: Routes - in all namespaces may be used by this Gateway. * Selector: - Routes in namespaces selected by the selector may - be used by this Gateway. * Same: Only Routes in the - same namespace may be used by this Gateway. \n Support: - Core" - enum: - - All - - Selector - - Same - type: string - selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - type: object - hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * TLS: The Listener Hostname MUST - match the SNI. * HTTP: The Listener Hostname MUST match the - Host header of the request. * HTTPS: The Listener Hostname - SHOULD match at both the TLS and HTTP protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n For HTTPRoute and TLSRoute resources, there - is an interaction with the `spec.hostnames` array. When both - listener and route specify hostnames, there MUST be an intersection - between the values for a Route to be accepted. For more information, - refer to the Route specific Hostnames documentation. \n Hostnames - that are prefixed with a wildcard label (`*.`) are interpreted - as a suffix match. That means that a match for `*.example.com` - would match both `test.example.com`, and `foo.test.example.com`, - but not `example.com`. \n 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])?)*$ + 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 - name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n 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])?)*$ + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 type: string - port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" - format: int32 - maximum: 65535 - minimum: 1 + 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 - protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n Support: Core" - maxLength: 255 + 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-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ type: string - tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" - properties: - certificateRefs: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n A single CertificateRef to - a Kubernetes Secret has \"Core\" support. Implementations - MAY choose to support attaching multiple certificates - to a Listener, but this behavior is implementation-specific. - \n References to a resource in different namespace are - invalid UNLESS there is a ReferenceGrant in the target - namespace that allows the certificate to be attached. - If a ReferenceGrant does not allow this reference, the - \"ResolvedRefs\" condition MUST be set to False for this - listener with the \"RefNotPermitted\" reason. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" - items: - description: "SecretObjectReference identifies an API - object including its namespace, defaulting to Secret. - \n 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. \n 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: - 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: Secret - description: Kind is kind of the referent. For example - "Secret". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. + items: + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_gateways.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: gateways.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gtw + singular: gateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + + Support: Extended + + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + + Support: Core + + + properties: + annotations: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Annotations that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. + For other implementations, this refers to any relevant (implementation specific) "annotations" concepts. + + + An implementation may chose to add additional implementation-specific annotations as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + labels: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Labels that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. + For other implementations, this refers to any relevant (implementation specific) "labels" concepts. + + + An implementation may chose to add additional implementation-specific labels as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the Gateway. This is optional if the + controller does not require any additional configuration. + + + This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis + + + The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: Implementation-specific + properties: + group: + description: Group is the group of the referent. + 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. + 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 + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + + HTTP Profile + + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + + TLS Profile + + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + + "Distinct" Listeners have the following property: + + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + + For example, the following Listener scenarios are distinct: + + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + + A Gateway's Listeners are considered "compatible" if: + + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + + Support: Core + items: + description: RouteGroupKind indicates the group and kind + of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + 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 + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + type: string + tls: + description: |- + TLS is the TLS configuration for the Listener. This field is required if + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + + 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: + 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: Secret + description: Kind is kind of the referent. For example + "Secret". + 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 referenced object. 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 + required: + - name + type: object + maxItems: 64 + type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + that requests a user to specify the client certificate. + The maximum depth of a certificate chain accepted in verification is Implementation specific. + + + Support: Extended + + + properties: + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to + Kubernetes objects that contain TLS certificates of + the Certificate Authorities that can be used + as a trust anchor to validate the certificates presented by the client. + + + A single CA certificate reference to a Kubernetes ConfigMap + has "Core" support. + Implementations MAY choose to support attaching multiple CA certificates to + a Listener, but this behavior is implementation-specific. + + + Support: Core - A single reference to a Kubernetes ConfigMap + with the CA certificate in a key named `ca.crt`. + + + Support: Implementation-specific (More than one reference, or other kinds + of resources). + + + References to a resource in a different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + description: |- + ObjectReference identifies an API object including its namespace. + + + 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 "ConfigMap" 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 + namespace: + description: |- + Namespace is the namespace of the referenced object. 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 + required: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Options are a list of key/value pairs to enable extended TLS + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + + Support: Implementation-specific + maxProperties: 16 + type: object + type: object + x-kubernetes-validations: + - message: certificateRefs or options must be specified when + mode is Terminate + rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) + > 0 || size(self.options) > 0 : true' + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: tls must not be specified for protocols ['HTTP', 'TCP', + 'UDP'] + rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? + !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' + - message: hostname must not be specified for protocols ['TCP', 'UDP'] + rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) + || l.hostname == '''') : true)' + - message: Listener name must be unique within the Gateway + rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) + - message: Combination of port, protocol and hostname must be unique + for each listener + rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol + == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname + == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + + This list may differ from the addresses provided in the spec under some + conditions: + + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the Gateway. + + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + + Known condition types are: + + + * "Accepted" + * "Programmed" + * "Ready" + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port + defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: |- + AttachedRoutes represents the total number of Routes that have been + successfully attached to this Listener. + + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + + Uses for this field include troubleshooting Route attachment and + measuring blast radius/impact of changes to a Listener. + format: int32 + type: integer + conditions: + description: Conditions describe the current condition of this + listener. + items: + description: "Condition contains details for one aspect of + the current state of this API Resource.\n---\nThis struct + is intended for direct use as an array at the field path + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status + corresponds to. + 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 + supportedKinds: + description: |- + SupportedKinds is the list indicating the Kinds supported by this + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. + items: + description: RouteGroupKind indicates the group and kind of + a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + + Support: Extended + + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + + Support: Core + + + properties: + annotations: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Annotations that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. + For other implementations, this refers to any relevant (implementation specific) "annotations" concepts. + + + An implementation may chose to add additional implementation-specific annotations as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + labels: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Labels that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. + For other implementations, this refers to any relevant (implementation specific) "labels" concepts. + + + An implementation may chose to add additional implementation-specific labels as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the Gateway. This is optional if the + controller does not require any additional configuration. + + + This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis + + + The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: Implementation-specific + properties: + group: + description: Group is the group of the referent. + 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. + 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 + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + + HTTP Profile + + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + + TLS Profile + + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + + "Distinct" Listeners have the following property: + + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + + For example, the following Listener scenarios are distinct: + + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + + A Gateway's Listeners are considered "compatible" if: + + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + + Support: Core + items: + description: RouteGroupKind indicates the group and kind + of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + 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 + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + type: string + tls: + description: |- + TLS is the TLS configuration for the Listener. This field is required if + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + + 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: + 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: Secret + description: Kind is kind of the referent. For example + "Secret". + 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 referenced object. 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 + required: + - name + type: object + maxItems: 64 + type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + that requests a user to specify the client certificate. + The maximum depth of a certificate chain accepted in verification is Implementation specific. + + + Support: Extended + + + properties: + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to + Kubernetes objects that contain TLS certificates of + the Certificate Authorities that can be used + as a trust anchor to validate the certificates presented by the client. + + + A single CA certificate reference to a Kubernetes ConfigMap + has "Core" support. + Implementations MAY choose to support attaching multiple CA certificates to + a Listener, but this behavior is implementation-specific. + + + Support: Core - A single reference to a Kubernetes ConfigMap + with the CA certificate in a key named `ca.crt`. + + + Support: Implementation-specific (More than one reference, or other kinds + of resources). + + + References to a resource in a different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + description: |- + ObjectReference identifies an API object including its namespace. + + + 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 "ConfigMap" 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 + namespace: + description: |- + Namespace is the namespace of the referenced object. 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 + required: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Options are a list of key/value pairs to enable extended TLS + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + + Support: Implementation-specific + maxProperties: 16 + type: object + type: object + x-kubernetes-validations: + - message: certificateRefs or options must be specified when + mode is Terminate + rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) + > 0 || size(self.options) > 0 : true' + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: tls must not be specified for protocols ['HTTP', 'TCP', + 'UDP'] + rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? + !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' + - message: hostname must not be specified for protocols ['TCP', 'UDP'] + rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) + || l.hostname == '''') : true)' + - message: Listener name must be unique within the Gateway + rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) + - message: Combination of port, protocol and hostname must be unique + for each listener + rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol + == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname + == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + + This list may differ from the addresses provided in the spec under some + conditions: + + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the Gateway. + + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + + Known condition types are: + + + * "Accepted" + * "Programmed" + * "Ready" + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port + defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: |- + AttachedRoutes represents the total number of Routes that have been + successfully attached to this Listener. + + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + + Uses for this field include troubleshooting Route attachment and + measuring blast radius/impact of changes to a Listener. + format: int32 + type: integer + conditions: + description: Conditions describe the current condition of this + listener. + items: + description: "Condition contains details for one aspect of + the current state of this API Resource.\n---\nThis struct + is intended for direct use as an array at the field path + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status + corresponds to. + 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 + supportedKinds: + description: |- + SupportedKinds is the list indicating the Kinds supported by this + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. + items: + description: RouteGroupKind indicates the group and kind of + a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: grpcroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GRPCRoute + listKind: GRPCRouteList + plural: grpcroutes + singular: grpcroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + GRPCRoute provides a way to route gRPC requests. This includes the capability + to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. + Filters can be used to specify additional processing steps. Backends specify + where matching requests will be routed. + + + GRPCRoute falls under extended support within the Gateway API. Within the + following specification, the word "MUST" indicates that an implementation + supporting GRPCRoute must conform to the indicated requirement, but an + implementation not supporting this route type need not follow the requirement + unless explicitly indicated. + + + Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST + accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via + ALPN. If the implementation does not support this, then it MUST set the + "Accepted" condition to "False" for the affected listener with a reason of + "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections + with an upgrade from HTTP/1. + + + Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST + support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial + upgrade from HTTP/1.1, i.e. with prior knowledge + (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation + does not support this, then it MUST set the "Accepted" condition to "False" + for the affected listener with a reason of "UnsupportedProtocol". + Implementations MAY also accept HTTP/2 connections with an upgrade from + HTTP/1, i.e. without prior knowledge. + 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 GRPCRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames to match against the GRPC + Host header to select a GRPCRoute to process the request. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label MUST appear by itself as the first label. + + + If a hostname is specified by both the Listener and GRPCRoute, there + MUST be at least one intersecting hostname for the GRPCRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and GRPCRoute have specified hostnames, any + GRPCRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + GRPCRoute specified `test.example.com` and `test.example.net`, + `test.example.net` MUST NOT be considered for a match. + + + If both the Listener and GRPCRoute have specified hostnames, and none + match with the criteria above, then the GRPCRoute MUST NOT be accepted by + the implementation. The implementation MUST raise an 'Accepted' Condition + with a status of `False` in the corresponding RouteParentStatus. + + + 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: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + The rejected Route MUST raise an 'Accepted' condition with a status of + 'False' in the corresponding RouteParentStatus. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. + 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 + maxItems: 16 + type: array + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. 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 other kinds 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. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + 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. + 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 + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName or port must be specified when parentRefs includes + 2 or more references to the same parent + rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ + == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) + || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName + == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) + || p2.port == 0)): true))' + - message: sectionName or port must be unique when parentRefs includes + 2 or more references to the same parent + rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ + == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) + || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName + == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName + == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) + || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port + == p2.port)))) + rules: + description: Rules are a list of GRPC matchers, filters and actions. + items: + description: |- + GRPCRouteRule defines the semantics for matching a gRPC request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive an `UNAVAILABLE` status. + + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + + When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive an `UNAVAILABLE` status. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. + Implementations may choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. + + + 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. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level MUST be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in GRPCRouteRule.) + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - 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-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + 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 + weight: + default: 1 + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support for this field varies based on the context where used. + format: int32 + maximum: 1000000 + minimum: 0 + 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + The effects of ordering of multiple behaviors are currently unspecified. + This can change in the future based on feedback during the alpha stage. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations that support + GRPCRoute. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + If an implementation can not support a combination of filters, it must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar + 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. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - 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-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + matches: + description: |- + Matches define conditions used for matching the rule against incoming + gRPC requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - method: + service: foo.bar + headers: + values: + version: 2 + - method: + service: foo.bar.v2 + ``` + + + For a request to match against this rule, it MUST satisfy + EITHER of the two conditions: + + + - service of foo.bar AND contains the header `version: 2` + - service of foo.bar.v2 + + + See the documentation for GRPCRouteMatch on how to specify multiple + match conditions to be ANDed together. + + + If no matches are specified, the implementation MUST match every gRPC request. + + + Proxy or Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing on + ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + * Characters in a matching service. + * Characters in a matching method. + * Header matches. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching rule meeting + the above criteria. + items: + description: |- + GRPCRouteMatch defines the predicate used to match requests to a given + action. Multiple match types are ANDed together, i.e. the match will + evaluate to true only if all conditions are satisfied. + + + For example, the match below will match a gRPC request only if its service + is `foo` AND it contains the `version: v1` header: + + + ``` + matches: + - method: + type: Exact + service: "foo" + headers: + - name: "version" + value "v1" + + + ``` + properties: + headers: + description: |- + Headers specifies gRPC request header matchers. Multiple match values are + ANDed together, meaning, a request MUST match all the specified headers + to select the route. + items: + description: |- + GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request + headers. + properties: + name: + description: |- + Name is the name of the gRPC Header to be matched. + + + If multiple entries specify equivalent header names, only 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 + type: + default: Exact + description: Type specifies how to match against + the value of the header. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of the gRPC Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies a gRPC request service/method matcher. If this field is + not specified, all services and methods will match. + properties: + method: + description: |- + Value of the method to match against. If left empty or omitted, will + match all services. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 + service: + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 type: string - namespace: - description: "Namespace is the namespace of the referenced - object. When unspecified, the local namespace is - inferred. \n 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. - \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: + default: Exact + description: |- + Type specifies how to match against the service and/or method. + Support: Core (Exact with service and method specified) + + + Support: Implementation-specific (Exact with method specified but no service specified) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - RegularExpression type: string - required: - - name type: object - maxItems: 64 - type: array - mode: - default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" - enum: - - Terminate - - Passthrough + x-kubernetes-validations: + - message: One or both of 'service' or 'method' must be + specified + rule: 'has(self.type) ? has(self.service) || has(self.method) + : true' + - message: service must only contain valid characters + (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): + true' + - message: method must only contain valid characters (matching + ^[A-Za-z_][A-Za-z_0-9]*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): + true' + type: object + maxItems: 8 + type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + 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 - options: - additionalProperties: - description: AnnotationValue is the value of an annotation - in Gateway API. This is used for validation of maps - such as TLS options. This roughly matches Kubernetes - annotation validation, although the length validation - in that case is based on the entire size of the annotations - struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Options are a list of key/value pairs to enable - extended TLS configuration for each implementation. For - example, configuring the minimum TLS version or supported - cipher suites. \n A set of common keys MAY be defined - by the API in the future. To avoid any ambiguity, implementation-specific - definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. - Un-prefixed names are reserved for key names defined by - Gateway API. \n Support: Implementation-specific" - maxProperties: 16 + cookieConfig: + description: |- + CookieConfig 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. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + sessionName: + 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. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use 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: certificateRefs must be specified when TLSModeType - is Terminate - rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' - required: - - name - - port - - protocol + - message: AbsoluteTimeout must be specified when cookie lifetimeType + is Permanent + rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' type: object - maxItems: 64 - minItems: 1 + maxItems: 16 type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - - message: tls must not be specified for protocols ['HTTP', 'TCP', - 'UDP'] - rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? - !has(l.tls) : true)' - - message: hostname must not be specified for protocols ['TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) - || l.hostname == '''') : true)' - - message: Listener name must be unique within the Gateway - rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) - - message: Combination of port, protocol and hostname must be unique - for each listener - rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol - == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname - == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' - required: - - gatewayClassName - - listeners type: object status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: Status defines the current state of Gateway. + description: Status defines the current state of GRPCRoute. properties: - addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * no addresses are - specified, all addresses are dynamically assigned * a combination - of specified and dynamic addresses are assigned * a specified address - was unusable (e.g. already in use) \n " - items: - description: GatewayStatusAddress describes a network address that - is bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n Implementations should prefer to express Gateway conditions using - the `GatewayConditionType` and `GatewayConditionReason` constants - so that operators and tools can converge on a common vocabulary - to describe Gateway state. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - 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. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - 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 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - listeners: - description: Listeners provide status for each unique listener port - defined in the Spec. + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. items: - description: ListenerStatus is the status associated with a Listener. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: - attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n Successful attachment of a Route to a Listener is based - solely on the combination of the AllowedRoutes field on the - corresponding Listener and the Route's ParentRefs field. A - Route is successfully attached to a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." - format: int32 - type: integer conditions: - description: Conditions describe the current condition of this - listener. + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -2724,12 +6356,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -2741,138 +6373,254 @@ spec: - type type: object maxItems: 8 + minItems: 1 type: array x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map - name: - description: Name is the name of the Listener that this status - corresponds to. + 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])?)*$ + 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 - supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n If kinds are specified in Spec that are not supported, - they MUST NOT appear in this list and an implementation MUST - set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" - reason. If both valid and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." - items: - description: RouteGroupKind indicates the group and kind of - a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array + parentRef: + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus 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 required: - - attachedRoutes - - conditions - - name - - supportedKinds + - controllerName + - parentRef type: object - maxItems: 64 + maxItems: 32 type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map + required: + - parents type: object - required: - - spec type: object served: true storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null ---- -# -# config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: grpcroutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: GRPCRoute - listKind: GRPCRouteList - plural: grpcroutes - singular: grpcroute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.hostnames - name: Hostnames - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date + - deprecated: true + deprecationWarning: The v1alpha2 version of GRPCRoute has been deprecated and + will be removed in a future release of the API. Please upgrade to v1. name: v1alpha2 schema: openAPIV3Schema: - description: "GRPCRoute provides a way to route gRPC requests. This includes - the capability to match requests by hostname, gRPC service, gRPC method, - or HTTP/2 header. Filters can be used to specify additional processing steps. - Backends specify where matching requests will be routed. \n GRPCRoute falls - under extended support within the Gateway API. Within the following specification, - the word \"MUST\" indicates that an implementation supporting GRPCRoute - must conform to the indicated requirement, but an implementation not supporting - this route type need not follow the requirement unless explicitly indicated. - \n Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` - MUST accept HTTP/2 connections without an initial upgrade from HTTP/1.1, - i.e. via ALPN. If the implementation does not support this, then it MUST - set the \"Accepted\" condition to \"False\" for the affected listener with - a reason of \"UnsupportedProtocol\". Implementations MAY also accept HTTP/2 - connections with an upgrade from HTTP/1. \n Implementations supporting `GRPCRoute` - with the `HTTP` `ProtocolType` MUST support HTTP/2 over cleartext TCP (h2c, - https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial upgrade - from HTTP/1.1, i.e. with prior knowledge (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). - If the implementation does not support this, then it MUST set the \"Accepted\" - condition to \"False\" for the affected listener with a reason of \"UnsupportedProtocol\". + description: |- + GRPCRoute provides a way to route gRPC requests. This includes the capability + to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. + Filters can be used to specify additional processing steps. Backends specify + where matching requests will be routed. + + + GRPCRoute falls under extended support within the Gateway API. Within the + following specification, the word "MUST" indicates that an implementation + supporting GRPCRoute must conform to the indicated requirement, but an + implementation not supporting this route type need not follow the requirement + unless explicitly indicated. + + + Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST + accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via + ALPN. If the implementation does not support this, then it MUST set the + "Accepted" condition to "False" for the affected listener with a reason of + "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections + with an upgrade from HTTP/1. + + + Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST + support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial + upgrade from HTTP/1.1, i.e. with prior knowledge + (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation + does not support this, then it MUST set the "Accepted" condition to "False" + for the affected listener with a reason of "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections with an upgrade from - HTTP/1, i.e. without prior knowledge." + HTTP/1, i.e. without prior knowledge. 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' + 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' + 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 @@ -2880,56 +6628,86 @@ spec: description: Spec defines the desired state of GRPCRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames to match against - the GRPC Host header to select a GRPCRoute to process the request. - This matches the RFC 1123 definition of a hostname with 2 notable - exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed - with a wildcard label (`*.`). The wildcard label MUST appear by - itself as the first label. \n If a hostname is specified by both - the Listener and GRPCRoute, there MUST be at least one intersecting - hostname for the GRPCRoute to be attached to the Listener. For example: - \n * A Listener with `test.example.com` as the hostname matches - GRPCRoutes that have either not specified any hostnames, or have - specified at least one of `test.example.com` or `*.example.com`. + description: |- + Hostnames defines a set of hostnames to match against the GRPC + Host header to select a GRPCRoute to process the request. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label MUST appear by itself as the first label. + + + If a hostname is specified by both the Listener and GRPCRoute, there + MUST be at least one intersecting hostname for the GRPCRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches GRPCRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `test.example.com` and `*.example.com` would both match. On the - other hand, `example.com` and `test.example.net` would not match. - \n Hostnames that are prefixed with a wildcard label (`*.`) are - interpreted as a suffix match. That means that a match for `*.example.com` - would match both `test.example.com`, and `foo.test.example.com`, - but not `example.com`. \n If both the Listener and GRPCRoute have - specified hostnames, any GRPCRoute hostnames that do not match the - Listener hostname MUST be ignored. For example, if a Listener specified - `*.example.com`, and the GRPCRoute specified `test.example.com` - and `test.example.net`, `test.example.net` MUST NOT be considered - for a match. \n If both the Listener and GRPCRoute have specified - hostnames, and none match with the criteria above, then the GRPCRoute - MUST NOT be accepted by the implementation. The implementation MUST - raise an 'Accepted' Condition with a status of `False` in the corresponding - RouteParentStatus. \n 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: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n The rejected Route MUST raise an 'Accepted' condition with a - status of 'False' in the corresponding RouteParentStatus. \n Support: - Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and GRPCRoute have specified hostnames, any + GRPCRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + GRPCRoute specified `test.example.com` and `test.example.net`, + `test.example.net` MUST NOT be considered for a match. + + + If both the Listener and GRPCRoute have specified hostnames, and none + match with the criteria above, then the GRPCRoute MUST NOT be accepted by + the implementation. The implementation MUST raise an 'Accepted' Condition + with a status of `False` in the corresponding RouteParentStatus. + + + 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: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + The rejected Route MUST raise an 'Accepted' condition with a status of + 'False' in the corresponding RouteParentStatus. + + + Support: Core items: - description: "Hostname is the fully qualified domain name of a network - host. This matches the RFC 1123 definition of a hostname with - 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname - may be prefixed with a wildcard label (`*.`). The wildcard label - must appear by itself as the first label. \n Hostname can be \"precise\" - which is a domain name without the terminating dot of a network - host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain - name prefixed with a single wildcard label (e.g. `*.example.com`). - \n Note that as per RFC1035 and RFC1123, a *label* must consist - of lower case alphanumeric characters or '-', and must start and - end with an alphanumeric character. No other punctuation is allowed." + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. maxLength: 253 minLength: 1 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ @@ -2937,165 +6715,246 @@ spec: maxItems: 16 type: array parentRefs: - description: "ParentRefs references the resources (usually Gateways) - that a Route wants to be attached to. Note that the referenced parent - resource needs to allow this for the attachment to be complete. - For Gateways, that means the Gateway needs to allow attachment from - Routes of this kind and namespace. For Services, that means the - Service must either be in the same namespace for a \"producer\" - route, or the mesh implementation must support and allow \"consumer\" - routes for the referenced Service. ReferenceGrant is not applicable - for governing ParentRefs to Services - it is not possible to create - a \"producer\" route for a Service in a different namespace from - the Route. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * They select different objects. If this is the case, - then parentRef entries are distinct. In terms of fields, this means - that the multi-part key defined by `group`, `kind`, `namespace`, - and `name` must be unique across all parentRef entries in the Route. - * They do not select different objects, but for each optional field - used, each ParentRef that selects the same object must set the same - set of optional fields to different values. If one ParentRef sets - a combination of optional fields, all must set the same combination. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same - object must also set `port`. * If one ParentRef sets `sectionName` - and `port`, all ParentRefs referencing the same object must also - set `sectionName` and `port`. \n It is possible to separately reference - multiple distinct objects that may be collapsed by an implementation. - For example, some implementations may choose to merge compatible - Gateway Listeners together. If that is the case, the list of routes - attached to those resources should also be merged. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific rules. 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 other kinds of cross-namespace - reference. \n 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. \n 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. \n " + 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 other kinds 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. + + + + + + items: - description: "ParentReference identifies an API object (usually - a Gateway) that can be considered a parent of this resource (usually - a route). There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + 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. 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -3131,82 +6990,117 @@ spec: rules: description: Rules are a list of GRPC matchers, filters and actions. items: - description: GRPCRouteRule defines the semantics for matching a - gRPC request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + GRPCRouteRule defines the semantics for matching a gRPC request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n If *all* entries in BackendRefs are invalid, and there - are also no filters specified in this route rule, *all* traffic - which matches this rule MUST receive an `UNAVAILABLE` status. - \n See the GRPCBackendRef definition for the rules about what - makes a single GRPCBackendRef invalid. \n When a GRPCBackendRef - is invalid, `UNAVAILABLE` statuses MUST be returned for requests - that would have otherwise been routed to an invalid backend. - If multiple backends are specified, and some are invalid, - the proportion of requests that would otherwise have been - routed to an invalid backend MUST receive an `UNAVAILABLE` - status. \n For example, if two backends are specified with - equal weights, and one is invalid, 50 percent of traffic MUST - receive an `UNAVAILABLE` status. Implementations may choose - how that 50 percent is determined. \n Support: Core for Kubernetes - Service \n Support: Implementation-specific for any other - resource \n Support for weight: Core" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive an `UNAVAILABLE` status. + + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + + When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive an `UNAVAILABLE` status. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. + Implementations may choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Implementation-specific for any other resource + + + Support for weight: Core items: - description: "GRPCBackendRef defines how a GRPCRoute forwards - a gRPC request. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + description: |- + GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. + + + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n If a Service appProtocol isn't specified, - an implementation MAY infer the backend protocol through - its own means. Implementations MAY infer the protocol from - the Route type referring to the backend Service. \n If a - Route is not able to send traffic to the backend using the - specified protocol then the backend is considered invalid. - Implementations MUST set the \"ResolvedRefs\" condition - to \"False\" with the \"UnsupportedProtocol\" reason. \n - " + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + properties: filters: - description: "Filters defined at this level MUST be executed - if and only if the request is being forwarded to the - backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in GRPCRouteRule.)" + description: |- + Filters defined at this level MUST be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in GRPCRouteRule.) items: - description: GRPCRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. GRPCRouteFilters are meant as an extension - point to express processing that may be done in Gateway - implementations. Some examples include request or - response modification, implementing authentication - strategies, rate-limiting, and traffic shaping. API - guarantee/conformance is defined based on the type - of the filter. + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. properties: extensionRef: - description: "ExtensionRef is an optional, implementation-specific - extension to the \"filter\" behavior. For example, - resource \"myroutefilter\" in group \"networking.example.net\"). - ExtensionRef MUST NOT be used for core and extended - filters. \n Support: Implementation-specific \n - This filter can be used multiple times within - the same rule." + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. 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. + 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 @@ -3228,35 +7122,50 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It - appends to any existing values associated - with the header name. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -3277,44 +7186,68 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from - the HTTP request before the action. The value - of Remove is a list of HTTP header names. - Note that the header names are case-insensitive - (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with - the given header (name, value) before the - action. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -3336,64 +7269,80 @@ spec: x-kubernetes-list-type: map type: object requestMirror: - description: "RequestMirror defines a schema for - a filter that mirrors requests. Requests are sent - to the specified destination, but responses from - that destination are ignored. \n This filter can - be used multiple times within the same rule. Note - that not all implementations will be able to support - mirroring to multiple backends. \n Support: Extended" + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended properties: backendRef: - description: "BackendRef references a resource - where mirrored requests are sent. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n If the referent cannot be found, - this BackendRef is invalid and must be dropped - from the Gateway. The controller must ensure - the \"ResolvedRefs\" condition on the Route - status is set to `status: False` and not configure + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. - \n If there is a cross-namespace reference - to an *existing* object that is not allowed - by a ReferenceGrant, the controller must ensure - the \"ResolvedRefs\" condition on the Route - is set to `status: False`, with the \"RefNotPermitted\" - reason and not configure this backend in the - underlying implementation. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -3404,29 +7353,29 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -3442,35 +7391,50 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It - appends to any existing values associated - with the header name. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -3491,44 +7455,68 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from - the HTTP request before the action. The value - of Remove is a list of HTTP header names. - Note that the header names are case-insensitive - (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with - the given header (name, value) before the - action. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -3550,32 +7538,38 @@ spec: x-kubernetes-list-type: map type: object type: - description: "Type identifies the type of filter - to apply. As with other API fields, types are - classified into three conformance levels: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - supporting GRPCRoute MUST support core filters. - \n - Extended: Filter types and their corresponding - configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - - Implementation-specific: Filters that are defined - and supported by specific vendors. In the future, - filters showing convergence in behavior across - multiple implementations will be considered for - inclusion in extended or core conformance levels. - Filter-specific configuration for such filters - is specified using the ExtensionRef field. `Type` - MUST be set to \"ExtensionRef\" for custom filters. - \n Implementers are encouraged to define custom - implementation types to extend the core API with - implementation-specific behavior. \n If a reference - to a custom filter type cannot be resolved, the - filter MUST NOT be skipped. Instead, requests - that would have been processed by that filter - MUST receive a HTTP error response. \n " + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + enum: - ResponseHeaderModifier - RequestHeaderModifier @@ -3626,25 +7620,33 @@ spec: <= 1 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -3655,43 +7657,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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 weight: default: 1 - description: "Weight specifies the proportion of requests - forwarded to the referenced backend. This is computed - as weight/(sum of all weights in this BackendRefs list). - For non-zero values, there may be some epsilon from - the exact proportion defined here depending on the precision - an implementation supports. Weight is not a percentage - and the sum of weights does not need to equal 100. \n - If only one backend is specified and it has a weight - greater than 0, 100% of the traffic is forwarded to - that backend. If weight is set to 0, no traffic should - be forwarded for this entry. If unspecified, weight - defaults to 1. \n Support for this field varies based - on the context where used." + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support for this field varies based on the context where used. format: int32 maximum: 1000000 minimum: 0 @@ -3706,44 +7716,63 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - ALL core filters MUST be supported by - all implementations that support GRPCRoute. - Implementers - are encouraged to support extended filters. - Implementation-specific - custom filters have no API guarantees across implementations. - \n Specifying the same filter multiple times is not supported - unless explicitly indicated in the filter. \n If an implementation - can not support a combination of filters, it must clearly + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + The effects of ordering of multiple behaviors are currently unspecified. + This can change in the future based on feedback during the alpha stage. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations that support + GRPCRoute. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + If an implementation can not support a combination of filters, it must clearly document that limitation. In cases where incompatible or unsupported - filters are specified and cause the `Accepted` condition to - be set to status `False`, implementations may use the `IncompatibleFilters` - reason to specify this configuration error. \n Support: Core" + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core items: - description: GRPCRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - GRPCRouteFilters are meant as an extension point to express - processing that may be done in Gateway implementations. - Some examples include request or response modification, - implementing authentication strategies, rate-limiting, and - traffic shaping. API guarantee/conformance is defined based - on the type of the filter. + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. properties: extensionRef: - description: "ExtensionRef is an optional, implementation-specific - extension to the \"filter\" behavior. For example, - resource \"myroutefilter\" in group \"networking.example.net\"). - ExtensionRef MUST NOT be used for core and extended - filters. \n Support: Implementation-specific \n This - filter can be used multiple times within the same rule." + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. 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. + 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 @@ -3765,32 +7794,49 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It appends - to any existing values associated with the header - name. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -3811,40 +7857,67 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from the - HTTP request before the action. The value of Remove - is a list of HTTP header names. Note that the header - names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with the - given header (name, value) before the action. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -3866,60 +7939,80 @@ spec: x-kubernetes-list-type: map type: object requestMirror: - description: "RequestMirror defines a schema for a filter - that mirrors requests. Requests are sent to the specified - destination, but responses from that destination are - ignored. \n This filter can be used multiple times within - the same rule. Note that not all implementations will - be able to support mirroring to multiple backends. \n - Support: Extended" + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended properties: backendRef: - description: "BackendRef references a resource where - mirrored requests are sent. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - If the referent cannot be found, this BackendRef - is invalid and must be dropped from the Gateway. - The controller must ensure the \"ResolvedRefs\" - condition on the Route status is set to `status: - False` and not configure this backend in the underlying - implementation. \n If there is a cross-namespace - reference to an *existing* object that is not allowed - by a ReferenceGrant, the controller must ensure - the \"ResolvedRefs\" condition on the Route is - set to `status: False`, with the \"RefNotPermitted\" - reason and not configure this backend in the underlying - implementation. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -3930,25 +8023,28 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -3965,32 +8061,49 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It appends - to any existing values associated with the header - name. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -4011,40 +8124,67 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from the - HTTP request before the action. The value of Remove - is a list of HTTP header names. Note that the header - names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with the - given header (name, value) before the action. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -4066,29 +8206,38 @@ spec: x-kubernetes-list-type: map type: object type: - description: "Type identifies the type of filter to apply. - As with other API fields, types are classified into - three conformance levels: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations supporting GRPCRoute MUST support - core filters. \n - Extended: Filter types and their - corresponding configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - Implementation-specific: - Filters that are defined and supported by specific vendors. - In the future, filters showing convergence in behavior - across multiple implementations will be considered for - inclusion in extended or core conformance levels. Filter-specific - configuration for such filters is specified using the - ExtensionRef field. `Type` MUST be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n If a reference - to a custom filter type cannot be resolved, the filter - MUST NOT be skipped. Instead, requests that would have - been processed by that filter MUST receive a HTTP error - response. \n " + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + enum: - ResponseHeaderModifier - RequestHeaderModifier @@ -4137,60 +8286,110 @@ spec: rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1 matches: - description: "Matches define conditions used for matching the - rule against incoming gRPC requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - method: service: foo.bar headers: values: - version: 2 - method: service: foo.bar.v2 ``` \n For a request - to match against this rule, it MUST satisfy EITHER of the - two conditions: \n - service of foo.bar AND contains the header - `version: 2` - service of foo.bar.v2 \n See the documentation - for GRPCRouteMatch on how to specify multiple match conditions - to be ANDed together. \n If no matches are specified, the - implementation MUST match every gRPC request. \n Proxy or - Load Balancer routing configuration generated from GRPCRoutes - MUST prioritize rules based on the following criteria, continuing - on ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. - Precedence MUST be given to the rule with the largest number - of: \n * Characters in a matching non-wildcard hostname. * - Characters in a matching hostname. * Characters in a matching - service. * Characters in a matching method. * Header matches. - \n If ties still exist across multiple Routes, matching precedence - MUST be determined in order of the following criteria, continuing - on ties: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n If ties still exist within the Route that has been given - precedence, matching precedence MUST be granted to the first - matching rule meeting the above criteria." + description: |- + Matches define conditions used for matching the rule against incoming + gRPC requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - method: + service: foo.bar + headers: + values: + version: 2 + - method: + service: foo.bar.v2 + ``` + + + For a request to match against this rule, it MUST satisfy + EITHER of the two conditions: + + + - service of foo.bar AND contains the header `version: 2` + - service of foo.bar.v2 + + + See the documentation for GRPCRouteMatch on how to specify multiple + match conditions to be ANDed together. + + + If no matches are specified, the implementation MUST match every gRPC request. + + + Proxy or Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing on + ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + * Characters in a matching service. + * Characters in a matching method. + * Header matches. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching rule meeting + the above criteria. items: - description: "GRPCRouteMatch defines the predicate used to - match requests to a given action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a gRPC request only if its service is `foo` - AND it contains the `version: v1` header: \n ``` matches: - - method: type: Exact service: \"foo\" headers: - name: - \"version\" value \"v1\" \n ```" + description: |- + GRPCRouteMatch defines the predicate used to match requests to a given + action. Multiple match types are ANDed together, i.e. the match will + evaluate to true only if all conditions are satisfied. + + + For example, the match below will match a gRPC request only if its service + is `foo` AND it contains the `version: v1` header: + + + ``` + matches: + - method: + type: Exact + service: "foo" + headers: + - name: "version" + value "v1" + + + ``` properties: headers: - description: Headers specifies gRPC request header matchers. - Multiple match values are ANDed together, meaning, a - request MUST match all the specified headers to select - the route. + description: |- + Headers specifies gRPC request header matchers. Multiple match values are + ANDed together, meaning, a request MUST match all the specified headers + to select the route. items: - description: GRPCHeaderMatch describes how to select - a gRPC route by matching gRPC request headers. + description: |- + GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request + headers. properties: name: - description: "Name is the name of the gRPC Header - to be matched. \n If multiple entries specify - equivalent header names, only 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." + description: |- + Name is the name of the gRPC Header to be matched. + + + If multiple entries specify equivalent header names, only 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|~]+$ @@ -4219,31 +8418,39 @@ spec: - name x-kubernetes-list-type: map method: - description: Method specifies a gRPC request service/method - matcher. If this field is not specified, all services - and methods will match. + description: |- + Method specifies a gRPC request service/method matcher. If this field is + not specified, all services and methods will match. properties: method: - description: "Value of the method to match against. - If left empty or omitted, will match all services. - \n At least one of Service and Method MUST be a - non-empty string." + description: |- + Value of the method to match against. If left empty or omitted, will + match all services. + + + At least one of Service and Method MUST be a non-empty string. maxLength: 1024 type: string service: - description: "Value of the service to match against. - If left empty or omitted, will match any service. - \n At least one of Service and Method MUST be a - non-empty string." + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + + At least one of Service and Method MUST be a non-empty string. maxLength: 1024 type: string type: default: Exact - description: "Type specifies how to match against - the service and/or method. Support: Core (Exact - with service and method specified) \n Support: Implementation-specific - (Exact with method specified but no service specified) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the service and/or method. + Support: Core (Exact with service and method specified) + + + Support: Implementation-specific (Exact with method specified but no service specified) + + + Support: Implementation-specific (RegularExpression) enum: - Exact - RegularExpression @@ -4267,6 +8474,106 @@ spec: type: object maxItems: 8 type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + 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 + cookieConfig: + description: |- + CookieConfig 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. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + sessionName: + 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. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use 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.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' type: object maxItems: 16 type: array @@ -4275,81 +8582,94 @@ spec: description: Status defines the current state of GRPCRoute. properties: parents: - description: "Parents is a list of parent resources (usually Gateways) - that are associated with the route, and the status of the route - with respect to each parent. When this route attaches to a parent, - the controller that manages the parent must add an entry to this - list when the controller first sees the route and should update - the entry as appropriate when the route or gateway is modified. - \n Note that parent references that cannot be resolved by an implementation - of this API will not be added to this list. Implementations of this - API can only populate Route status for the Gateways/parent resources - they are responsible for. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. items: - description: RouteParentStatus describes the status of a route with - respect to an associated Parent. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: conditions: - description: "Conditions describes the status of the route with - respect to the Gateway. Note that the route's availability - is also subject to the Gateway's own status conditions and - listener status. \n If the Route's ParentRef specifies an - existing Gateway that supports Routes of this kind AND that - Gateway's controller has sufficient access, then that Gateway's - controller MUST set the \"Accepted\" condition on the Route, - to indicate whether the route has been accepted or rejected - by the Gateway, and why. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * The Route refers to a non-existent - parent. * The Route is of a type that the controller does - not support. * The Route is in a namespace the controller - does not have access to." + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -4363,12 +8683,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -4386,131 +8706,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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 parentRef: - description: ParentRef corresponds with a ParentRef in the spec - that this RouteParentStatus struct describes the status of. + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -4529,9 +8893,7 @@ spec: type: object type: object served: true - storage: true - subresources: - status: {} + storage: false status: acceptedNames: kind: "" @@ -4546,8 +8908,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: httproutes.gateway.networking.k8s.io @@ -4572,20 +8934,26 @@ spec: name: v1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -4593,57 +8961,90 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed - with a wildcard label (`*.`). The wildcard label must appear by - itself as the first label. \n If a hostname is specified by both - the Listener and HTTPRoute, there must be at least one intersecting - hostname for the HTTPRoute to be attached to the Listener. For example: - \n * A Listener with `test.example.com` as the hostname matches - HTTPRoutes that have either not specified any hostnames, or have - specified at least one of `test.example.com` or `*.example.com`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n Hostnames that are prefixed with a wildcard - label (`*.`) are interpreted as a suffix match. That means that - a match for `*.example.com` would match both `test.example.com`, - and `foo.test.example.com`, but not `example.com`. \n If both the - Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames - that do not match the Listener hostname MUST be ignored. For example, - if a Listener specified `*.example.com`, and the HTTPRoute specified - `test.example.com` and `test.example.net`, `test.example.net` must - not be considered for a match. \n If both the Listener and HTTPRoute - have specified hostnames, and none match with the criteria above, - then the HTTPRoute is not accepted. The implementation must raise - an 'Accepted' Condition with a status of `False` in the corresponding - RouteParentStatus. \n In the event that multiple HTTPRoutes specify - intersecting hostnames (e.g. overlapping wildcard matching and exact - matching hostnames), precedence must be given to rules from the - HTTPRoute with the largest number of: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + + * 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. + + + Support: Core items: - description: "Hostname is the fully qualified domain name of a network - host. This matches the RFC 1123 definition of a hostname with - 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname - may be prefixed with a wildcard label (`*.`). The wildcard label - must appear by itself as the first label. \n Hostname can be \"precise\" - which is a domain name without the terminating dot of a network - host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain - name prefixed with a single wildcard label (e.g. `*.example.com`). - \n Note that as per RFC1035 and RFC1123, a *label* must consist - of lower case alphanumeric characters or '-', and must start and - end with an alphanumeric character. No other punctuation is allowed." + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. maxLength: 253 minLength: 1 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ @@ -4651,165 +9052,246 @@ spec: maxItems: 16 type: array parentRefs: - description: "ParentRefs references the resources (usually Gateways) - that a Route wants to be attached to. Note that the referenced parent - resource needs to allow this for the attachment to be complete. - For Gateways, that means the Gateway needs to allow attachment from - Routes of this kind and namespace. For Services, that means the - Service must either be in the same namespace for a \"producer\" - route, or the mesh implementation must support and allow \"consumer\" - routes for the referenced Service. ReferenceGrant is not applicable - for governing ParentRefs to Services - it is not possible to create - a \"producer\" route for a Service in a different namespace from - the Route. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * They select different objects. If this is the case, - then parentRef entries are distinct. In terms of fields, this means - that the multi-part key defined by `group`, `kind`, `namespace`, - and `name` must be unique across all parentRef entries in the Route. - * They do not select different objects, but for each optional field - used, each ParentRef that selects the same object must set the same - set of optional fields to different values. If one ParentRef sets - a combination of optional fields, all must set the same combination. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same - object must also set `port`. * If one ParentRef sets `sectionName` - and `port`, all ParentRefs referencing the same object must also - set `sectionName` and `port`. \n It is possible to separately reference - multiple distinct objects that may be collapsed by an implementation. - For example, some implementations may choose to merge compatible - Gateway Listeners together. If that is the case, the list of routes - attached to those resources should also be merged. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific rules. 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 other kinds of cross-namespace - reference. \n 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. \n 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. \n " + 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 other kinds 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. + + + + + + items: - description: "ParentReference identifies an API object (usually - a Gateway) that can be considered a parent of this resource (usually - a route). There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + 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. 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -4850,81 +9332,120 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n If *all* entries in BackendRefs are invalid, and there - are also no filters specified in this route rule, *all* traffic - which matches this rule MUST receive a 500 status code. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef - is invalid, 500 status codes MUST be returned for requests - that would have otherwise been routed to an invalid backend. - If multiple backends are specified, and some are invalid, - the proportion of requests that would otherwise have been - routed to an invalid backend MUST receive a 500 status code. - \n For example, if two backends are specified with equal weights, - and one is invalid, 50 percent of traffic must receive a 500. - Implementations may choose how that 50 percent is determined. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Core items: - description: "HTTPBackendRef defines how a HTTPRoute forwards - a HTTP request. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n If a Service appProtocol isn't specified, - an implementation MAY infer the backend protocol through - its own means. Implementations MAY infer the protocol from - the Route type referring to the backend Service. \n If a - Route is not able to send traffic to the backend using the - specified protocol then the backend is considered invalid. - Implementations MUST set the \"ResolvedRefs\" condition - to \"False\" with the \"UnsupportedProtocol\" reason. \n - " + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + properties: filters: - description: "Filters defined at this level should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) items: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters are meant as an extension - point to express processing that may be done in Gateway - implementations. Some examples include request or - response modification, implementing authentication - strategies, rate-limiting, and traffic shaping. API - guarantee/conformance is defined based on the type - of the filter. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. properties: extensionRef: - description: "ExtensionRef is an optional, implementation-specific - extension to the \"filter\" behavior. For example, - resource \"myroutefilter\" in group \"networking.example.net\"). - ExtensionRef MUST NOT be used for core and extended - filters. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -4946,35 +9467,50 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It - appends to any existing values associated - with the header name. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -4995,44 +9531,68 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from - the HTTP request before the action. The value - of Remove is a list of HTTP header names. - Note that the header names are case-insensitive - (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with - the given header (name, value) before the - action. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -5054,64 +9614,80 @@ spec: x-kubernetes-list-type: map type: object requestMirror: - description: "RequestMirror defines a schema for - a filter that mirrors requests. Requests are sent - to the specified destination, but responses from - that destination are ignored. \n This filter can - be used multiple times within the same rule. Note - that not all implementations will be able to support - mirroring to multiple backends. \n Support: Extended" + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended properties: backendRef: - description: "BackendRef references a resource - where mirrored requests are sent. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n If the referent cannot be found, - this BackendRef is invalid and must be dropped - from the Gateway. The controller must ensure - the \"ResolvedRefs\" condition on the Route - status is set to `status: False` and not configure + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. - \n If there is a cross-namespace reference - to an *existing* object that is not allowed - by a ReferenceGrant, the controller must ensure - the \"ResolvedRefs\" condition on the Route - is set to `status: False`, with the \"RefNotPermitted\" - reason and not configure this backend in the - underlying implementation. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -5122,29 +9698,29 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -5160,84 +9736,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n Note that - this matches the behavior of the PathPrefix - match type. This matches full path elements. - A path element refers to the list of labels - in the path split by the `/` separator. - When specified, a trailing `/` is ignored. - For example, the paths `/abc`, `/abc/`, - and `/abc/def` would all match the prefix - `/abc`, but the path `/abcd` would not. - \n ReplacePrefixMatch is only compatible - with a `PathPrefix` HTTPRouteMatch. Using - any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the - Route to `status: False`. \n Request Path - | Prefix Match | Replace Prefix | Modified - Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | - /xyz/ | /xyz/bar /foo/bar | - /foo/ | /xyz | /xyz/bar - /foo/bar | /foo/ | /xyz/ | - /xyz/bar /foo | /foo | - /xyz | /xyz /foo/ | /foo - \ | /xyz | /xyz/ /foo/bar - \ | /foo | | - /bar /foo/ | /foo | | / /foo | /foo | - | / /foo/ | /foo - \ | / | / /foo | - /foo | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -5263,95 +9843,128 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * If redirect scheme is not-empty, - the redirect port MUST be the well-known port - associated with the redirect scheme. Specifically - \"http\" to port 80 and \"https\" to port - 443. If the redirect scheme does not have - a well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * A Location header - that will use HTTP (whether that is determined - via the Listener protocol or the Scheme field) - _and_ use port 80. * A Location header that - will use HTTPS (whether that is determined - via the Listener protocol or the Scheme field) - _and_ use port 443. \n Support: Extended" + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended format: int32 maximum: 65535 minimum: 1 type: integer scheme: - description: "Scheme is the scheme to be used - in the value of the `Location` header in the - response. When empty, the scheme of the request - is used. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended enum: - http - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core enum: - 301 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It - appends to any existing values associated - with the header name. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -5372,44 +9985,68 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from - the HTTP request before the action. The value - of Remove is a list of HTTP header names. - Note that the header names are case-insensitive - (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with - the given header (name, value) before the - action. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -5431,37 +10068,46 @@ spec: x-kubernetes-list-type: map type: object type: - description: "Type identifies the type of filter - to apply. As with other API fields, types are - classified into three conformance levels: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - Implementation-specific: - Filters that are defined and supported by specific - vendors. In the future, filters showing convergence - in behavior across multiple implementations will - be considered for inclusion in extended or core - conformance levels. Filter-specific configuration - for such filters is specified using the ExtensionRef - field. `Type` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n If a reference to a custom filter type cannot - be resolved, the filter MUST NOT be skipped. Instead, - requests that would have been processed by that - filter MUST receive a HTTP error response. \n + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + Note that values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -5471,79 +10117,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: Extended 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n Note that - this matches the behavior of the PathPrefix - match type. This matches full path elements. - A path element refers to the list of labels - in the path split by the `/` separator. - When specified, a trailing `/` is ignored. - For example, the paths `/abc`, `/abc/`, - and `/abc/def` would all match the prefix - `/abc`, but the path `/abcd` would not. - \n ReplacePrefixMatch is only compatible - with a `PathPrefix` HTTPRouteMatch. Using - any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the - Route to `status: False`. \n Request Path - | Prefix Match | Replace Prefix | Modified - Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | - /xyz/ | /xyz/bar /foo/bar | - /foo/ | /xyz | /xyz/bar - /foo/bar | /foo/ | /xyz/ | - /xyz/bar /foo | /foo | - /xyz | /xyz /foo/ | /foo - \ | /xyz | /xyz/ /foo/bar - \ | /foo | | - /bar /foo/ | /foo | | / /foo | /foo | - | / /foo/ | /foo - \ | / | / /foo | - /foo | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -5641,25 +10292,33 @@ spec: <= 1 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -5670,43 +10329,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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 weight: default: 1 - description: "Weight specifies the proportion of requests - forwarded to the referenced backend. This is computed - as weight/(sum of all weights in this BackendRefs list). - For non-zero values, there may be some epsilon from - the exact proportion defined here depending on the precision - an implementation supports. Weight is not a percentage - and the sum of weights does not need to equal 100. \n - If only one backend is specified and it has a weight - greater than 0, 100% of the traffic is forwarded to - that backend. If weight is set to 0, no traffic should - be forwarded for this entry. If unspecified, weight - defaults to 1. \n Support for this field varies based - on the context where used." + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support for this field varies based on the context where used. format: int32 maximum: 1000000 minimum: 0 @@ -5721,46 +10388,77 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - ALL core filters MUST be supported by - all implementations. - Implementers are encouraged to support - extended filters. - Implementation-specific custom filters - have no API guarantees across implementations. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n All filters are expected to be - compatible with each other except for the URLRewrite and RequestRedirect - filters, which may not be combined. If an implementation can - not support other combinations of filters, they must clearly + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly document that limitation. In cases where incompatible or unsupported - filters are specified and cause the `Accepted` condition to - be set to status `False`, implementations may use the `IncompatibleFilters` - reason to specify this configuration error. \n Support: Core" + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core items: - description: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters are meant as an extension point to express - processing that may be done in Gateway implementations. - Some examples include request or response modification, - implementing authentication strategies, rate-limiting, and - traffic shaping. API guarantee/conformance is defined based - on the type of the filter. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. properties: extensionRef: - description: "ExtensionRef is an optional, implementation-specific - extension to the \"filter\" behavior. For example, - resource \"myroutefilter\" in group \"networking.example.net\"). - ExtensionRef MUST NOT be used for core and extended - filters. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -5782,32 +10480,49 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It appends - to any existing values associated with the header - name. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -5828,40 +10543,67 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from the - HTTP request before the action. The value of Remove - is a list of HTTP header names. Note that the header - names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with the - given header (name, value) before the action. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -5883,60 +10625,80 @@ spec: x-kubernetes-list-type: map type: object requestMirror: - description: "RequestMirror defines a schema for a filter - that mirrors requests. Requests are sent to the specified - destination, but responses from that destination are - ignored. \n This filter can be used multiple times within - the same rule. Note that not all implementations will - be able to support mirroring to multiple backends. \n - Support: Extended" + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended properties: backendRef: - description: "BackendRef references a resource where - mirrored requests are sent. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - If the referent cannot be found, this BackendRef - is invalid and must be dropped from the Gateway. - The controller must ensure the \"ResolvedRefs\" - condition on the Route status is set to `status: - False` and not configure this backend in the underlying - implementation. \n If there is a cross-namespace - reference to an *existing* object that is not allowed - by a ReferenceGrant, the controller must ensure - the \"ResolvedRefs\" condition on the Route is - set to `status: False`, with the \"RefNotPermitted\" - reason and not configure this backend in the underlying - implementation. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -5947,25 +10709,28 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -5982,77 +10747,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n Note that this matches the behavior of the - PathPrefix match type. This matches full path - elements. A path element refers to the list - of labels in the path split by the `/` separator. - When specified, a trailing `/` is ignored. For - example, the paths `/abc`, `/abc/`, and `/abc/def` - would all match the prefix `/abc`, but the path - `/abcd` would not. \n ReplacePrefixMatch is - only compatible with a `PathPrefix` HTTPRouteMatch. - Using any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the Route - to `status: False`. \n Request Path | Prefix - Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | /xyz/ - \ | /xyz/bar /foo/bar | /foo/ | - /xyz | /xyz/bar /foo/bar | /foo/ - \ | /xyz/ | /xyz/bar /foo | - /foo | /xyz | /xyz /foo/ | - /foo | /xyz | /xyz/ /foo/bar - \ | /foo | | /bar - /foo/ | /foo | - | / /foo | /foo | - | / /foo/ | /foo | / | - / /foo | /foo | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -6078,88 +10854,127 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * If redirect - scheme is not-empty, the redirect port MUST be the - well-known port associated with the redirect scheme. - Specifically \"http\" to port 80 and \"https\" to - port 443. If the redirect scheme does not have a - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * A Location header that will use HTTP (whether - that is determined via the Listener protocol or - the Scheme field) _and_ use port 80. * A Location - header that will use HTTPS (whether that is determined - via the Listener protocol or the Scheme field) _and_ - use port 443. \n Support: Extended" + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended format: int32 maximum: 65535 minimum: 1 type: integer scheme: - description: "Scheme is the scheme to be used in the - value of the `Location` header in the response. - When empty, the scheme of the request is used. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended enum: - http - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core enum: - 301 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It appends - to any existing values associated with the header - name. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -6180,40 +10995,67 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from the - HTTP request before the action. The value of Remove - is a list of HTTP header names. Note that the header - names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with the - given header (name, value) before the action. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -6235,33 +11077,46 @@ spec: x-kubernetes-list-type: map type: object type: - description: "Type identifies the type of filter to apply. - As with other API fields, types are classified into - three conformance levels: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - Implementation-specific: Filters - that are defined and supported by specific vendors. - In the future, filters showing convergence in behavior - across multiple implementations will be considered for - inclusion in extended or core conformance levels. Filter-specific - configuration for such filters is specified using the - ExtensionRef field. `Type` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n If a reference - to a custom filter type cannot be resolved, the filter - MUST NOT be skipped. Instead, requests that would have - been processed by that filter MUST receive a HTTP error - response. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -6271,73 +11126,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: Extended 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n Note that this matches the behavior of the - PathPrefix match type. This matches full path - elements. A path element refers to the list - of labels in the path split by the `/` separator. - When specified, a trailing `/` is ignored. For - example, the paths `/abc`, `/abc/`, and `/abc/def` - would all match the prefix `/abc`, but the path - `/abcd` would not. \n ReplacePrefixMatch is - only compatible with a `PathPrefix` HTTPRouteMatch. - Using any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the Route - to `status: False`. \n Request Path | Prefix - Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | /xyz/ - \ | /xyz/bar /foo/bar | /foo/ | - /xyz | /xyz/bar /foo/bar | /foo/ - \ | /xyz/ | /xyz/bar /foo | - /foo | /xyz | /xyz /foo/ | - /foo | /xyz | /xyz/ /foo/bar - \ | /foo | | /bar - /foo/ | /foo | - | / /foo | /foo | - | / /foo/ | /foo | / | - / /foo | /foo | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -6430,86 +11296,134 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n Proxy or Load Balancer routing configuration generated - from HTTPRoutes MUST prioritize matches based on the following - criteria, continuing on ties. Across all rules specified on - applicable Routes, precedence must be given to the match having: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n If ties - still exist within an HTTPRoute, matching precedence MUST - be granted to the FIRST matching rule (in list order) with - a match meeting the above criteria. \n When no rules matching - a request have been successfully attached to the parent a - request is coming from, a HTTP 404 status code MUST be returned." + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + + Note: The precedence of RegularExpression path matches are implementation-specific. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. items: description: "HTTPRouteMatch defines the predicate used to - match requests to a given action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + match requests to a given\naction. Multiple match types + are ANDed together, i.e. the match will\nevaluate to true + only if all conditions are satisfied.\n\n\nFor example, + the match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n If multiple entries specify equivalent header - names, only 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. - \n When a header is repeated in an HTTP request, - it is implementation-specific behavior as to how - this is represented. Generally, proxies should - follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, only 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. + + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". maxLength: 256 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the header. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n Since RegularExpression HeaderMatchType has - implementation-specific conformance, implementations - can support POSIX, PCRE or any other dialects - of regular expressions. Please read the implementation's - documentation to determine the supported dialect." + description: |- + Type specifies how to match against the value of the header. + + + Support: Core (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. enum: - Exact - RegularExpression @@ -6530,9 +11444,13 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended enum: - GET - HEAD @@ -6548,15 +11466,20 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -6615,48 +11538,60 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n If multiple entries specify equivalent query - param names, only the first entry with an equivalent - name MUST be considered for a match. Subsequent - entries with an equivalent query param name MUST - be ignored. \n If a query param is repeated in - an HTTP request, the behavior is purposely left - undefined, since different data planes have different - capabilities. However, it is *recommended* that - implementations should match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. maxLength: 256 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + description: |- + Type specifies how to match against the value of the query parameter. + + + Support: Extended (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -6679,39 +11614,168 @@ spec: type: object maxItems: 8 type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + 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 + cookieConfig: + description: |- + CookieConfig 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. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + sessionName: + 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. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use 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.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + + Support: Extended + + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway to a backend. This - covers the time from when the request first starts being - sent from the gateway to when the full response has been - received from the backend. \n An entire client HTTP transaction - with a gateway, covered by the Request timeout, may result - in more than one call from the gateway to the destination - backend, for example, if automatic retries are supported. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + to a backend. This covers the time from when the request first starts being + sent from the gateway to when the full response has been received from the backend. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + An entire client HTTP transaction with a gateway, covered by the Request timeout, + may result in more than one call from the gateway to the destination backend, + for example, if automatic retries are supported. + + + Because the Request timeout encompasses the BackendRequest timeout, the value of + BackendRequest must be <= the value of Request timeout. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n For example, - setting the `rules.timeouts.request` field to the value - `10s` in an `HTTPRoute` will cause a timeout if a client - request is taking longer than 10 seconds to complete. - \n This timeout is intended to cover as close to the whole - request-response transaction as possible although an implementation - MAY choose to start the timeout after the entire request - stream has been received instead of immediately after - the transaction is initiated by the client. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + If the gateway has not been able to respond before this deadline is met, the gateway + MUST return a timeout error. + + + For example, setting the `rules.timeouts.request` field to the value `10s` in an + `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds + to complete. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + This timeout is intended to cover as close to the whole request-response transaction + as possible although an implementation MAY choose to start the timeout after the entire + request stream has been received instead of immediately after the transaction is + initiated by the client. + + + When this field is unspecified, request timeout behavior is implementation-specific. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -6769,81 +11833,94 @@ spec: description: Status defines the current state of HTTPRoute. properties: parents: - description: "Parents is a list of parent resources (usually Gateways) - that are associated with the route, and the status of the route - with respect to each parent. When this route attaches to a parent, - the controller that manages the parent must add an entry to this - list when the controller first sees the route and should update - the entry as appropriate when the route or gateway is modified. - \n Note that parent references that cannot be resolved by an implementation - of this API will not be added to this list. Implementations of this - API can only populate Route status for the Gateways/parent resources - they are responsible for. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. items: - description: RouteParentStatus describes the status of a route with - respect to an associated Parent. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: conditions: - description: "Conditions describes the status of the route with - respect to the Gateway. Note that the route's availability - is also subject to the Gateway's own status conditions and - listener status. \n If the Route's ParentRef specifies an - existing Gateway that supports Routes of this kind AND that - Gateway's controller has sufficient access, then that Gateway's - controller MUST set the \"Accepted\" condition on the Route, - to indicate whether the route has been accepted or rejected - by the Gateway, and why. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * The Route refers to a non-existent - parent. * The Route is of a type that the controller does - not support. * The Route is in a namespace the controller - does not have access to." + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -6857,12 +11934,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -6880,131 +11957,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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 parentRef: - description: ParentRef corresponds with a ParentRef in the spec - that this RouteParentStatus struct describes the status of. + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -7025,7 +12146,7 @@ spec: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: @@ -7038,20 +12159,26 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -7059,57 +12186,90 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed - with a wildcard label (`*.`). The wildcard label must appear by - itself as the first label. \n If a hostname is specified by both - the Listener and HTTPRoute, there must be at least one intersecting - hostname for the HTTPRoute to be attached to the Listener. For example: - \n * A Listener with `test.example.com` as the hostname matches - HTTPRoutes that have either not specified any hostnames, or have - specified at least one of `test.example.com` or `*.example.com`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n Hostnames that are prefixed with a wildcard - label (`*.`) are interpreted as a suffix match. That means that - a match for `*.example.com` would match both `test.example.com`, - and `foo.test.example.com`, but not `example.com`. \n If both the - Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames - that do not match the Listener hostname MUST be ignored. For example, - if a Listener specified `*.example.com`, and the HTTPRoute specified - `test.example.com` and `test.example.net`, `test.example.net` must - not be considered for a match. \n If both the Listener and HTTPRoute - have specified hostnames, and none match with the criteria above, - then the HTTPRoute is not accepted. The implementation must raise - an 'Accepted' Condition with a status of `False` in the corresponding - RouteParentStatus. \n In the event that multiple HTTPRoutes specify - intersecting hostnames (e.g. overlapping wildcard matching and exact - matching hostnames), precedence must be given to rules from the - HTTPRoute with the largest number of: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + + * 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. + + + Support: Core items: - description: "Hostname is the fully qualified domain name of a network - host. This matches the RFC 1123 definition of a hostname with - 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname - may be prefixed with a wildcard label (`*.`). The wildcard label - must appear by itself as the first label. \n Hostname can be \"precise\" - which is a domain name without the terminating dot of a network - host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain - name prefixed with a single wildcard label (e.g. `*.example.com`). - \n Note that as per RFC1035 and RFC1123, a *label* must consist - of lower case alphanumeric characters or '-', and must start and - end with an alphanumeric character. No other punctuation is allowed." + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. maxLength: 253 minLength: 1 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ @@ -7117,165 +12277,246 @@ spec: maxItems: 16 type: array parentRefs: - description: "ParentRefs references the resources (usually Gateways) - that a Route wants to be attached to. Note that the referenced parent - resource needs to allow this for the attachment to be complete. - For Gateways, that means the Gateway needs to allow attachment from - Routes of this kind and namespace. For Services, that means the - Service must either be in the same namespace for a \"producer\" - route, or the mesh implementation must support and allow \"consumer\" - routes for the referenced Service. ReferenceGrant is not applicable - for governing ParentRefs to Services - it is not possible to create - a \"producer\" route for a Service in a different namespace from - the Route. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * They select different objects. If this is the case, - then parentRef entries are distinct. In terms of fields, this means - that the multi-part key defined by `group`, `kind`, `namespace`, - and `name` must be unique across all parentRef entries in the Route. - * They do not select different objects, but for each optional field - used, each ParentRef that selects the same object must set the same - set of optional fields to different values. If one ParentRef sets - a combination of optional fields, all must set the same combination. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same - object must also set `port`. * If one ParentRef sets `sectionName` - and `port`, all ParentRefs referencing the same object must also - set `sectionName` and `port`. \n It is possible to separately reference - multiple distinct objects that may be collapsed by an implementation. - For example, some implementations may choose to merge compatible - Gateway Listeners together. If that is the case, the list of routes - attached to those resources should also be merged. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific rules. 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 other kinds of cross-namespace - reference. \n 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. \n 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. \n " + 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 other kinds 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. + + + + + + items: - description: "ParentReference identifies an API object (usually - a Gateway) that can be considered a parent of this resource (usually - a route). There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + 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. 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -7316,81 +12557,120 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n If *all* entries in BackendRefs are invalid, and there - are also no filters specified in this route rule, *all* traffic - which matches this rule MUST receive a 500 status code. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef - is invalid, 500 status codes MUST be returned for requests - that would have otherwise been routed to an invalid backend. - If multiple backends are specified, and some are invalid, - the proportion of requests that would otherwise have been - routed to an invalid backend MUST receive a 500 status code. - \n For example, if two backends are specified with equal weights, - and one is invalid, 50 percent of traffic must receive a 500. - Implementations may choose how that 50 percent is determined. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Core items: - description: "HTTPBackendRef defines how a HTTPRoute forwards - a HTTP request. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n If a Service appProtocol isn't specified, - an implementation MAY infer the backend protocol through - its own means. Implementations MAY infer the protocol from - the Route type referring to the backend Service. \n If a - Route is not able to send traffic to the backend using the - specified protocol then the backend is considered invalid. - Implementations MUST set the \"ResolvedRefs\" condition - to \"False\" with the \"UnsupportedProtocol\" reason. \n - " + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + properties: filters: - description: "Filters defined at this level should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) items: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters are meant as an extension - point to express processing that may be done in Gateway - implementations. Some examples include request or - response modification, implementing authentication - strategies, rate-limiting, and traffic shaping. API - guarantee/conformance is defined based on the type - of the filter. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. properties: extensionRef: - description: "ExtensionRef is an optional, implementation-specific - extension to the \"filter\" behavior. For example, - resource \"myroutefilter\" in group \"networking.example.net\"). - ExtensionRef MUST NOT be used for core and extended - filters. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -7412,35 +12692,50 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It - appends to any existing values associated - with the header name. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -7461,44 +12756,68 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from - the HTTP request before the action. The value - of Remove is a list of HTTP header names. - Note that the header names are case-insensitive - (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with - the given header (name, value) before the - action. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -7520,64 +12839,80 @@ spec: x-kubernetes-list-type: map type: object requestMirror: - description: "RequestMirror defines a schema for - a filter that mirrors requests. Requests are sent - to the specified destination, but responses from - that destination are ignored. \n This filter can - be used multiple times within the same rule. Note - that not all implementations will be able to support - mirroring to multiple backends. \n Support: Extended" + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended properties: backendRef: - description: "BackendRef references a resource - where mirrored requests are sent. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n If the referent cannot be found, - this BackendRef is invalid and must be dropped - from the Gateway. The controller must ensure - the \"ResolvedRefs\" condition on the Route - status is set to `status: False` and not configure + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. - \n If there is a cross-namespace reference - to an *existing* object that is not allowed - by a ReferenceGrant, the controller must ensure - the \"ResolvedRefs\" condition on the Route - is set to `status: False`, with the \"RefNotPermitted\" - reason and not configure this backend in the - underlying implementation. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -7588,29 +12923,29 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -7626,84 +12961,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n Note that - this matches the behavior of the PathPrefix - match type. This matches full path elements. - A path element refers to the list of labels - in the path split by the `/` separator. - When specified, a trailing `/` is ignored. - For example, the paths `/abc`, `/abc/`, - and `/abc/def` would all match the prefix - `/abc`, but the path `/abcd` would not. - \n ReplacePrefixMatch is only compatible - with a `PathPrefix` HTTPRouteMatch. Using - any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the - Route to `status: False`. \n Request Path - | Prefix Match | Replace Prefix | Modified - Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | - /xyz/ | /xyz/bar /foo/bar | - /foo/ | /xyz | /xyz/bar - /foo/bar | /foo/ | /xyz/ | - /xyz/bar /foo | /foo | - /xyz | /xyz /foo/ | /foo - \ | /xyz | /xyz/ /foo/bar - \ | /foo | | - /bar /foo/ | /foo | | / /foo | /foo | - | / /foo/ | /foo - \ | / | / /foo | - /foo | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -7729,95 +13068,128 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * If redirect scheme is not-empty, - the redirect port MUST be the well-known port - associated with the redirect scheme. Specifically - \"http\" to port 80 and \"https\" to port - 443. If the redirect scheme does not have - a well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * A Location header - that will use HTTP (whether that is determined - via the Listener protocol or the Scheme field) - _and_ use port 80. * A Location header that - will use HTTPS (whether that is determined - via the Listener protocol or the Scheme field) - _and_ use port 443. \n Support: Extended" + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended format: int32 maximum: 65535 minimum: 1 type: integer scheme: - description: "Scheme is the scheme to be used - in the value of the `Location` header in the - response. When empty, the scheme of the request - is used. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended enum: - http - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core enum: - 301 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It - appends to any existing values associated - with the header name. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -7838,44 +13210,68 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from - the HTTP request before the action. The value - of Remove is a list of HTTP header names. - Note that the header names are case-insensitive - (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with - the given header (name, value) before the - action. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -7897,37 +13293,46 @@ spec: x-kubernetes-list-type: map type: object type: - description: "Type identifies the type of filter - to apply. As with other API fields, types are - classified into three conformance levels: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - Implementation-specific: - Filters that are defined and supported by specific - vendors. In the future, filters showing convergence - in behavior across multiple implementations will - be considered for inclusion in extended or core - conformance levels. Filter-specific configuration - for such filters is specified using the ExtensionRef - field. `Type` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n If a reference to a custom filter type cannot - be resolved, the filter MUST NOT be skipped. Instead, - requests that would have been processed by that - filter MUST receive a HTTP error response. \n + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + Note that values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -7937,79 +13342,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: Extended 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n Note that - this matches the behavior of the PathPrefix - match type. This matches full path elements. - A path element refers to the list of labels - in the path split by the `/` separator. - When specified, a trailing `/` is ignored. - For example, the paths `/abc`, `/abc/`, - and `/abc/def` would all match the prefix - `/abc`, but the path `/abcd` would not. - \n ReplacePrefixMatch is only compatible - with a `PathPrefix` HTTPRouteMatch. Using - any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the - Route to `status: False`. \n Request Path - | Prefix Match | Replace Prefix | Modified - Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | - /xyz/ | /xyz/bar /foo/bar | - /foo/ | /xyz | /xyz/bar - /foo/bar | /foo/ | /xyz/ | - /xyz/bar /foo | /foo | - /xyz | /xyz /foo/ | /foo - \ | /xyz | /xyz/ /foo/bar - \ | /foo | | - /bar /foo/ | /foo | | / /foo | /foo | - | / /foo/ | /foo - \ | / | / /foo | - /foo | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -8107,25 +13517,33 @@ spec: <= 1 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -8136,43 +13554,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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 weight: default: 1 - description: "Weight specifies the proportion of requests - forwarded to the referenced backend. This is computed - as weight/(sum of all weights in this BackendRefs list). - For non-zero values, there may be some epsilon from - the exact proportion defined here depending on the precision - an implementation supports. Weight is not a percentage - and the sum of weights does not need to equal 100. \n - If only one backend is specified and it has a weight - greater than 0, 100% of the traffic is forwarded to - that backend. If weight is set to 0, no traffic should - be forwarded for this entry. If unspecified, weight - defaults to 1. \n Support for this field varies based - on the context where used." + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support for this field varies based on the context where used. format: int32 maximum: 1000000 minimum: 0 @@ -8187,46 +13613,77 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - ALL core filters MUST be supported by - all implementations. - Implementers are encouraged to support - extended filters. - Implementation-specific custom filters - have no API guarantees across implementations. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n All filters are expected to be - compatible with each other except for the URLRewrite and RequestRedirect - filters, which may not be combined. If an implementation can - not support other combinations of filters, they must clearly + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly document that limitation. In cases where incompatible or unsupported - filters are specified and cause the `Accepted` condition to - be set to status `False`, implementations may use the `IncompatibleFilters` - reason to specify this configuration error. \n Support: Core" + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core items: - description: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters are meant as an extension point to express - processing that may be done in Gateway implementations. - Some examples include request or response modification, - implementing authentication strategies, rate-limiting, and - traffic shaping. API guarantee/conformance is defined based - on the type of the filter. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. properties: extensionRef: - description: "ExtensionRef is an optional, implementation-specific - extension to the \"filter\" behavior. For example, - resource \"myroutefilter\" in group \"networking.example.net\"). - ExtensionRef MUST NOT be used for core and extended - filters. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -8248,32 +13705,49 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It appends - to any existing values associated with the header - name. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -8294,40 +13768,67 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from the - HTTP request before the action. The value of Remove - is a list of HTTP header names. Note that the header - names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with the - given header (name, value) before the action. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -8349,60 +13850,80 @@ spec: x-kubernetes-list-type: map type: object requestMirror: - description: "RequestMirror defines a schema for a filter - that mirrors requests. Requests are sent to the specified - destination, but responses from that destination are - ignored. \n This filter can be used multiple times within - the same rule. Note that not all implementations will - be able to support mirroring to multiple backends. \n - Support: Extended" + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended properties: backendRef: - description: "BackendRef references a resource where - mirrored requests are sent. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - If the referent cannot be found, this BackendRef - is invalid and must be dropped from the Gateway. - The controller must ensure the \"ResolvedRefs\" - condition on the Route status is set to `status: - False` and not configure this backend in the underlying - implementation. \n If there is a cross-namespace - reference to an *existing* object that is not allowed - by a ReferenceGrant, the controller must ensure - the \"ResolvedRefs\" condition on the Route is - set to `status: False`, with the \"RefNotPermitted\" - reason and not configure this backend in the underlying - implementation. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -8413,25 +13934,28 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -8448,77 +13972,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n Note that this matches the behavior of the - PathPrefix match type. This matches full path - elements. A path element refers to the list - of labels in the path split by the `/` separator. - When specified, a trailing `/` is ignored. For - example, the paths `/abc`, `/abc/`, and `/abc/def` - would all match the prefix `/abc`, but the path - `/abcd` would not. \n ReplacePrefixMatch is - only compatible with a `PathPrefix` HTTPRouteMatch. - Using any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the Route - to `status: False`. \n Request Path | Prefix - Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | /xyz/ - \ | /xyz/bar /foo/bar | /foo/ | - /xyz | /xyz/bar /foo/bar | /foo/ - \ | /xyz/ | /xyz/bar /foo | - /foo | /xyz | /xyz /foo/ | - /foo | /xyz | /xyz/ /foo/bar - \ | /foo | | /bar - /foo/ | /foo | - | / /foo | /foo | - | / /foo/ | /foo | / | - / /foo | /foo | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -8544,88 +14079,127 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * If redirect - scheme is not-empty, the redirect port MUST be the - well-known port associated with the redirect scheme. - Specifically \"http\" to port 80 and \"https\" to - port 443. If the redirect scheme does not have a - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * A Location header that will use HTTP (whether - that is determined via the Listener protocol or - the Scheme field) _and_ use port 80. * A Location - header that will use HTTPS (whether that is determined - via the Listener protocol or the Scheme field) _and_ - use port 443. \n Support: Extended" + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended format: int32 maximum: 65535 minimum: 1 type: integer scheme: - description: "Scheme is the scheme to be used in the - value of the `Location` header in the response. - When empty, the scheme of the request is used. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended enum: - http - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core enum: - 301 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended properties: add: - description: "Add adds the given header(s) (name, - value) to the request before the action. It appends - to any existing values associated with the header - name. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz 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). - \n 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." + 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|~]+$ @@ -8646,40 +14220,67 @@ spec: - name x-kubernetes-list-type: map remove: - description: "Remove the given header(s) from the - HTTP request before the action. The value of Remove - is a list of HTTP header names. Note that the header - names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + my-header2: bar items: type: string maxItems: 16 type: array x-kubernetes-list-type: set set: - description: "Set overwrites the request with the - given header (name, value) before the action. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + my-header: bar 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). - \n 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." + 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|~]+$ @@ -8701,33 +14302,46 @@ spec: x-kubernetes-list-type: map type: object type: - description: "Type identifies the type of filter to apply. - As with other API fields, types are classified into - three conformance levels: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - Implementation-specific: Filters - that are defined and supported by specific vendors. - In the future, filters showing convergence in behavior - across multiple implementations will be considered for - inclusion in extended or core conformance levels. Filter-specific - configuration for such filters is specified using the - ExtensionRef field. `Type` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n If a reference - to a custom filter type cannot be resolved, the filter - MUST NOT be skipped. Instead, requests that would have - been processed by that filter MUST receive a HTTP error - response. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -8737,73 +14351,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: Extended 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n Note that this matches the behavior of the - PathPrefix match type. This matches full path - elements. A path element refers to the list - of labels in the path split by the `/` separator. - When specified, a trailing `/` is ignored. For - example, the paths `/abc`, `/abc/`, and `/abc/def` - would all match the prefix `/abc`, but the path - `/abcd` would not. \n ReplacePrefixMatch is - only compatible with a `PathPrefix` HTTPRouteMatch. - Using any other HTTPRouteMatch type on the same - HTTPRouteRule will result in the implementation - setting the Accepted Condition for the Route - to `status: False`. \n Request Path | Prefix - Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- - /foo/bar | /foo | /xyz | - /xyz/bar /foo/bar | /foo | /xyz/ - \ | /xyz/bar /foo/bar | /foo/ | - /xyz | /xyz/bar /foo/bar | /foo/ - \ | /xyz/ | /xyz/bar /foo | - /foo | /xyz | /xyz /foo/ | - /foo | /xyz | /xyz/ /foo/bar - \ | /foo | | /bar - /foo/ | /foo | - | / /foo | /foo | - | / /foo/ | /foo | / | - / /foo | /foo | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / maxLength: 1024 type: string type: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -8896,86 +14521,134 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n Proxy or Load Balancer routing configuration generated - from HTTPRoutes MUST prioritize matches based on the following - criteria, continuing on ties. Across all rules specified on - applicable Routes, precedence must be given to the match having: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n If ties - still exist within an HTTPRoute, matching precedence MUST - be granted to the FIRST matching rule (in list order) with - a match meeting the above criteria. \n When no rules matching - a request have been successfully attached to the parent a - request is coming from, a HTTP 404 status code MUST be returned." + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + + Note: The precedence of RegularExpression path matches are implementation-specific. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. items: description: "HTTPRouteMatch defines the predicate used to - match requests to a given action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + match requests to a given\naction. Multiple match types + are ANDed together, i.e. the match will\nevaluate to true + only if all conditions are satisfied.\n\n\nFor example, + the match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n If multiple entries specify equivalent header - names, only 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. - \n When a header is repeated in an HTTP request, - it is implementation-specific behavior as to how - this is represented. Generally, proxies should - follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, only 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. + + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". maxLength: 256 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the header. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n Since RegularExpression HeaderMatchType has - implementation-specific conformance, implementations - can support POSIX, PCRE or any other dialects - of regular expressions. Please read the implementation's - documentation to determine the supported dialect." + description: |- + Type specifies how to match against the value of the header. + + + Support: Core (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. enum: - Exact - RegularExpression @@ -8996,9 +14669,13 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended enum: - GET - HEAD @@ -9014,15 +14691,20 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -9081,48 +14763,60 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n If multiple entries specify equivalent query - param names, only the first entry with an equivalent - name MUST be considered for a match. Subsequent - entries with an equivalent query param name MUST - be ignored. \n If a query param is repeated in - an HTTP request, the behavior is purposely left - undefined, since different data planes have different - capabilities. However, it is *recommended* that - implementations should match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. maxLength: 256 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + description: |- + Type specifies how to match against the value of the query parameter. + + + Support: Extended (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -9145,39 +14839,168 @@ spec: type: object maxItems: 8 type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + 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 + cookieConfig: + description: |- + CookieConfig 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. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + sessionName: + 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. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use 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.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + + Support: Extended + + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway to a backend. This - covers the time from when the request first starts being - sent from the gateway to when the full response has been - received from the backend. \n An entire client HTTP transaction - with a gateway, covered by the Request timeout, may result - in more than one call from the gateway to the destination - backend, for example, if automatic retries are supported. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + to a backend. This covers the time from when the request first starts being + sent from the gateway to when the full response has been received from the backend. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + An entire client HTTP transaction with a gateway, covered by the Request timeout, + may result in more than one call from the gateway to the destination backend, + for example, if automatic retries are supported. + + + Because the Request timeout encompasses the BackendRequest timeout, the value of + BackendRequest must be <= the value of Request timeout. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n For example, - setting the `rules.timeouts.request` field to the value - `10s` in an `HTTPRoute` will cause a timeout if a client - request is taking longer than 10 seconds to complete. - \n This timeout is intended to cover as close to the whole - request-response transaction as possible although an implementation - MAY choose to start the timeout after the entire request - stream has been received instead of immediately after - the transaction is initiated by the client. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + If the gateway has not been able to respond before this deadline is met, the gateway + MUST return a timeout error. + + + For example, setting the `rules.timeouts.request` field to the value `10s` in an + `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds + to complete. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + This timeout is intended to cover as close to the whole request-response transaction + as possible although an implementation MAY choose to start the timeout after the entire + request stream has been received instead of immediately after the transaction is + initiated by the client. + + + When this field is unspecified, request timeout behavior is implementation-specific. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -9235,81 +15058,94 @@ spec: description: Status defines the current state of HTTPRoute. properties: parents: - description: "Parents is a list of parent resources (usually Gateways) - that are associated with the route, and the status of the route - with respect to each parent. When this route attaches to a parent, - the controller that manages the parent must add an entry to this - list when the controller first sees the route and should update - the entry as appropriate when the route or gateway is modified. - \n Note that parent references that cannot be resolved by an implementation - of this API will not be added to this list. Implementations of this - API can only populate Route status for the Gateways/parent resources - they are responsible for. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. items: - description: RouteParentStatus describes the status of a route with - respect to an associated Parent. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: conditions: - description: "Conditions describes the status of the route with - respect to the Gateway. Note that the route's availability - is also subject to the Gateway's own status conditions and - listener status. \n If the Route's ParentRef specifies an - existing Gateway that supports Routes of this kind AND that - Gateway's controller has sufficient access, then that Gateway's - controller MUST set the \"Accepted\" condition on the Route, - to indicate whether the route has been accepted or rejected - by the Gateway, and why. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * The Route refers to a non-existent - parent. * The Route is of a type that the controller does - not support. * The Route is in a namespace the controller - does not have access to." + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -9323,12 +15159,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -9346,131 +15182,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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 parentRef: - description: ParentRef corresponds with a ParentRef in the spec - that this RouteParentStatus struct describes the status of. + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -9491,7 +15371,7 @@ spec: - spec type: object served: true - storage: true + storage: false subresources: status: {} status: @@ -9508,8 +15388,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: referencegrants.gateway.networking.k8s.io @@ -9536,32 +15416,45 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: "ReferenceGrant identifies kinds of resources in other namespaces - that are trusted to reference the specified kinds of resources in the same - namespace as the policy. \n Each ReferenceGrant can be used to represent - a unique trust relationship. Additional Reference Grants can be used to - add to the set of trusted sources of inbound references for the namespace - they are defined within. \n A ReferenceGrant is required for all cross-namespace - references in Gateway API (with the exception of cross-namespace Route-Gateway - attachment, which is governed by the AllowedRoutes configuration on the - Gateway, and cross-namespace Service ParentRefs on a \"consumer\" mesh Route, - which defines routing rules applicable only to workloads in the Route namespace). - ReferenceGrants allowing a reference from a Route to a Service are only - applicable to BackendRefs. \n ReferenceGrant is a form of runtime verification - allowing users to assert which cross-namespace object references are permitted. - Implementations that support ReferenceGrant MUST NOT permit cross-namespace - references which have no grant, and MUST respond to the removal of a grant - by revoking the access that the grant allowed." + description: |- + ReferenceGrant identifies kinds of resources in other namespaces that are + trusted to reference the specified kinds of resources in the same namespace + as the policy. + + + Each ReferenceGrant can be used to represent a unique trust relationship. + Additional Reference Grants can be used to add to the set of trusted + sources of inbound references for the namespace they are defined within. + + + A ReferenceGrant is required for all cross-namespace references in Gateway API + (with the exception of cross-namespace Route-Gateway attachment, which is + governed by the AllowedRoutes configuration on the Gateway, and cross-namespace + Service ParentRefs on a "consumer" mesh Route, which defines routing rules + applicable only to workloads in the Route namespace). ReferenceGrants allowing + a reference from a Route to a Service are only applicable to BackendRefs. + + + ReferenceGrant is a form of runtime verification allowing users to assert + which cross-namespace object references are permitted. Implementations that + support ReferenceGrant MUST NOT permit cross-namespace references which have + no grant, and MUST respond to the removal of a grant by revoking the access + that the grant allowed. 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' + 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' + 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 @@ -9569,35 +15462,59 @@ spec: description: Spec defines the desired state of ReferenceGrant. properties: from: - description: "From describes the trusted namespaces and kinds that - can reference the resources described in \"To\". Each entry in this - list MUST be considered to be an additional place that references - can be valid from, or to put this another way, entries MUST be combined - using OR. \n Support: Core" + description: |- + From describes the trusted namespaces and kinds that can reference the + resources described in "To". Each entry in this list MUST be considered + to be an additional place that references can be valid from, or to put + this another way, entries MUST be combined using OR. + + + Support: Core items: description: ReferenceGrantFrom describes trusted namespaces and kinds. properties: group: - description: "Group is the group of the referent. When empty, - the Kubernetes core API group is inferred. \n Support: Core" + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + 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: - description: "Kind is the kind of the referent. Although implementations - may support additional resources, the following types are - part of the \"Core\" support level for this field. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + description: |- + Kind is the kind of the referent. Although implementations may support + additional resources, the following types are part of the "Core" + support level for this field. + + + When used to permit a SecretObjectReference: + + + * Gateway + + + When used to permit a BackendObjectReference: + + + * GRPCRoute + * HTTPRoute + * TCPRoute + * TLSRoute + * UDPRoute maxLength: 63 minLength: 1 pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ type: string namespace: - description: "Namespace is the namespace of the referent. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -9611,35 +15528,47 @@ spec: minItems: 1 type: array to: - description: "To describes the resources that may be referenced by - the resources described in \"From\". Each entry in this list MUST - be considered to be an additional place that references can be valid - to, or to put this another way, entries MUST be combined using OR. - \n Support: Core" + description: |- + To describes the resources that may be referenced by the resources + described in "From". Each entry in this list MUST be considered to be an + additional place that references can be valid to, or to put this another + way, entries MUST be combined using OR. + + + Support: Core items: - description: ReferenceGrantTo describes what Kinds are allowed as - targets of the references. + description: |- + ReferenceGrantTo describes what Kinds are allowed as targets of the + references. properties: group: - description: "Group is the group of the referent. When empty, - the Kubernetes core API group is inferred. \n Support: Core" + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + 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: - description: "Kind is the kind of the referent. Although implementations - may support additional resources, the following types are - part of the \"Core\" support level for this field: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + description: |- + Kind is the kind of the referent. Although implementations may support + additional resources, the following types are part of the "Core" + support level for this field: + + + * Secret when used to permit a SecretObjectReference + * Service when used to permit a BackendObjectReference 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. When unspecified, - this policy refers to all resources of the specified Group - and Kind in the local namespace. + description: |- + Name is the name of the referent. When unspecified, this policy + refers to all resources of the specified Group and Kind in the local + namespace. maxLength: 253 minLength: 1 type: string @@ -9665,28 +15594,41 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: "ReferenceGrant identifies kinds of resources in other namespaces - that are trusted to reference the specified kinds of resources in the same - namespace as the policy. \n Each ReferenceGrant can be used to represent - a unique trust relationship. Additional Reference Grants can be used to - add to the set of trusted sources of inbound references for the namespace - they are defined within. \n All cross-namespace references in Gateway API - (with the exception of cross-namespace Gateway-route attachment) require - a ReferenceGrant. \n ReferenceGrant is a form of runtime verification allowing - users to assert which cross-namespace object references are permitted. Implementations - that support ReferenceGrant MUST NOT permit cross-namespace references which - have no grant, and MUST respond to the removal of a grant by revoking the - access that the grant allowed." + description: |- + ReferenceGrant identifies kinds of resources in other namespaces that are + trusted to reference the specified kinds of resources in the same namespace + as the policy. + + + Each ReferenceGrant can be used to represent a unique trust relationship. + Additional Reference Grants can be used to add to the set of trusted + sources of inbound references for the namespace they are defined within. + + + All cross-namespace references in Gateway API (with the exception of cross-namespace + Gateway-route attachment) require a ReferenceGrant. + + + ReferenceGrant is a form of runtime verification allowing users to assert + which cross-namespace object references are permitted. Implementations that + support ReferenceGrant MUST NOT permit cross-namespace references which have + no grant, and MUST respond to the removal of a grant by revoking the access + that the grant allowed. 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' + 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' + 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 @@ -9694,35 +15636,59 @@ spec: description: Spec defines the desired state of ReferenceGrant. properties: from: - description: "From describes the trusted namespaces and kinds that - can reference the resources described in \"To\". Each entry in this - list MUST be considered to be an additional place that references - can be valid from, or to put this another way, entries MUST be combined - using OR. \n Support: Core" + description: |- + From describes the trusted namespaces and kinds that can reference the + resources described in "To". Each entry in this list MUST be considered + to be an additional place that references can be valid from, or to put + this another way, entries MUST be combined using OR. + + + Support: Core items: description: ReferenceGrantFrom describes trusted namespaces and kinds. properties: group: - description: "Group is the group of the referent. When empty, - the Kubernetes core API group is inferred. \n Support: Core" + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + 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: - description: "Kind is the kind of the referent. Although implementations - may support additional resources, the following types are - part of the \"Core\" support level for this field. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + description: |- + Kind is the kind of the referent. Although implementations may support + additional resources, the following types are part of the "Core" + support level for this field. + + + When used to permit a SecretObjectReference: + + + * Gateway + + + When used to permit a BackendObjectReference: + + + * GRPCRoute + * HTTPRoute + * TCPRoute + * TLSRoute + * UDPRoute maxLength: 63 minLength: 1 pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ type: string namespace: - description: "Namespace is the namespace of the referent. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -9736,35 +15702,47 @@ spec: minItems: 1 type: array to: - description: "To describes the resources that may be referenced by - the resources described in \"From\". Each entry in this list MUST - be considered to be an additional place that references can be valid - to, or to put this another way, entries MUST be combined using OR. - \n Support: Core" + description: |- + To describes the resources that may be referenced by the resources + described in "From". Each entry in this list MUST be considered to be an + additional place that references can be valid to, or to put this another + way, entries MUST be combined using OR. + + + Support: Core items: - description: ReferenceGrantTo describes what Kinds are allowed as - targets of the references. + description: |- + ReferenceGrantTo describes what Kinds are allowed as targets of the + references. properties: group: - description: "Group is the group of the referent. When empty, - the Kubernetes core API group is inferred. \n Support: Core" + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + 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: - description: "Kind is the kind of the referent. Although implementations - may support additional resources, the following types are - part of the \"Core\" support level for this field: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + description: |- + Kind is the kind of the referent. Although implementations may support + additional resources, the following types are part of the "Core" + support level for this field: + + + * Secret when used to permit a SecretObjectReference + * Service when used to permit a BackendObjectReference 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. When unspecified, - this policy refers to all resources of the specified Group - and Kind in the local namespace. + description: |- + Name is the name of the referent. When unspecified, this policy + refers to all resources of the specified Group and Kind in the local + namespace. maxLength: 253 minLength: 1 type: string @@ -9797,8 +15775,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tcproutes.gateway.networking.k8s.io @@ -9820,19 +15798,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: TCPRoute provides a way to route TCP requests. When combined - with a Gateway listener, it can be used to forward connections on the port - specified by the listener to a set of backends specified by the TCPRoute. + description: |- + TCPRoute provides a way to route TCP requests. When combined with a Gateway + listener, it can be used to forward connections on the port specified by the + listener to a set of backends specified by the TCPRoute. 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' + 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' + 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 @@ -9840,165 +15824,246 @@ spec: description: Spec defines the desired state of TCPRoute. properties: parentRefs: - description: "ParentRefs references the resources (usually Gateways) - that a Route wants to be attached to. Note that the referenced parent - resource needs to allow this for the attachment to be complete. - For Gateways, that means the Gateway needs to allow attachment from - Routes of this kind and namespace. For Services, that means the - Service must either be in the same namespace for a \"producer\" - route, or the mesh implementation must support and allow \"consumer\" - routes for the referenced Service. ReferenceGrant is not applicable - for governing ParentRefs to Services - it is not possible to create - a \"producer\" route for a Service in a different namespace from - the Route. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * They select different objects. If this is the case, - then parentRef entries are distinct. In terms of fields, this means - that the multi-part key defined by `group`, `kind`, `namespace`, - and `name` must be unique across all parentRef entries in the Route. - * They do not select different objects, but for each optional field - used, each ParentRef that selects the same object must set the same - set of optional fields to different values. If one ParentRef sets - a combination of optional fields, all must set the same combination. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same - object must also set `port`. * If one ParentRef sets `sectionName` - and `port`, all ParentRefs referencing the same object must also - set `sectionName` and `port`. \n It is possible to separately reference - multiple distinct objects that may be collapsed by an implementation. - For example, some implementations may choose to merge compatible - Gateway Listeners together. If that is the case, the list of routes - attached to those resources should also be merged. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific rules. 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 other kinds of cross-namespace - reference. \n 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. \n 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. \n " + 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 other kinds 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. + + + + + + items: - description: "ParentReference identifies an API object (usually - a Gateway) that can be considered a parent of this resource (usually - a route). There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + 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. 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -10037,62 +16102,94 @@ spec: description: TCPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Connection rejections must respect - weight; if an invalid backend is requested to have 80% of + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Connection rejections must + respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Extended" + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Extended items: - description: "BackendRef defines how a Route should forward - a request to a Kubernetes resource. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n If a Service appProtocol isn't specified, - an implementation MAY infer the backend protocol through - its own means. Implementations MAY infer the protocol from - the Route type referring to the backend Service. \n If a - Route is not able to send traffic to the backend using the - specified protocol then the backend is considered invalid. - Implementations MUST set the \"ResolvedRefs\" condition - to \"False\" with the \"UnsupportedProtocol\" reason. \n - \n Note that when the - BackendTLSPolicy object is enabled by the implementation, - there are some extra rules about validity to consider here. - See the fields where this struct is used for more information - about the exact behavior." + description: |- + BackendRef defines how a Route should forward a request to a Kubernetes + resource. + + + 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. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + + + Note that when the BackendTLSPolicy object is enabled by the implementation, + there are some extra rules about validity to consider here. See the fields + where this struct is used for more information about the exact behavior. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -10103,43 +16200,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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 weight: default: 1 - description: "Weight specifies the proportion of requests - forwarded to the referenced backend. This is computed - as weight/(sum of all weights in this BackendRefs list). - For non-zero values, there may be some epsilon from - the exact proportion defined here depending on the precision - an implementation supports. Weight is not a percentage - and the sum of weights does not need to equal 100. \n - If only one backend is specified and it has a weight - greater than 0, 100% of the traffic is forwarded to - that backend. If weight is set to 0, no traffic should - be forwarded for this entry. If unspecified, weight - defaults to 1. \n Support for this field varies based - on the context where used." + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support for this field varies based on the context where used. format: int32 maximum: 1000000 minimum: 0 @@ -10165,81 +16270,94 @@ spec: description: Status defines the current state of TCPRoute. properties: parents: - description: "Parents is a list of parent resources (usually Gateways) - that are associated with the route, and the status of the route - with respect to each parent. When this route attaches to a parent, - the controller that manages the parent must add an entry to this - list when the controller first sees the route and should update - the entry as appropriate when the route or gateway is modified. - \n Note that parent references that cannot be resolved by an implementation - of this API will not be added to this list. Implementations of this - API can only populate Route status for the Gateways/parent resources - they are responsible for. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. items: - description: RouteParentStatus describes the status of a route with - respect to an associated Parent. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: conditions: - description: "Conditions describes the status of the route with - respect to the Gateway. Note that the route's availability - is also subject to the Gateway's own status conditions and - listener status. \n If the Route's ParentRef specifies an - existing Gateway that supports Routes of this kind AND that - Gateway's controller has sufficient access, then that Gateway's - controller MUST set the \"Accepted\" condition on the Route, - to indicate whether the route has been accepted or rejected - by the Gateway, and why. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * The Route refers to a non-existent - parent. * The Route is of a type that the controller does - not support. * The Route is in a namespace the controller - does not have access to." + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -10253,12 +16371,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -10276,131 +16394,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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 parentRef: - description: ParentRef corresponds with a ParentRef in the spec - that this RouteParentStatus struct describes the status of. + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -10438,8 +16600,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tlsroutes.gateway.networking.k8s.io @@ -10461,21 +16623,29 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: "The TLSRoute resource is similar to TCPRoute, but can be configured - to match against TLS-specific metadata. This allows more flexibility in - matching streams for a given TLS listener. \n If you need to forward traffic - to a single target for a TLS listener, you could choose to use a TCPRoute - with a TLS listener." + description: |- + The TLSRoute resource is similar to TCPRoute, but can be configured + to match against TLS-specific metadata. This allows more flexibility + in matching streams for a given TLS listener. + + + If you need to forward traffic to a single target for a TLS listener, you + could choose to use a TCPRoute with a TLS listener. 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' + 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' + 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 @@ -10483,43 +16653,65 @@ spec: description: Spec defines the desired state of TLSRoute. properties: hostnames: - description: "Hostnames defines a set of SNI names that should match - against the SNI attribute of TLS ClientHello message in TLS handshake. - This matches the RFC 1123 definition of a hostname with 2 notable - exceptions: \n 1. IPs are not allowed in SNI names per RFC 6066. - 2. A hostname may be prefixed with a wildcard label (`*.`). The - wildcard label must appear by itself as the first label. \n If a - hostname is specified by both the Listener and TLSRoute, there must - be at least one intersecting hostname for the TLSRoute to be attached - to the Listener. For example: \n * A Listener with `test.example.com` - as the hostname matches TLSRoutes that have either not specified - any hostnames, or have specified at least one of `test.example.com` - or `*.example.com`. * A Listener with `*.example.com` as the hostname - matches TLSRoutes that have either not specified any hostnames or - have specified at least one hostname that matches the Listener hostname. - For example, `test.example.com` and `*.example.com` would both match. - On the other hand, `example.com` and `test.example.net` would not - match. \n If both the Listener and TLSRoute have specified hostnames, - any TLSRoute hostnames that do not match the Listener hostname MUST - be ignored. For example, if a Listener specified `*.example.com`, - and the TLSRoute specified `test.example.com` and `test.example.net`, - `test.example.net` must not be considered for a match. \n If both - the Listener and TLSRoute have specified hostnames, and none match - with the criteria above, then the TLSRoute is not accepted. The - implementation must raise an 'Accepted' Condition with a status - of `False` in the corresponding RouteParentStatus. \n Support: Core" + description: |- + Hostnames defines a set of SNI names that should match against the + SNI attribute of TLS ClientHello message in TLS handshake. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed in SNI names per RFC 6066. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and TLSRoute, there + must be at least one intersecting hostname for the TLSRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches TLSRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches TLSRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + If both the Listener and TLSRoute have specified hostnames, any + TLSRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + TLSRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and TLSRoute have specified hostnames, and none + match with the criteria above, then the TLSRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + Support: Core items: - description: "Hostname is the fully qualified domain name of a network - host. This matches the RFC 1123 definition of a hostname with - 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname - may be prefixed with a wildcard label (`*.`). The wildcard label - must appear by itself as the first label. \n Hostname can be \"precise\" - which is a domain name without the terminating dot of a network - host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain - name prefixed with a single wildcard label (e.g. `*.example.com`). - \n Note that as per RFC1035 and RFC1123, a *label* must consist - of lower case alphanumeric characters or '-', and must start and - end with an alphanumeric character. No other punctuation is allowed." + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. maxLength: 253 minLength: 1 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ @@ -10527,165 +16719,246 @@ spec: maxItems: 16 type: array parentRefs: - description: "ParentRefs references the resources (usually Gateways) - that a Route wants to be attached to. Note that the referenced parent - resource needs to allow this for the attachment to be complete. - For Gateways, that means the Gateway needs to allow attachment from - Routes of this kind and namespace. For Services, that means the - Service must either be in the same namespace for a \"producer\" - route, or the mesh implementation must support and allow \"consumer\" - routes for the referenced Service. ReferenceGrant is not applicable - for governing ParentRefs to Services - it is not possible to create - a \"producer\" route for a Service in a different namespace from - the Route. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * They select different objects. If this is the case, - then parentRef entries are distinct. In terms of fields, this means - that the multi-part key defined by `group`, `kind`, `namespace`, - and `name` must be unique across all parentRef entries in the Route. - * They do not select different objects, but for each optional field - used, each ParentRef that selects the same object must set the same - set of optional fields to different values. If one ParentRef sets - a combination of optional fields, all must set the same combination. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same - object must also set `port`. * If one ParentRef sets `sectionName` - and `port`, all ParentRefs referencing the same object must also - set `sectionName` and `port`. \n It is possible to separately reference - multiple distinct objects that may be collapsed by an implementation. - For example, some implementations may choose to merge compatible - Gateway Listeners together. If that is the case, the list of routes - attached to those resources should also be merged. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific rules. 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 other kinds of cross-namespace - reference. \n 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. \n 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. \n " + 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 other kinds 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. + + + + + + items: - description: "ParentReference identifies an API object (usually - a Gateway) that can be considered a parent of this resource (usually - a route). There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + 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. 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -10724,65 +16997,97 @@ spec: description: TLSRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the rule performs no forwarding; if no filters are specified - that would result in a response being sent, the underlying - implementation must actively reject request attempts to this - backend, by rejecting the connection or returning a 500 status - code. Request rejections must respect weight; if an invalid - backend is requested to have 80% of requests, then 80% of - requests must be rejected instead. \n Support: Core for Kubernetes - Service \n Support: Extended for Kubernetes ServiceImport - \n Support: Implementation-specific for any other resource - \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or + a Service with no endpoints), the rule performs no forwarding; if no + filters are specified that would result in a response being sent, the + underlying implementation must actively reject request attempts to this + backend, by rejecting the connection or returning a 500 status code. + Request rejections must respect weight; if an invalid backend is + requested to have 80% of requests, then 80% of requests must be rejected + instead. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Extended items: - description: "BackendRef defines how a Route should forward - a request to a Kubernetes resource. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n If a Service appProtocol isn't specified, - an implementation MAY infer the backend protocol through - its own means. Implementations MAY infer the protocol from - the Route type referring to the backend Service. \n If a - Route is not able to send traffic to the backend using the - specified protocol then the backend is considered invalid. - Implementations MUST set the \"ResolvedRefs\" condition - to \"False\" with the \"UnsupportedProtocol\" reason. \n - \n Note that when the - BackendTLSPolicy object is enabled by the implementation, - there are some extra rules about validity to consider here. - See the fields where this struct is used for more information - about the exact behavior." + description: |- + BackendRef defines how a Route should forward a request to a Kubernetes + resource. + + + 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. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + + + Note that when the BackendTLSPolicy object is enabled by the implementation, + there are some extra rules about validity to consider here. See the fields + where this struct is used for more information about the exact behavior. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -10793,43 +17098,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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 weight: default: 1 - description: "Weight specifies the proportion of requests - forwarded to the referenced backend. This is computed - as weight/(sum of all weights in this BackendRefs list). - For non-zero values, there may be some epsilon from - the exact proportion defined here depending on the precision - an implementation supports. Weight is not a percentage - and the sum of weights does not need to equal 100. \n - If only one backend is specified and it has a weight - greater than 0, 100% of the traffic is forwarded to - that backend. If weight is set to 0, no traffic should - be forwarded for this entry. If unspecified, weight - defaults to 1. \n Support for this field varies based - on the context where used." + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support for this field varies based on the context where used. format: int32 maximum: 1000000 minimum: 0 @@ -10855,81 +17168,94 @@ spec: description: Status defines the current state of TLSRoute. properties: parents: - description: "Parents is a list of parent resources (usually Gateways) - that are associated with the route, and the status of the route - with respect to each parent. When this route attaches to a parent, - the controller that manages the parent must add an entry to this - list when the controller first sees the route and should update - the entry as appropriate when the route or gateway is modified. - \n Note that parent references that cannot be resolved by an implementation - of this API will not be added to this list. Implementations of this - API can only populate Route status for the Gateways/parent resources - they are responsible for. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. items: - description: RouteParentStatus describes the status of a route with - respect to an associated Parent. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: conditions: - description: "Conditions describes the status of the route with - respect to the Gateway. Note that the route's availability - is also subject to the Gateway's own status conditions and - listener status. \n If the Route's ParentRef specifies an - existing Gateway that supports Routes of this kind AND that - Gateway's controller has sufficient access, then that Gateway's - controller MUST set the \"Accepted\" condition on the Route, - to indicate whether the route has been accepted or rejected - by the Gateway, and why. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * The Route refers to a non-existent - parent. * The Route is of a type that the controller does - not support. * The Route is in a namespace the controller - does not have access to." + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -10943,12 +17269,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -10966,131 +17292,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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 parentRef: - description: ParentRef corresponds with a ParentRef in the spec - that this RouteParentStatus struct describes the status of. + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -11128,8 +17498,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0-rc2 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: udproutes.gateway.networking.k8s.io @@ -11151,19 +17521,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: UDPRoute provides a way to route UDP traffic. When combined with - a Gateway listener, it can be used to forward traffic on the port specified - by the listener to a set of backends specified by the UDPRoute. + description: |- + UDPRoute provides a way to route UDP traffic. When combined with a Gateway + listener, it can be used to forward traffic on the port specified by the + listener to a set of backends specified by the UDPRoute. 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' + 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' + 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 @@ -11171,165 +17547,246 @@ spec: description: Spec defines the desired state of UDPRoute. properties: parentRefs: - description: "ParentRefs references the resources (usually Gateways) - that a Route wants to be attached to. Note that the referenced parent - resource needs to allow this for the attachment to be complete. - For Gateways, that means the Gateway needs to allow attachment from - Routes of this kind and namespace. For Services, that means the - Service must either be in the same namespace for a \"producer\" - route, or the mesh implementation must support and allow \"consumer\" - routes for the referenced Service. ReferenceGrant is not applicable - for governing ParentRefs to Services - it is not possible to create - a \"producer\" route for a Service in a different namespace from - the Route. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * They select different objects. If this is the case, - then parentRef entries are distinct. In terms of fields, this means - that the multi-part key defined by `group`, `kind`, `namespace`, - and `name` must be unique across all parentRef entries in the Route. - * They do not select different objects, but for each optional field - used, each ParentRef that selects the same object must set the same - set of optional fields to different values. If one ParentRef sets - a combination of optional fields, all must set the same combination. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same - object must also set `port`. * If one ParentRef sets `sectionName` - and `port`, all ParentRefs referencing the same object must also - set `sectionName` and `port`. \n It is possible to separately reference - multiple distinct objects that may be collapsed by an implementation. - For example, some implementations may choose to merge compatible - Gateway Listeners together. If that is the case, the list of routes - attached to those resources should also be merged. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific rules. 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 other kinds of cross-namespace - reference. \n 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. \n 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. \n " + 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 other kinds 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. + + + + + + items: - description: "ParentReference identifies an API object (usually - a Gateway) that can be considered a parent of this resource (usually - a route). There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + 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. 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -11368,62 +17825,94 @@ spec: description: UDPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Packet drops must respect weight; - if an invalid backend is requested to have 80% of the packets, - then 80% of packets must be dropped instead. \n Support: Core - for Kubernetes Service \n Support: Extended for Kubernetes - ServiceImport \n Support: Implementation-specific for any - other resource \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Packet drops must + respect weight; if an invalid backend is requested to have 80% of + the packets, then 80% of packets must be dropped instead. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Extended items: - description: "BackendRef defines how a Route should forward - a request to a Kubernetes resource. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n If a Service appProtocol isn't specified, - an implementation MAY infer the backend protocol through - its own means. Implementations MAY infer the protocol from - the Route type referring to the backend Service. \n If a - Route is not able to send traffic to the backend using the - specified protocol then the backend is considered invalid. - Implementations MUST set the \"ResolvedRefs\" condition - to \"False\" with the \"UnsupportedProtocol\" reason. \n - \n Note that when the - BackendTLSPolicy object is enabled by the implementation, - there are some extra rules about validity to consider here. - See the fields where this struct is used for more information - about the exact behavior." + description: |- + BackendRef defines how a Route should forward a request to a Kubernetes + resource. + + + 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. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + + + Note that when the BackendTLSPolicy object is enabled by the implementation, + there are some extra rules about validity to consider here. See the fields + where this struct is used for more information about the exact behavior. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -11434,43 +17923,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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 weight: default: 1 - description: "Weight specifies the proportion of requests - forwarded to the referenced backend. This is computed - as weight/(sum of all weights in this BackendRefs list). - For non-zero values, there may be some epsilon from - the exact proportion defined here depending on the precision - an implementation supports. Weight is not a percentage - and the sum of weights does not need to equal 100. \n - If only one backend is specified and it has a weight - greater than 0, 100% of the traffic is forwarded to - that backend. If weight is set to 0, no traffic should - be forwarded for this entry. If unspecified, weight - defaults to 1. \n Support for this field varies based - on the context where used." + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support for this field varies based on the context where used. format: int32 maximum: 1000000 minimum: 0 @@ -11496,81 +17993,94 @@ spec: description: Status defines the current state of UDPRoute. properties: parents: - description: "Parents is a list of parent resources (usually Gateways) - that are associated with the route, and the status of the route - with respect to each parent. When this route attaches to a parent, - the controller that manages the parent must add an entry to this - list when the controller first sees the route and should update - the entry as appropriate when the route or gateway is modified. - \n Note that parent references that cannot be resolved by an implementation - of this API will not be added to this list. Implementations of this - API can only populate Route status for the Gateways/parent resources - they are responsible for. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. items: - description: RouteParentStatus describes the status of a route with - respect to an associated Parent. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: conditions: - description: "Conditions describes the status of the route with - respect to the Gateway. Note that the route's availability - is also subject to the Gateway's own status conditions and - listener status. \n If the Route's ParentRef specifies an - existing Gateway that supports Routes of this kind AND that - Gateway's controller has sufficient access, then that Gateway's - controller MUST set the \"Accepted\" condition on the Route, - to indicate whether the route has been accepted or rejected - by the Gateway, and why. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * The Route refers to a non-existent - parent. * The Route is of a type that the controller does - not support. * The Route is in a namespace the controller - does not have access to." + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // + +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" 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. + 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. + 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. + 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. + 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_])?$ @@ -11584,12 +18094,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across - resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability - to deconflict is important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 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 @@ -11607,131 +18117,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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 parentRef: - description: ParentRef corresponds with a ParentRef in the spec - that this RouteParentStatus struct describes the status of. + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 94433f5715c..eb8457a116b 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -866,16 +866,6 @@ spec: maxLength: 253 minLength: 1 type: string - namespace: - description: |- - Namespace is the namespace of the referent. When unspecified, the local - namespace is inferred. Even when policy targets a resource in a different - namespace, it MUST only apply to traffic originating from the same - namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string sectionName: description: |- SectionName is the name of a section within the target resource. When @@ -883,8 +873,9 @@ spec: resources, SectionName is interpreted as the following: - * Gateway: Listener Name - * Service: Port Name + * Gateway: Listener name + * HTTPRoute: HTTPRouteRule name + * Service: Port name If a SectionName is specified, but does not exist on the targeted object, @@ -1079,7 +1070,7 @@ spec: * Gateway (Gateway conformance profile) - * Service (Mesh conformance profile, experimental, ClusterIP Services only) + * Service (Mesh conformance profile, ClusterIP Services only) Support for other resources is Implementation-Specific. @@ -1165,9 +1156,6 @@ spec: Support: Extended - - - format: int32 maximum: 65535 minimum: 1 @@ -1178,14 +1166,12 @@ spec: following resources, SectionName is interpreted as the following: - * Gateway: Listener Name. When both Port (experimental) and SectionName + * 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 + * Service: Port name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match - both specified values. Note that attaching Routes to Services as Parents - is part of experimental Mesh support and is not supported for any other - purpose. + both specified values. Implementations MAY choose to support attaching Routes to other resources. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index e82d67b932d..c308847ea0d 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -270,16 +270,6 @@ spec: maxLength: 253 minLength: 1 type: string - namespace: - description: |- - Namespace is the namespace of the referent. When unspecified, the local - namespace is inferred. Even when policy targets a resource in a different - namespace, it MUST only apply to traffic originating from the same - namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string sectionName: description: |- SectionName is the name of a section within the target resource. When @@ -287,8 +277,9 @@ spec: resources, SectionName is interpreted as the following: - * Gateway: Listener Name - * Service: Port Name + * Gateway: Listener name + * HTTPRoute: HTTPRouteRule name + * Service: Port name If a SectionName is specified, but does not exist on the targeted object, @@ -639,7 +630,7 @@ spec: * Gateway (Gateway conformance profile) - * Service (Mesh conformance profile, experimental, ClusterIP Services only) + * Service (Mesh conformance profile, ClusterIP Services only) Support for other resources is Implementation-Specific. @@ -725,9 +716,6 @@ spec: Support: Extended - - - format: int32 maximum: 65535 minimum: 1 @@ -738,14 +726,12 @@ spec: following resources, SectionName is interpreted as the following: - * Gateway: Listener Name. When both Port (experimental) and SectionName + * 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 + * Service: Port name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match - both specified values. Note that attaching Routes to Services as Parents - is part of experimental Mesh support and is not supported for any other - purpose. + both specified values. Implementations MAY choose to support attaching Routes to other resources. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index 6e8c04b96b5..7f13dee07cd 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -214,16 +214,6 @@ spec: maxLength: 253 minLength: 1 type: string - namespace: - description: |- - Namespace is the namespace of the referent. When unspecified, the local - namespace is inferred. Even when policy targets a resource in a different - namespace, it MUST only apply to traffic originating from the same - namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string sectionName: description: |- SectionName is the name of a section within the target resource. When @@ -231,8 +221,9 @@ spec: resources, SectionName is interpreted as the following: - * Gateway: Listener Name - * Service: Port Name + * Gateway: Listener name + * HTTPRoute: HTTPRouteRule name + * Service: Port name If a SectionName is specified, but does not exist on the targeted object, @@ -510,7 +501,7 @@ spec: * Gateway (Gateway conformance profile) - * Service (Mesh conformance profile, experimental, ClusterIP Services only) + * Service (Mesh conformance profile, ClusterIP Services only) Support for other resources is Implementation-Specific. @@ -596,9 +587,6 @@ spec: Support: Extended - - - format: int32 maximum: 65535 minimum: 1 @@ -609,14 +597,12 @@ spec: following resources, SectionName is interpreted as the following: - * Gateway: Listener Name. When both Port (experimental) and SectionName + * 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 + * Service: Port name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match - both specified values. Note that attaching Routes to Services as Parents - is part of experimental Mesh support and is not supported for any other - purpose. + both specified values. Implementations MAY choose to support attaching Routes to other resources. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml index 9bd88ed1bb3..e385b0d4bb0 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml @@ -124,7 +124,7 @@ spec: description: |- TargetRef is the name of the Gateway API resource this policy is being attached to. - By default attaching to Gateway is supported and + By default, attaching to Gateway is supported and when mergeGateways is enabled it should attach to GatewayClass. This Policy and the TargetRef MUST be in the same namespace for this Policy to have effect and be applied to the Gateway @@ -146,16 +146,6 @@ spec: maxLength: 253 minLength: 1 type: string - namespace: - description: |- - Namespace is the namespace of the referent. When unspecified, the local - namespace is inferred. Even when policy targets a resource in a different - namespace, it MUST only apply to traffic originating from the same - namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string required: - group - kind @@ -278,7 +268,7 @@ spec: * Gateway (Gateway conformance profile) - * Service (Mesh conformance profile, experimental, ClusterIP Services only) + * Service (Mesh conformance profile, ClusterIP Services only) Support for other resources is Implementation-Specific. @@ -364,9 +354,6 @@ spec: Support: Extended - - - format: int32 maximum: 65535 minimum: 1 @@ -377,14 +364,12 @@ spec: following resources, SectionName is interpreted as the following: - * Gateway: Listener Name. When both Port (experimental) and SectionName + * 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 + * Service: Port name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match - both specified values. Note that attaching Routes to Services as Parents - is part of experimental Mesh support and is not supported for any other - purpose. + both specified values. Implementations MAY choose to support attaching Routes to other resources. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 2758a9c2524..7c314e20cd7 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -697,16 +697,6 @@ spec: maxLength: 253 minLength: 1 type: string - namespace: - description: |- - Namespace is the namespace of the referent. When unspecified, the local - namespace is inferred. Even when policy targets a resource in a different - namespace, it MUST only apply to traffic originating from the same - namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string sectionName: description: |- SectionName is the name of a section within the target resource. When @@ -714,8 +704,9 @@ spec: resources, SectionName is interpreted as the following: - * Gateway: Listener Name - * Service: Port Name + * Gateway: Listener name + * HTTPRoute: HTTPRouteRule name + * Service: Port name If a SectionName is specified, but does not exist on the targeted object, @@ -846,7 +837,7 @@ spec: * Gateway (Gateway conformance profile) - * Service (Mesh conformance profile, experimental, ClusterIP Services only) + * Service (Mesh conformance profile, ClusterIP Services only) Support for other resources is Implementation-Specific. @@ -932,9 +923,6 @@ spec: Support: Extended - - - format: int32 maximum: 65535 minimum: 1 @@ -945,14 +933,12 @@ spec: following resources, SectionName is interpreted as the following: - * Gateway: Listener Name. When both Port (experimental) and SectionName + * 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 + * Service: Port name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match - both specified values. Note that attaching Routes to Services as Parents - is part of experimental Mesh support and is not supported for any other - purpose. + both specified values. Implementations MAY choose to support attaching Routes to other resources. diff --git a/go.mod b/go.mod index 114fcdce2a3..b928d00b108 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.26.0 go.opentelemetry.io/proto/otlp v1.2.0 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f golang.org/x/sys v0.20.0 google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.34.0 @@ -49,9 +49,9 @@ require ( k8s.io/cli-runtime v0.30.0 k8s.io/client-go v0.30.0 k8s.io/kubectl v0.30.0 - k8s.io/utils v0.0.0-20230726121419-3b25d923346b + k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 sigs.k8s.io/controller-runtime v0.18.1 - sigs.k8s.io/gateway-api v1.0.0 + sigs.k8s.io/gateway-api v1.1.0-rc2 sigs.k8s.io/mcs-api v0.1.0 sigs.k8s.io/yaml v1.4.0 ) @@ -123,7 +123,7 @@ require ( github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect github.com/evanphx/json-patch v5.9.0+incompatible github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect @@ -131,16 +131,16 @@ require ( github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/imdario/mergo v0.3.16 // indirect @@ -172,16 +172,15 @@ require ( go.opentelemetry.io/otel/trace v1.26.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.16.0 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.24.0 - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.6.0 // indirect + golang.org/x/oauth2 v0.19.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.19.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.20.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect @@ -189,7 +188,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/component-base v0.30.0 // indirect k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect diff --git a/go.sum b/go.sum index 185c5f15525..f0b252fc375 100644 --- a/go.sum +++ b/go.sum @@ -124,7 +124,6 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -168,8 +167,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= +github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.12.1-0.20240425230418-212e93054f1a h1:OmSlDWdXUzNgoMWOtrcEAmiO9BxTt6cGotwz7cZwIyw= github.com/envoyproxy/go-control-plane v0.12.1-0.20240425230418-212e93054f1a/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA= @@ -237,16 +236,15 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -269,9 +267,8 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= @@ -312,8 +309,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= @@ -330,7 +325,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -360,8 +354,8 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/grafana/tempo v1.5.0 h1:JSwulLVtXvUw2MyuUPcvRg3MJiwTUs5XWnbG6fOKatc= @@ -426,7 +420,6 @@ github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -628,8 +621,6 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -637,9 +628,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/telepresenceio/telepresence/rpc/v2 v2.6.8 h1:q5V85LBT9bA/c4YPa/kMvJGyKZDgBPJTftlAMqJx7j4= @@ -735,8 +723,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4 golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -744,8 +732,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -775,8 +763,8 @@ golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= +golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -785,8 +773,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -835,15 +823,14 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -861,8 +848,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -874,8 +861,6 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -904,8 +889,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -982,14 +965,14 @@ k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108 h1:Q8Z7VlGhcJgBHJHYugJ/K/7iB8a2eSxCyxdVjJp+lLY= +k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/kubectl v0.30.0 h1:xbPvzagbJ6RNYVMVuiHArC1grrV5vSmmIcSZuCdzRyk= k8s.io/kubectl v0.30.0/go.mod h1:zgolRw2MQXLPwmic2l/+iHs239L49fhSeICuMhQQXTI= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 h1:ao5hUqGhsqdm+bYbjH/pRkCs0unBGe9UyDahzs9zQzQ= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY= oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= @@ -997,8 +980,8 @@ sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gE sigs.k8s.io/controller-runtime v0.18.1 h1:RpWbigmuiylbxOCLy0tGnq1cU1qWPwNIQzoJk+QeJx4= sigs.k8s.io/controller-runtime v0.18.1/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= -sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs= -sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c= +sigs.k8s.io/gateway-api v1.1.0-rc2 h1:uMHSylqzNHYD4kgp6OCDZv9o7ukzgtjuI6G6/e+TSUo= +sigs.k8s.io/gateway-api v1.1.0-rc2/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kind v0.8.1/go.mod h1:oNKTxUVPYkV9lWzY6CVMNluVq8cBsyq+UgPJdvA3uu4= diff --git a/internal/cmd/egctl/status.go b/internal/cmd/egctl/status.go index 3a23b36afe4..791488ea02d 100644 --- a/internal/cmd/egctl/status.go +++ b/internal/cmd/egctl/status.go @@ -20,6 +20,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gwv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" ) @@ -140,7 +141,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s resourcesList = &httproute case "grpcroute": - grpcroute := gwv1a2.GRPCRouteList{} + grpcroute := gwv1.GRPCRouteList{} if err := cli.List(ctx, &grpcroute, client.InNamespace(namespace)); err != nil { return err } @@ -168,7 +169,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s resourcesList = &tlsroute case "btlspolicy", "backendtlspolicy": - btlspolicy := gwv1a2.BackendTLSPolicyList{} + btlspolicy := gwv1a3.BackendTLSPolicyList{} if err := cli.List(ctx, &btlspolicy, client.InNamespace(namespace)); err != nil { return err } diff --git a/internal/cmd/egctl/status_test.go b/internal/cmd/egctl/status_test.go index 9ffccabf893..eddaa0a5507 100644 --- a/internal/cmd/egctl/status_test.go +++ b/internal/cmd/egctl/status_test.go @@ -15,6 +15,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gwv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" ) func TestWriteStatus(t *testing.T) { @@ -470,8 +471,8 @@ http2 foobar4 test-status-4 test reason 4 }, { name: "egctl x status btlspolicy", - resourceList: &gwv1a2.BackendTLSPolicyList{ - Items: []gwv1a2.BackendTLSPolicy{ + resourceList: &gwv1a3.BackendTLSPolicyList{ + Items: []gwv1a3.BackendTLSPolicy{ { ObjectMeta: metav1.ObjectMeta{ Name: "btls", diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml index 7b8319b6376..11a124f387c 100644 --- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml @@ -322,6 +322,7 @@ grpcRoutes: - method: method: DoThing service: com.example.Things + sessionPersistence: null status: parents: - conditions: @@ -361,6 +362,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml index 3d88f20f51d..4506e5f7bab 100644 --- a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml +++ b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.cluster.yaml @@ -70,6 +70,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json index 41dfd6683e7..0dbd6eb6a37 100644 --- a/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json +++ b/internal/cmd/egctl/testdata/translate/out/echo-gateway-api.route.json @@ -115,7 +115,8 @@ "port": 3000, "weight": 1 } - ] + ], + "sessionPersistence": null } ] }, diff --git a/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml b/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml index c7ad9cde133..07bfeb1a95a 100644 --- a/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml @@ -202,6 +202,7 @@ grpcRoutes: - method: method: DoThing service: com.example.Things + sessionPersistence: null status: parents: - conditions: @@ -241,6 +242,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml b/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml index 3ea1f3f2bc7..e9f3058be76 100644 --- a/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml @@ -56,6 +56,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml b/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml index c578d14aef5..9f550da41dd 100644 --- a/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml +++ b/internal/cmd/egctl/testdata/translate/out/rejected-http-route.route.yaml @@ -63,6 +63,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml b/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml index ef42d68c93e..818dba2b03b 100644 --- a/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/valid-envoyproxy.all.yaml @@ -195,6 +195,7 @@ grpcRoutes: - method: method: DoThing service: com.example.Things + sessionPersistence: null status: parents: - conditions: @@ -234,6 +235,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go index 056dc47ac54..9c787d04a20 100644 --- a/internal/cmd/egctl/translate.go +++ b/internal/cmd/egctl/translate.go @@ -556,7 +556,7 @@ func addMissingServices(requiredServices map[string]*v1.Service, obj interface{} refs = append(refs, httpBakcendRef.BackendRef) } } - case *gwapiv1a2.GRPCRoute: + case *gwapiv1.GRPCRoute: objNamespace = route.Namespace for _, rule := range route.Spec.Rules { for _, gRPCBakcendRef := range rule.BackendRefs { @@ -762,7 +762,7 @@ func kubernetesYAMLToResources(str string, addMissingResources bool) (*gatewayap resources.HTTPRoutes = append(resources.HTTPRoutes, httpRoute) case gatewayapi.KindGRPCRoute: typedSpec := spec.Interface() - grpcRoute := &gwapiv1a2.GRPCRoute{ + grpcRoute := &gwapiv1.GRPCRoute{ TypeMeta: metav1.TypeMeta{ Kind: gatewayapi.KindGRPCRoute, }, @@ -770,7 +770,7 @@ func kubernetesYAMLToResources(str string, addMissingResources bool) (*gatewayap Name: name, Namespace: namespace, }, - Spec: typedSpec.(gwapiv1a2.GRPCRouteSpec), + Spec: typedSpec.(gwapiv1.GRPCRouteSpec), } resources.GRPCRoutes = append(resources.GRPCRoutes, grpcRoute) case gatewayapi.KindNamespace: diff --git a/internal/envoygateway/scheme.go b/internal/envoygateway/scheme.go index 78567e9208c..94eefbf0d44 100644 --- a/internal/envoygateway/scheme.go +++ b/internal/envoygateway/scheme.go @@ -6,11 +6,11 @@ package envoygateway import ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gwapischeme "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/scheme" mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" @@ -25,27 +25,15 @@ import ( var scheme = runtime.NewScheme() func init() { - if err := clientgoscheme.AddToScheme(scheme); err != nil { - panic(err) - } + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) // Add Envoy Gateway types. - if err := egv1a1.AddToScheme(scheme); err != nil { - panic(err) - } + utilruntime.Must(egv1a1.AddToScheme(scheme)) // Add Gateway API types. - if err := gwapiv1.AddToScheme(scheme); err != nil { - panic(err) - } - if err := gwapiv1b1.AddToScheme(scheme); err != nil { - panic(err) - } - if err := gwapiv1a2.AddToScheme(scheme); err != nil { - panic(err) - } + utilruntime.Must(gwapischeme.AddToScheme(scheme)) // Add mcs api types. - if err := mcsapi.AddToScheme(scheme); err != nil { - panic(err) - } + utilruntime.Must(mcsapi.AddToScheme(scheme)) + // Add CRD kind to known types, experimental conformance test requires this. + utilruntime.Must(apiextensionsv1.AddToScheme(scheme)) } // GetScheme returns a scheme with types supported by the Kubernetes provider. diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go index 3dcfc9ad214..e29a6a968d9 100644 --- a/internal/gatewayapi/backendtlspolicy.go +++ b/internal/gatewayapi/backendtlspolicy.go @@ -12,6 +12,7 @@ import ( "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/status" @@ -108,13 +109,13 @@ func (t *Translator) processBackendTLSPolicy( return tlsBundle } -func backendTLSTargetMatched(policy gwapiv1a2.BackendTLSPolicy, target gwapiv1a2.PolicyTargetReferenceWithSectionName) bool { - policyTarget := policy.Spec.TargetRef +func backendTLSTargetMatched(policy gwapiv1a3.BackendTLSPolicy, target gwapiv1a2.LocalPolicyTargetReferenceWithSectionName) bool { + // TODO: support multiple targetRefs + policyTarget := policy.Spec.TargetRefs[0] if target.Group == policyTarget.Group && target.Kind == policyTarget.Kind && - target.Name == policyTarget.Name && - NamespaceDerefOr(policyTarget.Namespace, policy.Namespace) == string(*target.Namespace) { + target.Name == policyTarget.Name { if policyTarget.SectionName != nil && *policyTarget.SectionName != *target.SectionName { return false } @@ -123,7 +124,7 @@ func backendTLSTargetMatched(policy gwapiv1a2.BackendTLSPolicy, target gwapiv1a2 return false } -func getBackendTLSPolicy(policies []*gwapiv1a2.BackendTLSPolicy, backendRef gwapiv1a2.BackendObjectReference, backendNamespace string) *gwapiv1a2.BackendTLSPolicy { +func getBackendTLSPolicy(policies []*gwapiv1a3.BackendTLSPolicy, backendRef gwapiv1a2.BackendObjectReference, backendNamespace string) *gwapiv1a3.BackendTLSPolicy { target := GetTargetBackendReference(backendRef, backendNamespace) for _, policy := range policies { if backendTLSTargetMatched(*policy, target) { @@ -133,7 +134,7 @@ func getBackendTLSPolicy(policies []*gwapiv1a2.BackendTLSPolicy, backendRef gwap return nil } -func getBackendTLSBundle(policies []*gwapiv1a2.BackendTLSPolicy, configmaps []*corev1.ConfigMap, backendRef gwapiv1a2.BackendObjectReference, backendNamespace string) (*ir.TLSUpstreamConfig, error) { +func getBackendTLSBundle(policies []*gwapiv1a3.BackendTLSPolicy, configmaps []*corev1.ConfigMap, backendRef gwapiv1a2.BackendObjectReference, backendNamespace string) (*ir.TLSUpstreamConfig, error) { backendTLSPolicy := getBackendTLSPolicy(policies, backendRef, backendNamespace) if backendTLSPolicy == nil { @@ -141,8 +142,8 @@ func getBackendTLSBundle(policies []*gwapiv1a2.BackendTLSPolicy, configmaps []*c } tlsBundle := &ir.TLSUpstreamConfig{ - SNI: string(backendTLSPolicy.Spec.TLS.Hostname), - UseSystemTrustStore: ptr.Deref(backendTLSPolicy.Spec.TLS.WellKnownCACerts, "") == gwapiv1a2.WellKnownCACertSystem, + SNI: string(backendTLSPolicy.Spec.Validation.Hostname), + UseSystemTrustStore: ptr.Deref(backendTLSPolicy.Spec.Validation.WellKnownCACertificates, "") == gwapiv1a3.WellKnownCACertificatesSystem, } if tlsBundle.UseSystemTrustStore { return tlsBundle, nil @@ -150,7 +151,7 @@ func getBackendTLSBundle(policies []*gwapiv1a2.BackendTLSPolicy, configmaps []*c caRefMap := make(map[string]string) - for _, caRef := range backendTLSPolicy.Spec.TLS.CACertRefs { + for _, caRef := range backendTLSPolicy.Spec.Validation.CACertificateRefs { caRefMap[string(caRef.Name)] = string(caRef.Kind) } diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 65d9607bb08..4c83277f9a1 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -19,7 +19,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gwv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" @@ -199,16 +198,11 @@ func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv } func resolveBTPolicyGatewayTargetRef(policy *egv1a1.BackendTrafficPolicy, gateways map[types.NamespacedName]*policyGatewayTargetContext) (*GatewayContext, *status.PolicyResolveError) { - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1b1.Namespace(policy.Namespace)) - } - + targetNs := policy.Namespace // Check if the gateway exists key := types.NamespacedName{ Name: string(policy.Spec.TargetRef.Name), - Namespace: string(*targetNs), + Namespace: targetNs, } gateway, ok := gateways[key] @@ -218,9 +212,9 @@ func resolveBTPolicyGatewayTargetRef(policy *egv1a1.BackendTrafficPolicy, gatewa } // Ensure Policy and target are in the same namespace - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, BackendTrafficPolicy can only target a resource in the same namespace.", - policy.Namespace, *targetNs) + policy.Namespace, targetNs) return gateway.GatewayContext, &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, @@ -246,17 +240,13 @@ func resolveBTPolicyGatewayTargetRef(policy *egv1a1.BackendTrafficPolicy, gatewa } func resolveBTPolicyRouteTargetRef(policy *egv1a1.BackendTrafficPolicy, routes map[policyTargetRouteKey]*policyRouteTargetContext) (RouteContext, *status.PolicyResolveError) { - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1b1.Namespace(policy.Namespace)) - } + targetNs := policy.Namespace // Check if the route exists key := policyTargetRouteKey{ Kind: string(policy.Spec.TargetRef.Kind), Name: string(policy.Spec.TargetRef.Name), - Namespace: string(*targetNs), + Namespace: targetNs, } route, ok := routes[key] @@ -266,9 +256,9 @@ func resolveBTPolicyRouteTargetRef(policy *egv1a1.BackendTrafficPolicy, routes m } // Ensure Policy and target are in the same namespace - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, BackendTrafficPolicy can only target a resource in the same namespace.", - policy.Namespace, *targetNs) + policy.Namespace, targetNs) return route.RouteContext, &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, @@ -457,10 +447,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back // Should exist since we've validated this ir := xdsIR[irKey] - policyTarget := irStringKey( - string(ptr.Deref(policy.Spec.TargetRef.Namespace, gwv1a2.Namespace(policy.Namespace))), - string(policy.Spec.TargetRef.Name), - ) + policyTarget := irStringKey(policy.Namespace, string(policy.Spec.TargetRef.Name)) if policy.Spec.Timeout != nil { if ct, err = t.buildTimeout(policy, nil); err != nil { diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index bc04f7c3b2d..3f38ddc597c 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -17,7 +17,6 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" - gwv1b1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" @@ -266,16 +265,12 @@ func (t *Translator) ProcessClientTrafficPolicies(resources *Resources, } func resolveCTPolicyTargetRef(policy *egv1a1.ClientTrafficPolicy, gateways map[types.NamespacedName]*policyGatewayTargetContext) (*GatewayContext, *status.PolicyResolveError) { - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1b1.Namespace(policy.Namespace)) - } + targetNs := policy.Namespace // Check if the gateway exists key := types.NamespacedName{ Name: string(policy.Spec.TargetRef.Name), - Namespace: string(*targetNs), + Namespace: targetNs, } gateway, ok := gateways[key] @@ -285,9 +280,9 @@ func resolveCTPolicyTargetRef(policy *egv1a1.ClientTrafficPolicy, gateways map[t } // Ensure Policy and target Gateway are in the same namespace - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, ClientTrafficPolicy can only target a Gateway in the same namespace.", - policy.Namespace, *targetNs) + policy.Namespace, targetNs) return gateway.GatewayContext, &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go index 1ee327302b1..a61814bd232 100644 --- a/internal/gatewayapi/contexts.go +++ b/internal/gatewayapi/contexts.go @@ -173,7 +173,7 @@ type GRPCRouteContext struct { // GatewayControllerName is the name of the Gateway API controller. GatewayControllerName string - *v1alpha2.GRPCRoute + *gwapiv1.GRPCRoute ParentRefs map[gwapiv1.ParentReference]*RouteParentContext } @@ -355,7 +355,7 @@ type RouteParentContext struct { // TODO: [v1alpha2-gwapiv1] This can probably be replaced with // a single field pointing to *gwapiv1.RouteStatus. HTTPRoute *gwapiv1.HTTPRoute - GRPCRoute *v1alpha2.GRPCRoute + GRPCRoute *gwapiv1.GRPCRoute TLSRoute *v1alpha2.TLSRoute TCPRoute *v1alpha2.TCPRoute UDPRoute *v1alpha2.UDPRoute diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index 2e1fe34ffde..21c32b47773 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -16,9 +16,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" - gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gwv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" @@ -198,16 +196,12 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv } func resolveEEPolicyGatewayTargetRef(policy *egv1a1.EnvoyExtensionPolicy, gateways map[types.NamespacedName]*policyGatewayTargetContext) (*GatewayContext, *status.PolicyResolveError) { - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1b1.Namespace(policy.Namespace)) - } + targetNs := policy.Namespace // Check if the gateway exists key := types.NamespacedName{ Name: string(policy.Spec.TargetRef.Name), - Namespace: string(*targetNs), + Namespace: targetNs, } gateway, ok := gateways[key] @@ -217,9 +211,9 @@ func resolveEEPolicyGatewayTargetRef(policy *egv1a1.EnvoyExtensionPolicy, gatewa } // Ensure Policy and target are in the same namespace - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, EnvoyExtensionPolicy can only target a resource in the same namespace.", - policy.Namespace, *targetNs) + policy.Namespace, targetNs) return gateway.GatewayContext, &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, @@ -245,17 +239,13 @@ func resolveEEPolicyGatewayTargetRef(policy *egv1a1.EnvoyExtensionPolicy, gatewa } func resolveEEPolicyRouteTargetRef(policy *egv1a1.EnvoyExtensionPolicy, routes map[policyTargetRouteKey]*policyRouteTargetContext) (RouteContext, *status.PolicyResolveError) { - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1b1.Namespace(policy.Namespace)) - } + targetNs := policy.Namespace // Check if the route exists key := policyTargetRouteKey{ Kind: string(policy.Spec.TargetRef.Kind), Name: string(policy.Spec.TargetRef.Name), - Namespace: string(*targetNs), + Namespace: targetNs, } route, ok := routes[key] @@ -265,9 +255,9 @@ func resolveEEPolicyRouteTargetRef(policy *egv1a1.EnvoyExtensionPolicy, routes m } // Ensure Policy and target are in the same namespace - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, EnvoyExtensionPolicy can only target a resource in the same namespace.", - policy.Namespace, *targetNs) + policy.Namespace, targetNs) return route.RouteContext, &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, @@ -357,10 +347,7 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway(policy *egv1a1.Envo // Should exist since we've validated this ir := xdsIR[irKey] - policyTarget := irStringKey( - string(ptr.Deref(policy.Spec.TargetRef.Namespace, gwv1a2.Namespace(policy.Namespace))), - string(policy.Spec.TargetRef.Name), - ) + policyTarget := irStringKey(policy.Namespace, string(policy.Spec.TargetRef.Name)) if extProcs, err = t.buildExtProcs(policy, resources); err != nil { errs = errors.Join(errs, err) diff --git a/internal/gatewayapi/envoypatchpolicy.go b/internal/gatewayapi/envoypatchpolicy.go index 5be04d21972..517deb85a77 100644 --- a/internal/gatewayapi/envoypatchpolicy.go +++ b/internal/gatewayapi/envoypatchpolicy.go @@ -10,7 +10,6 @@ import ( "sort" "k8s.io/apimachinery/pkg/types" - "k8s.io/utils/ptr" gwv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" @@ -34,11 +33,7 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo irKey string ) - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1.Namespace(policy.Namespace)) - } + targetNs := policy.Namespace if t.MergeGateways { targetKind = KindGatewayClass @@ -54,7 +49,7 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo } else { targetKind = KindGateway gatewayNN := types.NamespacedName{ - Namespace: string(*targetNs), + Namespace: targetNs, Name: string(policy.Spec.TargetRef.Name), } // It must exist since the gateways have already been processed @@ -115,9 +110,9 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo } // Ensure EnvoyPatchPolicy and target Gateway are in the same namespace - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, EnvoyPatchPolicy can only target a %s in the same namespace.", - policy.Namespace, *targetNs, targetKind) + policy.Namespace, targetNs, targetKind) resolveErr = &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go index 1cde4541f48..29d9914d2c7 100644 --- a/internal/gatewayapi/filters.go +++ b/internal/gatewayapi/filters.go @@ -11,7 +11,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - "sigs.k8s.io/gateway-api/apis/v1alpha2" "github.com/envoyproxy/gateway/internal/ir" ) @@ -107,7 +106,7 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext, // ProcessGRPCFilters translates gateway api grpc filters to IRs. func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext, route RouteContext, - filters []v1alpha2.GRPCRouteFilter, + filters []gwapiv1.GRPCRouteFilter, resources *Resources, ) *HTTPFiltersContext { httpFiltersContext := &HTTPFiltersContext{ @@ -128,13 +127,13 @@ func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext, } switch filter.Type { - case v1alpha2.GRPCRouteFilterRequestHeaderModifier: + case gwapiv1.GRPCRouteFilterRequestHeaderModifier: t.processRequestHeaderModifierFilter(filter.RequestHeaderModifier, httpFiltersContext) - case v1alpha2.GRPCRouteFilterResponseHeaderModifier: + case gwapiv1.GRPCRouteFilterResponseHeaderModifier: t.processResponseHeaderModifierFilter(filter.ResponseHeaderModifier, httpFiltersContext) - case v1alpha2.GRPCRouteFilterRequestMirror: + case gwapiv1.GRPCRouteFilterRequestMirror: t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources) - case v1alpha2.GRPCRouteFilterExtensionRef: + case gwapiv1.GRPCRouteFilterExtensionRef: t.processExtensionRefHTTPFilter(filter.ExtensionRef, httpFiltersContext, resources) default: t.processUnsupportedHTTPFilter(string(filter.Type), httpFiltersContext) diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index e17e595fc9f..246c1f12251 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -72,7 +72,7 @@ func ObjectNamePtr(val string) *v1alpha2.ObjectName { var ( PathMatchTypeDerefOr = ptr.Deref[gwapiv1.PathMatchType] - GRPCMethodMatchTypeDerefOr = ptr.Deref[v1alpha2.GRPCMethodMatchType] + GRPCMethodMatchTypeDerefOr = ptr.Deref[gwapiv1.GRPCMethodMatchType] HeaderMatchTypeDerefOr = ptr.Deref[gwapiv1.HeaderMatchType] QueryParamMatchTypeDerefOr = ptr.Deref[gwapiv1.QueryParamMatchType] ) @@ -185,15 +185,15 @@ func ValidateHTTPRouteFilter(filter *gwapiv1.HTTPRouteFilter, extGKs ...schema.G } // ValidateGRPCRouteFilter validates the provided filter within GRPCRoute. -func ValidateGRPCRouteFilter(filter *v1alpha2.GRPCRouteFilter, extGKs ...schema.GroupKind) error { +func ValidateGRPCRouteFilter(filter *gwapiv1.GRPCRouteFilter, extGKs ...schema.GroupKind) error { switch { case filter == nil: return errors.New("filter is nil") - case filter.Type == v1alpha2.GRPCRouteFilterRequestMirror || - filter.Type == v1alpha2.GRPCRouteFilterRequestHeaderModifier || - filter.Type == v1alpha2.GRPCRouteFilterResponseHeaderModifier: + case filter.Type == gwapiv1.GRPCRouteFilterRequestMirror || + filter.Type == gwapiv1.GRPCRouteFilterRequestHeaderModifier || + filter.Type == gwapiv1.GRPCRouteFilterResponseHeaderModifier: return nil - case filter.Type == v1alpha2.GRPCRouteFilterExtensionRef: + case filter.Type == gwapiv1.GRPCRouteFilterExtensionRef: switch { case filter.ExtensionRef == nil: return errors.New("extensionRef field must be specified for an extended filter") diff --git a/internal/gatewayapi/helpers_test.go b/internal/gatewayapi/helpers_test.go index 6c8f6623067..5f61a1cc1a7 100644 --- a/internal/gatewayapi/helpers_test.go +++ b/internal/gatewayapi/helpers_test.go @@ -17,40 +17,39 @@ import ( "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/runtime/schema" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) func TestValidateGRPCFilterRef(t *testing.T) { testCases := []struct { name string - filter *gwapiv1a2.GRPCRouteFilter + filter *gwapiv1.GRPCRouteFilter expected bool }{ { name: "request mirror filter", - filter: &gwapiv1a2.GRPCRouteFilter{ - Type: gwapiv1a2.GRPCRouteFilterRequestMirror, + filter: &gwapiv1.GRPCRouteFilter{ + Type: gwapiv1.GRPCRouteFilterRequestMirror, }, expected: true, }, { name: "request header modifier filter", - filter: &gwapiv1a2.GRPCRouteFilter{ - Type: gwapiv1a2.GRPCRouteFilterRequestHeaderModifier, + filter: &gwapiv1.GRPCRouteFilter{ + Type: gwapiv1.GRPCRouteFilterRequestHeaderModifier, }, expected: true, }, { name: "response header modifier filter", - filter: &gwapiv1a2.GRPCRouteFilter{ - Type: gwapiv1a2.GRPCRouteFilterResponseHeaderModifier, + filter: &gwapiv1.GRPCRouteFilter{ + Type: gwapiv1.GRPCRouteFilterResponseHeaderModifier, }, expected: true, }, { name: "valid extension resource", - filter: &gwapiv1a2.GRPCRouteFilter{ - Type: gwapiv1a2.GRPCRouteFilterExtensionRef, + filter: &gwapiv1.GRPCRouteFilter{ + Type: gwapiv1.GRPCRouteFilterExtensionRef, ExtensionRef: &gwapiv1.LocalObjectReference{ Group: "example.io", Kind: "Foo", @@ -61,8 +60,8 @@ func TestValidateGRPCFilterRef(t *testing.T) { }, { name: "unsupported extended filter", - filter: &gwapiv1a2.GRPCRouteFilter{ - Type: gwapiv1a2.GRPCRouteFilterExtensionRef, + filter: &gwapiv1.GRPCRouteFilter{ + Type: gwapiv1.GRPCRouteFilterExtensionRef, ExtensionRef: &gwapiv1.LocalObjectReference{ Group: "UnsupportedGroup", Kind: "UnsupportedKind", @@ -73,14 +72,14 @@ func TestValidateGRPCFilterRef(t *testing.T) { }, { name: "empty extended filter", - filter: &gwapiv1a2.GRPCRouteFilter{ - Type: gwapiv1a2.GRPCRouteFilterExtensionRef, + filter: &gwapiv1.GRPCRouteFilter{ + Type: gwapiv1.GRPCRouteFilterExtensionRef, }, expected: false, }, { name: "invalid filter type", - filter: &gwapiv1a2.GRPCRouteFilter{ + filter: &gwapiv1.GRPCRouteFilter{ Type: "Invalid", ExtensionRef: &gwapiv1.LocalObjectReference{ Group: "example.io", diff --git a/internal/gatewayapi/resource.go b/internal/gatewayapi/resource.go index 7ba85502b99..636966aa5e1 100644 --- a/internal/gatewayapi/resource.go +++ b/internal/gatewayapi/resource.go @@ -15,6 +15,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" @@ -36,7 +37,7 @@ type Resources struct { GatewayClass *gwapiv1.GatewayClass `json:"gatewayClass,omitempty" yaml:"gatewayClass,omitempty"` Gateways []*gwapiv1.Gateway `json:"gateways,omitempty" yaml:"gateways,omitempty"` HTTPRoutes []*gwapiv1.HTTPRoute `json:"httpRoutes,omitempty" yaml:"httpRoutes,omitempty"` - GRPCRoutes []*gwapiv1a2.GRPCRoute `json:"grpcRoutes,omitempty" yaml:"grpcRoutes,omitempty"` + GRPCRoutes []*gwapiv1.GRPCRoute `json:"grpcRoutes,omitempty" yaml:"grpcRoutes,omitempty"` TLSRoutes []*gwapiv1a2.TLSRoute `json:"tlsRoutes,omitempty" yaml:"tlsRoutes,omitempty"` TCPRoutes []*gwapiv1a2.TCPRoute `json:"tcpRoutes,omitempty" yaml:"tcpRoutes,omitempty"` UDPRoutes []*gwapiv1a2.UDPRoute `json:"udpRoutes,omitempty" yaml:"udpRoutes,omitempty"` @@ -53,7 +54,7 @@ type Resources struct { ClientTrafficPolicies []*egv1a1.ClientTrafficPolicy `json:"clientTrafficPolicies,omitempty" yaml:"clientTrafficPolicies,omitempty"` BackendTrafficPolicies []*egv1a1.BackendTrafficPolicy `json:"backendTrafficPolicies,omitempty" yaml:"backendTrafficPolicies,omitempty"` SecurityPolicies []*egv1a1.SecurityPolicy `json:"securityPolicies,omitempty" yaml:"securityPolicies,omitempty"` - BackendTLSPolicies []*gwapiv1a2.BackendTLSPolicy `json:"backendTLSPolicies,omitempty" yaml:"backendTLSPolicies,omitempty"` + BackendTLSPolicies []*gwapiv1a3.BackendTLSPolicy `json:"backendTLSPolicies,omitempty" yaml:"backendTLSPolicies,omitempty"` EnvoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy `json:"envoyExtensionPolicies,omitempty" yaml:"envoyExtensionPolicies,omitempty"` } @@ -61,7 +62,7 @@ func NewResources() *Resources { return &Resources{ Gateways: []*gwapiv1.Gateway{}, HTTPRoutes: []*gwapiv1.HTTPRoute{}, - GRPCRoutes: []*gwapiv1a2.GRPCRoute{}, + GRPCRoutes: []*gwapiv1.GRPCRoute{}, TLSRoutes: []*gwapiv1a2.TLSRoute{}, Services: []*v1.Service{}, EndpointSlices: []*discoveryv1.EndpointSlice{}, @@ -74,7 +75,7 @@ func NewResources() *Resources { ClientTrafficPolicies: []*egv1a1.ClientTrafficPolicy{}, BackendTrafficPolicies: []*egv1a1.BackendTrafficPolicy{}, SecurityPolicies: []*egv1a1.SecurityPolicy{}, - BackendTLSPolicies: []*gwapiv1a2.BackendTLSPolicy{}, + BackendTLSPolicies: []*gwapiv1a3.BackendTLSPolicy{}, EnvoyExtensionPolicies: []*egv1a1.EnvoyExtensionPolicy{}, } } diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index 4a7dc8dc2d4..5eacf84d4b1 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -39,7 +39,7 @@ var ( type RoutesTranslator interface { ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*HTTPRouteContext - ProcessGRPCRoutes(grpcRoutes []*gwapiv1a2.GRPCRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*GRPCRouteContext + ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*GRPCRouteContext ProcessTLSRoutes(tlsRoutes []*gwapiv1a2.TLSRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*TLSRouteContext ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*TCPRouteContext ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*UDPRouteContext @@ -73,7 +73,7 @@ func (t *Translator) ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways return relevantHTTPRoutes } -func (t *Translator) ProcessGRPCRoutes(grpcRoutes []*gwapiv1a2.GRPCRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*GRPCRouteContext { +func (t *Translator) ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways []*GatewayContext, resources *Resources, xdsIR XdsIRMap) []*GRPCRouteContext { var relevantGRPCRoutes []*GRPCRouteContext for _, g := range grpcRoutes { @@ -505,7 +505,7 @@ func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRe return routeRoutes, nil } -func (t *Translator) processGRPCRouteRule(grpcRoute *GRPCRouteContext, ruleIdx int, httpFiltersContext *HTTPFiltersContext, rule gwapiv1a2.GRPCRouteRule) ([]*ir.HTTPRoute, error) { +func (t *Translator) processGRPCRouteRule(grpcRoute *GRPCRouteContext, ruleIdx int, httpFiltersContext *HTTPFiltersContext, rule gwapiv1.GRPCRouteRule) ([]*ir.HTTPRoute, error) { var ruleRoutes []*ir.HTTPRoute // If no matches are specified, the implementation MUST match every gRPC request. @@ -545,10 +545,10 @@ func (t *Translator) processGRPCRouteRule(grpcRoute *GRPCRouteContext, ruleIdx i if match.Method != nil { // GRPC's path is in the form of "//" - switch GRPCMethodMatchTypeDerefOr(match.Method.Type, gwapiv1a2.GRPCMethodMatchExact) { - case gwapiv1a2.GRPCMethodMatchExact: + switch GRPCMethodMatchTypeDerefOr(match.Method.Type, gwapiv1.GRPCMethodMatchExact) { + case gwapiv1.GRPCMethodMatchExact: t.processGRPCRouteMethodExact(match.Method, irRoute) - case gwapiv1a2.GRPCMethodMatchRegularExpression: + case gwapiv1.GRPCMethodMatchRegularExpression: if match.Method.Service != nil { if err := regex.Validate(*match.Method.Service); err != nil { return nil, err @@ -569,7 +569,7 @@ func (t *Translator) processGRPCRouteRule(grpcRoute *GRPCRouteContext, ruleIdx i return ruleRoutes, nil } -func (t *Translator) processGRPCRouteMethodExact(method *gwapiv1a2.GRPCMethodMatch, irRoute *ir.HTTPRoute) { +func (t *Translator) processGRPCRouteMethodExact(method *gwapiv1.GRPCMethodMatch, irRoute *ir.HTTPRoute) { switch { case method.Service != nil && method.Method != nil: irRoute.PathMatch = &ir.StringMatch{ @@ -588,7 +588,7 @@ func (t *Translator) processGRPCRouteMethodExact(method *gwapiv1a2.GRPCMethodMat } } -func (t *Translator) processGRPCRouteMethodRegularExpression(method *gwapiv1a2.GRPCMethodMatch, irRoute *ir.HTTPRoute) { +func (t *Translator) processGRPCRouteMethodRegularExpression(method *gwapiv1.GRPCMethodMatch, irRoute *ir.HTTPRoute) { switch { case method.Service != nil && method.Method != nil: irRoute.PathMatch = &ir.StringMatch{ @@ -1326,9 +1326,9 @@ func getIREndpointsFromEndpointSlice(endpointSlice *discoveryv1.EndpointSlice, p return endpoints } -func GetTargetBackendReference(backendRef gwapiv1a2.BackendObjectReference, namespace string) gwapiv1a2.PolicyTargetReferenceWithSectionName { - ref := gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ +func GetTargetBackendReference(backendRef gwapiv1a2.BackendObjectReference, namespace string) gwapiv1a2.LocalPolicyTargetReferenceWithSectionName { + ref := gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: func() gwapiv1a2.Group { if backendRef.Group == nil { return "" @@ -1341,8 +1341,7 @@ func GetTargetBackendReference(backendRef gwapiv1a2.BackendObjectReference, name } return *backendRef.Kind }(), - Name: backendRef.Name, - Namespace: NamespacePtr(NamespaceDerefOr(backendRef.Namespace, namespace)), + Name: backendRef.Name, }, SectionName: func() *gwapiv1.SectionName { if backendRef.Port != nil { diff --git a/internal/gatewayapi/runner/runner_test.go b/internal/gatewayapi/runner/runner_test.go index a48188cccb7..204d4e84348 100644 --- a/internal/gatewayapi/runner/runner_test.go +++ b/internal/gatewayapi/runner/runner_test.go @@ -162,7 +162,7 @@ func TestDeleteStatusKeys(t *testing.T) { r.ProviderResources.GatewayStatuses.Store(keys[0], &gwapiv1.GatewayStatus{}) r.ProviderResources.HTTPRouteStatuses.Store(keys[1], &gwapiv1.HTTPRouteStatus{}) - r.ProviderResources.GRPCRouteStatuses.Store(keys[2], &gwapiv1a2.GRPCRouteStatus{}) + r.ProviderResources.GRPCRouteStatuses.Store(keys[2], &gwapiv1.GRPCRouteStatus{}) r.ProviderResources.TLSRouteStatuses.Store(keys[3], &gwapiv1a2.TLSRouteStatus{}) r.ProviderResources.TCPRouteStatuses.Store(keys[4], &gwapiv1a2.TCPRouteStatus{}) r.ProviderResources.UDPRouteStatuses.Store(keys[5], &gwapiv1a2.UDPRouteStatus{}) @@ -248,7 +248,7 @@ func TestDeleteAllStatusKeys(t *testing.T) { r.ProviderResources.GatewayStatuses.Store(keys[0], &gwapiv1.GatewayStatus{}) r.ProviderResources.HTTPRouteStatuses.Store(keys[1], &gwapiv1.HTTPRouteStatus{}) - r.ProviderResources.GRPCRouteStatuses.Store(keys[2], &gwapiv1a2.GRPCRouteStatus{}) + r.ProviderResources.GRPCRouteStatuses.Store(keys[2], &gwapiv1.GRPCRouteStatus{}) r.ProviderResources.TLSRouteStatuses.Store(keys[3], &gwapiv1a2.TLSRouteStatus{}) r.ProviderResources.TCPRouteStatuses.Store(keys[4], &gwapiv1a2.TCPRouteStatus{}) r.ProviderResources.UDPRouteStatuses.Store(keys[5], &gwapiv1a2.UDPRouteStatus{}) diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index 6723376c00c..cb6a63dc4d4 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -23,7 +23,6 @@ import ( "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gwv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" @@ -228,16 +227,12 @@ func resolveSecurityPolicyGatewayTargetRef( policy *egv1a1.SecurityPolicy, gateways map[types.NamespacedName]*policyGatewayTargetContext, ) (*GatewayContext, *status.PolicyResolveError) { - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1b1.Namespace(policy.Namespace)) - } + targetNs := policy.Namespace // Find the Gateway key := types.NamespacedName{ Name: string(policy.Spec.TargetRef.Name), - Namespace: string(*targetNs), + Namespace: targetNs, } gateway, ok := gateways[key] @@ -250,10 +245,10 @@ func resolveSecurityPolicyGatewayTargetRef( } // Ensure Policy and target are in the same namespace - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { // TODO zhaohuabing use CEL to validate cross-namespace reference message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, SecurityPolicy can only target a resource in the same namespace.", - policy.Namespace, *targetNs) + policy.Namespace, targetNs) return gateway.GatewayContext, &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, @@ -282,17 +277,13 @@ func resolveSecurityPolicyRouteTargetRef( policy *egv1a1.SecurityPolicy, routes map[policyTargetRouteKey]*policyRouteTargetContext, ) (RouteContext, *status.PolicyResolveError) { - targetNs := policy.Spec.TargetRef.Namespace - // If empty, default to namespace of policy - if targetNs == nil { - targetNs = ptr.To(gwv1b1.Namespace(policy.Namespace)) - } + targetNs := policy.Namespace // Check if the route exists key := policyTargetRouteKey{ Kind: string(policy.Spec.TargetRef.Kind), Name: string(policy.Spec.TargetRef.Name), - Namespace: string(*targetNs), + Namespace: targetNs, } route, ok := routes[key] @@ -306,9 +297,9 @@ func resolveSecurityPolicyRouteTargetRef( // Ensure Policy and target are in the same namespace // TODO zhaohuabing use CEL to validate cross-namespace reference - if policy.Namespace != string(*targetNs) { + if policy.Namespace != targetNs { message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, SecurityPolicy can only target a resource in the same namespace.", - policy.Namespace, *targetNs) + policy.Namespace, targetNs) return route.RouteContext, &status.PolicyResolveError{ Reason: gwv1a2.PolicyReasonInvalid, @@ -463,10 +454,7 @@ func (t *Translator) translateSecurityPolicyForGateway( // Should exist since we've validated this x := xdsIR[irKey] - policyTarget := irStringKey( - string(ptr.Deref(policy.Spec.TargetRef.Namespace, gwv1a2.Namespace(policy.Namespace))), - string(policy.Spec.TargetRef.Name), - ) + policyTarget := irStringKey(policy.Namespace, string(policy.Spec.TargetRef.Name)) for _, h := range x.HTTP { gatewayName := h.Name[0:strings.LastIndex(h.Name, "/")] if t.MergeGateways && gatewayName != policyTarget { diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml index 391eeb060bf..a6edb4dff64 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.in.yaml @@ -69,7 +69,6 @@ services: protocol: TCP targetPort: 8080 - endpointSlices: - apiVersion: discovery.k8s.io/v1 kind: EndpointSlice @@ -123,15 +122,14 @@ backendTLSPolicies: name: policy-btls namespace: policies spec: - targetRef: - group: '' - kind: Service - name: http-backend - namespace: backends - sectionName: "8080" - tls: - caCertRefs: + targetRefs: + - group: "" + kind: Service + name: http-backend + sectionName: "8080" + validation: + caCertificateRefs: - name: ca-cmap - group: '' + group: "" kind: ConfigMap hostname: example.com diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml index 13b0f649be7..6fb63ad96a5 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml @@ -6,14 +6,13 @@ backendTLSPolicies: name: policy-btls namespace: policies spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: http-backend - namespace: backends sectionName: "8080" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -93,6 +92,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml index f935b78dc7d..abc821f8eab 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.in.yaml @@ -69,7 +69,6 @@ services: protocol: TCP targetPort: 8080 - endpointSlices: - apiVersion: discovery.k8s.io/v1 kind: EndpointSlice @@ -89,7 +88,6 @@ endpointSlices: conditions: ready: true - configMaps: - apiVersion: v1 kind: ConfigMap @@ -124,14 +122,14 @@ backendTLSPolicies: name: policy-btls namespace: default spec: - targetRef: - group: '' - kind: Service - name: http-backend - sectionName: "8080" - tls: - caCertRefs: + targetRefs: + - group: "" + kind: Service + name: http-backend + sectionName: "8080" + validation: + caCertificateRefs: - name: ca-cmap - group: '' + group: "" kind: ConfigMap hostname: example.com diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml index 515b77057bc..1075be15e75 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml @@ -6,13 +6,13 @@ backendTLSPolicies: name: policy-btls namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: http-backend sectionName: "8080" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -92,6 +92,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml index d11c1a5f289..1a82eb7de6e 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml @@ -69,7 +69,6 @@ services: protocol: TCP targetPort: 8080 - endpointSlices: - apiVersion: discovery.k8s.io/v1 kind: EndpointSlice @@ -105,15 +104,14 @@ backendTLSPolicies: name: policy-btls namespace: policies spec: - targetRef: - group: '' - kind: Service - name: http-backend - namespace: backends - sectionName: "8080" - tls: - caCertRefs: + targetRefs: + - group: "" + kind: Service + name: http-backend + sectionName: "8080" + validation: + caCertificateRefs: - name: no-ca-cmap - group: '' + group: "" kind: ConfigMap hostname: example.com diff --git a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml index 47e7c66c07e..0a991b985c4 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml @@ -6,14 +6,13 @@ backendTLSPolicies: name: policy-btls namespace: policies spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: http-backend - namespace: backends sectionName: "8080" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: no-ca-cmap @@ -93,6 +92,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml index 88fb94bc116..3b20aa31ee5 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.in.yaml @@ -69,7 +69,6 @@ services: protocol: TCP targetPort: 8080 - endpointSlices: - apiVersion: discovery.k8s.io/v1 kind: EndpointSlice @@ -95,11 +94,11 @@ backendTLSPolicies: name: policy-btls namespace: default spec: - targetRef: - group: '' - kind: Service - name: http-backend - sectionName: "8080" - tls: - wellKnownCACerts: System + targetRefs: + - group: "" + kind: Service + name: http-backend + sectionName: "8080" + validation: + wellKnownCACertificates: System hostname: example.com diff --git a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml index a28101f7810..bb6f84a8919 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml @@ -6,14 +6,14 @@ backendTLSPolicies: name: policy-btls namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: http-backend sectionName: "8080" - tls: + validation: hostname: example.com - wellKnownCACerts: System + wellKnownCACertificates: System status: ancestors: - ancestorRef: @@ -89,6 +89,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.in.yaml index f773f200881..e87b3ad1cb9 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.in.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.in.yaml @@ -66,7 +66,6 @@ services: protocol: TCP targetPort: 8080 - endpointSlices: - apiVersion: discovery.k8s.io/v1 kind: EndpointSlice @@ -120,15 +119,14 @@ backendTLSPolicies: name: policy-btls namespace: policies spec: - targetRef: - group: '' - kind: Service - name: http-backend - namespace: backends - sectionName: "8080" - tls: - caCertRefs: + targetRefs: + - group: "" + kind: Service + name: http-backend + sectionName: "8080" + validation: + caCertificateRefs: - name: ca-cmap - group: '' + group: "" kind: ConfigMap hostname: example.com diff --git a/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml index 6922e60d7c8..975eca74e57 100755 --- a/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml @@ -6,14 +6,13 @@ backendTLSPolicies: name: policy-btls namespace: policies spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: http-backend - namespace: backends sectionName: "8080" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -94,6 +93,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.in.yaml index f45af0115be..b9f40aee084 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.in.yaml @@ -63,7 +63,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway loadBalancer: type: Random timeout: @@ -82,7 +81,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default loadBalancer: type: ConsistentHash consistentHash: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml index 18879240a3c..eec0eef7a45 100755 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml @@ -14,7 +14,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -43,7 +42,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway timeout: http: connectionIdleTimeout: 21s @@ -132,6 +130,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -170,6 +169,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.in.yaml index f46fce90546..a189199c521 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.in.yaml @@ -9,7 +9,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -20,7 +19,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -31,7 +29,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -42,7 +39,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: not-same-namespace-gateway - namespace: another-namespace - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -53,7 +49,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -64,7 +59,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -75,7 +69,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -86,7 +79,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: unknown-httproute - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -97,7 +89,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: not-same-namespace-httproute - namespace: another-namespace httpRoutes: - apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml index b223f3990f4..00ffdeb9cf7 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -36,7 +35,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -63,7 +61,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -89,7 +86,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: unknown-httproute - namespace: envoy-gateway status: ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -103,22 +99,8 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: not-same-namespace-httproute - namespace: another-namespace status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: not-same-namespace-gateway - namespace: another-namespace - conditions: - - lastTransitionTime: null - message: Namespace:envoy-gateway TargetRef.Namespace:another-namespace, BackendTrafficPolicy - can only target a resource in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller + ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: @@ -130,7 +112,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -162,7 +143,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -189,7 +169,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway status: ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -203,22 +182,8 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: not-same-namespace-gateway - namespace: another-namespace status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: not-same-namespace-gateway - namespace: another-namespace - conditions: - - lastTransitionTime: null - message: Namespace:envoy-gateway TargetRef.Namespace:another-namespace, BackendTrafficPolicy - can only target a resource in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller + ancestors: null gateways: - apiVersion: gateway.networking.k8s.io/v1beta1 kind: Gateway @@ -411,6 +376,7 @@ grpcRoutes: - name: magic type: Exact value: foo + sessionPersistence: null status: parents: - conditions: @@ -446,6 +412,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -480,6 +447,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.in.yaml index 23d2e8d2afc..26eb85dae2b 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.in.yaml @@ -92,7 +92,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway faultInjection: abort: httpStatus: 14 @@ -107,7 +106,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default faultInjection: abort: httpStatus: 500 @@ -125,7 +123,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: default faultInjection: abort: grpcStatus: 14 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml index b322ce55192..4ff9353ca0d 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml @@ -17,7 +17,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -51,7 +50,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: default status: ancestors: - ancestorRef: @@ -82,7 +80,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -200,6 +197,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -239,6 +237,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -277,6 +276,7 @@ httpRoutes: matches: - path: value: /route2 + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.in.yaml index 5cb15cfc3c6..306da4d9e1d 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.in.yaml @@ -44,6 +44,5 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway useClientProtocol: true diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml index e2f632b1a52..852830593ac 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway useClientProtocol: true status: ancestors: @@ -88,6 +87,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.in.yaml index ac4333ec752..783218141ad 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.in.yaml @@ -92,7 +92,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway circuitBreaker: maxConnections: -1 - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -105,7 +104,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default circuitBreaker: maxRequestsPerConnection: -1 - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -118,6 +116,5 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default circuitBreaker: maxParallelRetries: -1 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml index 45d95e8aaf9..a6bafa1554d 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml @@ -12,7 +12,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -41,7 +40,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default status: ancestors: - ancestorRef: @@ -70,7 +68,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -182,6 +179,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -221,6 +219,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -259,6 +258,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.in.yaml index dc6513eeec1..65e5c50de57 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.in.yaml @@ -73,7 +73,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway circuitBreaker: maxConnections: 2048 maxPendingRequests: 1 @@ -90,7 +89,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default circuitBreaker: maxConnections: 42 maxPendingRequests: 42 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml index 1c0c622624e..5eb2af5c093 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml @@ -16,7 +16,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -49,7 +48,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -161,6 +159,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -200,6 +199,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml index bd11501ac10..5cb832646b3 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml @@ -111,7 +111,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway healthCheck: active: timeout: "500ms" @@ -146,7 +145,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default healthCheck: active: timeout: "1s" @@ -181,7 +179,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default healthCheck: active: timeout: "1s" @@ -214,7 +211,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-3 - namespace: default healthCheck: active: timeout: 1s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml index 2205a1cc1b6..13bd67d0bbb 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml @@ -34,7 +34,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -83,7 +82,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default status: ancestors: - ancestorRef: @@ -132,7 +130,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-3 - namespace: default status: ancestors: - ancestorRef: @@ -183,7 +180,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -295,6 +291,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -334,6 +331,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -372,6 +370,7 @@ httpRoutes: matches: - path: value: /v2 + sessionPersistence: null status: parents: - conditions: @@ -410,6 +409,7 @@ httpRoutes: matches: - path: value: /v3 + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml index 5f8b1a5f236..8dc0366ed44 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml @@ -92,7 +92,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway loadBalancer: type: Random - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -105,7 +104,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default loadBalancer: type: ConsistentHash consistentHash: @@ -120,7 +118,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway loadBalancer: type: RoundRobin slowStart: @@ -135,7 +132,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default loadBalancer: type: LeastRequest slowStart: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml index f3836170e44..c7113bd1252 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml @@ -14,7 +14,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -45,7 +44,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default status: ancestors: - ancestorRef: @@ -74,7 +72,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -104,7 +101,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -222,6 +218,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -261,6 +258,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -299,6 +297,7 @@ httpRoutes: matches: - path: value: /test2 + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.in.yaml index c1136403c36..27a45c9a47d 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.in.yaml @@ -44,7 +44,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway rateLimit: type: Local local: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml index 4f4cb6d5165..76098c166c2 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml @@ -34,7 +34,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -111,6 +110,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.in.yaml index c1d34e70480..a72ea353662 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.in.yaml @@ -44,7 +44,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway rateLimit: type: Local local: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml index 0b81c2dd0de..047e9b3bfd1 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml @@ -37,7 +37,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -115,6 +114,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.in.yaml index e6a595b157a..ec707534842 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.in.yaml @@ -44,7 +44,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway rateLimit: type: Local local: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml index 68ed3affde6..2a1053b4cbf 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml @@ -34,7 +34,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -111,6 +110,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.in.yaml index 9a2f3b94246..7a91f3b65d5 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.in.yaml @@ -44,7 +44,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway rateLimit: type: Local local: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml index 32d1661ea55..e1a5e808d23 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml @@ -40,7 +40,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -118,6 +117,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.in.yaml index 7f9d36ab484..fd0b6e797fd 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.in.yaml @@ -44,7 +44,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway rateLimit: type: Local local: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml index 11012aa6940..b9a04a2f22c 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml @@ -37,7 +37,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -114,6 +113,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.in.yaml index 93d2e980837..1078b57eed6 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.in.yaml @@ -73,7 +73,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway proxyProtocol: version: V1 - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -86,6 +85,5 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default proxyProtocol: version: V2 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml index 2344cae4a31..66668308089 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml @@ -12,7 +12,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -41,7 +40,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -153,6 +151,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -192,6 +191,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.in.yaml index 72a5e4d8b7c..ac2eb17f7b1 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.in.yaml @@ -39,7 +39,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway rateLimit: type: Global global: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml index 360544da250..36b1e01e52d 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml @@ -24,7 +24,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -97,6 +96,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml index cc6fa9714ed..e4f1fc10c64 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.in.yaml @@ -73,7 +73,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway rateLimit: type: Global global: @@ -97,7 +96,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default rateLimit: type: Global global: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml index 750b4243777..b0be3b80718 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml @@ -21,7 +21,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -61,7 +60,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -173,6 +171,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -212,6 +211,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml index 6ed617254cc..be4649ab425 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml @@ -73,7 +73,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway retry: retryOn: triggers: @@ -93,7 +92,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default retry: numRetries: 5 retryOn: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml index 206b93b9f6a..fc515a1f5c6 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml @@ -24,7 +24,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -60,7 +59,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -172,6 +170,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -211,6 +210,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.in.yaml index 18612699537..ed26cc533c1 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.in.yaml @@ -63,7 +63,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default circuitBreaker: maxConnections: 2048 maxPendingRequests: 1 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml index 130958f4d46..8a8cdd28dfd 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml @@ -14,7 +14,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -92,6 +91,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -130,6 +130,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.in.yaml index 1945d3559cd..1d4e95a682f 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.in.yaml @@ -63,7 +63,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: UDPRoute name: udp-app-1 - namespace: default circuitBreaker: maxConnections: 2048 maxPendingRequests: 1 @@ -120,7 +119,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: TCPRoute name: tcp-app-1 - namespace: default circuitBreaker: maxConnections: 2048 maxPendingRequests: 1 diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml index 75c5d4cd01d..811442554f4 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml @@ -46,7 +46,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: UDPRoute name: udp-app-1 - namespace: default tcpKeepalive: idleTime: 20m interval: 60s @@ -119,7 +118,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: TCPRoute name: tcp-app-1 - namespace: default tcpKeepalive: idleTime: 20m interval: 60s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.in.yaml index df14e30971b..bc094e45b4f 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.in.yaml @@ -73,7 +73,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tcpKeepalive: probes: 3 idleTime: 20m @@ -88,7 +87,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default tcpKeepalive: probes: 6 idleTime: 10s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml index ea98b67e005..39754199ae2 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default tcpKeepalive: idleTime: 10s interval: 30m @@ -41,7 +40,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tcpKeepalive: idleTime: 20m interval: 60s @@ -157,6 +155,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -196,6 +195,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.in.yaml index 8025e82f1d8..de9c243bcb1 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.in.yaml @@ -39,7 +39,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway timeout: http: connectionIdleTimeout: 21s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml index 3adff744df7..210a3c66b6f 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway timeout: http: connectionIdleTimeout: 21s @@ -88,6 +87,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml index c73a4504d4c..ef8843f70c4 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.in.yaml @@ -73,7 +73,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway timeout: tcp: connectTimeout: 15s @@ -90,7 +89,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default timeout: tcp: connectTimeout: 20s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml index 58ea2d64060..12b72a9e4d3 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default timeout: http: connectionIdleTimeout: 21s @@ -43,7 +42,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway timeout: http: connectionIdleTimeout: 16s @@ -161,6 +159,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -200,6 +199,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.in.yaml index ddd40c3344c..a09e10e9449 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.in.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -24,7 +23,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml index f82580ce39f..8a366de05d8 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -41,7 +40,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.in.yaml index f3e7f0306e9..dfe043b7d7a 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.in.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -24,7 +23,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml index 08c7f6dbbd9..9f983a0d2c0 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -41,7 +40,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.in.yaml index 58258e81ef4..9eae041771c 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.in.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -24,7 +23,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml index 6969904a40f..9c277092c6a 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -41,7 +40,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml index 11204555a03..12f89598c83 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy @@ -28,7 +27,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-2 - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy @@ -44,7 +42,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-3 gateways: - apiVersion: gateway.networking.k8s.io/v1 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml index 61ff96bfeca..24c543ec27b 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml @@ -13,7 +13,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -45,7 +44,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-2 status: ancestors: @@ -77,7 +75,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-3 status: ancestors: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.in.yaml index 97f91027aac..d8885d55b8b 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.in.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -26,7 +25,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml index 2dfb99f691e..5eb39d934e6 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml @@ -14,7 +14,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -42,7 +41,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tcpKeepalive: {} status: ancestors: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.in.yaml index 825c1f83807..e0d4a99c92e 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.in.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -26,7 +25,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml index 651f18ecd1c..086f084f712 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml @@ -14,7 +14,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -43,7 +42,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml index 136450f2abd..c21285612d9 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml index 4a71a59d6d0..8fa939ac327 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml @@ -13,7 +13,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml index 8d54877593d..5ea01c15336 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -27,7 +26,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-2 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -42,7 +40,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-3 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml index df2e0592b6b..d0e2660dc12 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -43,7 +42,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-2 status: ancestors: @@ -74,7 +72,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-3 status: ancestors: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml index 150b652d513..fd435bbb51e 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml @@ -14,7 +14,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -30,7 +29,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-2 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml index 96d1fc82fec..e94e1ffed1e 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml @@ -14,7 +14,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: @@ -46,7 +45,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-2 status: ancestors: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.in.yaml index 7454914952b..f146d068945 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.in.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml index a58801dd58b..40a3cb49ebb 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml @@ -11,7 +11,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -91,6 +90,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.in.yaml index dfa5f302103..6afd9df203c 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway timeout: http: requestReceivedTimeout: "10sec" diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml index 0854e41ef4d..18b814b82d8 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway timeout: http: requestReceivedTimeout: 10sec diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.in.yaml index bbf4446fa36..534af7b7596 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway sectionName: http-1 timeout: http: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml index efd85a62185..f69a88e87cd 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway sectionName: http-1 timeout: http: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.in.yaml index 9d7c42676b7..b3785072914 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tls: clientValidation: optional: false @@ -26,7 +25,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway tls: clientValidation: optional: true diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml index f288cfcff8f..de3d0c727f3 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tls: clientValidation: caCertificateRefs: @@ -43,7 +42,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway tls: clientValidation: caCertificateRefs: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.in.yaml index 05ff5b87294..eceadcb89ed 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tls: clientValidation: caCertificateRefs: @@ -25,7 +24,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway tls: clientValidation: caCertificateRefs: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml index 98db6708cf7..7a39aabfc94 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tls: clientValidation: caCertificateRefs: @@ -43,7 +42,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway tls: clientValidation: caCertificateRefs: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.in.yaml index 9ce6115418c..cb8c9d2c27f 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.in.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml index e16a5cf2344..cdeaa2fb329 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml @@ -13,7 +13,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.in.yaml index 5a5711f32ed..deae7544d8a 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.in.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml index af97e2397ca..e4d63d3f4c7 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml @@ -13,7 +13,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml index 5198e82d098..60ac2d95a7a 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml @@ -11,7 +11,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml index 7b57484d3df..118c84b5ec6 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml @@ -11,7 +11,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 status: ancestors: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.in.yaml index 0f44d839bbd..eab52dcef7c 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -20,7 +19,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -31,7 +29,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -42,7 +39,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway sectionName: http - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy @@ -54,7 +50,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway sectionName: https - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy @@ -66,7 +61,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway sectionName: https - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy @@ -78,7 +72,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -89,7 +82,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: not-same-namespace-gateway - namespace: not-same-namespace - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -100,7 +92,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-3 - namespace: envoy-gateway sectionName: foo-bar gateways: - apiVersion: gateway.networking.k8s.io/v1 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml index 84ec9e07658..dbb9bf781c7 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway sectionName: http status: ancestors: @@ -38,7 +37,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway sectionName: https status: ancestors: @@ -66,7 +64,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway sectionName: https status: ancestors: @@ -95,7 +92,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-3 - namespace: envoy-gateway sectionName: foo-bar status: ancestors: @@ -123,7 +119,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -149,7 +144,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -176,7 +170,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -208,7 +201,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway status: ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -222,22 +214,8 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: not-same-namespace-gateway - namespace: not-same-namespace status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: not-same-namespace-gateway - namespace: not-same-namespace - conditions: - - lastTransitionTime: null - message: Namespace:envoy-gateway TargetRef.Namespace:not-same-namespace, ClientTrafficPolicy - can only target a Gateway in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller + ancestors: null gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.in.yaml index d263b45df77..0305999e7ba 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.in.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: @@ -26,7 +25,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-1 sectionName: http-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml index c7557020382..a33510d2586 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway sectionName: http-1 tcpKeepalive: idleTime: 20m @@ -42,7 +41,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tcpKeepalive: {} status: ancestors: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.in.yaml index b9cad3568bc..07b4930e132 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway timeout: http: requestReceivedTimeout: "5sec" diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml index eaf13c0af18..d162dce4b47 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway timeout: http: requestReceivedTimeout: 5sec diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.in.yaml index 0c962e72fe8..11ea0bba150 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway sectionName: http-1 timeout: http: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml index 9c83084ce76..e1d222f64cc 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway - namespace: envoy-gateway sectionName: http-1 timeout: http: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml index 7d23dc8b307..59dc2819c7c 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.in.yaml @@ -9,7 +9,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tls: minVersion: "1.0" maxVersion: "1.3" diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml index 924a9a14920..6c69f78a706 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway tls: alpnProtocols: - h2 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.in.yaml index c9b087d3ff4..1fd6e9ede30 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.in.yaml @@ -11,7 +11,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml index b2c1145c06c..281809324c7 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml @@ -12,7 +12,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/conflicting-policies.in.yaml b/internal/gatewayapi/testdata/conflicting-policies.in.yaml index 79e07e48919..0019de717be 100644 --- a/internal/gatewayapi/testdata/conflicting-policies.in.yaml +++ b/internal/gatewayapi/testdata/conflicting-policies.in.yaml @@ -113,7 +113,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: mfqjpuycbgjrtdww - namespace: default timeout: http: requestReceivedTimeout: "5s" diff --git a/internal/gatewayapi/testdata/conflicting-policies.out.yaml b/internal/gatewayapi/testdata/conflicting-policies.out.yaml index 3f2a1d53418..b7cd684dc05 100644 --- a/internal/gatewayapi/testdata/conflicting-policies.out.yaml +++ b/internal/gatewayapi/testdata/conflicting-policies.out.yaml @@ -10,7 +10,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: mfqjpuycbgjrtdww - namespace: default timeout: http: requestReceivedTimeout: 5s @@ -133,6 +132,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: @@ -176,6 +176,7 @@ httpRoutes: - path: type: PathPrefix value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/custom-filter-order.in.yaml b/internal/gatewayapi/testdata/custom-filter-order.in.yaml index d0a4bedc2e1..7bbef11264b 100644 --- a/internal/gatewayapi/testdata/custom-filter-order.in.yaml +++ b/internal/gatewayapi/testdata/custom-filter-order.in.yaml @@ -64,7 +64,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway cors: allowOrigins: - "https://*.test.com:8080" @@ -106,7 +105,6 @@ envoyextensionpolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway wasm: - name: wasm-filter-1 code: diff --git a/internal/gatewayapi/testdata/custom-filter-order.out.yaml b/internal/gatewayapi/testdata/custom-filter-order.out.yaml index eea919c09fe..3ce5e39b67f 100755 --- a/internal/gatewayapi/testdata/custom-filter-order.out.yaml +++ b/internal/gatewayapi/testdata/custom-filter-order.out.yaml @@ -10,7 +10,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway wasm: - code: http: @@ -108,6 +107,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -201,7 +201,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml index 6f4ed53ab78..1406f33fdfe 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml @@ -24,7 +24,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway extProc: - backendRefs: - name: grpc-backend-4 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml index a545e58625b..8df179d85bf 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml @@ -14,22 +14,8 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Namespace:default TargetRef.Namespace:envoy-gateway, EnvoyExtensionPolicy - can only target a resource in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller + ancestors: null gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml index 1d4c61cc7f7..3ad36f07152 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml @@ -84,7 +84,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway extProc: - backendRefs: - name: grpc-backend @@ -99,7 +98,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default extProc: - backendRefs: - name: grpc-backend-2 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml index cc9921a6bd7..d5784cbd780 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml @@ -14,7 +14,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -45,7 +44,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -128,6 +126,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -166,6 +165,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.in.yaml index 3e2c4c63e1a..e0cf2363bc2 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.in.yaml @@ -9,7 +9,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -20,7 +19,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -31,7 +29,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -42,7 +39,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: not-same-namespace-gateway - namespace: another-namespace - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -53,7 +49,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -64,7 +59,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -75,7 +69,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -86,7 +79,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: unknown-httproute - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -97,7 +89,6 @@ EnvoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: not-same-namespace-httproute - namespace: another-namespace httpRoutes: - apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml index d1978c3ef4c..406518cdedf 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml @@ -10,7 +10,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -36,7 +35,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -63,7 +61,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -89,7 +86,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: unknown-httproute - namespace: envoy-gateway status: ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -103,22 +99,8 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: not-same-namespace-httproute - namespace: another-namespace status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: not-same-namespace-gateway - namespace: another-namespace - conditions: - - lastTransitionTime: null - message: Namespace:envoy-gateway TargetRef.Namespace:another-namespace, EnvoyExtensionPolicy - can only target a resource in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller + ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -130,7 +112,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -162,7 +143,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -189,7 +169,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway status: ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -203,22 +182,8 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: not-same-namespace-gateway - namespace: another-namespace status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: not-same-namespace-gateway - namespace: another-namespace - conditions: - - lastTransitionTime: null - message: Namespace:envoy-gateway TargetRef.Namespace:another-namespace, EnvoyExtensionPolicy - can only target a resource in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller + ancestors: null gateways: - apiVersion: gateway.networking.k8s.io/v1beta1 kind: Gateway @@ -411,6 +376,7 @@ grpcRoutes: - name: magic type: Exact value: foo + sessionPersistence: null status: parents: - conditions: @@ -446,6 +412,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -480,6 +447,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml index 982d7da84e6..7eb4b360544 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml @@ -53,7 +53,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extProc: - backendRefs: - name: grpc-backend diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml index 740230fbf21..84c324dee2a 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml @@ -14,7 +14,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: @@ -91,6 +90,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml index abb0bf36596..abd4f653886 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml @@ -53,7 +53,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extProc: - backendRefs: - name: grpc-backend diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml index 50c1a7371d4..8f5e97c7f86 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml @@ -13,7 +13,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: @@ -91,6 +90,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml index 71f453ec95b..d0408cda7c9 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml @@ -53,7 +53,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extProc: - backendRefs: - name: grpc-backend diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml index f62b31daa94..b69c1fb0fbd 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml @@ -15,7 +15,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: @@ -93,6 +92,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml index b58eeee0978..dc475a1d73f 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml @@ -44,7 +44,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extProc: - backendRefs: - name: grpc-backend diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml index 3ea2c40f4d9..0f76696a927 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml @@ -15,7 +15,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: @@ -92,6 +91,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml index fb3d3cab153..83d6dbdb9b8 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml @@ -159,14 +159,13 @@ backendTLSPolicies: name: policy-btls-grpc namespace: default spec: - targetRef: - group: '' + targetRefs: + - group: '' kind: Service name: grpc-backend - namespace: envoy-gateway sectionName: "8000" - tls: - caCertRefs: + validation: + caCertificateRefs: - name: ca-cmap group: '' kind: ConfigMap @@ -177,13 +176,13 @@ backendTLSPolicies: name: policy-btls-grpc-2 namespace: default spec: - targetRef: - group: '' + targetRefs: + - group: '' kind: Service name: grpc-backend-2 sectionName: "9000" - tls: - caCertRefs: + validation: + caCertificateRefs: - name: ca-cmap group: '' kind: ConfigMap @@ -199,7 +198,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extProc: - backendRefs: - Name: grpc-backend @@ -222,7 +220,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default extProc: - backendRefs: - Name: grpc-backend-2 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml index e33b83f0ec4..1298a770452 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml @@ -6,14 +6,13 @@ backendTLSPolicies: name: policy-btls-grpc namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: grpc-backend - namespace: envoy-gateway sectionName: "8000" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -39,13 +38,13 @@ backendTLSPolicies: name: policy-btls-grpc-2 namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: grpc-backend-2 sectionName: "9000" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -83,7 +82,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -122,7 +120,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: @@ -205,6 +202,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -243,6 +241,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml index a278b45a903..4551a9dfe17 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml @@ -159,14 +159,13 @@ backendTLSPolicies: name: policy-btls-grpc namespace: default spec: - targetRef: - group: '' + targetRefs: + - group: '' kind: Service name: grpc-backend - namespace: envoy-gateway sectionName: "8000" - tls: - caCertRefs: + validation: + caCertificateRefs: - name: ca-cmap group: '' kind: ConfigMap @@ -182,7 +181,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default extProc: - backendRefs: - Name: grpc-backend diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml index a26a321d6e6..1c863229baf 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml @@ -6,14 +6,13 @@ backendTLSPolicies: name: policy-btls-grpc namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: grpc-backend - namespace: envoy-gateway sectionName: "8000" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -51,7 +50,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -129,6 +127,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -167,6 +166,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml index 640e1bc189e..4d3e39cf48a 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml @@ -63,7 +63,6 @@ envoyextensionpolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway wasm: - name: wasm-filter-1 code: @@ -95,7 +94,6 @@ envoyextensionpolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default wasm: - name: wasm-filter-3 code: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml index 24b531e70f5..c563f6ee6eb 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml @@ -10,7 +10,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default wasm: - code: http: @@ -51,7 +50,6 @@ envoyExtensionPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway wasm: - code: http: @@ -155,6 +153,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -193,6 +192,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.in.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.in.yaml index ee6050b5118..cab3bc1ee4c 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.in.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.in.yaml @@ -10,7 +10,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway jsonPatches: - type: "type.googleapis.com/envoy.config.listener.v3.Listener" name: "envoy-gateway-gateway-1-http" diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml index b91f140014a..6a084857341 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml @@ -60,24 +60,6 @@ xdsIR: accessLog: text: - path: /dev/stdout - envoyPatchPolicies: - - name: edit-conn-buffer-bytes - namespace: envoy-gateway-2 - status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Namespace:envoy-gateway-2 TargetRef.Namespace:envoy-gateway, - EnvoyPatchPolicy can only target a Gateway in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller http: - address: 0.0.0.0 hostnames: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.in.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.in.yaml index 4942b803092..d75a6e91e49 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.in.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.in.yaml @@ -18,7 +18,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: GatewayClass name: envoy-gateway-class - namespace: envoy-gateway jsonPatches: - type: "type.googleapis.com/envoy.config.listener.v3.Listener" name: "envoy-gateway-gateway-1-http" diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.in.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.in.yaml index 573018430f2..8d00c96d3a8 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.in.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.in.yaml @@ -18,7 +18,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway jsonPatches: - type: "type.googleapis.com/envoy.config.listener.v3.Listener" name: "envoy-gateway-gateway-1-http" diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.in.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.in.yaml index 57a5d4abd14..7d39be69f68 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.in.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.in.yaml @@ -10,7 +10,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: MyGateway name: gateway-1 - namespace: envoy-gateway jsonPatches: - type: "type.googleapis.com/envoy.config.listener.v3.Listener" name: "envoy-gateway-gateway-1-http" diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-no-status-for-unknown-gateway.in.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-no-status-for-unknown-gateway.in.yaml index f23931ad622..08e4a4d6112 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-no-status-for-unknown-gateway.in.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-no-status-for-unknown-gateway.in.yaml @@ -10,4 +10,3 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.in.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.in.yaml index d3604de1363..3daa484dc73 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.in.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.in.yaml @@ -18,7 +18,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: GatewayClass name: envoy-gateway-class - namespace: envoy-gateway jsonPatches: - type: "type.googleapis.com/envoy.config.listener.v3.Listener" name: "envoy-gateway-gateway-1-http" @@ -37,7 +36,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: GatewayClass name: envoy-gateway-class - namespace: envoy-gateway # Higher priority priority: -1 jsonPatches: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-valid.in.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-valid.in.yaml index 4cbe335873b..1d4a47aefc0 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-valid.in.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-valid.in.yaml @@ -10,7 +10,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway jsonPatches: - type: "type.googleapis.com/envoy.config.listener.v3.Listener" name: "envoy-gateway-gateway-1-http" @@ -29,7 +28,6 @@ envoyPatchPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway # Higher priority priority: -1 jsonPatches: diff --git a/internal/gatewayapi/testdata/envoyproxy-tls-settings.in.yaml b/internal/gatewayapi/testdata/envoyproxy-tls-settings.in.yaml index f46ecc052e2..0e61ff11e90 100644 --- a/internal/gatewayapi/testdata/envoyproxy-tls-settings.in.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-tls-settings.in.yaml @@ -90,12 +90,12 @@ backendTLSPolicies: name: policy-tls namespace: default spec: - targetRef: - group: '' - kind: Service - name: https-backend - tls: - wellKnownCACerts: System + targetRefs: + - group: "" + kind: Service + name: https-backend + validation: + wellKnownCACertificates: System hostname: example.com envoyproxy: apiVersion: gateway.envoyproxy.io/v1alpha1 diff --git a/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml index 36ecc443361..0448f8cdcec 100644 --- a/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml @@ -6,13 +6,13 @@ backendTLSPolicies: name: policy-tls namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: https-backend - tls: + validation: hostname: example.com - wellKnownCACerts: System + wellKnownCACertificates: System status: ancestors: - ancestorRef: @@ -86,6 +86,7 @@ httpRoutes: - name: https-backend namespace: default port: 443 + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml index 0607032af8f..7d6ad143aa9 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml index 0a691324cda..d2285055196 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml index 2f8e19d300e..0cf518ac3f2 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml index ed697a91ad0..3f39a6b2267 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml index 7ec08cdd2c8..f720416c86b 100644 --- a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml @@ -57,6 +57,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml index e04a9abcc61..125aec09f25 100644 --- a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml @@ -57,6 +57,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml b/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml index 2cca7a21513..d20af809b03 100644 --- a/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml +++ b/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml @@ -70,6 +70,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-namespaces-selector.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-namespaces-selector.out.yaml index 6525ecfc32e..f1c9f724819 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-namespaces-selector.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-namespaces-selector.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-group.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-group.out.yaml index 182b2b17313..4bfec1c940a 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-group.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-group.out.yaml @@ -51,6 +51,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind-and-supported.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind-and-supported.out.yaml index a21d579d0e8..5592c3019e8 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind-and-supported.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind-and-supported.out.yaml @@ -53,6 +53,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind.out.yaml index 460da331ff4..186f7acbe9b 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-allowed-routes-kind.out.yaml @@ -51,6 +51,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml index d503d2875cb..8b3e18f47d8 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml @@ -66,6 +66,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-invalid-mode.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-invalid-mode.out.yaml index f5b1bd561dd..30c07b262fa 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-invalid-mode.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-invalid-mode.out.yaml @@ -59,6 +59,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-certificate-refs.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-certificate-refs.out.yaml index 84dd3118e90..ca3eb454062 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-certificate-refs.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-certificate-refs.out.yaml @@ -54,6 +54,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.out.yaml index d67fa87f9b6..778bf57b589 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.out.yaml @@ -61,6 +61,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-does-not-exist.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-does-not-exist.out.yaml index cac358ab651..5d981db7089 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-does-not-exist.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-does-not-exist.out.yaml @@ -58,6 +58,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-in-other-namespace.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-in-other-namespace.out.yaml index 3c27f730a57..6b0202d4695 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-in-other-namespace.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-in-other-namespace.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-is-not-valid.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-is-not-valid.out.yaml index 72c30d42149..004cab611f0 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-is-not-valid.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-secret-is-not-valid.out.yaml @@ -58,6 +58,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-missing-allowed-namespaces-selector.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-missing-allowed-namespaces-selector.out.yaml index 2e8f83dbaf9..1bfafa84126 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-missing-allowed-namespaces-selector.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-missing-allowed-namespaces-selector.out.yaml @@ -53,6 +53,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml index a501e2a7ccd..ea56f5e0503 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml @@ -64,6 +64,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml index 8b6f602c543..12fadd79667 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml @@ -94,6 +94,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml index 123a0171cb6..453dbdd3060 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-unsupported-protocol.out.yaml @@ -53,6 +53,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml index e197d01d60b..994a353b5c5 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml @@ -66,6 +66,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml index e9534d5bd7b..93fbb690e7f 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml @@ -66,6 +66,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml index cdc613c4a9a..a7ee12a5649 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml @@ -63,6 +63,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml index aefd53705de..6b9f68c11c1 100644 --- a/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml @@ -57,6 +57,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml index acb517c5b82..8e697e48eff 100644 --- a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml @@ -63,6 +63,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-http-and-tlsroute-same-hostname-and-port.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-http-and-tlsroute-same-hostname-and-port.out.yaml index dfe1d49dc37..ebcec620f83 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-http-and-tlsroute-same-hostname-and-port.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-http-and-tlsroute-same-hostname-and-port.out.yaml @@ -88,6 +88,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml index e43457681d5..9645705ec48 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml @@ -88,6 +88,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -122,6 +123,7 @@ httpRoutes: matches: - path: value: /test + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-hostname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-hostname.out.yaml index bf051ef6c79..5c8cc89b5aa 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-hostname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-hostname.out.yaml @@ -88,6 +88,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-incompatible-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-incompatible-protocol.out.yaml index acbd772d0f6..fdd5efd90df 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-incompatible-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-and-incompatible-protocol.out.yaml @@ -88,6 +88,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml index 3dc939e6f55..8ab5d79f575 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml @@ -85,6 +85,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml index 7ac4c4e14b3..b794998a690 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml @@ -85,6 +85,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml index 23d899faad6..220dc1ca432 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml @@ -56,6 +56,7 @@ grpcRoutes: - method: service: com.ExampleExact type: Exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml index 2c5ecc13bf0..a663c9d9b91 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml @@ -60,6 +60,7 @@ grpcRoutes: - name: magic type: Exact value: foo + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml index eb7ce849a96..b432a28b038 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml @@ -64,6 +64,7 @@ grpcRoutes: method: Foobar service: foo.* type: RegularExpression + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml index 82a2584d195..67e1e718afa 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml @@ -62,6 +62,7 @@ grpcRoutes: - method: method: FooBar[0-9]+ type: RegularExpression + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml index ad5e96b684b..2bdc75396bc 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml @@ -61,6 +61,7 @@ grpcRoutes: - name: my-header value: foo type: RequestHeaderModifier + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml index aa2ef46b259..f1370181e05 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml @@ -62,6 +62,7 @@ grpcRoutes: - method: service: com.[A-Z]+ type: RegularExpression + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.in.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.in.yaml index c95fd909515..48d99d57558 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.in.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.in.yaml @@ -46,7 +46,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default timeout: tcp: connectTimeout: 20kib diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml index 88becd8a82a..4e0692bce7a 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default timeout: http: maxConnectionDuration: 22s @@ -93,6 +92,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null timeouts: request: 1s status: diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.in.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.in.yaml index 90157f5e80f..546590b1a61 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.in.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.in.yaml @@ -75,7 +75,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway timeout: tcp: connectTimeout: 15s @@ -92,7 +91,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default timeout: tcp: connectTimeout: 20s diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml index 6ece1834d62..97060b16a2e 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default timeout: http: maxConnectionDuration: 22s @@ -42,7 +41,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway timeout: http: connectionIdleTimeout: 16s @@ -160,6 +158,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -199,6 +198,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null timeouts: request: 1s status: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml index 197503b51c5..0e8ebf56128 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml @@ -268,6 +268,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml index 1c238cdf039..4ad3cd050ab 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml @@ -268,6 +268,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml index e16ff66b0ea..306a51773ae 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml @@ -92,6 +92,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml index 1d39beaf5e7..4b07cb89f8c 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml @@ -88,6 +88,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml index 352a6da41a5..79894ea62c0 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml @@ -57,6 +57,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml index 6ddbd88af2a..a32ad8b8b59 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml @@ -59,6 +59,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml index 3e2ef78a015..e2dbac7a7c8 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml @@ -89,6 +89,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml index e2a3401c217..8d99f3721b2 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml @@ -64,6 +64,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml index a1e080d6482..7a36c8edcd9 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml @@ -64,6 +64,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml index 134162f6b5c..315b6035cc1 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml index 8a3c4a0587a..8a4a5708a91 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml index c1bb62b6797..830c09ae44a 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml index 0d0d1755ef4..da28b843d1a 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml @@ -58,6 +58,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml index f56835ccb2e..ebca1dc84cb 100644 --- a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml @@ -58,6 +58,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null timeouts: backendRequest: 1s status: diff --git a/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml b/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml index e7474693b36..74d6a60e23b 100644 --- a/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml @@ -59,6 +59,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml index 3d3f73076ee..c8b7ed44385 100644 --- a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml @@ -58,6 +58,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null timeouts: request: 5s status: diff --git a/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml index 6a99fbe90e3..70ff286d301 100644 --- a/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml @@ -54,6 +54,7 @@ httpRoutes: - matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml index 8a8b799c552..0d8dbfcafbe 100644 --- a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml +++ b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml @@ -61,6 +61,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml index b962d108c8b..1e7b1c19d13 100644 --- a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml +++ b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml index a170bf0e21f..b79309da483 100644 --- a/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml @@ -59,6 +59,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml index 2501f9d8c20..cbd5462a3bc 100644 --- a/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml @@ -61,6 +61,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml b/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml index d345186e64c..f804cf23445 100644 --- a/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml @@ -55,6 +55,7 @@ httpRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml index d1b3c41b858..51e4384374f 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml @@ -76,6 +76,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml index ec57fd25d09..08cf9499f1c 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml @@ -86,6 +86,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml index c290d1a96c5..b4b013cc2df 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml @@ -72,6 +72,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml index d6d97d8e7d4..e6601bfb3ad 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml index c74c9294dab..30b37bf854a 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml @@ -70,6 +70,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml index 5065aa523df..929edefe2c5 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml @@ -72,6 +72,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml index 93f152ffea8..680d319b225 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml @@ -72,6 +72,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml index d06a9820f7a..65688a9a41f 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml @@ -64,6 +64,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml index 3329848de05..ea43a60f2bd 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml index f0e08c90108..bded3d891b1 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml index d976cb93f38..a18355c2e64 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml @@ -58,6 +58,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml index fe064903ada..97c7aad4334 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml @@ -60,6 +60,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml index bee00784ac7..ceed40de337 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml @@ -59,6 +59,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml index 417f53c7dfb..bf978848d56 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml @@ -57,6 +57,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml index a6c22425e84..51372057d42 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml @@ -60,6 +60,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml index 2bf53591ed3..a0dcd08d937 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml @@ -58,6 +58,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml index 26c803f9d91..40e65a2f8e2 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml @@ -64,6 +64,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml index cc0cc881a87..5aa2f3b4bf9 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml @@ -59,6 +59,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml index a8e06b4fa54..926080b94f6 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml @@ -98,6 +98,7 @@ httpRoutes: - path: type: RegularExpression value: '*.foo.bar.com' + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml index 8ed5fe11eff..09abe4aa790 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml @@ -74,6 +74,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml index 425bebf34b3..a83dd355382 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml @@ -86,6 +86,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml index 60b599dcdd7..c32c9b1cb2c 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml index 724d00e1ecc..f3099777fec 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml index d98e16bd4d3..abcaef49993 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml index ebe71a52556..096cc52e907 100644 --- a/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml index c1f9030ef3c..c82dcef2071 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml @@ -66,6 +66,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml index 0cc17703e29..6d21d6cac99 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml @@ -64,6 +64,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml index a7a57501a4e..d6fc90e7159 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml index c408f51ffb5..19e1652557e 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml @@ -63,6 +63,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml index 99c291b14ae..ab8c4747024 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml @@ -63,6 +63,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml index bb9d2644130..24618e0df2c 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml index b3625b41e1a..cab37a40e49 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml @@ -82,6 +82,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml index 05f34deb133..9c800f170d0 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml @@ -76,6 +76,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml index 6c95d3dbc5f..41895ef3ab0 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml @@ -86,6 +86,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml index 3183508ec02..42dcb03960a 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml @@ -72,6 +72,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml index e20ab6f52fc..77156ae3d43 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml index 4de5380a305..75149d48e14 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml @@ -70,6 +70,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml index c0a449536bd..92156218b1f 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml @@ -72,6 +72,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml index 14f957bb880..135d21fef14 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml @@ -72,6 +72,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml index 41667e93380..e2a6e66ccfd 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml @@ -64,6 +64,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml index 2ee89577ab9..36df78d7342 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml index 4e06010a1a2..6ef2d9914fe 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml index 9f7d91d4ec7..80a119f1897 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml @@ -58,6 +58,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml index 55059d9d6ee..d92fb4b035e 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml @@ -56,6 +56,7 @@ httpRoutes: port: 8080 matches: - method: POST + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml index 7cae3475b67..83b7a6ef1a7 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml @@ -66,6 +66,7 @@ httpRoutes: - name: QueryParam-1 type: Exact value: exact + sessionPersistence: null - backendRefs: - name: service-2 port: 8080 @@ -73,6 +74,7 @@ httpRoutes: - path: type: PathPrefix value: /prefix + sessionPersistence: null - backendRefs: - name: service-3 port: 8080 @@ -88,6 +90,7 @@ httpRoutes: - name: QueryParam-1 type: RegularExpression value: '*regex*' + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml index f48725ca3ce..2e539164861 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml @@ -62,6 +62,7 @@ httpRoutes: value: Val-2 path: value: /pathprefix + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml b/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml index da444284df0..f514cf8eb8e 100644 --- a/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml @@ -62,6 +62,7 @@ httpRoutes: - path: type: Exact value: /exact + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml index f2aab324c92..351c32f0ecc 100644 --- a/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml index f07df0591d4..84cbce084ba 100644 --- a/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml @@ -61,6 +61,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml index e2cbea3dd90..85a062ff0a4 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml index 2b59d98a5b1..839914f0efb 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml index 6a2571e0e26..8c9b7411ac7 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml @@ -65,6 +65,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml index 79131ac54f1..1d787ce79c5 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml @@ -65,6 +65,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml index 21596a52d42..4d0cb5df2fd 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml index 7f25b160719..e4e55540028 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml @@ -73,6 +73,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml index 6429820c1a3..b33025f3223 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml index 0cf9358e1ac..aae559beae4 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml @@ -68,6 +68,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml index 8d3cb231dd9..0ba3ce0d850 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml @@ -66,6 +66,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml index 44067c28c56..90e15f6908a 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml @@ -67,6 +67,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml index 0353ec71963..71b31e58ae0 100644 --- a/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml @@ -59,6 +59,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml b/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml index 58921ad7474..f511a7b1bc5 100644 --- a/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml +++ b/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml @@ -57,6 +57,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -94,6 +95,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -133,6 +135,7 @@ httpRoutes: queryParams: - name: debug value: "yes" + sessionPersistence: null status: parents: - conditions: @@ -169,6 +172,7 @@ httpRoutes: matches: - path: value: /v1/example + sessionPersistence: null status: parents: - conditions: @@ -208,6 +212,7 @@ httpRoutes: value: one path: value: /v1/status + sessionPersistence: null status: parents: - conditions: @@ -244,6 +249,7 @@ httpRoutes: matches: - path: value: /v1/status + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml b/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml index e02cf0852f4..52bc437aadb 100644 --- a/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml @@ -128,6 +128,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -166,6 +167,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.in.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.in.yaml index 888c4e4b713..d343d0070ff 100644 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.in.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.in.yaml @@ -139,7 +139,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default cors: allowOrigins: - "*" @@ -163,7 +162,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-3 - namespace: default cors: allowOrigins: - "*" @@ -189,7 +187,6 @@ clientTrafficPolicies: kind: Gateway name: gateway-2 sectionName: http - namespace: default timeout: http: requestReceivedTimeout: "5s" @@ -203,7 +200,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default timeout: http: requestReceivedTimeout: "5s" @@ -218,7 +214,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default tcpKeepalive: probes: 3 idleTime: 20m diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml index f8797d895ca..e4752f75b46 100755 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default tcpKeepalive: idleTime: 20m interval: 60s @@ -41,7 +40,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: default sectionName: http timeout: http: @@ -73,7 +71,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default timeout: http: requestReceivedTimeout: 5s @@ -255,6 +252,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -293,6 +291,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -331,6 +330,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -369,6 +369,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -445,7 +446,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-3 - namespace: default status: ancestors: - ancestorRef: @@ -485,7 +485,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies.in.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies.in.yaml index 2ce31b166c6..1f5291f72df 100644 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies.in.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies.in.yaml @@ -85,7 +85,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default cors: allowOrigins: - "*" @@ -110,7 +109,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: default timeout: http: requestReceivedTimeout: "5s" @@ -125,7 +123,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default tcpKeepalive: probes: 3 idleTime: 20m diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml index 8eb08db7bfd..cb0560704a6 100644 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml @@ -10,7 +10,6 @@ backendTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default tcpKeepalive: idleTime: 20m interval: 60s @@ -41,7 +40,6 @@ clientTrafficPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-2 - namespace: default timeout: http: requestReceivedTimeout: 5s @@ -161,6 +159,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -199,6 +198,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -275,7 +275,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.in.yaml b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.in.yaml index d43a1c06734..b7b9a034c1a 100644 --- a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.in.yaml @@ -24,7 +24,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway cors: allowOrigins: - "http://*.example.com" diff --git a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml index fd0c493464e..eef9b4a36e8 100755 --- a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml @@ -82,22 +82,8 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Namespace:default TargetRef.Namespace:envoy-gateway, SecurityPolicy - can only target a resource in the same namespace. - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller + ancestors: null xdsIR: envoy-gateway/gateway-1: accessLog: diff --git a/internal/gatewayapi/testdata/securitypolicy-override-replace.in.yaml b/internal/gatewayapi/testdata/securitypolicy-override-replace.in.yaml index 3ab602888d5..debfe1dd46d 100644 --- a/internal/gatewayapi/testdata/securitypolicy-override-replace.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-override-replace.in.yaml @@ -63,7 +63,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway cors: allowOrigins: - "http://*.example.com" @@ -100,7 +99,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default cors: allowOrigins: - "https://*.test.com:8080" diff --git a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml index f7c7b74db9c..0399092e84f 100755 --- a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -98,6 +99,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: @@ -158,7 +160,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -211,7 +212,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.in.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.in.yaml index 504deaab89d..910a5ce627f 100644 --- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.in.yaml @@ -9,7 +9,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -20,7 +19,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -31,7 +29,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -42,7 +39,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -53,7 +49,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -64,7 +59,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -75,7 +69,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: unknown-httproute - namespace: envoy-gateway httpRoutes: - apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml index 01db3ebbdec..bc83d374079 100755 --- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml @@ -150,6 +150,7 @@ grpcRoutes: - name: magic type: Exact value: foo + sessionPersistence: null status: parents: - conditions: @@ -185,6 +186,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -252,7 +254,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -278,7 +279,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -305,7 +305,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: GRPCRoute name: grpcroute-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -331,7 +330,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: unknown-httproute - namespace: envoy-gateway status: ancestors: null - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -345,7 +343,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -377,7 +374,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: @@ -404,7 +400,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: unknown-gateway - namespace: envoy-gateway status: ancestors: null xdsIR: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml index 3a696360dbc..3402292d15d 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml @@ -84,7 +84,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default basicAuth: users: name: "users-secret1" @@ -98,7 +97,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default basicAuth: users: name: "users-secret2" diff --git a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml index cc05125f7ee..18b2e947913 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml @@ -60,12 +60,14 @@ httpRoutes: matches: - path: value: /foo1 + sessionPersistence: null - backendRefs: - name: service-2 port: 8080 matches: - path: value: /foo2 + sessionPersistence: null status: parents: - conditions: @@ -104,6 +106,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: @@ -155,7 +158,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -187,7 +189,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-cors.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-cors.in.yaml index 3b773726448..c68757603ad 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-cors.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-cors.in.yaml @@ -106,7 +106,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway cors: allowOrigins: - "http://*.example.com" @@ -132,7 +131,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default cors: allowOrigins: - "https://*.test.com:8080" @@ -157,7 +155,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default cors: allowOrigins: - "*" diff --git a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml index 1d11e3a4cda..36825939f02 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml @@ -135,6 +135,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -174,6 +175,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -212,6 +214,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -302,7 +305,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -342,7 +344,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default status: ancestors: - ancestorRef: @@ -384,7 +385,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml index 4a6ba7412f4..1ffcb302787 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml @@ -53,7 +53,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extAuth: http: backendRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml index d23b2a7d8f7..c7b7d346e8c 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -116,7 +117,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml index cec6e9ce285..75c777585a6 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml @@ -53,7 +53,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extAuth: http: backendRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml index fb8d90097a0..2efca502b49 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -115,7 +116,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml index f713a1dc730..c0397d6784f 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml @@ -53,7 +53,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extAuth: http: backendRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml index 5d31bd10a9b..48790201e4a 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -116,7 +117,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml index eb02ed446ac..3c2fba3e700 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml @@ -44,7 +44,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extAuth: http: backendRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml index da185ff74a0..53c2483939a 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -116,7 +117,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml index b7769b524bd..f75698ddd93 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml @@ -123,7 +123,7 @@ referenceGrants: kind: BackendTLSPolicy namespace: default to: - - group: '' + - group: "" kind: Service configMaps: - apiVersion: v1 @@ -159,16 +159,15 @@ backendTLSPolicies: name: policy-btls-http namespace: default spec: - targetRef: - group: '' - kind: Service - name: http-backend - namespace: envoy-gateway - sectionName: "80" - tls: - caCertRefs: + targetRefs: + - group: "" + kind: Service + name: http-backend + sectionName: "80" + validation: + caCertificateRefs: - name: ca-cmap - group: '' + group: "" kind: ConfigMap hostname: http-backend - apiVersion: gateway.networking.k8s.io/v1alpha2 @@ -177,15 +176,15 @@ backendTLSPolicies: name: policy-btls-grpc namespace: default spec: - targetRef: - group: '' - kind: Service - name: grpc-backend - sectionName: "9000" - tls: - caCertRefs: + targetRefs: + - group: "" + kind: Service + name: grpc-backend + sectionName: "9000" + validation: + caCertificateRefs: - name: ca-cmap - group: '' + group: "" kind: ConfigMap hostname: grpc-backend securityPolicies: @@ -199,7 +198,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extAuth: http: backendRef: @@ -221,7 +219,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default extAuth: headersToExtAuth: - header1 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml index a30a343eaee..bf2f0f9a235 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml @@ -6,14 +6,13 @@ backendTLSPolicies: name: policy-btls-http namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: http-backend - namespace: envoy-gateway sectionName: "80" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -39,13 +38,13 @@ backendTLSPolicies: name: policy-btls-grpc namespace: default spec: - targetRef: - group: "" + targetRefs: + - group: "" kind: Service name: grpc-backend sectionName: "9000" - tls: - caCertRefs: + validation: + caCertificateRefs: - group: "" kind: ConfigMap name: ca-cmap @@ -126,6 +125,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -164,6 +164,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: @@ -219,7 +220,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -257,7 +257,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml index 9d7f17e93d3..e362583125b 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml @@ -139,7 +139,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default extAuth: failOpen: true headersToExtAuth: @@ -159,7 +158,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default extAuth: failOpen: false http: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml index 4628a35cc11..20ffe990ca2 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml @@ -60,12 +60,14 @@ httpRoutes: matches: - path: value: /foo1 + sessionPersistence: null - backendRefs: - name: service-2 port: 8080 matches: - path: value: /foo2 + sessionPersistence: null status: parents: - conditions: @@ -104,6 +106,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: @@ -159,7 +162,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -197,7 +199,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: default status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.in.yaml index 833c2b70c13..12e31664930 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.in.yaml @@ -63,7 +63,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway jwt: providers: - name: example1 @@ -91,7 +90,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default jwt: providers: - name: example2 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml index b4e2932f294..7d168614492 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -98,6 +99,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: @@ -163,7 +165,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-2 - namespace: default status: ancestors: - ancestorRef: @@ -209,7 +210,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.in.yaml index 1ae633f805c..a70419f71c7 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.in.yaml @@ -73,7 +73,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway jwt: providers: - name: example1 @@ -104,7 +103,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default jwt: providers: - name: example3 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.out.yaml index caf5e85171f..da9dffa3557 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.out.yaml @@ -95,6 +95,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -134,6 +135,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -215,7 +217,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -262,7 +263,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.in.yaml index 4c43bc662e0..a74229753d2 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.in.yaml @@ -73,7 +73,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway jwt: providers: - name: example1 @@ -104,7 +103,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default jwt: providers: - name: example3 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml index 73a2e8e33a0..20b53b56bd7 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml @@ -95,6 +95,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -134,6 +135,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -214,7 +216,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -261,7 +262,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt.in.yaml index 4e51d2c903c..d0778135ce5 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt.in.yaml @@ -73,7 +73,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway jwt: providers: - name: example1 @@ -104,7 +103,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default jwt: providers: - name: example3 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml index d2bb96f0d8d..f9f1fb2c967 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml @@ -95,6 +95,7 @@ grpcRoutes: - backendRefs: - name: service-1 port: 8080 + sessionPersistence: null status: parents: - conditions: @@ -134,6 +135,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -206,7 +208,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -253,7 +254,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml index 9ebcd924698..2aa2fdf753c 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml @@ -93,7 +93,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway oidc: provider: issuer: "https://accounts.google.com" @@ -113,7 +112,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default oidc: provider: issuer: "https://oauth.foo.com" diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml index 2015f492d63..3a317aef686 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml @@ -60,6 +60,7 @@ httpRoutes: matches: - path: value: /foo + sessionPersistence: null status: parents: - conditions: @@ -98,6 +99,7 @@ httpRoutes: matches: - path: value: /bar + sessionPersistence: null status: parents: - conditions: @@ -163,7 +165,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: HTTPRoute name: httproute-1 - namespace: default status: ancestors: - ancestorRef: @@ -201,7 +202,6 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway status: ancestors: - ancestorRef: diff --git a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml index 08e2e85c06e..3d44a6ec050 100755 --- a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml @@ -128,6 +128,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -166,6 +167,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml index fb5c6f89acc..b761e77e592 100755 --- a/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml @@ -128,6 +128,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: @@ -166,6 +167,7 @@ httpRoutes: matches: - path: value: / + sessionPersistence: null status: parents: - conditions: diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index c0764e583ab..d0ea8244366 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -9,7 +9,7 @@ import ( "golang.org/x/exp/maps" "k8s.io/apimachinery/pkg/runtime/schema" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - egv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" @@ -113,7 +113,7 @@ func newTranslateResult(gateways []*GatewayContext, clientTrafficPolicies []*egv1a1.ClientTrafficPolicy, backendTrafficPolicies []*egv1a1.BackendTrafficPolicy, securityPolicies []*egv1a1.SecurityPolicy, - backendTLSPolicies []*egv1a2.BackendTLSPolicy, + backendTLSPolicies []*gwapiv1a3.BackendTLSPolicy, envoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy, xdsIR XdsIRMap, infraIR InfraIRMap, ) *TranslateResult { diff --git a/internal/gatewayapi/validate.go b/internal/gatewayapi/validate.go index 09561698c66..7ab85a01a75 100644 --- a/internal/gatewayapi/validate.go +++ b/internal/gatewayapi/validate.go @@ -93,7 +93,7 @@ func (t *Translator) validateBackendRefFilters(backendRef BackendRefContext, par filters := GetFilters(backendRef).([]gwapiv1.HTTPRouteFilter) filtersLen = len(filters) case KindGRPCRoute: - filters := GetFilters(backendRef).([]gwapiv1a2.GRPCRouteFilter) + filters := GetFilters(backendRef).([]gwapiv1.GRPCRouteFilter) filtersLen = len(filters) default: return true diff --git a/internal/gatewayapi/zz_generated.deepcopy.go b/internal/gatewayapi/zz_generated.deepcopy.go index 336498b2214..adbbdcca40a 100644 --- a/internal/gatewayapi/zz_generated.deepcopy.go +++ b/internal/gatewayapi/zz_generated.deepcopy.go @@ -16,6 +16,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" + "sigs.k8s.io/gateway-api/apis/v1alpha3" "sigs.k8s.io/gateway-api/apis/v1beta1" "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" ) @@ -52,11 +53,11 @@ func (in *Resources) DeepCopyInto(out *Resources) { } if in.GRPCRoutes != nil { in, out := &in.GRPCRoutes, &out.GRPCRoutes - *out = make([]*v1alpha2.GRPCRoute, len(*in)) + *out = make([]*v1.GRPCRoute, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(v1alpha2.GRPCRoute) + *out = new(v1.GRPCRoute) (*in).DeepCopyInto(*out) } } @@ -229,11 +230,11 @@ func (in *Resources) DeepCopyInto(out *Resources) { } if in.BackendTLSPolicies != nil { in, out := &in.BackendTLSPolicies, &out.BackendTLSPolicies - *out = make([]*v1alpha2.BackendTLSPolicy, len(*in)) + *out = make([]*v1alpha3.BackendTLSPolicy, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(v1alpha2.BackendTLSPolicy) + *out = new(v1alpha3.BackendTLSPolicy) (*in).DeepCopyInto(*out) } } diff --git a/internal/message/types.go b/internal/message/types.go index 9db1b824f81..48eb2a52121 100644 --- a/internal/message/types.go +++ b/internal/message/types.go @@ -72,7 +72,7 @@ func (p *ProviderResources) Close() { type GatewayAPIStatuses struct { GatewayStatuses watchable.Map[types.NamespacedName, *gwapiv1.GatewayStatus] HTTPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1.HTTPRouteStatus] - GRPCRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.GRPCRouteStatus] + GRPCRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1.GRPCRouteStatus] TLSRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.TLSRouteStatus] TCPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.TCPRouteStatus] UDPRouteStatuses watchable.Map[types.NamespacedName, *gwapiv1a2.UDPRouteStatus] diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 0cdbe5c8f7f..d779fffb9f9 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -29,6 +29,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" @@ -866,7 +867,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicies( func (r *gatewayAPIReconciler) processBackendTLSPolicies( ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, ) error { - backendTLSPolicies := gwapiv1a2.BackendTLSPolicyList{} + backendTLSPolicies := gwapiv1a3.BackendTLSPolicyList{} if err := r.client.List(ctx, &backendTLSPolicies); err != nil { return fmt.Errorf("error listing BackendTLSPolicies: %w", err) } @@ -992,17 +993,17 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch GRPCRoute CRUDs and process affected Gateways. - grpcrPredicates := []predicate.TypedPredicate[*gwapiv1a2.GRPCRoute]{ - predicate.TypedGenerationChangedPredicate[*gwapiv1a2.GRPCRoute]{}, + grpcrPredicates := []predicate.TypedPredicate[*gwapiv1.GRPCRoute]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1.GRPCRoute]{}, } if r.namespaceLabel != nil { - grpcrPredicates = append(grpcrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.GRPCRoute](func(grpc *gwapiv1a2.GRPCRoute) bool { + grpcrPredicates = append(grpcrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1.GRPCRoute](func(grpc *gwapiv1.GRPCRoute) bool { return r.hasMatchingNamespaceLabels(grpc) })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1a2.GRPCRoute{}, - handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.GRPCRoute](func(ctx context.Context, route *gwapiv1a2.GRPCRoute) []reconcile.Request { + source.Kind(mgr.GetCache(), &gwapiv1.GRPCRoute{}, + handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1.GRPCRoute](func(ctx context.Context, route *gwapiv1.GRPCRoute) []reconcile.Request { return r.enqueueClass(ctx, route) }), grpcrPredicates...)); err != nil { @@ -1329,18 +1330,18 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch BackendTLSPolicy - btlsPredicates := []predicate.TypedPredicate[*gwapiv1a2.BackendTLSPolicy]{ - predicate.TypedGenerationChangedPredicate[*gwapiv1a2.BackendTLSPolicy]{}, + btlsPredicates := []predicate.TypedPredicate[*gwapiv1a3.BackendTLSPolicy]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1a3.BackendTLSPolicy]{}, } if r.namespaceLabel != nil { - btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.BackendTLSPolicy](func(btp *gwapiv1a2.BackendTLSPolicy) bool { + btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a3.BackendTLSPolicy](func(btp *gwapiv1a3.BackendTLSPolicy) bool { return r.hasMatchingNamespaceLabels(btp) })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1a2.BackendTLSPolicy{}, - handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1a2.BackendTLSPolicy) []reconcile.Request { + source.Kind(mgr.GetCache(), &gwapiv1a3.BackendTLSPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1a3.BackendTLSPolicy) []reconcile.Request { return r.enqueueClass(ctx, btp) }), btlsPredicates...)); err != nil { @@ -1506,10 +1507,10 @@ func (r *gatewayAPIReconciler) serviceImportCRDExists(mgr manager.Manager) bool func (r *gatewayAPIReconciler) processBackendTLSPolicyConfigMapRefs(ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) { for _, policy := range resourceTree.BackendTLSPolicies { - tls := policy.Spec.TLS + tls := policy.Spec.Validation - if tls.CACertRefs != nil { - for _, caCertRef := range tls.CACertRefs { + if tls.CACertificateRefs != nil { + for _, caCertRef := range tls.CACertificateRefs { if string(caCertRef.Kind) == gatewayapi.KindConfigMap { caRefNew := gwapiv1b1.SecretObjectReference{ Group: gatewayapi.GroupPtr(string(caCertRef.Group)), diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go index 511802e2e38..62b11f68903 100644 --- a/internal/provider/kubernetes/indexers.go +++ b/internal/provider/kubernetes/indexers.go @@ -13,6 +13,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/envoyproxy/gateway/api/v1alpha1" @@ -112,11 +113,11 @@ func backendHTTPRouteIndexFunc(rawObj client.Object) []string { // referenced in GRPCRoute objects via `.spec.rules.backendRefs`. This helps in // querying for GRPCRoutes that are affected by a particular Service CRUD. func addGRPCRouteIndexers(ctx context.Context, mgr manager.Manager) error { - if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a2.GRPCRoute{}, gatewayGRPCRouteIndex, gatewayGRPCRouteIndexFunc); err != nil { + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1.GRPCRoute{}, gatewayGRPCRouteIndex, gatewayGRPCRouteIndexFunc); err != nil { return err } - if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a2.GRPCRoute{}, backendGRPCRouteIndex, backendGRPCRouteIndexFunc); err != nil { + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1.GRPCRoute{}, backendGRPCRouteIndex, backendGRPCRouteIndexFunc); err != nil { return err } @@ -124,7 +125,7 @@ func addGRPCRouteIndexers(ctx context.Context, mgr manager.Manager) error { } func gatewayGRPCRouteIndexFunc(rawObj client.Object) []string { - grpcroute := rawObj.(*gwapiv1a2.GRPCRoute) + grpcroute := rawObj.(*gwapiv1.GRPCRoute) var gateways []string for _, parent := range grpcroute.Spec.ParentRefs { if parent.Kind == nil || string(*parent.Kind) == gatewayapi.KindGateway { @@ -142,7 +143,7 @@ func gatewayGRPCRouteIndexFunc(rawObj client.Object) []string { } func backendGRPCRouteIndexFunc(rawObj client.Object) []string { - grpcroute := rawObj.(*gwapiv1a2.GRPCRoute) + grpcroute := rawObj.(*gwapiv1.GRPCRoute) var backendRefs []string for _, rule := range grpcroute.Spec.Rules { for _, backend := range rule.BackendRefs { @@ -488,7 +489,7 @@ func secretCtpIndexFunc(rawObj client.Object) []string { // referenced in BackendTLSPolicy objects. This helps in querying for BackendTLSPolicies that are // affected by a particular ConfigMap CRUD. func addBtlsIndexers(ctx context.Context, mgr manager.Manager) error { - if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a2.BackendTLSPolicy{}, configMapBtlsIndex, configMapBtlsIndexFunc); err != nil { + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a3.BackendTLSPolicy{}, configMapBtlsIndex, configMapBtlsIndexFunc); err != nil { return err } @@ -496,10 +497,10 @@ func addBtlsIndexers(ctx context.Context, mgr manager.Manager) error { } func configMapBtlsIndexFunc(rawObj client.Object) []string { - btls := rawObj.(*gwapiv1a2.BackendTLSPolicy) + btls := rawObj.(*gwapiv1a3.BackendTLSPolicy) var configMapReferences []string - if btls.Spec.TLS.CACertRefs != nil { - for _, caCertRef := range btls.Spec.TLS.CACertRefs { + if btls.Spec.Validation.CACertificateRefs != nil { + for _, caCertRef := range btls.Spec.Validation.CACertificateRefs { if string(caCertRef.Kind) == gatewayapi.KindConfigMap { configMapReferences = append(configMapReferences, types.NamespacedName{ diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index 1c0668f1a9b..c852bffda73 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -20,6 +20,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" @@ -289,7 +290,7 @@ func (r *gatewayAPIReconciler) isRouteReferencingBackend(nsName *types.Namespace return false } - grpcRouteList := &gwapiv1a2.GRPCRouteList{} + grpcRouteList := &gwapiv1.GRPCRouteList{} if err := r.client.List(ctx, grpcRouteList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(backendGRPCRouteIndex, nsName.String()), }); err != nil { @@ -520,7 +521,7 @@ func (r *gatewayAPIReconciler) validateConfigMapForReconcile(obj client.Object) return false } - btlsList := &gwapiv1a2.BackendTLSPolicyList{} + btlsList := &gwapiv1a3.BackendTLSPolicyList{} if err := r.client.List(context.Background(), btlsList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(configMapBtlsIndex, utils.NamespacedName(configMap).String()), }); err != nil { diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go index 6f327b0c23a..debeacdf1f7 100644 --- a/internal/provider/kubernetes/predicates_test.go +++ b/internal/provider/kubernetes/predicates_test.go @@ -223,8 +223,8 @@ func TestValidateSecretForReconcile(t *testing.T) { Name: "oidc", }, Spec: v1alpha1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Kind: "Gateway", Name: "scheduled-status-test", }, @@ -256,8 +256,8 @@ func TestValidateSecretForReconcile(t *testing.T) { Name: "basic-auth", }, Spec: v1alpha1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Kind: "Gateway", Name: "scheduled-status-test", }, @@ -362,7 +362,7 @@ func TestValidateEndpointSliceForReconcile(t *testing.T) { WithScheme(envoygateway.GetScheme()). WithObjects(tc.configs...). WithIndex(&gwapiv1.HTTPRoute{}, backendHTTPRouteIndex, backendHTTPRouteIndexFunc). - WithIndex(&gwapiv1a2.GRPCRoute{}, backendGRPCRouteIndex, backendGRPCRouteIndexFunc). + WithIndex(&gwapiv1.GRPCRoute{}, backendGRPCRouteIndex, backendGRPCRouteIndexFunc). WithIndex(&gwapiv1a2.TLSRoute{}, backendTLSRouteIndex, backendTLSRouteIndexFunc). WithIndex(&gwapiv1a2.TCPRoute{}, backendTCPRouteIndex, backendTCPRouteIndexFunc). WithIndex(&gwapiv1a2.UDPRoute{}, backendUDPRouteIndex, backendUDPRouteIndexFunc). @@ -495,8 +495,8 @@ func TestValidateServiceForReconcile(t *testing.T) { Name: "ext-auth-http", }, Spec: v1alpha1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Kind: "Gateway", Name: "scheduled-status-test", }, @@ -522,8 +522,8 @@ func TestValidateServiceForReconcile(t *testing.T) { Name: "ext-proc", }, Spec: v1alpha1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Kind: "Gateway", Name: "scheduled-status-test", }, @@ -553,8 +553,8 @@ func TestValidateServiceForReconcile(t *testing.T) { Name: "ext-proc", }, Spec: v1alpha1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Kind: "Gateway", Name: "scheduled-status-test", }, @@ -628,7 +628,7 @@ func TestValidateServiceForReconcile(t *testing.T) { WithScheme(envoygateway.GetScheme()). WithObjects(tc.configs...). WithIndex(&gwapiv1.HTTPRoute{}, backendHTTPRouteIndex, backendHTTPRouteIndexFunc). - WithIndex(&gwapiv1a2.GRPCRoute{}, backendGRPCRouteIndex, backendGRPCRouteIndexFunc). + WithIndex(&gwapiv1.GRPCRoute{}, backendGRPCRouteIndex, backendGRPCRouteIndexFunc). WithIndex(&gwapiv1a2.TLSRoute{}, backendTLSRouteIndex, backendTLSRouteIndexFunc). WithIndex(&gwapiv1a2.TCPRoute{}, backendTCPRouteIndex, backendTCPRouteIndexFunc). WithIndex(&gwapiv1a2.UDPRoute{}, backendUDPRouteIndex, backendUDPRouteIndexFunc). diff --git a/internal/provider/kubernetes/routes.go b/internal/provider/kubernetes/routes.go index b1b2524e25a..1608f5147a3 100644 --- a/internal/provider/kubernetes/routes.go +++ b/internal/provider/kubernetes/routes.go @@ -96,7 +96,7 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNamespaceName string, resourceMap *resourceMappings, resourceTree *gatewayapi.Resources, ) error { - grpcRouteList := &gwapiv1a2.GRPCRouteList{} + grpcRouteList := &gwapiv1.GRPCRouteList{} if err := r.client.List(ctx, grpcRouteList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(gatewayGRPCRouteIndex, gatewayNamespaceName), @@ -169,7 +169,7 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam r.log.Error(err, "bypassing filter rule", "index", i) continue } - if filter.Type == gwapiv1a2.GRPCRouteFilterExtensionRef { + if filter.Type == gwapiv1.GRPCRouteFilterExtensionRef { // NOTE: filters must be in the same namespace as the GRPCRoute // Check if it's a Kind managed by an extension and add to resourceTree key := types.NamespacedName{ @@ -195,7 +195,7 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam resourceMap.allAssociatedNamespaces[grpcRoute.Namespace] = struct{}{} // Discard Status to reduce memory consumption in watchable // It will be recomputed by the gateway-api layer - grpcRoute.Status = gwapiv1a2.GRPCRouteStatus{} + grpcRoute.Status = gwapiv1.GRPCRouteStatus{} resourceTree.GRPCRoutes = append(resourceTree.GRPCRoutes, &grpcRoute) } diff --git a/internal/provider/kubernetes/routes_test.go b/internal/provider/kubernetes/routes_test.go index 5b31a04db8f..9a230e6824b 100644 --- a/internal/provider/kubernetes/routes_test.go +++ b/internal/provider/kubernetes/routes_test.go @@ -21,7 +21,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/envoygateway" @@ -343,19 +342,19 @@ func TestProcessGRPCRoutes(t *testing.T) { testCases := []struct { name string - routes []*gwapiv1a2.GRPCRoute + routes []*gwapiv1.GRPCRoute extensionAPIGroups []schema.GroupVersionKind expected bool }{ { name: "valid grpcroute", - routes: []*gwapiv1a2.GRPCRoute{ + routes: []*gwapiv1.GRPCRoute{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "test", Name: "test", }, - Spec: gwapiv1a2.GRPCRouteSpec{ + Spec: gwapiv1.GRPCRouteSpec{ CommonRouteSpec: gwapiv1.CommonRouteSpec{ ParentRefs: []gwapiv1.ParentReference{ { @@ -363,16 +362,16 @@ func TestProcessGRPCRoutes(t *testing.T) { }, }, }, - Rules: []gwapiv1a2.GRPCRouteRule{ + Rules: []gwapiv1.GRPCRouteRule{ { - Matches: []gwapiv1a2.GRPCRouteMatch{ + Matches: []gwapiv1.GRPCRouteMatch{ { - Method: &gwapiv1a2.GRPCMethodMatch{ + Method: &gwapiv1.GRPCMethodMatch{ Method: ptr.To("Ping"), }, }, }, - BackendRefs: []gwapiv1a2.GRPCBackendRef{ + BackendRefs: []gwapiv1.GRPCBackendRef{ { BackendRef: gwapiv1.BackendRef{ BackendObjectReference: gwapiv1.BackendObjectReference{ @@ -419,7 +418,7 @@ func TestProcessGRPCRoutes(t *testing.T) { r.client = fakeclient.NewClientBuilder(). WithScheme(envoygateway.GetScheme()). WithObjects(objs...). - WithIndex(&gwapiv1a2.GRPCRoute{}, gatewayGRPCRouteIndex, gatewayGRPCRouteIndexFunc). + WithIndex(&gwapiv1.GRPCRoute{}, gatewayGRPCRouteIndex, gatewayGRPCRouteIndexFunc). Build() // Process the test case httproutes. diff --git a/internal/provider/kubernetes/status.go b/internal/provider/kubernetes/status.go index 33988675073..8fba36cca13 100644 --- a/internal/provider/kubernetes/status.go +++ b/internal/provider/kubernetes/status.go @@ -14,6 +14,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/message" @@ -84,7 +85,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { // GRPCRoute object status updater go func() { message.HandleSubscription(message.Metadata{Runner: string(v1alpha1.LogComponentProviderRunner), Message: "grpcroute-status"}, r.resources.GRPCRouteStatuses.Subscribe(ctx), - func(update message.Update[types.NamespacedName, *gwapiv1a2.GRPCRouteStatus], errChan chan error) { + func(update message.Update[types.NamespacedName, *gwapiv1.GRPCRouteStatus], errChan chan error) { // skip delete updates. if update.Delete { return @@ -93,9 +94,9 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { val := update.Value r.statusUpdater.Send(status.Update{ NamespacedName: key, - Resource: new(gwapiv1a2.GRPCRoute), + Resource: new(gwapiv1.GRPCRoute), Mutator: status.MutatorFunc(func(obj client.Object) client.Object { - h, ok := obj.(*gwapiv1a2.GRPCRoute) + h, ok := obj.(*gwapiv1.GRPCRoute) if !ok { err := fmt.Errorf("unsupported object type %T", obj) errChan <- err @@ -347,9 +348,9 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { val := update.Value r.statusUpdater.Send(status.Update{ NamespacedName: key, - Resource: new(gwapiv1a2.BackendTLSPolicy), + Resource: new(gwapiv1a3.BackendTLSPolicy), Mutator: status.MutatorFunc(func(obj client.Object) client.Object { - t, ok := obj.(*gwapiv1a2.BackendTLSPolicy) + t, ok := obj.(*gwapiv1a3.BackendTLSPolicy) if !ok { err := fmt.Errorf("unsupported object type %T", obj) errChan <- err diff --git a/internal/provider/kubernetes/test/utils.go b/internal/provider/kubernetes/test/utils.go index a221d067f20..ae798b57d77 100644 --- a/internal/provider/kubernetes/test/utils.go +++ b/internal/provider/kubernetes/test/utils.go @@ -138,21 +138,21 @@ func GetHTTPRoute(nsName types.NamespacedName, parent string, serviceName types. } // GetGRPCRoute returns a sample GRPCRoute with a parent reference. -func GetGRPCRoute(nsName types.NamespacedName, parent string, serviceName types.NamespacedName, port int32) *gwapiv1a2.GRPCRoute { - return &gwapiv1a2.GRPCRoute{ +func GetGRPCRoute(nsName types.NamespacedName, parent string, serviceName types.NamespacedName, port int32) *gwapiv1.GRPCRoute { + return &gwapiv1.GRPCRoute{ ObjectMeta: metav1.ObjectMeta{ Namespace: nsName.Namespace, Name: nsName.Name, }, - Spec: gwapiv1a2.GRPCRouteSpec{ + Spec: gwapiv1.GRPCRouteSpec{ CommonRouteSpec: gwapiv1.CommonRouteSpec{ ParentRefs: []gwapiv1.ParentReference{ {Name: gwapiv1.ObjectName(parent)}, }, }, - Rules: []gwapiv1a2.GRPCRouteRule{ + Rules: []gwapiv1.GRPCRouteRule{ { - BackendRefs: []gwapiv1a2.GRPCBackendRef{ + BackendRefs: []gwapiv1.GRPCBackendRef{ { BackendRef: gwapiv1.BackendRef{ BackendObjectReference: gwapiv1.BackendObjectReference{ diff --git a/internal/status/status.go b/internal/status/status.go index ce27858a325..4fce4fd8d6e 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -26,6 +26,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" ) @@ -210,8 +211,8 @@ func isStatusEqual(objA, objB interface{}) bool { return true } } - case *gwapiv1a2.GRPCRoute: - if b, ok := objB.(*gwapiv1a2.GRPCRoute); ok { + case *gwapiv1.GRPCRoute: + if b, ok := objB.(*gwapiv1.GRPCRoute); ok { if cmp.Equal(a.Status, b.Status, opts) { return true } @@ -240,8 +241,8 @@ func isStatusEqual(objA, objB interface{}) bool { return true } } - case gwapiv1a2.BackendTLSPolicy: - if b, ok := objB.(*gwapiv1a2.BackendTLSPolicy); ok { + case gwapiv1a3.BackendTLSPolicy: + if b, ok := objB.(*gwapiv1a3.BackendTLSPolicy); ok { if cmp.Equal(a.Status, b.Status, opts) { return true } diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index e5bd11a440e..c00e9d8a915 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -273,7 +273,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `targetRef` | _[PolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName)_ | true | targetRef is the name of the resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway. | +| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | targetRef is the name of the resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway. | | `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests
to a predefined value based on attributes within the traffic flow. | | `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to
the backend endpoints | | `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. | @@ -461,7 +461,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `targetRef` | _[PolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the Gateway resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway.
TargetRef | +| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the Gateway resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway.
TargetRef | | `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the downstream client connection.
If defined, sets SO_KEEPALIVE on the listener socket to enable TCP Keepalives.
Disabled by default. | | `enableProxyProtocol` | _boolean_ | false | EnableProxyProtocol interprets the ProxyProtocol header and adds the
Client Address into the X-Forwarded-For header.
Note Proxy Protocol must be present when this field is set, else the connection
is closed. | | `clientIPDetection` | _[ClientIPDetectionSettings](#clientipdetectionsettings)_ | false | ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. | @@ -689,7 +689,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `targetRef` | _[PolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway or xRoute. | +| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway or xRoute. | | `wasm` | _[Wasm](#wasm) array_ | false | Wasm is a list of Wasm extensions to be loaded by the Gateway.
Order matters, as the extensions will be loaded in the order they are
defined in this list. | | `extProc` | _[ExtProc](#extproc) array_ | false | ExtProc is an ordered list of external processing filters
that should added to the envoy filter chain | @@ -1075,7 +1075,7 @@ _Appears in:_ | --- | --- | --- | --- | | `type` | _[EnvoyPatchType](#envoypatchtype)_ | true | Type decides the type of patch.
Valid EnvoyPatchType values are "JSONPatch". | | `jsonPatches` | _[EnvoyJSONPatchConfig](#envoyjsonpatchconfig) array_ | false | JSONPatch defines the JSONPatch configuration. | -| `targetRef` | _[PolicyTargetReference](#policytargetreference)_ | true | TargetRef is the name of the Gateway API resource this policy
is being attached to.
By default attaching to Gateway is supported and
when mergeGateways is enabled it should attach to GatewayClass.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway
TargetRef | +| `targetRef` | _[LocalPolicyTargetReference](#localpolicytargetreference)_ | true | TargetRef is the name of the Gateway API resource this policy
is being attached to.
By default, attaching to Gateway is supported and
when mergeGateways is enabled it should attach to GatewayClass.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway
TargetRef | | `priority` | _integer_ | true | Priority of the EnvoyPatchPolicy.
If multiple EnvoyPatchPolicies are applied to the same
TargetRef, they will be applied in the ascending order of
the priority i.e. int32.min has the highest priority and
int32.max has the lowest priority.
Defaults to 0. | @@ -2911,7 +2911,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `targetRef` | _[PolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the Gateway resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway. | +| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the Gateway resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway. | | `cors` | _[CORS](#cors)_ | false | CORS defines the configuration for Cross-Origin Resource Sharing (CORS). | | `basicAuth` | _[BasicAuth](#basicauth)_ | false | BasicAuth defines the configuration for the HTTP Basic Authentication. | | `jwt` | _[JWT](#jwt)_ | false | JWT defines the configuration for JSON Web Token (JWT) authentication. | diff --git a/test/cel-validation/backendtrafficpolicy_test.go b/test/cel-validation/backendtrafficpolicy_test.go index 2cefef85e3e..a1dd7ac7eb7 100644 --- a/test/cel-validation/backendtrafficpolicy_test.go +++ b/test/cel-validation/backendtrafficpolicy_test.go @@ -45,8 +45,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "valid gateway targetRef", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -60,8 +60,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "valid httproute targetRef", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("HTTPRoute"), Name: gwapiv1a2.ObjectName("httpbin-route"), @@ -87,8 +87,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "targetRef unsupported kind", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("foo"), Name: gwapiv1a2.ObjectName("eg"), @@ -104,8 +104,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "targetRef unsupported group", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -121,8 +121,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "targetRef unsupported group and kind", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("bar"), Name: gwapiv1a2.ObjectName("eg"), @@ -139,8 +139,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "sectionName disabled until supported", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -157,8 +157,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "consistentHash field not nil when type is consistentHash", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -178,8 +178,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "consistentHash field nil when type is consistentHash", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -198,8 +198,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "leastRequest with ConsistentHash nil", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -216,8 +216,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "leastRequest with SlowStar is set", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -239,8 +239,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "roundrobin with SlowStart is set", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -262,8 +262,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: " random with SlowStart is set", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -287,8 +287,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: " consistenthash with SlowStart is set", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -312,8 +312,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "Using both httpStatus and grpcStatus in abort fault injection", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -335,8 +335,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "Using httpStatus in abort fault injection", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -356,8 +356,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "Using grpcStatus in abort fault injection", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -377,8 +377,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "httpStatus and grpcStatus are set at least one", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -397,8 +397,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "Neither delay nor abort faults are set", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -413,8 +413,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "Using delay fault injection", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -437,8 +437,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { valMax := ptr.To[int64](4294967295) valMin := ptr.To[int64](0) btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -460,8 +460,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { valOverMax := ptr.To[int64](4294967296) valUnderMin := ptr.To[int64](-1) btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -488,8 +488,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid path of http health checker", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -513,8 +513,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid unhealthy threshold", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -539,8 +539,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid healthy threshold", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -565,8 +565,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid health checker type", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -588,8 +588,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid http expected statuses", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -614,8 +614,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "valid http expected statuses", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -638,8 +638,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid http expected statuses - out of range", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -664,8 +664,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "http expected responses - invalid text payload", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -693,8 +693,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "http expected responses - invalid binary payload", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -722,8 +722,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid tcp send", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -754,8 +754,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { desc: "invalid tcp receive", mutate: func(btp *egv1a1.BackendTrafficPolicy) { btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -787,8 +787,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { mutate: func(btp *egv1a1.BackendTrafficPolicy) { d := gwapiv1.Duration("3s") btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -822,8 +822,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { } btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -854,8 +854,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { } btp.Spec = egv1a1.BackendTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), diff --git a/test/cel-validation/clienttrafficpolicy_test.go b/test/cel-validation/clienttrafficpolicy_test.go index 2b132ea969e..ed898aa7e1d 100644 --- a/test/cel-validation/clienttrafficpolicy_test.go +++ b/test/cel-validation/clienttrafficpolicy_test.go @@ -46,8 +46,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "valid targetRef", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -73,8 +73,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "targetRef unsupported kind", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("foo"), Name: gwapiv1a2.ObjectName("eg"), @@ -90,8 +90,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "targetRef unsupported group", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -107,8 +107,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "targetRef unsupported group and kind", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("bar"), Name: gwapiv1a2.ObjectName("eg"), @@ -125,8 +125,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "sectionName disabled until supported", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), }, @@ -142,8 +142,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "tls minimal version greater than tls maximal version", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -165,8 +165,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "tls maximal version lesser than default tls minimal version", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -187,8 +187,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "clientIPDetection xForwardedFor and customHeader set", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -212,8 +212,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "http3 enabled and ALPN protocols not set with other TLS parameters set", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -233,8 +233,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "setting ciphers with minimum TLS version set to 1.3", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -257,8 +257,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { mutate: func(ctp *egv1a1.ClientTrafficPolicy) { d := gwapiv1.Duration("300s") ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -277,8 +277,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "invalid bufferLimit format", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -297,8 +297,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "invalid InitialStreamWindowSize format", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -317,8 +317,8 @@ func TestClientTrafficPolicyTarget(t *testing.T) { desc: "invalid InitialConnectionWindowSize format", mutate: func(ctp *egv1a1.ClientTrafficPolicy) { ctp.Spec = egv1a1.ClientTrafficPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go index efad71d74f8..53d55412f23 100644 --- a/test/cel-validation/envoyextensionpolicy_test.go +++ b/test/cel-validation/envoyextensionpolicy_test.go @@ -46,8 +46,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { desc: "valid gateway targetRef", mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -61,8 +61,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { desc: "valid httproute targetRef", mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("HTTPRoute"), Name: gwapiv1a2.ObjectName("httpbin-route"), @@ -88,8 +88,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { desc: "targetRef unsupported kind", mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("foo"), Name: gwapiv1a2.ObjectName("eg"), @@ -105,8 +105,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { desc: "targetRef unsupported group", mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -122,8 +122,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { desc: "targetRef unsupported group and kind", mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("bar"), Name: gwapiv1a2.ObjectName("eg"), @@ -140,8 +140,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { desc: "sectionName disabled until supported", mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -172,8 +172,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -200,8 +200,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -228,8 +228,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -263,8 +263,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", diff --git a/test/cel-validation/securitypolicy_test.go b/test/cel-validation/securitypolicy_test.go index 8d7d830eee6..12511c6d4c0 100644 --- a/test/cel-validation/securitypolicy_test.go +++ b/test/cel-validation/securitypolicy_test.go @@ -46,8 +46,8 @@ func TestSecurityPolicyTarget(t *testing.T) { desc: "valid targetRef", mutate: func(sp *egv1a1.SecurityPolicy) { sp.Spec = egv1a1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -73,8 +73,8 @@ func TestSecurityPolicyTarget(t *testing.T) { desc: "targetRef unsupported kind", mutate: func(sp *egv1a1.SecurityPolicy) { sp.Spec = egv1a1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("foo"), Name: gwapiv1a2.ObjectName("eg"), @@ -90,8 +90,8 @@ func TestSecurityPolicyTarget(t *testing.T) { desc: "targetRef unsupported group", mutate: func(sp *egv1a1.SecurityPolicy) { sp.Spec = egv1a1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -107,8 +107,8 @@ func TestSecurityPolicyTarget(t *testing.T) { desc: "targetRef unsupported group and kind", mutate: func(sp *egv1a1.SecurityPolicy) { sp.Spec = egv1a1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("foo"), Kind: gwapiv1a2.Kind("bar"), Name: gwapiv1a2.ObjectName("eg"), @@ -125,8 +125,8 @@ func TestSecurityPolicyTarget(t *testing.T) { desc: "sectionName disabled until supported", mutate: func(sp *egv1a1.SecurityPolicy) { sp.Spec = egv1a1.SecurityPolicySpec{ - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -150,8 +150,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "https://foo.bar.com", // valid }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -170,8 +170,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "https://foo.bar.com:8080", // valid }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -190,8 +190,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "https://*.foo.bar", // valid }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -210,8 +210,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "http://*.foo.com:8080", // valid }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -230,8 +230,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "http://*", // valid }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -250,8 +250,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "*", // valid }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -270,8 +270,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "http://localhost", // valid }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -290,8 +290,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "https://foo.*.com", // invalid, wildcard must be at the beginning }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -312,8 +312,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "foo.bar.com", // invalid, no scheme }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -334,8 +334,8 @@ func TestSecurityPolicyTarget(t *testing.T) { "grpc://foo.bar.com", // invalid, unsupported scheme }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: gwapiv1a2.Group("gateway.networking.k8s.io"), Kind: gwapiv1a2.Kind("Gateway"), Name: gwapiv1a2.ObjectName("eg"), @@ -361,8 +361,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -384,8 +384,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -400,8 +400,8 @@ func TestSecurityPolicyTarget(t *testing.T) { mutate: func(sp *egv1a1.SecurityPolicy) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{}, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -431,8 +431,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -457,8 +457,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -483,8 +483,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -509,8 +509,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -535,8 +535,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -563,8 +563,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -594,8 +594,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -620,8 +620,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", @@ -652,8 +652,8 @@ func TestSecurityPolicyTarget(t *testing.T) { }, }, }, - TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: "eg", diff --git a/test/conformance/conformance_test.go b/test/conformance/conformance_test.go index 7eca6ea9d26..9faa95cf19b 100644 --- a/test/conformance/conformance_test.go +++ b/test/conformance/conformance_test.go @@ -1,57 +1,41 @@ -//go:build conformance -// +build conformance - // Copyright Envoy Gateway Authors // SPDX-License-Identifier: Apache-2.0 // The full text of the Apache license is available in the LICENSE file at // the root of the repo. +//go:build conformance +// +build conformance + package conformance import ( "flag" "testing" - "github.com/stretchr/testify/require" - "k8s.io/client-go/kubernetes" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/config" - v1 "sigs.k8s.io/gateway-api/apis/v1" - "sigs.k8s.io/gateway-api/apis/v1alpha2" - "sigs.k8s.io/gateway-api/apis/v1beta1" + "sigs.k8s.io/gateway-api/conformance" "sigs.k8s.io/gateway-api/conformance/tests" - "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/pkg/features" ) func TestGatewayAPIConformance(t *testing.T) { flag.Parse() - cfg, err := config.GetConfig() - require.NoError(t, err) - - client, err := client.New(cfg, client.Options{}) - require.NoError(t, err) - - clientset, err := kubernetes.NewForConfig(cfg) - require.NoError(t, err) - - require.NoError(t, v1alpha2.AddToScheme(client.Scheme())) - require.NoError(t, v1beta1.AddToScheme(client.Scheme())) - require.NoError(t, v1.AddToScheme(client.Scheme())) - - cSuite := suite.New(suite.Options{ - Client: client, - GatewayClassName: *flags.GatewayClassName, - Debug: *flags.ShowDebug, - Clientset: clientset, - CleanupBaseResources: *flags.CleanupBaseResources, - SupportedFeatures: suite.AllFeatures, - SkipTests: []string{ - tests.GatewayStaticAddresses.ShortName, - }, - ExemptFeatures: suite.MeshCoreFeatures, - }) - cSuite.Setup(t) - cSuite.Run(t, tests.ConformanceTests) + opts := conformance.DefaultOptions(t) + opts.SkipTests = []string{ + tests.GatewayStaticAddresses.ShortName, + tests.GatewayHTTPListenerIsolation.ShortName, // https://github.com/kubernetes-sigs/gateway-api/issues/3049 + tests.HTTPRouteBackendRequestHeaderModifier.ShortName, // https://github.com/envoyproxy/gateway/issues/3338 + } + opts.SupportedFeatures = features.AllFeatures + opts.ExemptFeatures = features.MeshCoreFeatures + + cSuite, err := suite.NewConformanceTestSuite(opts) + if err != nil { + t.Fatalf("Error creating conformance test suite: %v", err) + } + cSuite.Setup(t, tests.ConformanceTests) + if err := cSuite.Run(t, tests.ConformanceTests); err != nil { + t.Fatalf("Error running conformance tests: %v", err) + } } diff --git a/test/conformance/experimental_conformance_test.go b/test/conformance/experimental_conformance_test.go index fa3598be1e0..702e919bca4 100644 --- a/test/conformance/experimental_conformance_test.go +++ b/test/conformance/experimental_conformance_test.go @@ -1,114 +1,54 @@ -//go:build experimental -// +build experimental - // Copyright Envoy Gateway Authors // SPDX-License-Identifier: Apache-2.0 // The full text of the Apache license is available in the LICENSE file at // the root of the repo. +//go:build experimental +// +build experimental + package conformance import ( + "flag" "os" "testing" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/config" - "sigs.k8s.io/yaml" - - v1 "sigs.k8s.io/gateway-api/apis/v1" - "sigs.k8s.io/gateway-api/apis/v1alpha2" - "sigs.k8s.io/gateway-api/apis/v1beta1" - confv1a1 "sigs.k8s.io/gateway-api/conformance/apis/v1alpha1" + "sigs.k8s.io/gateway-api/conformance" + conformancev1 "sigs.k8s.io/gateway-api/conformance/apis/v1" "sigs.k8s.io/gateway-api/conformance/tests" "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/suite" -) - -var ( - cfg *rest.Config - k8sClientset *kubernetes.Clientset - mgrClient client.Client - implementation *confv1a1.Implementation - conformanceProfiles sets.Set[suite.ConformanceProfileName] + "sigs.k8s.io/gateway-api/pkg/features" + "sigs.k8s.io/yaml" ) func TestExperimentalConformance(t *testing.T) { - var err error - cfg, err = config.GetConfig() - if err != nil { - t.Fatalf("Error loading Kubernetes config: %v", err) - } - mgrClient, err = client.New(cfg, client.Options{}) - if err != nil { - t.Fatalf("Error initializing Kubernetes client: %v", err) - } - k8sClientset, err = kubernetes.NewForConfig(cfg) - if err != nil { - t.Fatalf("Error initializing Kubernetes REST client: %v", err) - } - - err = v1alpha2.AddToScheme(mgrClient.Scheme()) - require.NoError(t, err) - err = v1beta1.AddToScheme(mgrClient.Scheme()) - require.NoError(t, err) - err = v1.AddToScheme(mgrClient.Scheme()) - require.NoError(t, err) + flag.Parse() - // experimental conformance flags - conformanceProfiles = sets.New( - suite.HTTPConformanceProfileName, - suite.TLSConformanceProfileName, - ) - - // if some conformance profiles have been set, run the experimental conformance suite... - implementation, err = suite.ParseImplementation( - *flags.ImplementationOrganization, - *flags.ImplementationProject, - *flags.ImplementationURL, - *flags.ImplementationVersion, - *flags.ImplementationContact, - ) - if err != nil { - t.Fatalf("Error parsing implementation's details: %v", err) + opts := conformance.DefaultOptions(t) + opts.SkipTests = []string{ + tests.GatewayStaticAddresses.ShortName, + tests.GatewayHTTPListenerIsolation.ShortName, // https://github.com/kubernetes-sigs/gateway-api/issues/3049 + tests.HTTPRouteBackendRequestHeaderModifier.ShortName, // https://github.com/envoyproxy/gateway/issues/3338 } + opts.SupportedFeatures = features.AllFeatures + opts.ExemptFeatures = features.MeshCoreFeatures + opts.ConformanceProfiles = sets.New( + suite.GatewayHTTPConformanceProfileName, + suite.GatewayTLSConformanceProfileName, + ) - experimentalConformance(t) -} - -func experimentalConformance(t *testing.T) { t.Logf("Running experimental conformance tests with %s GatewayClass\n cleanup: %t\n debug: %t\n enable all features: %t \n conformance profiles: [%v]", - *flags.GatewayClassName, *flags.CleanupBaseResources, *flags.ShowDebug, *flags.EnableAllSupportedFeatures, conformanceProfiles) + *flags.GatewayClassName, *flags.CleanupBaseResources, *flags.ShowDebug, *flags.EnableAllSupportedFeatures, opts.ConformanceProfiles) - cSuite, err := suite.NewExperimentalConformanceTestSuite( - suite.ExperimentalConformanceOptions{ - Options: suite.Options{ - Client: mgrClient, - RestConfig: cfg, - // This clientset is needed in addition to the client only because - // controller-runtime client doesn't support non CRUD sub-resources yet (https://github.com/kubernetes-sigs/controller-runtime/issues/452). - Clientset: k8sClientset, - GatewayClassName: *flags.GatewayClassName, - Debug: *flags.ShowDebug, - CleanupBaseResources: *flags.CleanupBaseResources, - SupportedFeatures: suite.AllFeatures, - SkipTests: []string{ - tests.GatewayStaticAddresses.ShortName, - }, - ExemptFeatures: suite.MeshCoreFeatures, - }, - Implementation: *implementation, - ConformanceProfiles: conformanceProfiles, - }) + cSuite, err := suite.NewConformanceTestSuite(opts) if err != nil { t.Fatalf("error creating experimental conformance test suite: %v", err) } - cSuite.Setup(t) + cSuite.Setup(t, tests.ConformanceTests) err = cSuite.Run(t, tests.ConformanceTests) if err != nil { t.Fatalf("error running conformance profile report: %v", err) @@ -122,7 +62,7 @@ func experimentalConformance(t *testing.T) { require.NoError(t, err) } -func experimentalConformanceReport(logf func(string, ...any), report confv1a1.ConformanceReport, output string) error { +func experimentalConformanceReport(logf func(string, ...any), report conformancev1.ConformanceReport, output string) error { rawReport, err := yaml.Marshal(report) if err != nil { return err diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 3159f0bd2a4..89e8cb4b19c 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -10,15 +10,19 @@ package e2e import ( "flag" + "io/fs" "testing" "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/pkg/features" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/test/e2e/tests" @@ -32,6 +36,7 @@ func TestE2E(t *testing.T) { c, err := client.New(cfg, client.Options{}) require.NoError(t, err) + require.NoError(t, gwapiv1a3.AddToScheme(c.Scheme())) require.NoError(t, gwapiv1a2.AddToScheme(c.Scheme())) require.NoError(t, gwapiv1.AddToScheme(c.Scheme())) require.NoError(t, egv1a1.AddToScheme(c.Scheme())) @@ -44,19 +49,29 @@ func TestE2E(t *testing.T) { *flags.GatewayClassName, *flags.CleanupBaseResources, *flags.ShowDebug) } - cSuite := suite.New(suite.Options{ + cSuite, err := suite.NewConformanceTestSuite(suite.ConformanceOptions{ Client: c, GatewayClassName: *flags.GatewayClassName, Debug: *flags.ShowDebug, CleanupBaseResources: *flags.CleanupBaseResources, - FS: &Manifests, + ManifestFS: []fs.FS{Manifests}, RunTest: *flags.RunTest, + // SupportedFeatures cannot be empty, so we set it to SupportGateway + // All e2e tests should leave Features empty. + SupportedFeatures: sets.New[features.SupportedFeature](features.SupportGateway), SkipTests: []string{ - tests.ClientTimeoutTest.ShortName, // https://github.com/envoyproxy/gateway/issues/2720 + tests.ClientTimeoutTest.ShortName, // https://github.com/envoyproxy/gateway/issues/2720 + tests.GatewayInfraResourceTest.ShortName, // https://github.com/envoyproxy/gateway/issues/3191 }, }) + if err != nil { + t.Fatalf("Failed to create ConformanceTestSuite: %v", err) + } - cSuite.Setup(t) + cSuite.Setup(t, tests.ConformanceTests) t.Logf("Running %d E2E tests", len(tests.ConformanceTests)) - cSuite.Run(t, tests.ConformanceTests) + err = cSuite.Run(t, tests.ConformanceTests) + if err != nil { + t.Fatalf("Failed to run E2E tests: %v", err) + } } diff --git a/test/e2e/merge_gateways/merge_gateways_test.go b/test/e2e/merge_gateways/merge_gateways_test.go index 6bfbb3a9539..f994445087d 100644 --- a/test/e2e/merge_gateways/merge_gateways_test.go +++ b/test/e2e/merge_gateways/merge_gateways_test.go @@ -10,16 +10,20 @@ package mergegateways import ( "flag" + "io/fs" "testing" "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/pkg/features" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/test/e2e" @@ -34,6 +38,7 @@ func TestMergeGateways(t *testing.T) { c, err := client.New(cfg, client.Options{}) require.NoError(t, err) + require.NoError(t, gwapiv1a3.AddToScheme(c.Scheme())) require.NoError(t, gwapiv1a2.AddToScheme(c.Scheme())) require.NoError(t, gwapiv1.AddToScheme(c.Scheme())) require.NoError(t, egv1a1.AddToScheme(c.Scheme())) @@ -46,21 +51,30 @@ func TestMergeGateways(t *testing.T) { *flags.GatewayClassName, *flags.CleanupBaseResources, *flags.ShowDebug) } - cSuite := suite.New(suite.Options{ + cSuite, err := suite.NewConformanceTestSuite(suite.ConformanceOptions{ Client: c, GatewayClassName: *flags.GatewayClassName, Debug: *flags.ShowDebug, CleanupBaseResources: *flags.CleanupBaseResources, RunTest: *flags.RunTest, - SkipTests: []string{}, + // SupportedFeatures cannot be empty, so we set it to SupportGateway + // All e2e tests should leave Features empty. + SupportedFeatures: sets.New[features.SupportedFeature](features.SupportGateway), + SkipTests: []string{}, }) + if err != nil { + t.Fatalf("Failed to create ConformanceTestSuite: %v", err) + } // Setting up the necessary arguments for the suite instead of calling Suite.Setup method again, // since this test suite reuse the base resources of previous test suite. - cSuite.Applier.FS = e2e.Manifests + cSuite.Applier.ManifestFS = []fs.FS{e2e.Manifests} cSuite.Applier.GatewayClass = *flags.GatewayClassName cSuite.ControllerName = kubernetes.GWCMustHaveAcceptedConditionTrue(t, cSuite.Client, cSuite.TimeoutConfig, cSuite.GatewayClassName) t.Logf("Running %d MergeGateways tests", len(tests.MergeGatewaysTests)) - cSuite.Run(t, tests.MergeGatewaysTests) + err = cSuite.Run(t, tests.MergeGatewaysTests) + if err != nil { + t.Fatalf("Failed to run MergeGateways tests: %v", err) + } } diff --git a/test/e2e/testdata/backend-tls.yaml b/test/e2e/testdata/backend-tls.yaml index 1ad708c2fb5..cdd6960c6d2 100644 --- a/test/e2e/testdata/backend-tls.yaml +++ b/test/e2e/testdata/backend-tls.yaml @@ -100,21 +100,21 @@ spec: - key: tls.key path: key --- -apiVersion: gateway.networking.k8s.io/v1alpha2 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: policy-btls namespace: gateway-conformance-infra spec: - targetRef: - group: '' - kind: Service - name: tls-backend-2 - sectionName: "443" - tls: - caCertRefs: + targetRefs: + - group: "" + kind: Service + name: tls-backend-2 + sectionName: "443" + validation: + caCertificateRefs: - name: backend-tls-checks-certificate - group: '' + group: "" kind: ConfigMap hostname: example.com --- diff --git a/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml b/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml index 1e8df0a4d54..840977aa60a 100644 --- a/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml +++ b/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml @@ -52,19 +52,19 @@ spec: namespace: gateway-conformance-infra port: 9002 --- -apiVersion: gateway.networking.k8s.io/v1alpha2 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: grpc-ext-auth-btls namespace: gateway-conformance-infra spec: - targetRef: - group: '' + targetRefs: + - group: '' kind: Service name: grpc-ext-auth sectionName: "9002" - tls: - caCertRefs: + validation: + caCertificateRefs: - name: grpc-ext-auth-ca group: '' kind: ConfigMap diff --git a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml index e88657fee1b..32ee0eef4a2 100644 --- a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml +++ b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml @@ -70,19 +70,19 @@ spec: namespace: gateway-conformance-infra port: 9002 --- -apiVersion: gateway.networking.k8s.io/v1alpha2 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: grpc-ext-proc-btls namespace: gateway-conformance-infra spec: - targetRef: - group: '' + targetRefs: + - group: '' kind: Service name: grpc-ext-proc sectionName: "9002" - tls: - caCertRefs: + validation: + caCertificateRefs: - name: grpc-ext-proc-ca group: '' kind: ConfigMap diff --git a/test/e2e/tests/gateway_infra_resource.go b/test/e2e/tests/gateway_infra_resource.go index c14cb145050..7a468b80f60 100644 --- a/test/e2e/tests/gateway_infra_resource.go +++ b/test/e2e/tests/gateway_infra_resource.go @@ -24,11 +24,9 @@ import ( ) func init() { - // nolint - // ConformanceTests = append(ConformanceTests, GatewayInfraResourceTest) + ConformanceTests = append(ConformanceTests, GatewayInfraResourceTest) } -// nolint var GatewayInfraResourceTest = suite.ConformanceTest{ ShortName: "GatewayInfraResourceTest", Description: "Gateway Infra Resource E2E Test", diff --git a/test/e2e/tests/merge_gateways.go b/test/e2e/tests/merge_gateways.go index ae170e6039b..fa8665dbc1d 100644 --- a/test/e2e/tests/merge_gateways.go +++ b/test/e2e/tests/merge_gateways.go @@ -186,7 +186,7 @@ var MergeGatewaysTest = suite.ConformanceTest{ }) t.Run("gateway with conflicted listener cannot be merged", func(t *testing.T) { - gw4HostPort, err := kubernetes.WaitForGatewayAddress(t, suite.Client, suite.TimeoutConfig, gw4NN) + gw4HostPort, err := kubernetes.WaitForGatewayAddress(t, suite.Client, suite.TimeoutConfig, kubernetes.GatewayRef{NamespacedName: gw4NN}) if err != nil { t.Errorf("failed to get the address of gateway %s", gw4NN.String()) } diff --git a/test/e2e/tests/udproute.go b/test/e2e/tests/udproute.go index 3961727fb56..019d90060af 100644 --- a/test/e2e/tests/udproute.go +++ b/test/e2e/tests/udproute.go @@ -97,7 +97,9 @@ func NewGatewayRef(nn types.NamespacedName, listenerNames ...string) GatewayRef func GatewayAndUDPRoutesMustBeAccepted(t *testing.T, c client.Client, timeoutConfig config.TimeoutConfig, controllerName string, gw GatewayRef, routeNNs ...types.NamespacedName) string { t.Helper() - gwAddr, err := kubernetes.WaitForGatewayAddress(t, c, timeoutConfig, gw.NamespacedName) + gwAddr, err := kubernetes.WaitForGatewayAddress(t, c, timeoutConfig, kubernetes.GatewayRef{ + NamespacedName: gw.NamespacedName, + }) require.NoErrorf(t, err, "timed out waiting for Gateway address to be assigned") ns := gatewayv1.Namespace(gw.Namespace) diff --git a/test/e2e/upgrade/eg_upgrade_test.go b/test/e2e/upgrade/eg_upgrade_test.go index 999a85ccc53..f366c6e7b0b 100644 --- a/test/e2e/upgrade/eg_upgrade_test.go +++ b/test/e2e/upgrade/eg_upgrade_test.go @@ -10,15 +10,19 @@ package upgrade import ( "flag" + "io/fs" "testing" "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/pkg/features" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/test/e2e" @@ -33,6 +37,7 @@ func TestEGUpgrade(t *testing.T) { c, err := client.New(cfg, client.Options{}) require.NoError(t, err) + require.NoError(t, gwapiv1a3.AddToScheme(c.Scheme())) require.NoError(t, gwapiv1a2.AddToScheme(c.Scheme())) require.NoError(t, gwapiv1.AddToScheme(c.Scheme())) require.NoError(t, egv1a1.AddToScheme(c.Scheme())) @@ -45,20 +50,30 @@ func TestEGUpgrade(t *testing.T) { *flags.GatewayClassName, *flags.CleanupBaseResources, *flags.ShowDebug) } - cSuite := suite.New(suite.Options{ + cSuite, err := suite.NewConformanceTestSuite(suite.ConformanceOptions{ Client: c, GatewayClassName: *flags.GatewayClassName, Debug: *flags.ShowDebug, CleanupBaseResources: *flags.CleanupBaseResources, - FS: &e2e.Manifests, + ManifestFS: []fs.FS{e2e.Manifests}, RunTest: *flags.RunTest, + // SupportedFeatures cannot be empty, so we set it to SupportGateway + // All e2e tests should leave Features empty. + SupportedFeatures: sets.New[features.SupportedFeature](features.SupportGateway), SkipTests: []string{ tests.EnvoyShutdownTest.ShortName, // https://github.com/envoyproxy/gateway/issues/3262 tests.EGUpgradeTest.ShortName, // https://github.com/envoyproxy/gateway/issues/3311 }, }) + if err != nil { + t.Fatalf("Failed to create test suite: %v", err) + } - cSuite.Setup(t) t.Logf("Running %d Upgrade tests", len(tests.UpgradeTests)) - cSuite.Run(t, tests.UpgradeTests) + cSuite.Setup(t, tests.UpgradeTests) + + err = cSuite.Run(t, tests.UpgradeTests) + if err != nil { + t.Fatalf("Failed to run tests: %v", err) + } } diff --git a/tools/crd-ref-docs/config.yaml b/tools/crd-ref-docs/config.yaml index d6fa4e4fc1f..2356eda591c 100644 --- a/tools/crd-ref-docs/config.yaml +++ b/tools/crd-ref-docs/config.yaml @@ -17,6 +17,6 @@ render: - name: SecretObjectReference package: sigs.k8s.io/gateway-api/apis/v1 link: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference - - name: PolicyTargetReferenceWithSectionName + - name: LocalPolicyTargetReferenceWithSectionName package: sigs.k8s.io/gateway-api/apis/v1alpha2 - link: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName + link: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName diff --git a/tools/linter/yamllint/.yamllint b/tools/linter/yamllint/.yamllint index 9bafddf18f0..06a6494f56e 100644 --- a/tools/linter/yamllint/.yamllint +++ b/tools/linter/yamllint/.yamllint @@ -6,6 +6,7 @@ ignore: | # after running `make generate-manifests` which creates # the Install YAML in bin/ charts/gateway-helm/ + bin/install.yaml rules: braces: diff --git a/tools/make/lint.mk b/tools/make/lint.mk index f68bc85ea10..74a161b5819 100644 --- a/tools/make/lint.mk +++ b/tools/make/lint.mk @@ -20,7 +20,7 @@ lint: lint.golint lint-deps: $(tools/golangci-lint) lint.golint: $(tools/golangci-lint) @$(LOG_TARGET) - $(tools/golangci-lint) run $(GOLANGCI_LINT_FLAGS) --build-tags=e2e,celvalidation --config=tools/linter/golangci-lint/.golangci.yml + $(tools/golangci-lint) run $(GOLANGCI_LINT_FLAGS) --build-tags=e2e,celvalidation,conformance,experimental --config=tools/linter/golangci-lint/.golangci.yml .PHONY: lint.yamllint lint: lint.yamllint From bdaeefe51ed9d954482e6e14dc0b2904a1325be8 Mon Sep 17 00:00:00 2001 From: sh2 Date: Wed, 8 May 2024 11:15:25 +0800 Subject: [PATCH 12/17] refactor: separate conditions computing for listeners and routes into status pkg (#2951) * separate conditions computing for listeners and routes into status pkg Signed-off-by: shawnh2 * simplify conditions computing Signed-off-by: shawnh2 * organize status pkg to make it more logical Signed-off-by: shawnh2 * fix license-check Signed-off-by: shawnh2 * move status updater into k8s provider Signed-off-by: shawnh2 * move status into gatewayapi/status Signed-off-by: shawnh2 --------- Signed-off-by: shawnh2 Co-authored-by: zirain --- internal/cmd/egctl/translate.go | 11 +- internal/gatewayapi/backendtlspolicy.go | 2 +- internal/gatewayapi/backendtrafficpolicy.go | 2 +- internal/gatewayapi/clienttrafficpolicy.go | 2 +- internal/gatewayapi/contexts.go | 66 ------- internal/gatewayapi/contexts_test.go | 5 +- internal/gatewayapi/envoyextensionpolicy.go | 2 +- internal/gatewayapi/envoypatchpolicy.go | 2 +- internal/gatewayapi/filters.go | 140 ++++++++++++--- internal/gatewayapi/listener.go | 4 +- internal/gatewayapi/route.go | 137 +++++++++++--- internal/gatewayapi/securitypolicy.go | 2 +- internal/gatewayapi/status/conditions.go | 91 ++++++++++ .../status/conditions_test.go | 157 ---------------- .../status/envoypatchpolicy.go | 0 internal/{ => gatewayapi}/status/gateway.go | 56 ++++++ .../{ => gatewayapi}/status/gateway_test.go | 101 +++++++++++ internal/gatewayapi/status/gatewayclass.go | 63 +++++++ .../gatewayapi/status/gatewayclass_test.go | 68 +++++++ internal/{ => gatewayapi}/status/policy.go | 0 internal/gatewayapi/status/route.go | 28 +++ internal/gatewayapi/validate.go | 130 ++++++++++---- internal/provider/kubernetes/controller.go | 6 +- internal/provider/kubernetes/kubernetes.go | 3 +- internal/provider/kubernetes/status.go | 54 +++--- .../kubernetes/status_updater.go} | 10 +- internal/status/conditions.go | 167 ------------------ internal/status/gatewayclass.go | 25 --- internal/xds/translator/jsonpatch.go | 2 +- 29 files changed, 772 insertions(+), 564 deletions(-) create mode 100644 internal/gatewayapi/status/conditions.go rename internal/{ => gatewayapi}/status/conditions_test.go (58%) rename internal/{ => gatewayapi}/status/envoypatchpolicy.go (100%) rename internal/{ => gatewayapi}/status/gateway.go (55%) rename internal/{ => gatewayapi}/status/gateway_test.go (54%) create mode 100644 internal/gatewayapi/status/gatewayclass.go create mode 100644 internal/gatewayapi/status/gatewayclass_test.go rename internal/{ => gatewayapi}/status/policy.go (100%) create mode 100644 internal/gatewayapi/status/route.go rename internal/{status/status.go => provider/kubernetes/status_updater.go} (95%) delete mode 100644 internal/status/conditions.go delete mode 100644 internal/status/gatewayclass.go diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go index 9c787d04a20..fe2fef48eba 100644 --- a/internal/cmd/egctl/translate.go +++ b/internal/cmd/egctl/translate.go @@ -15,29 +15,28 @@ import ( "sort" "strings" + adminv3 "github.com/envoyproxy/go-control-plane/envoy/admin/v3" + bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3" + resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3" "github.com/spf13/cobra" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - "sigs.k8s.io/yaml" - - adminv3 "github.com/envoyproxy/go-control-plane/envoy/admin/v3" - bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3" - resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/sets" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + "sigs.k8s.io/yaml" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/api/v1alpha1/validation" "github.com/envoyproxy/gateway/internal/envoygateway" "github.com/envoyproxy/gateway/internal/envoygateway/config" "github.com/envoyproxy/gateway/internal/gatewayapi" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/xds/bootstrap" "github.com/envoyproxy/gateway/internal/xds/translator" xds_types "github.com/envoyproxy/gateway/internal/xds/types" diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go index e29a6a968d9..e9dd8d9ac72 100644 --- a/internal/gatewayapi/backendtlspolicy.go +++ b/internal/gatewayapi/backendtlspolicy.go @@ -14,8 +14,8 @@ import ( gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" ) func (t *Translator) processBackendTLSPolicy( diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 4c83277f9a1..37d61a2a41d 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -21,8 +21,8 @@ import ( gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/utils" "github.com/envoyproxy/gateway/internal/utils/regex" ) diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 3f38ddc597c..8cc054dee71 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -20,8 +20,8 @@ import ( gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/utils" ) diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go index a61814bd232..28e0affa217 100644 --- a/internal/gatewayapi/contexts.go +++ b/internal/gatewayapi/contexts.go @@ -7,7 +7,6 @@ package gatewayapi import ( "reflect" - "time" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -54,38 +53,6 @@ type ListenerContext struct { tlsSecrets []*v1.Secret } -func (l *ListenerContext) SetCondition(conditionType gwapiv1.ListenerConditionType, status metav1.ConditionStatus, reason gwapiv1.ListenerConditionReason, message string) { - cond := metav1.Condition{ - Type: string(conditionType), - Status: status, - Reason: string(reason), - Message: message, - ObservedGeneration: l.gateway.Generation, - LastTransitionTime: metav1.NewTime(time.Now()), - } - - idx := -1 - for i, existing := range l.gateway.Status.Listeners[l.listenerStatusIdx].Conditions { - if existing.Type == cond.Type { - // return early if the condition is unchanged - if existing.Status == cond.Status && - existing.Reason == cond.Reason && - existing.Message == cond.Message && - existing.ObservedGeneration == cond.ObservedGeneration { - return - } - idx = i - break - } - } - - if idx > -1 { - l.gateway.Status.Listeners[l.listenerStatusIdx].Conditions[idx] = cond - } else { - l.gateway.Status.Listeners[l.listenerStatusIdx].Conditions = append(l.gateway.Status.Listeners[l.listenerStatusIdx].Conditions, cond) - } -} - func (l *ListenerContext) SetSupportedKinds(kinds ...gwapiv1.RouteGroupKind) { l.gateway.Status.Listeners[l.listenerStatusIdx].SupportedKinds = kinds } @@ -368,39 +335,6 @@ func (r *RouteParentContext) SetListeners(listeners ...*ListenerContext) { r.listeners = append(r.listeners, listeners...) } -func (r *RouteParentContext) SetCondition(route RouteContext, conditionType gwapiv1.RouteConditionType, status metav1.ConditionStatus, reason gwapiv1.RouteConditionReason, message string) { - cond := metav1.Condition{ - Type: string(conditionType), - Status: status, - Reason: string(reason), - Message: message, - ObservedGeneration: route.GetGeneration(), - LastTransitionTime: metav1.NewTime(time.Now()), - } - - idx := -1 - routeStatus := GetRouteStatus(route) - for i, existing := range routeStatus.Parents[r.routeParentStatusIdx].Conditions { - if existing.Type == cond.Type { - // return early if the condition is unchanged - if existing.Status == cond.Status && - existing.Reason == cond.Reason && - existing.Message == cond.Message && - existing.ObservedGeneration == cond.ObservedGeneration { - return - } - idx = i - break - } - } - - if idx > -1 { - routeStatus.Parents[r.routeParentStatusIdx].Conditions[idx] = cond - } else { - routeStatus.Parents[r.routeParentStatusIdx].Conditions = append(routeStatus.Parents[r.routeParentStatusIdx].Conditions, cond) - } -} - func (r *RouteParentContext) ResetConditions(route RouteContext) { routeStatus := GetRouteStatus(route) routeStatus.Parents[r.routeParentStatusIdx].Conditions = make([]metav1.Condition, 0) diff --git a/internal/gatewayapi/contexts_test.go b/internal/gatewayapi/contexts_test.go index 5c016f8b40b..ee17cec5fcd 100644 --- a/internal/gatewayapi/contexts_test.go +++ b/internal/gatewayapi/contexts_test.go @@ -11,6 +11,8 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + + "github.com/envoyproxy/gateway/internal/gatewayapi/status" ) func TestContexts(t *testing.T) { @@ -37,7 +39,8 @@ func TestContexts(t *testing.T) { lctx := gctx.listeners[0] require.NotNil(t, lctx) - lctx.SetCondition(gwapiv1.ListenerConditionAccepted, metav1.ConditionFalse, gwapiv1.ListenerReasonUnsupportedProtocol, "HTTPS protocol is not supported yet") + status.SetGatewayListenerStatusCondition(lctx.gateway, lctx.listenerStatusIdx, + gwapiv1.ListenerConditionAccepted, metav1.ConditionFalse, gwapiv1.ListenerReasonUnsupportedProtocol, "HTTPS protocol is not supported yet") require.Len(t, gateway.Status.Listeners, 1) require.EqualValues(t, "http", gateway.Status.Listeners[0].Name) diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index 21c32b47773..905919ea852 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -19,8 +19,8 @@ import ( gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/utils" ) diff --git a/internal/gatewayapi/envoypatchpolicy.go b/internal/gatewayapi/envoypatchpolicy.go index 517deb85a77..c2533b18a76 100644 --- a/internal/gatewayapi/envoypatchpolicy.go +++ b/internal/gatewayapi/envoypatchpolicy.go @@ -14,8 +14,8 @@ import ( gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" ) func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.EnvoyPatchPolicy, xdsIR XdsIRMap) { diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go index 29d9914d2c7..476d821e721 100644 --- a/internal/gatewayapi/filters.go +++ b/internal/gatewayapi/filters.go @@ -12,6 +12,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" ) @@ -148,7 +149,10 @@ func (t *Translator) processURLRewriteFilter( filterContext *HTTPFiltersContext, ) { if filterContext.URLRewrite != nil { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -165,7 +169,10 @@ func (t *Translator) processURLRewriteFilter( if rewrite.Hostname != nil { if err := t.validateHostname(string(*rewrite.Hostname)); err != nil { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -182,7 +189,10 @@ func (t *Translator) processURLRewriteFilter( case gwapiv1.FullPathHTTPPathModifier: if rewrite.Path.ReplacePrefixMatch != nil { errMsg := "ReplacePrefixMatch cannot be set when rewrite path type is \"ReplaceFullPath\"" - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -192,7 +202,10 @@ func (t *Translator) processURLRewriteFilter( } if rewrite.Path.ReplaceFullPath == nil { errMsg := "ReplaceFullPath must be set when rewrite path type is \"ReplaceFullPath\"" - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -208,7 +221,10 @@ func (t *Translator) processURLRewriteFilter( case gwapiv1.PrefixMatchHTTPPathModifier: if rewrite.Path.ReplaceFullPath != nil { errMsg := "ReplaceFullPath cannot be set when rewrite path type is \"ReplacePrefixMatch\"" - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -218,7 +234,10 @@ func (t *Translator) processURLRewriteFilter( } if rewrite.Path.ReplacePrefixMatch == nil { errMsg := "ReplacePrefixMatch must be set when rewrite path type is \"ReplacePrefixMatch\"" - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -233,7 +252,10 @@ func (t *Translator) processURLRewriteFilter( } default: errMsg := fmt.Sprintf("Rewrite path type: %s is invalid, only \"ReplaceFullPath\" and \"ReplacePrefixMatch\" are supported", rewrite.Path.Type) - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -252,7 +274,10 @@ func (t *Translator) processRedirectFilter( ) { // Can't have two redirects for the same route if filterContext.RedirectResponse != nil { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -273,7 +298,10 @@ func (t *Translator) processRedirectFilter( redir.Scheme = redirect.Scheme } else { errMsg := fmt.Sprintf("Scheme: %s is unsupported, only 'https' and 'http' are supported", *redirect.Scheme) - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -285,7 +313,10 @@ func (t *Translator) processRedirectFilter( if redirect.Hostname != nil { if err := t.validateHostname(string(*redirect.Hostname)); err != nil { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -313,7 +344,10 @@ func (t *Translator) processRedirectFilter( } default: errMsg := fmt.Sprintf("Redirect path type: %s is invalid, only \"ReplaceFullPath\" and \"ReplacePrefixMatch\" are supported", redirect.Path.Type) - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -330,7 +364,10 @@ func (t *Translator) processRedirectFilter( redir.StatusCode = &redirectCode } else { errMsg := fmt.Sprintf("Status code %d is invalid, only 302 and 301 are supported", redirectCode) - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -366,7 +403,10 @@ func (t *Translator) processRequestHeaderModifierFilter( for _, addHeader := range headersToAdd { emptyFilterConfig = false if addHeader.Name == "" { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -377,7 +417,10 @@ func (t *Translator) processRequestHeaderModifierFilter( } // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names if strings.Contains(string(addHeader.Name), "/") || strings.Contains(string(addHeader.Name), ":") { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -417,7 +460,10 @@ func (t *Translator) processRequestHeaderModifierFilter( for _, setHeader := range headersToSet { if setHeader.Name == "" { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -427,7 +473,10 @@ func (t *Translator) processRequestHeaderModifierFilter( } // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names if strings.Contains(string(setHeader.Name), "/") || strings.Contains(string(setHeader.Name), ":") { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -467,7 +516,10 @@ func (t *Translator) processRequestHeaderModifierFilter( } for _, removedHeader := range headersToRemove { if removedHeader == "" { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -493,7 +545,10 @@ func (t *Translator) processRequestHeaderModifierFilter( // Update the status if the filter failed to configure any valid headers to add/remove if len(filterContext.AddRequestHeaders) == 0 && len(filterContext.RemoveRequestHeaders) == 0 && !emptyFilterConfig { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -520,7 +575,10 @@ func (t *Translator) processResponseHeaderModifierFilter( for _, addHeader := range headersToAdd { emptyFilterConfig = false if addHeader.Name == "" { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -531,7 +589,10 @@ func (t *Translator) processResponseHeaderModifierFilter( } // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names if strings.Contains(string(addHeader.Name), "/") || strings.Contains(string(addHeader.Name), ":") { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -571,7 +632,10 @@ func (t *Translator) processResponseHeaderModifierFilter( for _, setHeader := range headersToSet { if setHeader.Name == "" { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -581,7 +645,10 @@ func (t *Translator) processResponseHeaderModifierFilter( } // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names if strings.Contains(string(setHeader.Name), "/") || strings.Contains(string(setHeader.Name), ":") { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -621,7 +688,10 @@ func (t *Translator) processResponseHeaderModifierFilter( } for _, removedHeader := range headersToRemove { if removedHeader == "" { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -648,7 +718,10 @@ func (t *Translator) processResponseHeaderModifierFilter( // Update the status if the filter failed to configure any valid headers to add/remove if len(filterContext.AddResponseHeaders) == 0 && len(filterContext.RemoveResponseHeaders) == 0 && !emptyFilterConfig { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -734,13 +807,18 @@ func (t *Translator) processRequestMirrorFilter( } func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *HTTPFiltersContext) { - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.RouteReasonBackendNotFound, errMsg, ) - filterContext.ParentRef.SetCondition(filterContext.Route, + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -754,7 +832,10 @@ func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *H func (t *Translator) processUnsupportedHTTPFilter(filterType string, filterContext *HTTPFiltersContext) { errMsg := fmt.Sprintf("Unsupported filter type: %s", filterType) - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -768,7 +849,10 @@ func (t *Translator) processUnsupportedHTTPFilter(filterType string, filterConte func (t *Translator) processInvalidHTTPFilter(filterType string, filterContext *HTTPFiltersContext, err error) { errMsg := fmt.Sprintf("Invalid filter %s: %v", filterType, err) - filterContext.ParentRef.SetCondition(filterContext.Route, + routeStatus := GetRouteStatus(filterContext.Route) + status.SetRouteStatusCondition(routeStatus, + filterContext.ParentRef.routeParentStatusIdx, + filterContext.Route.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index a5ca14da600..5a54968202d 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -12,6 +12,7 @@ import ( gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/utils" "github.com/envoyproxy/gateway/internal/utils/naming" @@ -68,7 +69,8 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap case gwapiv1.UDPProtocolType: t.validateAllowedRoutes(listener, KindUDPRoute) default: - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionAccepted, metav1.ConditionFalse, gwapiv1.ListenerReasonUnsupportedProtocol, diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index 5eacf84d4b1..a2a874e08b1 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -19,8 +19,8 @@ import ( gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/utils/regex" ) @@ -108,7 +108,10 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res // not on the Route as a whole. routeRoutes, err := t.processHTTPRouteRules(httpRoute, parentRef, resources) if err != nil { - parentRef.SetCondition(httpRoute, + routeStatus := GetRouteStatus(httpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + httpRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, // TODO: better reason @@ -119,7 +122,10 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res // If no negative condition has been set for ResolvedRefs, set "ResolvedRefs=True" if !parentRef.HasCondition(httpRoute, gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse) { - parentRef.SetCondition(httpRoute, + routeStatus := GetRouteStatus(httpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + httpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.RouteReasonResolvedRefs, @@ -134,7 +140,10 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res hasHostnameIntersection := t.processHTTPRouteParentRefListener(httpRoute, routeRoutes, parentRef, xdsIR) if !hasHostnameIntersection { - parentRef.SetCondition(httpRoute, + routeStatus := GetRouteStatus(httpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + httpRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonNoMatchingListenerHostname, @@ -145,7 +154,10 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res // If no negative conditions have been set, the route is considered "Accepted=True". if parentRef.HTTPRoute != nil && len(parentRef.HTTPRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 { - parentRef.SetCondition(httpRoute, + routeStatus := GetRouteStatus(httpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + httpRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionTrue, gwapiv1.RouteReasonAccepted, @@ -201,7 +213,10 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe // TODO: support mixed endpointslice address type between backendRefs if !t.EndpointRoutingDisabled && len(dstAddrTypeMap) > 1 { - parentRef.SetCondition(httpRoute, + routeStatus := GetRouteStatus(httpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + httpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1a2.RouteReasonResolvedRefs, @@ -401,7 +416,10 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res // not on the Route as a whole. routeRoutes, err := t.processGRPCRouteRules(grpcRoute, parentRef, resources) if err != nil { - parentRef.SetCondition(grpcRoute, + routeStatus := GetRouteStatus(grpcRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + grpcRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, // TODO: better reason @@ -412,7 +430,10 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res // If no negative condition has been set for ResolvedRefs, set "ResolvedRefs=True" if !parentRef.HasCondition(grpcRoute, gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse) { - parentRef.SetCondition(grpcRoute, + routeStatus := GetRouteStatus(grpcRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + grpcRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.RouteReasonResolvedRefs, @@ -425,7 +446,10 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res } hasHostnameIntersection := t.processHTTPRouteParentRefListener(grpcRoute, routeRoutes, parentRef, xdsIR) if !hasHostnameIntersection { - parentRef.SetCondition(grpcRoute, + routeStatus := GetRouteStatus(grpcRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + grpcRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonNoMatchingListenerHostname, @@ -436,7 +460,10 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res // If no negative conditions have been set, the route is considered "Accepted=True". if parentRef.GRPCRoute != nil && len(parentRef.GRPCRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 { - parentRef.SetCondition(grpcRoute, + routeStatus := GetRouteStatus(grpcRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + grpcRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionTrue, gwapiv1.RouteReasonAccepted, @@ -734,7 +761,10 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour // If no negative condition has been set for ResolvedRefs, set "ResolvedRefs=True" if !parentRef.HasCondition(tlsRoute, gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse) { - parentRef.SetCondition(tlsRoute, + routeStatus := GetRouteStatus(tlsRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tlsRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.RouteReasonResolvedRefs, @@ -777,7 +807,10 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour } if !hasHostnameIntersection { - parentRef.SetCondition(tlsRoute, + routeStatus := GetRouteStatus(tlsRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tlsRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonNoMatchingListenerHostname, @@ -788,7 +821,10 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour // If no negative conditions have been set, the route is considered "Accepted=True". if parentRef.TLSRoute != nil && len(parentRef.TLSRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 { - parentRef.SetCondition(tlsRoute, + routeStatus := GetRouteStatus(tlsRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tlsRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionTrue, gwapiv1.RouteReasonAccepted, @@ -837,7 +873,10 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour // compute backends if len(udpRoute.Spec.Rules) != 1 { - parentRef.SetCondition(udpRoute, + routeStatus := GetRouteStatus(udpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + udpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "InvalidRule", @@ -846,7 +885,10 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour continue } if len(udpRoute.Spec.Rules[0].BackendRefs) != 1 { - parentRef.SetCondition(udpRoute, + routeStatus := GetRouteStatus(udpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + udpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "InvalidBackend", @@ -865,7 +907,10 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour destSettings = append(destSettings, ds) // If no negative condition has been set for ResolvedRefs, set "ResolvedRefs=True" if !parentRef.HasCondition(udpRoute, gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse) { - parentRef.SetCondition(udpRoute, + routeStatus := GetRouteStatus(udpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + udpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.RouteReasonResolvedRefs, @@ -911,7 +956,10 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour // If no negative conditions have been set, the route is considered "Accepted=True". if accepted && parentRef.UDPRoute != nil && len(parentRef.UDPRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 { - parentRef.SetCondition(udpRoute, + routeStatus := GetRouteStatus(udpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + udpRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionTrue, gwapiv1.RouteReasonAccepted, @@ -920,7 +968,10 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour } if !accepted { - parentRef.SetCondition(udpRoute, + routeStatus := GetRouteStatus(udpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + udpRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -970,7 +1021,10 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour // compute backends if len(tcpRoute.Spec.Rules) != 1 { - parentRef.SetCondition(tcpRoute, + routeStatus := GetRouteStatus(tcpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tcpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "InvalidRule", @@ -979,7 +1033,10 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour continue } if len(tcpRoute.Spec.Rules[0].BackendRefs) != 1 { - parentRef.SetCondition(tcpRoute, + routeStatus := GetRouteStatus(tcpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tcpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "InvalidBackend", @@ -997,7 +1054,10 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour destSettings = append(destSettings, ds) // If no negative condition has been set for ResolvedRefs, set "ResolvedRefs=True" if !parentRef.HasCondition(tcpRoute, gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse) { - parentRef.SetCondition(tcpRoute, + routeStatus := GetRouteStatus(tcpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tcpRoute.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.RouteReasonResolvedRefs, @@ -1042,7 +1102,10 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour // If no negative conditions have been set, the route is considered "Accepted=True". if accepted && parentRef.TCPRoute != nil && len(parentRef.TCPRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 { - parentRef.SetCondition(tcpRoute, + routeStatus := GetRouteStatus(tcpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tcpRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionTrue, gwapiv1.RouteReasonAccepted, @@ -1050,7 +1113,10 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour ) } if !accepted { - parentRef.SetCondition(tcpRoute, + routeStatus := GetRouteStatus(tcpRoute) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + tcpRoute.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonUnsupportedValue, @@ -1159,7 +1225,10 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext, // TODO: support mixed endpointslice address type for the same backendRef if !t.EndpointRoutingDisabled && addrType != nil && *addrType == ir.MIXED { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1a2.RouteReasonResolvedRefs, @@ -1212,7 +1281,10 @@ func (t *Translator) processAllowedListenersForParentRefs(routeContext RouteCont parentRefCtx.ResetConditions(routeContext) if len(selectedListeners) == 0 { - parentRefCtx.SetCondition(routeContext, + routeStatus := GetRouteStatus(routeContext) + status.SetRouteStatusCondition(routeStatus, + parentRefCtx.routeParentStatusIdx, + routeContext.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonNoMatchingParent, @@ -1231,7 +1303,10 @@ func (t *Translator) processAllowedListenersForParentRefs(routeContext RouteCont } if len(allowedListeners) == 0 { - parentRefCtx.SetCondition(routeContext, + routeStatus := GetRouteStatus(routeContext) + status.SetRouteStatusCondition(routeStatus, + parentRefCtx.routeParentStatusIdx, + routeContext.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, gwapiv1.RouteReasonNotAllowedByListeners, @@ -1251,7 +1326,10 @@ func (t *Translator) processAllowedListenersForParentRefs(routeContext RouteCont } if !HasReadyListener(selectedListeners) { - parentRefCtx.SetCondition(routeContext, + routeStatus := GetRouteStatus(routeContext) + status.SetRouteStatusCondition(routeStatus, + parentRefCtx.routeParentStatusIdx, + routeContext.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionFalse, "NoReadyListeners", @@ -1262,7 +1340,10 @@ func (t *Translator) processAllowedListenersForParentRefs(routeContext RouteCont parentRefCtx.SetListeners(allowedListeners...) - parentRefCtx.SetCondition(routeContext, + routeStatus := GetRouteStatus(routeContext) + status.SetRouteStatusCondition(routeStatus, + parentRefCtx.routeParentStatusIdx, + routeContext.GetGeneration(), gwapiv1.RouteConditionAccepted, metav1.ConditionTrue, gwapiv1.RouteReasonAccepted, diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index cb6a63dc4d4..c7862d3ccb0 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -25,8 +25,8 @@ import ( gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/utils" ) diff --git a/internal/gatewayapi/status/conditions.go b/internal/gatewayapi/status/conditions.go new file mode 100644 index 00000000000..f2e735307d4 --- /dev/null +++ b/internal/gatewayapi/status/conditions.go @@ -0,0 +1,91 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +// This file contains code derived from Contour, +// https://github.com/projectcontour/contour +// from the source file +// https://github.com/projectcontour/contour/blob/main/internal/status/gatewayclassconditions.go +// and is provided here subject to the following: +// Copyright Project Contour Authors +// SPDX-License-Identifier: Apache-2.0 + +package status + +import ( + "time" + "unicode" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// MergeConditions adds or updates matching conditions, and updates the transition +// time if details of a condition have changed. Returns the updated condition array. +func MergeConditions(conditions []metav1.Condition, updates ...metav1.Condition) []metav1.Condition { + var additions []metav1.Condition + for i, update := range updates { + add := true + for j, cond := range conditions { + if cond.Type == update.Type { + add = false + if conditionChanged(cond, update) { + conditions[j].Status = update.Status + conditions[j].Reason = update.Reason + conditions[j].Message = update.Message + conditions[j].ObservedGeneration = update.ObservedGeneration + conditions[j].LastTransitionTime = update.LastTransitionTime + break + } + } + } + if add { + additions = append(additions, updates[i]) + } + } + conditions = append(conditions, additions...) + return conditions +} + +func newCondition(t string, status metav1.ConditionStatus, reason, msg string, lt time.Time, og int64) metav1.Condition { + return metav1.Condition{ + Type: t, + Status: status, + Reason: reason, + Message: msg, + LastTransitionTime: metav1.NewTime(lt), + ObservedGeneration: og, + } +} + +func conditionChanged(a, b metav1.Condition) bool { + opts := cmpopts.IgnoreFields(metav1.Condition{}, "Type", "LastTransitionTime") + return !cmp.Equal(a, b, opts) +} + +// Error2ConditionMsg format the error string to a Status condition message. +// * Convert the first letter to capital +// * Append "." to the string if it doesn't exit +func Error2ConditionMsg(err error) string { + if err == nil { + return "" + } + + message := err.Error() + if message == "" { + return message + } + + // Convert the string to a rune slice for easier manipulation + runes := []rune(message) + + // Check if the first rune is a letter and convert it to uppercase + if unicode.IsLetter(runes[0]) { + runes[0] = unicode.ToUpper(runes[0]) + } + + // Convert the rune slice back to a string + return string(runes) +} diff --git a/internal/status/conditions_test.go b/internal/gatewayapi/status/conditions_test.go similarity index 58% rename from internal/status/conditions_test.go rename to internal/gatewayapi/status/conditions_test.go index a1181b89b98..066dcabd23f 100644 --- a/internal/status/conditions_test.go +++ b/internal/gatewayapi/status/conditions_test.go @@ -19,109 +19,14 @@ import ( "time" "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilclock "k8s.io/utils/clock" fakeclock "k8s.io/utils/clock/testing" - "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) var clock utilclock.Clock = utilclock.RealClock{} -func TestComputeGatewayClassAcceptedCondition(t *testing.T) { - testCases := []struct { - name string - accepted bool - expect metav1.Condition - }{ - { - name: "accepted gatewayclass", - accepted: true, - expect: metav1.Condition{ - Type: string(gwapiv1.GatewayClassConditionStatusAccepted), - Status: metav1.ConditionTrue, - Reason: string(gwapiv1.GatewayClassReasonAccepted), - Message: MsgValidGatewayClass, - }, - }, - { - name: "not accepted gatewayclass", - accepted: false, - expect: metav1.Condition{ - Type: string(gwapiv1.GatewayClassConditionStatusAccepted), - Status: metav1.ConditionFalse, - Reason: string(ReasonOlderGatewayClassExists), - Message: MsgOlderGatewayClassExists, - }, - }, - { - name: "invalid parameters gatewayclass", - accepted: false, - expect: metav1.Condition{ - Type: string(gwapiv1.GatewayClassConditionStatusAccepted), - Status: metav1.ConditionFalse, - Reason: string(gwapiv1.GatewayClassReasonInvalidParameters), - Message: MsgGatewayClassInvalidParams, - }, - }, - } - - for _, tc := range testCases { - gc := &gwapiv1.GatewayClass{ - ObjectMeta: metav1.ObjectMeta{ - Generation: 7, - }, - } - - got := computeGatewayClassAcceptedCondition(gc, tc.accepted, tc.expect.Reason, tc.expect.Message) - - assert.Equal(t, tc.expect.Type, got.Type) - assert.Equal(t, tc.expect.Status, got.Status) - assert.Equal(t, tc.expect.Reason, got.Reason) - assert.Equal(t, gc.Generation, got.ObservedGeneration) - } -} - -func TestComputeGatewayScheduledCondition(t *testing.T) { - testCases := []struct { - name string - sched bool - expect metav1.Condition - }{ - { - name: "scheduled gateway", - sched: true, - expect: metav1.Condition{ - Type: string(gwapiv1.GatewayReasonAccepted), - Status: metav1.ConditionTrue, - }, - }, - { - name: "not scheduled gateway", - sched: false, - expect: metav1.Condition{ - Type: string(gwapiv1.GatewayReasonAccepted), - Status: metav1.ConditionFalse, - }, - }, - } - - for _, tc := range testCases { - gw := &gwapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "test", - Name: "test", - }, - } - - got := computeGatewayAcceptedCondition(gw, tc.sched) - - assert.Equal(t, tc.expect.Type, got.Type) - assert.Equal(t, tc.expect.Status, got.Status) - } -} - func TestConditionChanged(t *testing.T) { testCases := []struct { name string @@ -280,68 +185,6 @@ func TestMergeConditions(t *testing.T) { } } -func TestGatewayReadyCondition(t *testing.T) { - testCases := []struct { - name string - serviceAddress bool - deploymentStatus appsv1.DeploymentStatus - expect metav1.Condition - }{ - { - name: "ready gateway", - serviceAddress: true, - deploymentStatus: appsv1.DeploymentStatus{AvailableReplicas: 1}, - expect: metav1.Condition{ - Status: metav1.ConditionTrue, - Reason: string(gwapiv1.GatewayConditionProgrammed), - }, - }, - { - name: "not ready gateway without address", - serviceAddress: false, - deploymentStatus: appsv1.DeploymentStatus{AvailableReplicas: 1}, - expect: metav1.Condition{ - Status: metav1.ConditionFalse, - Reason: string(gwapiv1.GatewayReasonAddressNotAssigned), - }, - }, - { - name: "not ready gateway with address unavailable pods", - serviceAddress: true, - deploymentStatus: appsv1.DeploymentStatus{AvailableReplicas: 0}, - expect: metav1.Condition{ - Status: metav1.ConditionFalse, - Reason: string(gwapiv1.GatewayReasonNoResources), - }, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - gtw := &gwapiv1.Gateway{} - if tc.serviceAddress { - gtw.Status = gwapiv1.GatewayStatus{ - Addresses: []gwapiv1.GatewayStatusAddress{ - { - Type: ptr.To(gwapiv1.IPAddressType), - Value: "1.1.1.1", - }, - }, - } - } - - deployment := &appsv1.Deployment{Status: tc.deploymentStatus} - got := computeGatewayProgrammedCondition(gtw, deployment) - - assert.Equal(t, string(gwapiv1.GatewayConditionProgrammed), got.Type) - assert.Equal(t, tc.expect.Status, got.Status) - assert.Equal(t, tc.expect.Reason, got.Reason) - }) - } -} - func TestError2ConditionMsg(t *testing.T) { testCases := []struct { name string diff --git a/internal/status/envoypatchpolicy.go b/internal/gatewayapi/status/envoypatchpolicy.go similarity index 100% rename from internal/status/envoypatchpolicy.go rename to internal/gatewayapi/status/envoypatchpolicy.go diff --git a/internal/status/gateway.go b/internal/gatewayapi/status/gateway.go similarity index 55% rename from internal/status/gateway.go rename to internal/gatewayapi/status/gateway.go index b62dffe66d4..5744824bbe4 100644 --- a/internal/status/gateway.go +++ b/internal/gatewayapi/status/gateway.go @@ -6,8 +6,12 @@ package status import ( + "fmt" + "time" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) @@ -89,3 +93,55 @@ func UpdateGatewayStatusProgrammedCondition(gw *gwapiv1.Gateway, svc *corev1.Ser // Update the programmed condition. gw.Status.Conditions = MergeConditions(gw.Status.Conditions, computeGatewayProgrammedCondition(gw, deployment)) } + +func SetGatewayListenerStatusCondition(gateway *gwapiv1.Gateway, listenerStatusIdx int, + conditionType gwapiv1.ListenerConditionType, status metav1.ConditionStatus, reason gwapiv1.ListenerConditionReason, message string, +) { + cond := metav1.Condition{ + Type: string(conditionType), + Status: status, + Reason: string(reason), + Message: message, + ObservedGeneration: gateway.Generation, + LastTransitionTime: metav1.NewTime(time.Now()), + } + gateway.Status.Listeners[listenerStatusIdx].Conditions = MergeConditions(gateway.Status.Listeners[listenerStatusIdx].Conditions, cond) +} + +// computeGatewayAcceptedCondition computes the Gateway Accepted status condition. +func computeGatewayAcceptedCondition(gw *gwapiv1.Gateway, accepted bool) metav1.Condition { + switch accepted { + case true: + return newCondition(string(gwapiv1.GatewayReasonAccepted), metav1.ConditionTrue, + string(gwapiv1.GatewayReasonAccepted), + "The Gateway has been scheduled by Envoy Gateway", time.Now(), gw.Generation) + default: + return newCondition(string(gwapiv1.GatewayReasonAccepted), metav1.ConditionFalse, + string(gwapiv1.GatewayReasonAccepted), + "The Gateway has not been scheduled by Envoy Gateway", time.Now(), gw.Generation) + } +} + +// computeGatewayProgrammedCondition computes the Gateway Programmed status condition. +// Programmed condition surfaces true when the Envoy Deployment status is ready. +func computeGatewayProgrammedCondition(gw *gwapiv1.Gateway, deployment *appsv1.Deployment) metav1.Condition { + if len(gw.Status.Addresses) == 0 { + return newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionFalse, + string(gwapiv1.GatewayReasonAddressNotAssigned), + "No addresses have been assigned to the Gateway", time.Now(), gw.Generation) + } + + // If there are no available replicas for the Envoy Deployment, don't + // mark the Gateway as ready yet. + + if deployment == nil || deployment.Status.AvailableReplicas == 0 { + return newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionFalse, + string(gwapiv1.GatewayReasonNoResources), + "Deployment replicas unavailable", time.Now(), gw.Generation) + } + + message := fmt.Sprintf("Address assigned to the Gateway, %d/%d envoy Deployment replicas available", + deployment.Status.AvailableReplicas, deployment.Status.Replicas) + return newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionTrue, + string(gwapiv1.GatewayConditionProgrammed), message, time.Now(), gw.Generation) +} diff --git a/internal/status/gateway_test.go b/internal/gatewayapi/status/gateway_test.go similarity index 54% rename from internal/status/gateway_test.go rename to internal/gatewayapi/status/gateway_test.go index c20d29b8ec0..55524349d15 100644 --- a/internal/status/gateway_test.go +++ b/internal/gatewayapi/status/gateway_test.go @@ -126,3 +126,104 @@ func TestUpdateGatewayStatusProgrammedCondition(t *testing.T) { }) } } + +func TestGatewayReadyCondition(t *testing.T) { + testCases := []struct { + name string + serviceAddress bool + deploymentStatus appsv1.DeploymentStatus + expect metav1.Condition + }{ + { + name: "ready gateway", + serviceAddress: true, + deploymentStatus: appsv1.DeploymentStatus{AvailableReplicas: 1}, + expect: metav1.Condition{ + Status: metav1.ConditionTrue, + Reason: string(gwapiv1.GatewayConditionProgrammed), + }, + }, + { + name: "not ready gateway without address", + serviceAddress: false, + deploymentStatus: appsv1.DeploymentStatus{AvailableReplicas: 1}, + expect: metav1.Condition{ + Status: metav1.ConditionFalse, + Reason: string(gwapiv1.GatewayReasonAddressNotAssigned), + }, + }, + { + name: "not ready gateway with address unavailable pods", + serviceAddress: true, + deploymentStatus: appsv1.DeploymentStatus{AvailableReplicas: 0}, + expect: metav1.Condition{ + Status: metav1.ConditionFalse, + Reason: string(gwapiv1.GatewayReasonNoResources), + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + gtw := &gwapiv1.Gateway{} + if tc.serviceAddress { + gtw.Status = gwapiv1.GatewayStatus{ + Addresses: []gwapiv1.GatewayStatusAddress{ + { + Type: ptr.To(gwapiv1.IPAddressType), + Value: "1.1.1.1", + }, + }, + } + } + + deployment := &appsv1.Deployment{Status: tc.deploymentStatus} + got := computeGatewayProgrammedCondition(gtw, deployment) + + assert.Equal(t, string(gwapiv1.GatewayConditionProgrammed), got.Type) + assert.Equal(t, tc.expect.Status, got.Status) + assert.Equal(t, tc.expect.Reason, got.Reason) + }) + } +} + +func TestComputeGatewayScheduledCondition(t *testing.T) { + testCases := []struct { + name string + sched bool + expect metav1.Condition + }{ + { + name: "scheduled gateway", + sched: true, + expect: metav1.Condition{ + Type: string(gwapiv1.GatewayReasonAccepted), + Status: metav1.ConditionTrue, + }, + }, + { + name: "not scheduled gateway", + sched: false, + expect: metav1.Condition{ + Type: string(gwapiv1.GatewayReasonAccepted), + Status: metav1.ConditionFalse, + }, + }, + } + + for _, tc := range testCases { + gw := &gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "test", + }, + } + + got := computeGatewayAcceptedCondition(gw, tc.sched) + + assert.Equal(t, tc.expect.Type, got.Type) + assert.Equal(t, tc.expect.Status, got.Status) + } +} diff --git a/internal/gatewayapi/status/gatewayclass.go b/internal/gatewayapi/status/gatewayclass.go new file mode 100644 index 00000000000..35813c4bc40 --- /dev/null +++ b/internal/gatewayapi/status/gatewayclass.go @@ -0,0 +1,63 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +// This file contains code derived from Contour, +// https://github.com/projectcontour/contour +// from the source file +// https://github.com/projectcontour/contour/blob/main/internal/status/gatewayclass.go +// and is provided here subject to the following: +// Copyright Project Contour Authors +// SPDX-License-Identifier: Apache-2.0 + +package status + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +const ( + ReasonOlderGatewayClassExists gwapiv1.GatewayClassConditionReason = "OlderGatewayClassExists" + + MsgOlderGatewayClassExists = "Invalid GatewayClass: another older GatewayClass with the same Spec.Controller exists" + MsgValidGatewayClass = "Valid GatewayClass" + MsgGatewayClassInvalidParams = "Invalid parametersRef" +) + +// SetGatewayClassAccepted inserts or updates the Accepted condition +// for the provided GatewayClass. +func SetGatewayClassAccepted(gc *gwapiv1.GatewayClass, accepted bool, reason, msg string) *gwapiv1.GatewayClass { + gc.Status.Conditions = MergeConditions(gc.Status.Conditions, computeGatewayClassAcceptedCondition(gc, accepted, reason, msg)) + return gc +} + +// computeGatewayClassAcceptedCondition computes the GatewayClass Accepted status condition. +func computeGatewayClassAcceptedCondition(gatewayClass *gwapiv1.GatewayClass, + accepted bool, + reason, msg string, +) metav1.Condition { + switch accepted { + case true: + return metav1.Condition{ + Type: string(gwapiv1.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionTrue, + Reason: reason, + Message: msg, + ObservedGeneration: gatewayClass.Generation, + LastTransitionTime: metav1.NewTime(time.Now()), + } + default: + return metav1.Condition{ + Type: string(gwapiv1.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionFalse, + Reason: reason, + Message: msg, + ObservedGeneration: gatewayClass.Generation, + LastTransitionTime: metav1.NewTime(time.Now()), + } + } +} diff --git a/internal/gatewayapi/status/gatewayclass_test.go b/internal/gatewayapi/status/gatewayclass_test.go new file mode 100644 index 00000000000..7b845408ecc --- /dev/null +++ b/internal/gatewayapi/status/gatewayclass_test.go @@ -0,0 +1,68 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package status + +import ( + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +func TestComputeGatewayClassAcceptedCondition(t *testing.T) { + testCases := []struct { + name string + accepted bool + expect metav1.Condition + }{ + { + name: "accepted gatewayclass", + accepted: true, + expect: metav1.Condition{ + Type: string(gwapiv1.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionTrue, + Reason: string(gwapiv1.GatewayClassReasonAccepted), + Message: MsgValidGatewayClass, + }, + }, + { + name: "not accepted gatewayclass", + accepted: false, + expect: metav1.Condition{ + Type: string(gwapiv1.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionFalse, + Reason: string(ReasonOlderGatewayClassExists), + Message: MsgOlderGatewayClassExists, + }, + }, + { + name: "invalid parameters gatewayclass", + accepted: false, + expect: metav1.Condition{ + Type: string(gwapiv1.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionFalse, + Reason: string(gwapiv1.GatewayClassReasonInvalidParameters), + Message: MsgGatewayClassInvalidParams, + }, + }, + } + + for _, tc := range testCases { + gc := &gwapiv1.GatewayClass{ + ObjectMeta: metav1.ObjectMeta{ + Generation: 7, + }, + } + + got := computeGatewayClassAcceptedCondition(gc, tc.accepted, tc.expect.Reason, tc.expect.Message) + + assert.Equal(t, tc.expect.Type, got.Type) + assert.Equal(t, tc.expect.Status, got.Status) + assert.Equal(t, tc.expect.Reason, got.Reason) + assert.Equal(t, gc.Generation, got.ObservedGeneration) + } +} diff --git a/internal/status/policy.go b/internal/gatewayapi/status/policy.go similarity index 100% rename from internal/status/policy.go rename to internal/gatewayapi/status/policy.go diff --git a/internal/gatewayapi/status/route.go b/internal/gatewayapi/status/route.go new file mode 100644 index 00000000000..7a5c44b1909 --- /dev/null +++ b/internal/gatewayapi/status/route.go @@ -0,0 +1,28 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package status + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +func SetRouteStatusCondition(route *gwapiv1.RouteStatus, routeParentStatusIdx int, routeGeneration int64, + conditionType gwapiv1.RouteConditionType, status metav1.ConditionStatus, reason gwapiv1.RouteConditionReason, message string, +) { + cond := metav1.Condition{ + Type: string(conditionType), + Status: status, + Reason: string(reason), + Message: message, + ObservedGeneration: routeGeneration, + LastTransitionTime: metav1.NewTime(time.Now()), + } + + route.Parents[routeParentStatusIdx].Conditions = MergeConditions(route.Parents[routeParentStatusIdx].Conditions, cond) +} diff --git a/internal/gatewayapi/validate.go b/internal/gatewayapi/validate.go index 7ab85a01a75..c3407135c96 100644 --- a/internal/gatewayapi/validate.go +++ b/internal/gatewayapi/validate.go @@ -20,6 +20,7 @@ import ( gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" ) func (t *Translator) validateBackendRef(backendRefContext BackendRefContext, parentRef *RouteParentContext, route RouteContext, @@ -62,7 +63,10 @@ func (t *Translator) validateBackendRef(backendRefContext BackendRefContext, par func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool { if backendRef.Group != nil && *backendRef.Group != "" && *backendRef.Group != GroupMultiClusterService { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.RouteReasonInvalidKind, @@ -75,7 +79,10 @@ func (t *Translator) validateBackendRefGroup(backendRef *gwapiv1a2.BackendRef, p func (t *Translator) validateBackendRefKind(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool { if backendRef.Kind != nil && *backendRef.Kind != KindService && *backendRef.Kind != KindServiceImport { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.RouteReasonInvalidKind, @@ -100,7 +107,10 @@ func (t *Translator) validateBackendRefFilters(backendRef BackendRefContext, par } if filtersLen > 0 { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "UnsupportedRefValue", @@ -130,7 +140,10 @@ func (t *Translator) validateBackendNamespace(backendRef *gwapiv1a2.BackendRef, }, resources.ReferenceGrants, ) { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.RouteReasonRefNotPermitted, @@ -144,7 +157,10 @@ func (t *Translator) validateBackendNamespace(backendRef *gwapiv1a2.BackendRef, func (t *Translator) validateBackendPort(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext) bool { if backendRef.Port == nil { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "PortNotSpecified", @@ -160,7 +176,10 @@ func (t *Translator) validateBackendService(backendRef *gwapiv1a2.BackendRef, pa ) bool { service := resources.GetService(serviceNamespace, string(backendRef.Name)) if service == nil { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.RouteReasonBackendNotFound, @@ -182,7 +201,10 @@ func (t *Translator) validateBackendService(backendRef *gwapiv1a2.BackendRef, pa } if !portFound { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "PortNotFound", @@ -199,7 +221,10 @@ func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendR ) bool { serviceImport := resources.GetServiceImport(serviceImportNamespace, string(backendRef.Name)) if serviceImport == nil { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.RouteReasonBackendNotFound, @@ -221,7 +246,10 @@ func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendR } if !portFound { - parentRef.SetCondition(route, + routeStatus := GetRouteStatus(route) + status.SetRouteStatusCondition(routeStatus, + parentRef.routeParentStatusIdx, + route.GetGeneration(), gwapiv1.RouteConditionResolvedRefs, metav1.ConditionFalse, "PortNotFound", @@ -236,11 +264,14 @@ func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendR func (t *Translator) validateListenerConditions(listener *ListenerContext) (isReady bool) { lConditions := listener.GetConditions() if len(lConditions) == 0 { - listener.SetCondition(gwapiv1.ListenerConditionProgrammed, metav1.ConditionTrue, gwapiv1.ListenerReasonProgrammed, + status.SetGatewayListenerStatusCondition(listener.gateway, listener.listenerStatusIdx, + gwapiv1.ListenerConditionProgrammed, metav1.ConditionTrue, gwapiv1.ListenerReasonProgrammed, "Sending translated listener configuration to the data plane") - listener.SetCondition(gwapiv1.ListenerConditionAccepted, metav1.ConditionTrue, gwapiv1.ListenerReasonAccepted, + status.SetGatewayListenerStatusCondition(listener.gateway, listener.listenerStatusIdx, + gwapiv1.ListenerConditionAccepted, metav1.ConditionTrue, gwapiv1.ListenerReasonAccepted, "Listener has been successfully translated") - listener.SetCondition(gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.ListenerReasonResolvedRefs, + status.SetGatewayListenerStatusCondition(listener.gateway, listener.listenerStatusIdx, + gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.ListenerReasonResolvedRefs, "Listener references have been resolved") return true } @@ -259,7 +290,8 @@ func (t *Translator) validateListenerConditions(listener *ListenerContext) (isRe } // set "Programmed: false" if it's not set already. if !hasProgrammedCond { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -268,7 +300,8 @@ func (t *Translator) validateListenerConditions(listener *ListenerContext) (isRe } // set "ResolvedRefs: true" if it's not set already. if !hasRefsCond { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionTrue, gwapiv1.ListenerReasonResolvedRefs, @@ -287,7 +320,8 @@ func (t *Translator) validateAllowedNamespaces(listener *ListenerContext) { listener.AllowedRoutes.Namespaces.From != nil && *listener.AllowedRoutes.Namespaces.From == gwapiv1.NamespacesFromSelector { if listener.AllowedRoutes.Namespaces.Selector == nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -296,7 +330,8 @@ func (t *Translator) validateAllowedNamespaces(listener *ListenerContext) { } else { selector, err := metav1.LabelSelectorAsSelector(listener.AllowedRoutes.Namespaces.Selector) if err != nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -311,7 +346,8 @@ func (t *Translator) validateAllowedNamespaces(listener *ListenerContext) { func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerContext, resources *Resources) []*v1.Secret { if len(listener.TLS.CertificateRefs) == 0 { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -324,7 +360,8 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon for _, certificateRef := range listener.TLS.CertificateRefs { // TODO zhaohuabing: reuse validateSecretRef if certificateRef.Group != nil && string(*certificateRef.Group) != "" { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidCertificateRef, @@ -334,7 +371,8 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon } if certificateRef.Kind != nil && string(*certificateRef.Kind) != KindSecret { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidCertificateRef, @@ -360,7 +398,8 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon }, resources.ReferenceGrants, ) { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonRefNotPermitted, @@ -375,7 +414,8 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon secret := resources.GetSecret(secretNamespace, string(certificateRef.Name)) if secret == nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidCertificateRef, @@ -385,7 +425,8 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon } if secret.Type != v1.SecretTypeTLS { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidCertificateRef, @@ -395,7 +436,8 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon } if len(secret.Data[v1.TLSCertKey]) == 0 || len(secret.Data[v1.TLSPrivateKeyKey]) == 0 { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidCertificateRef, @@ -409,7 +451,8 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon err := validateTLSSecretsData(secrets, listener.Hostname) if err != nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidCertificateRef, @@ -424,7 +467,8 @@ func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resourc switch listener.Protocol { case gwapiv1.HTTPProtocolType, gwapiv1.UDPProtocolType, gwapiv1.TCPProtocolType: if listener.TLS != nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -433,7 +477,8 @@ func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resourc } case gwapiv1.HTTPSProtocolType: if listener.TLS == nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -443,7 +488,8 @@ func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resourc } if listener.TLS.Mode != nil && *listener.TLS.Mode != gwapiv1.TLSModeTerminate { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, "UnsupportedTLSMode", @@ -457,7 +503,8 @@ func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resourc case gwapiv1.TLSProtocolType: if listener.TLS == nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -468,7 +515,8 @@ func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resourc if listener.TLS.Mode != nil && *listener.TLS.Mode == gwapiv1.TLSModePassthrough { if len(listener.TLS.CertificateRefs) > 0 { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -480,7 +528,8 @@ func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resourc if listener.TLS.Mode != nil && *listener.TLS.Mode == gwapiv1.TLSModeTerminate { if len(listener.TLS.CertificateRefs) == 0 { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -497,7 +546,8 @@ func (t *Translator) validateTLSConfiguration(listener *ListenerContext, resourc func (t *Translator) validateHostName(listener *ListenerContext) { if listener.Protocol == gwapiv1.UDPProtocolType || listener.Protocol == gwapiv1.TCPProtocolType { if listener.Hostname != nil { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionProgrammed, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalid, @@ -525,7 +575,8 @@ func (t *Translator) validateAllowedRoutes(listener *ListenerContext, routeKinds // if there is a group it must match `gateway.networking.k8s.io` if kind.Group != nil && string(*kind.Group) != gwapiv1.GroupName { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidRouteKinds, @@ -556,7 +607,8 @@ func (t *Translator) validateAllowedRoutes(listener *ListenerContext, routeKinds } else { printRouteKinds = supportedRouteKinds } - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionResolvedRefs, metav1.ConditionFalse, gwapiv1.ListenerReasonInvalidRouteKinds, @@ -584,7 +636,8 @@ func (t *Translator) validateConflictedMergedListeners(gateways []*GatewayContex } portProtocolHostname := fmt.Sprintf("%s:%s:%d", listener.Protocol, *hostname, listener.Port) if listenerSets.Has(portProtocolHostname) { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionConflicted, metav1.ConditionTrue, gwapiv1.ListenerReasonHostnameConflict, @@ -636,7 +689,8 @@ func (t *Translator) validateConflictedLayer7Listeners(gateways []*GatewayContex for _, info := range portListenerInfo { for _, listener := range info.listeners { if len(info.protocols) > 1 { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionConflicted, metav1.ConditionTrue, gwapiv1.ListenerReasonProtocolConflict, @@ -650,7 +704,8 @@ func (t *Translator) validateConflictedLayer7Listeners(gateways []*GatewayContex } if info.hostnames[hostname] > 1 { - listener.SetCondition( + status.SetGatewayListenerStatusCondition(listener.gateway, + listener.listenerStatusIdx, gwapiv1.ListenerConditionConflicted, metav1.ConditionTrue, gwapiv1.ListenerReasonHostnameConflict, @@ -681,7 +736,8 @@ func (t *Translator) validateConflictedLayer4Listeners(gateways []*GatewayContex for _, info := range portListenerInfo { if len(info.listeners) > 1 { for i := 1; i < len(info.listeners); i++ { - info.listeners[i].SetCondition( + status.SetGatewayListenerStatusCondition(info.listeners[i].gateway, + info.listeners[i].listenerStatusIdx, gwapiv1.ListenerConditionConflicted, metav1.ConditionTrue, gwapiv1.ListenerReasonProtocolConflict, diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index d779fffb9f9..8e23f656ad5 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -37,9 +37,9 @@ import ( "github.com/envoyproxy/gateway/api/v1alpha1/validation" "github.com/envoyproxy/gateway/internal/envoygateway/config" "github.com/envoyproxy/gateway/internal/gatewayapi" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/logging" "github.com/envoyproxy/gateway/internal/message" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/utils" "github.com/envoyproxy/gateway/internal/utils/slice" ) @@ -47,7 +47,7 @@ import ( type gatewayAPIReconciler struct { client client.Client log logging.Logger - statusUpdater status.Updater + statusUpdater Updater classController gwapiv1.GatewayController store *kubernetesProviderStore namespace string @@ -59,7 +59,7 @@ type gatewayAPIReconciler struct { } // newGatewayAPIController -func newGatewayAPIController(mgr manager.Manager, cfg *config.Server, su status.Updater, +func newGatewayAPIController(mgr manager.Manager, cfg *config.Server, su Updater, resources *message.ProviderResources, ) error { ctx := context.Background() diff --git a/internal/provider/kubernetes/kubernetes.go b/internal/provider/kubernetes/kubernetes.go index 668555b6725..df1c0d534b2 100644 --- a/internal/provider/kubernetes/kubernetes.go +++ b/internal/provider/kubernetes/kubernetes.go @@ -22,7 +22,6 @@ import ( "github.com/envoyproxy/gateway/internal/envoygateway" ec "github.com/envoyproxy/gateway/internal/envoygateway/config" "github.com/envoyproxy/gateway/internal/message" - "github.com/envoyproxy/gateway/internal/status" ) // Provider is the scaffolding for the Kubernetes provider. It sets up dependencies @@ -84,7 +83,7 @@ func New(cfg *rest.Config, svr *ec.Server, resources *message.ProviderResources) return nil, fmt.Errorf("failed to create manager: %w", err) } - updateHandler := status.NewUpdateHandler(mgr.GetLogger(), mgr.GetClient()) + updateHandler := NewUpdateHandler(mgr.GetLogger(), mgr.GetClient()) if err := mgr.Add(updateHandler); err != nil { return nil, fmt.Errorf("failed to add status update handler %w", err) } diff --git a/internal/provider/kubernetes/status.go b/internal/provider/kubernetes/status.go index 8fba36cca13..fdd4fe01280 100644 --- a/internal/provider/kubernetes/status.go +++ b/internal/provider/kubernetes/status.go @@ -17,8 +17,8 @@ import ( gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/message" - "github.com/envoyproxy/gateway/internal/status" "github.com/envoyproxy/gateway/internal/utils" ) @@ -62,10 +62,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(gwapiv1.HTTPRoute), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { h, ok := obj.(*gwapiv1.HTTPRoute) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -92,10 +92,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(gwapiv1.GRPCRoute), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { h, ok := obj.(*gwapiv1.GRPCRoute) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -124,10 +124,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(gwapiv1a2.TLSRoute), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*gwapiv1a2.TLSRoute) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -156,10 +156,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(gwapiv1a2.TCPRoute), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*gwapiv1a2.TCPRoute) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -188,10 +188,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(gwapiv1a2.UDPRoute), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*gwapiv1a2.UDPRoute) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -220,10 +220,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(v1alpha1.EnvoyPatchPolicy), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*v1alpha1.EnvoyPatchPolicy) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -252,10 +252,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(v1alpha1.ClientTrafficPolicy), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*v1alpha1.ClientTrafficPolicy) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -284,10 +284,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(v1alpha1.BackendTrafficPolicy), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*v1alpha1.BackendTrafficPolicy) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -316,10 +316,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(v1alpha1.SecurityPolicy), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*v1alpha1.SecurityPolicy) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -346,10 +346,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(gwapiv1a3.BackendTLSPolicy), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*gwapiv1a3.BackendTLSPolicy) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -378,10 +378,10 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } key := update.Key val := update.Value - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(v1alpha1.EnvoyExtensionPolicy), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { t, ok := obj.(*v1alpha1.EnvoyExtensionPolicy) if !ok { err := fmt.Errorf("unsupported object type %T", obj) @@ -426,10 +426,10 @@ func (r *gatewayAPIReconciler) updateStatusForGateway(ctx context.Context, gtw * key := utils.NamespacedName(gtw) // publish status - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: key, Resource: new(gwapiv1.Gateway), - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { g, ok := obj.(*gwapiv1.Gateway) if !ok { panic(fmt.Sprintf("unsupported object type %T", obj)) @@ -451,10 +451,10 @@ func (r *gatewayAPIReconciler) updateStatusForGatewayClass( msg string, ) error { if r.statusUpdater != nil { - r.statusUpdater.Send(status.Update{ + r.statusUpdater.Send(Update{ NamespacedName: types.NamespacedName{Name: gc.Name}, Resource: &gwapiv1.GatewayClass{}, - Mutator: status.MutatorFunc(func(obj client.Object) client.Object { + Mutator: MutatorFunc(func(obj client.Object) client.Object { gc, ok := obj.(*gwapiv1.GatewayClass) if !ok { panic(fmt.Sprintf("unsupported object type %T", obj)) diff --git a/internal/status/status.go b/internal/provider/kubernetes/status_updater.go similarity index 95% rename from internal/status/status.go rename to internal/provider/kubernetes/status_updater.go index 4fce4fd8d6e..1b25cfbf489 100644 --- a/internal/status/status.go +++ b/internal/provider/kubernetes/status_updater.go @@ -3,15 +3,7 @@ // The full text of the Apache license is available in the LICENSE file at // the root of the repo. -// This file contains code derived from Contour, -// https://github.com/projectcontour/contour -// from the source file -// https://github.com/projectcontour/contour/blob/main/internal/k8s/status.go -// and is provided here subject to the following: -// Copyright Project Contour Authors -// SPDX-License-Identifier: Apache-2.0 - -package status +package kubernetes import ( "context" diff --git a/internal/status/conditions.go b/internal/status/conditions.go deleted file mode 100644 index 955dc26a7ab..00000000000 --- a/internal/status/conditions.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright Envoy Gateway Authors -// SPDX-License-Identifier: Apache-2.0 -// The full text of the Apache license is available in the LICENSE file at -// the root of the repo. - -// This file contains code derived from Contour, -// https://github.com/projectcontour/contour -// from the source file -// https://github.com/projectcontour/contour/blob/main/internal/status/gatewayclassconditions.go -// and is provided here subject to the following: -// Copyright Project Contour Authors -// SPDX-License-Identifier: Apache-2.0 - -package status - -import ( - "fmt" - "time" - "unicode" - - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" -) - -const ( - ReasonOlderGatewayClassExists gwapiv1.GatewayClassConditionReason = "OlderGatewayClassExists" - - MsgOlderGatewayClassExists = "Invalid GatewayClass: another older GatewayClass with the same Spec.Controller exists" - MsgValidGatewayClass = "Valid GatewayClass" - MsgGatewayClassInvalidParams = "Invalid parametersRef" -) - -// computeGatewayClassAcceptedCondition computes the GatewayClass Accepted status condition. -func computeGatewayClassAcceptedCondition(gatewayClass *gwapiv1.GatewayClass, - accepted bool, - reason, msg string, -) metav1.Condition { - switch accepted { - case true: - return metav1.Condition{ - Type: string(gwapiv1.GatewayClassConditionStatusAccepted), - Status: metav1.ConditionTrue, - Reason: reason, - Message: msg, - ObservedGeneration: gatewayClass.Generation, - LastTransitionTime: metav1.NewTime(time.Now()), - } - default: - return metav1.Condition{ - Type: string(gwapiv1.GatewayClassConditionStatusAccepted), - Status: metav1.ConditionFalse, - Reason: reason, - Message: msg, - ObservedGeneration: gatewayClass.Generation, - LastTransitionTime: metav1.NewTime(time.Now()), - } - } -} - -// computeGatewayAcceptedCondition computes the Gateway Accepted status condition. -func computeGatewayAcceptedCondition(gw *gwapiv1.Gateway, accepted bool) metav1.Condition { - switch accepted { - case true: - return newCondition(string(gwapiv1.GatewayReasonAccepted), metav1.ConditionTrue, - string(gwapiv1.GatewayReasonAccepted), - "The Gateway has been scheduled by Envoy Gateway", time.Now(), gw.Generation) - default: - return newCondition(string(gwapiv1.GatewayReasonAccepted), metav1.ConditionFalse, - string(gwapiv1.GatewayReasonAccepted), - "The Gateway has not been scheduled by Envoy Gateway", time.Now(), gw.Generation) - } -} - -// computeGatewayProgrammedCondition computes the Gateway Programmed status condition. -// Programmed condition surfaces true when the Envoy Deployment status is ready. -func computeGatewayProgrammedCondition(gw *gwapiv1.Gateway, deployment *appsv1.Deployment) metav1.Condition { - if len(gw.Status.Addresses) == 0 { - return newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionFalse, - string(gwapiv1.GatewayReasonAddressNotAssigned), - "No addresses have been assigned to the Gateway", time.Now(), gw.Generation) - } - - // If there are no available replicas for the Envoy Deployment, don't - // mark the Gateway as ready yet. - - if deployment == nil || deployment.Status.AvailableReplicas == 0 { - return newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionFalse, - string(gwapiv1.GatewayReasonNoResources), - "Deployment replicas unavailable", time.Now(), gw.Generation) - } - - message := fmt.Sprintf("Address assigned to the Gateway, %d/%d envoy Deployment replicas available", - deployment.Status.AvailableReplicas, deployment.Status.Replicas) - return newCondition(string(gwapiv1.GatewayConditionProgrammed), metav1.ConditionTrue, - string(gwapiv1.GatewayConditionProgrammed), message, time.Now(), gw.Generation) -} - -// MergeConditions adds or updates matching conditions, and updates the transition -// time if details of a condition have changed. Returns the updated condition array. -func MergeConditions(conditions []metav1.Condition, updates ...metav1.Condition) []metav1.Condition { - var additions []metav1.Condition - for i, update := range updates { - add := true - for j, cond := range conditions { - if cond.Type == update.Type { - add = false - if conditionChanged(cond, update) { - conditions[j].Status = update.Status - conditions[j].Reason = update.Reason - conditions[j].Message = update.Message - conditions[j].ObservedGeneration = update.ObservedGeneration - conditions[j].LastTransitionTime = update.LastTransitionTime - break - } - } - } - if add { - additions = append(additions, updates[i]) - } - } - conditions = append(conditions, additions...) - return conditions -} - -func newCondition(t string, status metav1.ConditionStatus, reason, msg string, lt time.Time, og int64) metav1.Condition { - return metav1.Condition{ - Type: t, - Status: status, - Reason: reason, - Message: msg, - LastTransitionTime: metav1.NewTime(lt), - ObservedGeneration: og, - } -} - -func conditionChanged(a, b metav1.Condition) bool { - return (a.Status != b.Status) || - (a.Reason != b.Reason) || - (a.Message != b.Message) || - (a.ObservedGeneration != b.ObservedGeneration) -} - -// Error2ConditionMsg format the error string to a Status condition message. -// * Convert the first letter to capital -// * Append "." to the string if it doesn't exit -func Error2ConditionMsg(err error) string { - if err == nil { - return "" - } - - message := err.Error() - if message == "" { - return message - } - - // Convert the string to a rune slice for easier manipulation - runes := []rune(message) - - // Check if the first rune is a letter and convert it to uppercase - if unicode.IsLetter(runes[0]) { - runes[0] = unicode.ToUpper(runes[0]) - } - - // Convert the rune slice back to a string - return string(runes) -} diff --git a/internal/status/gatewayclass.go b/internal/status/gatewayclass.go deleted file mode 100644 index 7a71ab23646..00000000000 --- a/internal/status/gatewayclass.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright Envoy Gateway Authors -// SPDX-License-Identifier: Apache-2.0 -// The full text of the Apache license is available in the LICENSE file at -// the root of the repo. - -// This file contains code derived from Contour, -// https://github.com/projectcontour/contour -// from the source file -// https://github.com/projectcontour/contour/blob/main/internal/status/gatewayclass.go -// and is provided here subject to the following: -// Copyright Project Contour Authors -// SPDX-License-Identifier: Apache-2.0 - -package status - -import ( - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" -) - -// SetGatewayClassAccepted inserts or updates the Accepted condition -// for the provided GatewayClass. -func SetGatewayClassAccepted(gc *gwapiv1.GatewayClass, accepted bool, reason, msg string) *gwapiv1.GatewayClass { - gc.Status.Conditions = MergeConditions(gc.Status.Conditions, computeGatewayClassAcceptedCondition(gc, accepted, reason, msg)) - return gc -} diff --git a/internal/xds/translator/jsonpatch.go b/internal/xds/translator/jsonpatch.go index 113b252fa5a..e7808abe0c5 100644 --- a/internal/xds/translator/jsonpatch.go +++ b/internal/xds/translator/jsonpatch.go @@ -20,8 +20,8 @@ import ( "google.golang.org/protobuf/encoding/protojson" "sigs.k8s.io/yaml" + "github.com/envoyproxy/gateway/internal/gatewayapi/status" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/status" _ "github.com/envoyproxy/gateway/internal/xds/extensions" // register the generated types to support protojson unmarshalling "github.com/envoyproxy/gateway/internal/xds/types" ) From 239fdd71b5e59e4c63444169525f8c928e72fc44 Mon Sep 17 00:00:00 2001 From: sh2 Date: Wed, 8 May 2024 11:28:11 +0800 Subject: [PATCH 13/17] feat: add xRoute and xPolicy support for egctl x status (#2949) * add xRoute and xPolicy support for egctl x status Signed-off-by: shawnh2 * change kind name to lower case and update latest doc Signed-off-by: shawnh2 * fix test and doc Signed-off-by: shawnh2 --------- Signed-off-by: shawnh2 --- ...{envoy_dashboard.go => dashboard_envoy.go} | 0 .../egctl/{envoy_stats.go => stats_envoy.go} | 0 internal/cmd/egctl/status.go | 268 ++++++++----- internal/cmd/egctl/status_test.go | 379 +++++++++++++++--- internal/gatewayapi/translator.go | 34 +- .../en/latest/tasks/operations/egctl.md | 27 +- 6 files changed, 527 insertions(+), 181 deletions(-) rename internal/cmd/egctl/{envoy_dashboard.go => dashboard_envoy.go} (100%) rename internal/cmd/egctl/{envoy_stats.go => stats_envoy.go} (100%) diff --git a/internal/cmd/egctl/envoy_dashboard.go b/internal/cmd/egctl/dashboard_envoy.go similarity index 100% rename from internal/cmd/egctl/envoy_dashboard.go rename to internal/cmd/egctl/dashboard_envoy.go diff --git a/internal/cmd/egctl/envoy_stats.go b/internal/cmd/egctl/stats_envoy.go similarity index 100% rename from internal/cmd/egctl/envoy_stats.go rename to internal/cmd/egctl/stats_envoy.go diff --git a/internal/cmd/egctl/status.go b/internal/cmd/egctl/status.go index 791488ea02d..80df4237207 100644 --- a/internal/cmd/egctl/status.go +++ b/internal/cmd/egctl/status.go @@ -23,13 +23,28 @@ import ( gwv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi" ) -// supportedTypes list all the resource types that status command supports. -var supportedTypes = []string{ - "GatewayClass", "Gateway", "HTTPRoute", "GRPCRoute", - "TLSRoute", "TCPRoute", "UDPRoute", "BackendTLSPolicy", - "BackendTrafficPolicy", "ClientTrafficPolicy", "EnvoyPatchPolicy", "SecurityPolicy", +var ( + supportedXRouteTypes = []string{ + gatewayapi.KindHTTPRoute, gatewayapi.KindGRPCRoute, gatewayapi.KindTCPRoute, + gatewayapi.KindUDPRoute, gatewayapi.KindTLSRoute, + } + + supportedXPolicyTypes = []string{ + gatewayapi.KindBackendTLSPolicy, gatewayapi.KindBackendTrafficPolicy, gatewayapi.KindClientTrafficPolicy, + gatewayapi.KindSecurityPolicy, gatewayapi.KindEnvoyPatchPolicy, + } + + supportedAllTypes = []string{ + gatewayapi.KindGatewayClass, gatewayapi.KindGateway, + } +) + +func init() { + supportedAllTypes = append(supportedAllTypes, supportedXRouteTypes...) + supportedAllTypes = append(supportedAllTypes, supportedXPolicyTypes...) } func newStatusCommand() *cobra.Command { @@ -53,8 +68,8 @@ func newStatusCommand() *cobra.Command { # Show the status of httproute resources with details under a specific namespace. egctl x status httproute -v -n foobar - # Show the status of httproute resources under all namespaces. - egctl x status httproute -A + # Show the status of all route resources under all namespaces. + egctl x status xroute -A # Show the status of all resources under all namespaces. egctl x status all -A @@ -75,14 +90,29 @@ func newStatusCommand() *cobra.Command { return fmt.Errorf("invalid args: must specific a resources type") } - if resourceType == "all" { - for _, rt := range supportedTypes { + switch strings.ToLower(resourceType) { + case "all": + for _, rt := range supportedAllTypes { if err = runStatus(ctx, k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil { return err } } return nil - } else { + case "xroute": + for _, rt := range supportedXRouteTypes { + if err = runStatus(ctx, k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil { + return err + } + } + return nil + case "xpolicy": + for _, rt := range supportedXPolicyTypes { + if err = runStatus(ctx, k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil { + return err + } + } + return nil + default: return runStatus(ctx, k8sClient, resourceType, namespace, quiet, verbose, allNamespaces, false, false) } }, @@ -100,17 +130,18 @@ func newStatusTableWriter(out io.Writer) *tabwriter.Writer { return tabwriter.NewWriter(out, 10, 0, 3, ' ', 0) } -func writeStatusTable(table *tabwriter.Writer, headers []string, bodies [][]string) { - fmt.Fprintln(table, strings.Join(headers, "\t")) - for _, body := range bodies { - fmt.Fprintln(table, strings.Join(body, "\t")) +func writeStatusTable(table *tabwriter.Writer, header []string, body [][]string) { + fmt.Fprintln(table, strings.Join(header, "\t")) + for _, b := range body { + fmt.Fprintln(table, strings.Join(b, "\t")) } } // runStatus find and write the summary table of status for a specific resource type. -func runStatus(ctx context.Context, cli client.Client, resourceType, namespace string, quiet, verbose, allNamespaces, ignoreEmpty, typedName bool) error { +func runStatus(ctx context.Context, cli client.Client, inputResourceType, namespace string, quiet, verbose, allNamespaces, ignoreEmpty, typedName bool) error { var ( resourcesList client.ObjectList + resourceKind string table = newStatusTableWriter(os.Stdout) ) @@ -118,13 +149,14 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s namespace = "" } - switch strings.ToLower(resourceType) { + switch strings.ToLower(inputResourceType) { case "gc", "gatewayclass": gc := gwv1.GatewayClassList{} if err := cli.List(ctx, &gc, client.InNamespace(namespace)); err != nil { return err } resourcesList = &gc + resourceKind = gatewayapi.KindGatewayClass case "gtw", "gateway": gtw := gwv1.GatewayList{} @@ -132,6 +164,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = >w + resourceKind = gatewayapi.KindGateway case "httproute": httproute := gwv1.HTTPRouteList{} @@ -139,6 +172,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &httproute + resourceKind = gatewayapi.KindHTTPRoute case "grpcroute": grpcroute := gwv1.GRPCRouteList{} @@ -146,6 +180,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &grpcroute + resourceKind = gatewayapi.KindGRPCRoute case "tcproute": tcproute := gwv1a2.TCPRouteList{} @@ -153,6 +188,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &tcproute + resourceKind = gatewayapi.KindTCPRoute case "udproute": udproute := gwv1a2.UDPRouteList{} @@ -160,6 +196,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &udproute + resourceKind = gatewayapi.KindUDPRoute case "tlsroute": tlsroute := gwv1a2.TLSRouteList{} @@ -167,6 +204,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &tlsroute + resourceKind = gatewayapi.KindTLSRoute case "btlspolicy", "backendtlspolicy": btlspolicy := gwv1a3.BackendTLSPolicyList{} @@ -174,6 +212,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &btlspolicy + resourceKind = gatewayapi.KindBackendTLSPolicy case "btp", "backendtrafficpolicy": btp := egv1a1.BackendTrafficPolicyList{} @@ -181,6 +220,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &btp + resourceKind = gatewayapi.KindBackendTrafficPolicy case "ctp", "clienttrafficpolicy": ctp := egv1a1.ClientTrafficPolicyList{} @@ -188,6 +228,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &ctp + resourceKind = gatewayapi.KindClientTrafficPolicy case "epp", "envoypatchpolicy": epp := egv1a1.EnvoyPatchPolicyList{} @@ -195,6 +236,7 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &epp + resourceKind = gatewayapi.KindEnvoyPatchPolicy case "sp", "securitypolicy": sp := egv1a1.SecurityPolicyList{} @@ -202,9 +244,11 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return err } resourcesList = &sp + resourceKind = gatewayapi.KindSecurityPolicy default: - return fmt.Errorf("unknown resource type: %s, supported types are: %s", resourceType, strings.Join(supportedTypes, ",")) + return fmt.Errorf("unknown input resource type: %s, supported input types are: %s", + inputResourceType, strings.Join(supportedAllTypes, ", ")) } namespaced, err := cli.IsObjectNamespaced(resourcesList) @@ -213,17 +257,14 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s } needNamespaceHeader := allNamespaces && namespaced - headers := fetchStatusHeaders(verbose, needNamespaceHeader) - bodies, err := fetchStatusBodies(resourcesList, resourceType, quiet, verbose, needNamespaceHeader, typedName) - if err != nil { - return err - } + header := fetchStatusHeader(resourceKind, verbose, needNamespaceHeader) + body := fetchStatusBody(resourcesList, resourceKind, quiet, verbose, needNamespaceHeader, typedName) - if ignoreEmpty && len(bodies) == 0 { + if ignoreEmpty && len(body) == 0 { return nil } - writeStatusTable(table, headers, bodies) + writeStatusTable(table, header, body) if err = table.Flush(); err != nil { return err } @@ -236,38 +277,68 @@ func runStatus(ctx context.Context, cli client.Client, resourceType, namespace s return nil } -func fetchStatusHeaders(verbose, needNamespace bool) []string { - headers := []string{"NAME", "TYPE", "STATUS", "REASON"} - +// extendStatusHeader extends header in the way of: +// - Insert `NAMESPACE` at first if needed +// - Append various details if verbose is on +func extendStatusHeader(header []string, verbose, needNamespace bool) []string { if needNamespace { - headers = append([]string{"NAMESPACE"}, headers...) + header = append([]string{"NAMESPACE"}, header...) } if verbose { - headers = append(headers, []string{"MESSAGE", "OBSERVED GENERATION", "LAST TRANSITION TIME"}...) + header = append(header, []string{"MESSAGE", "OBSERVED GENERATION", "LAST TRANSITION TIME"}...) } - return headers + return header } -func fetchStatusBodies(resourcesList client.ObjectList, resourceType string, quiet, verbose, needNamespace, typedName bool) ([][]string, error) { - v := reflect.ValueOf(resourcesList).Elem() +// extendStatusBodyWithNamespaceAndName extends current body with namespace and name at head. +func extendStatusBodyWithNamespaceAndName(body [][]string, namespace, name string, needNamespace bool) [][]string { + for i := 0; i < len(body); i++ { + if needNamespace { + body[i] = append([]string{namespace, name}, body[i]...) + } else { + body[i] = append([]string{name}, body[i]...) + } + // Only display once for the first row. + namespace, name = "", "" + } + return body +} - itemsField := v.FieldByName("Items") - if !itemsField.IsValid() { - return nil, fmt.Errorf("failed to load `.Items` field from %s", resourceType) +func kindName(kind, name string) string { + return strings.ToLower(kind) + "/" + name +} + +func fetchStatusHeader(resourceKind string, verbose, needNamespace bool) (header []string) { + defaultHeader := []string{"NAME", "TYPE", "STATUS", "REASON"} + xRouteHeader := []string{"NAME", "PARENT", "TYPE", "STATUS", "REASON"} + xPolicyHeader := []string{"NAME", "ANCESTOR REFERENCE", "TYPE", "STATUS", "REASON"} + + switch { + case strings.HasSuffix(resourceKind, "Route"): + return extendStatusHeader(xRouteHeader, verbose, needNamespace) + case strings.HasSuffix(resourceKind, "Policy"): + return extendStatusHeader(xPolicyHeader, verbose, needNamespace) + default: + return extendStatusHeader(defaultHeader, verbose, needNamespace) } +} + +func fetchStatusBody(resourcesList client.ObjectList, resourceKind string, quiet, verbose, needNamespace, typedName bool) (body [][]string) { + v := reflect.ValueOf(resourcesList).Elem() + itemsField := v.FieldByName("Items") - var body [][]string for i := 0; i < itemsField.Len(); i++ { - item := itemsField.Index(i) + var ( + name, namespace string + rows [][]string + item = itemsField.Index(i) + nameField = item.FieldByName("Name") + statusField = item.FieldByName("Status") + ) - // There's no need to check whether Name, Namespace and Kind field is valid, - // since all the objects in ObjectList are implemented k8s Object interface. - var name, namespace string - nameField := item.FieldByName("Name") if typedName { - kindField := item.FieldByName("Kind") - name = strings.ToLower(kindField.String()) + "/" + nameField.String() + name = kindName(resourceKind, nameField.String()) } else { name = nameField.String() } @@ -277,86 +348,73 @@ func fetchStatusBodies(resourcesList client.ObjectList, resourceType string, qui namespace = namespaceField.String() } - statusField := item.FieldByName("Status") - if !statusField.IsValid() { - return nil, fmt.Errorf("failed to find `.Items[i].Status` field from %s", resourceType) - } - - // Different resources store the conditions at different position. - switch strings.ToLower(resourceType) { - case "httproute", "grpcroute", "tlsroute", "tcproute", "udproute": - // Scrape conditions from `Resource.Status.Parents[i].Conditions` field + switch { + // For xRoute, the conditions are storing in `Resource.Status.Parents[i].Conditions`. + case strings.HasSuffix(resourceKind, "Route"): parentsField := statusField.FieldByName("Parents") - if !parentsField.IsValid() { - return nil, fmt.Errorf("failed to find `.Items[i].Status.Parents` field from %s", resourceType) - } - for j := 0; j < parentsField.Len(); j++ { parentItem := parentsField.Index(j) - rows, err := fetchConditionsField(parentItem, resourceType, name, namespace, quiet, verbose, needNamespace) - if err != nil { - return nil, err + conditions := fetchConditions(parentItem, quiet, verbose) + + // Extend conditions with parent. + parentRef := parentItem.FieldByName("ParentRef") + parentName := kindName( + parentRef.FieldByName("Kind").Elem().String(), + parentRef.FieldByName("Name").String(), + ) + for k := 0; k < len(conditions); k++ { + conditions[k] = append([]string{parentName}, conditions[k]...) + parentName = "" } - body = append(body, rows...) + rows = append(rows, conditions...) } - case "btlspolicy", "backendtlspolicy": - // Scrape conditions from `Resource.Status.Ancestors[i].Conditions` field + // For xPolicy, the conditions are storing in `Resource.Status.Ancestors[i].Conditions`. + case strings.HasSuffix(resourceKind, "Policy"): ancestorsField := statusField.FieldByName("Ancestors") - if !ancestorsField.IsValid() { - return nil, fmt.Errorf("failed to find `.Items[i].Status.Ancestors` field from %s", resourceType) - } - for j := 0; j < ancestorsField.Len(); j++ { - ancestorItem := ancestorsField.Index(j) - rows, err := fetchConditionsField(ancestorItem, resourceType, name, namespace, quiet, verbose, needNamespace) - if err != nil { - return nil, err + policyAncestorStatus := ancestorsField.Index(j) + conditions := fetchConditions(policyAncestorStatus, quiet, verbose) + + // Extend conditions with ancestor. + ancestorRef := policyAncestorStatus.FieldByName("AncestorRef") + ancestorName := kindName( + ancestorRef.FieldByName("Kind").Elem().String(), + ancestorRef.FieldByName("Name").String(), + ) + for k := 0; k < len(conditions); k++ { + conditions[k] = append([]string{ancestorName}, conditions[k]...) + ancestorName = "" } - body = append(body, rows...) + rows = append(rows, conditions...) } + // For others, the conditions are storing in `Resource.Status.Conditions`. default: - // Scrape conditions from `Resource.Status.Conditions` field - rows, err := fetchConditionsField(statusField, resourceType, name, namespace, quiet, verbose, needNamespace) - if err != nil { - return nil, err - } - - body = append(body, rows...) + conditions := fetchConditions(statusField, quiet, verbose) + rows = append(rows, conditions...) } - } - - return body, nil -} - -func fetchConditionsField(parent reflect.Value, resourceType, name, namespace string, quiet, verbose, needNamespace bool) ([][]string, error) { - conditionsField := parent.FieldByName("Conditions") - if !conditionsField.IsValid() { - return nil, fmt.Errorf("failed to find `Conditions` field for %s", resourceType) - } - conditions, ok := conditionsField.Interface().([]metav1.Condition) - if !ok { - return nil, fmt.Errorf("failed to convert `Conditions` field to type `[]metav1.Condition`") + rows = extendStatusBodyWithNamespaceAndName(rows, namespace, name, needNamespace) + body = append(body, rows...) } - rows := fetchConditions(conditions, name, namespace, quiet, verbose, needNamespace) - return rows, nil + return body } -func fetchConditions(conditions []metav1.Condition, name, namespace string, quiet, verbose, needNamespace bool) [][]string { +// fetchConditions fetches conditions from the `Conditions` field of parent +// by calling fetchCondition for each condition. +func fetchConditions(parent reflect.Value, quiet, verbose bool) [][]string { var rows [][]string - // Sort in descending order by time of each condition. - for i := len(conditions) - 1; i >= 0; i-- { - if i < len(conditions)-1 { - name, namespace = "", "" - } + conditionsField := parent.FieldByName("Conditions") + conditions := conditionsField.Interface().([]metav1.Condition) - row := fetchCondition(conditions[i], name, namespace, verbose, needNamespace) + // All conditions are sorted in descending order by time. + for i := len(conditions) - 1; i >= 0; i-- { + row := fetchCondition(conditions[i], verbose) rows = append(rows, row) if quiet { @@ -367,13 +425,11 @@ func fetchConditions(conditions []metav1.Condition, name, namespace string, quie return rows } -func fetchCondition(condition metav1.Condition, name, namespace string, verbose, needNamespace bool) []string { - row := []string{name, condition.Type, string(condition.Status), condition.Reason} +// fetchCondition fetches the Type, Status, Reason of one condition, and more if verbose. +func fetchCondition(condition metav1.Condition, verbose bool) []string { + row := []string{condition.Type, string(condition.Status), condition.Reason} - // Write conditions corresponding to its headers. - if needNamespace { - row = append([]string{namespace}, row...) - } + // Write more details about this condition if verbose is on. if verbose { row = append(row, []string{ condition.Message, diff --git a/internal/cmd/egctl/status_test.go b/internal/cmd/egctl/status_test.go index eddaa0a5507..2dd1455eb83 100644 --- a/internal/cmd/egctl/status_test.go +++ b/internal/cmd/egctl/status_test.go @@ -16,6 +16,9 @@ import ( gwv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi" ) func TestWriteStatus(t *testing.T) { @@ -25,27 +28,25 @@ func TestWriteStatus(t *testing.T) { name string resourceNamespaced bool resourceList client.ObjectList - resourceType string + resourceKind string namespace string quiet bool verbose bool allNamespaces bool typedName bool outputs string - expect bool }{ { name: "egctl x status gc -v, but no resources", resourceList: &gwv1.GatewayClassList{}, resourceNamespaced: false, - resourceType: "gatewayclass", + resourceKind: gatewayapi.KindGatewayClass, quiet: false, verbose: true, allNamespaces: false, typedName: false, outputs: `NAME TYPE STATUS REASON MESSAGE OBSERVED GENERATION LAST TRANSITION TIME `, - expect: true, }, { name: "egctl x status gc", @@ -79,7 +80,7 @@ func TestWriteStatus(t *testing.T) { }, }, resourceNamespaced: false, - resourceType: "gatewayclass", + resourceKind: gatewayapi.KindGatewayClass, quiet: false, verbose: false, allNamespaces: false, @@ -88,7 +89,6 @@ func TestWriteStatus(t *testing.T) { gc foobar2 test-status-2 test reason 2 foobar1 test-status-1 test reason 1 `, - expect: true, }, { name: "egctl x status gc -v", @@ -122,7 +122,7 @@ gc foobar2 test-status-2 test reason 2 }, }, resourceNamespaced: false, - resourceType: "gatewayclass", + resourceKind: gatewayapi.KindGatewayClass, quiet: false, verbose: true, allNamespaces: false, @@ -131,7 +131,6 @@ gc foobar2 test-status-2 test reason 2 gc foobar2 test-status-2 test reason 2 test message 2 123457 2024-01-01 01:00:00 +0000 UTC foobar1 test-status-1 test reason 1 test message 1 123456 2024-01-01 00:00:00 +0000 UTC `, - expect: true, }, { name: "egctl x status gc -v -q", @@ -165,7 +164,7 @@ gc foobar2 test-status-2 test reason 2 test message 2 123457 }, }, resourceNamespaced: false, - resourceType: "gatewayclass", + resourceKind: gatewayapi.KindGatewayClass, quiet: true, verbose: true, allNamespaces: false, @@ -173,20 +172,18 @@ gc foobar2 test-status-2 test reason 2 test message 2 123457 outputs: `NAME TYPE STATUS REASON MESSAGE OBSERVED GENERATION LAST TRANSITION TIME gc foobar2 test-status-2 test reason 2 test message 2 123457 2024-01-01 01:00:00 +0000 UTC `, - expect: true, }, { name: "egctl x status gtw -v -A, no resources", resourceList: &gwv1.GatewayList{}, resourceNamespaced: true, - resourceType: "gateway", + resourceKind: gatewayapi.KindGateway, quiet: false, verbose: true, allNamespaces: true, typedName: false, outputs: `NAMESPACE NAME TYPE STATUS REASON MESSAGE OBSERVED GENERATION LAST TRANSITION TIME `, - expect: true, }, { name: "egctl x status gtw -v -A", @@ -221,7 +218,7 @@ gc foobar2 test-status-2 test reason 2 test message 2 123457 }, }, resourceNamespaced: true, - resourceType: "gateway", + resourceKind: gatewayapi.KindGateway, quiet: false, verbose: true, allNamespaces: true, @@ -230,7 +227,6 @@ gc foobar2 test-status-2 test reason 2 test message 2 123457 default gtw foobar2 test-status-2 test reason 2 test message 2 123457 2024-01-01 01:00:00 +0000 UTC foobar1 test-status-1 test reason 1 test message 1 123456 2024-01-01 00:00:00 +0000 UTC `, - expect: true, }, { name: "egctl x status gtw -v -q -A", @@ -291,7 +287,7 @@ default gtw foobar2 test-status-2 test reason 2 test message 2 }, }, resourceNamespaced: true, - resourceType: "gateway", + resourceKind: gatewayapi.KindGateway, quiet: true, verbose: true, allNamespaces: true, @@ -300,7 +296,6 @@ default gtw foobar2 test-status-2 test reason 2 test message 2 default1 gtw1 foobar2 test-status-2 test reason 2 test message 2 123457 2024-01-01 01:00:00 +0000 UTC default2 gtw2 foobar4 test-status-4 test reason 4 test message 4 123459 2024-01-01 03:00:00 +0000 UTC `, - expect: true, }, { name: "egctl x status httproute -A", @@ -315,6 +310,10 @@ default2 gtw2 foobar4 test-status-4 test reason 4 test message 4 RouteStatus: gwv1.RouteStatus{ Parents: []gwv1.RouteParentStatus{ { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-1"), + }, Conditions: []metav1.Condition{ { Type: "foobar1", @@ -347,6 +346,10 @@ default2 gtw2 foobar4 test-status-4 test reason 4 test message 4 RouteStatus: gwv1.RouteStatus{ Parents: []gwv1.RouteParentStatus{ { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-2"), + }, Conditions: []metav1.Condition{ { Type: "foobar3", @@ -373,18 +376,17 @@ default2 gtw2 foobar4 test-status-4 test reason 4 test message 4 }, }, resourceNamespaced: true, - resourceType: "httproute", + resourceKind: gatewayapi.KindHTTPRoute, quiet: false, verbose: false, allNamespaces: true, typedName: false, - outputs: `NAMESPACE NAME TYPE STATUS REASON -default1 http1 foobar2 test-status-2 test reason 2 - foobar1 test-status-1 test reason 1 -default2 http2 foobar4 test-status-4 test reason 4 - foobar3 test-status-3 test reason 3 + outputs: `NAMESPACE NAME PARENT TYPE STATUS REASON +default1 http1 gateway/test-1 foobar2 test-status-2 test reason 2 + foobar1 test-status-1 test reason 1 +default2 http2 gateway/test-2 foobar4 test-status-4 test reason 4 + foobar3 test-status-3 test reason 3 `, - expect: true, }, { name: "egctl x status httproute -q -n default1", @@ -399,6 +401,10 @@ default2 http2 foobar4 test-status-4 test reason 4 RouteStatus: gwv1.RouteStatus{ Parents: []gwv1.RouteParentStatus{ { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-1"), + }, Conditions: []metav1.Condition{ { Type: "foobar1", @@ -431,6 +437,10 @@ default2 http2 foobar4 test-status-4 test reason 4 RouteStatus: gwv1.RouteStatus{ Parents: []gwv1.RouteParentStatus{ { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-2"), + }, Conditions: []metav1.Condition{ { Type: "foobar3", @@ -457,17 +467,16 @@ default2 http2 foobar4 test-status-4 test reason 4 }, }, resourceNamespaced: true, - resourceType: "httproute", + resourceKind: gatewayapi.KindHTTPRoute, quiet: true, verbose: false, allNamespaces: false, typedName: false, namespace: "default1", - outputs: `NAME TYPE STATUS REASON -http1 foobar2 test-status-2 test reason 2 -http2 foobar4 test-status-4 test reason 4 + outputs: `NAME PARENT TYPE STATUS REASON +http1 gateway/test-1 foobar2 test-status-2 test reason 2 +http2 gateway/test-2 foobar4 test-status-4 test reason 4 `, - expect: true, }, { name: "egctl x status btlspolicy", @@ -481,6 +490,10 @@ http2 foobar4 test-status-4 test reason 4 Status: gwv1a2.PolicyStatus{ Ancestors: []gwv1a2.PolicyAncestorStatus{ { + AncestorRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test"), + }, Conditions: []metav1.Condition{ { Type: "foobar1", @@ -506,18 +519,298 @@ http2 foobar4 test-status-4 test reason 4 }, }, resourceNamespaced: true, - resourceType: "btlspolicy", + resourceKind: gatewayapi.KindBackendTLSPolicy, quiet: false, verbose: false, allNamespaces: false, typedName: false, - outputs: `NAME TYPE STATUS REASON -btls foobar2 test-status-2 test reason 2 - foobar1 test-status-1 test reason 1 + outputs: `NAME ANCESTOR REFERENCE TYPE STATUS REASON +btls gateway/test foobar2 test-status-2 test reason 2 + foobar1 test-status-1 test reason 1 +`, + }, + { + name: "multiple httproutes with multiple parents", + resourceList: &gwv1.HTTPRouteList{ + Items: []gwv1.HTTPRoute{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "http1", + Namespace: "default1", + }, + Status: gwv1.HTTPRouteStatus{ + RouteStatus: gwv1.RouteStatus{ + Parents: []gwv1.RouteParentStatus{ + { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-1"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar1", + Status: metav1.ConditionStatus("test-status-1"), + ObservedGeneration: 123456, + LastTransitionTime: metav1.NewTime(testTime), + Reason: "test reason 1", + Message: "test message 1", + }, + { + Type: "foobar2", + Status: metav1.ConditionStatus("test-status-2"), + ObservedGeneration: 123457, + LastTransitionTime: metav1.NewTime(testTime.Add(1 * time.Hour)), + Reason: "test reason 2", + Message: "test message 2", + }, + }, + }, + { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-2"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar3", + Status: metav1.ConditionStatus("test-status-3"), + ObservedGeneration: 123456, + LastTransitionTime: metav1.NewTime(testTime), + Reason: "test reason 3", + Message: "test message 3", + }, + { + Type: "foobar4", + Status: metav1.ConditionStatus("test-status-4"), + ObservedGeneration: 123457, + LastTransitionTime: metav1.NewTime(testTime.Add(1 * time.Hour)), + Reason: "test reason 4", + Message: "test message 4", + }, + }, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "http2", + Namespace: "default2", + }, + Status: gwv1.HTTPRouteStatus{ + RouteStatus: gwv1.RouteStatus{ + Parents: []gwv1.RouteParentStatus{ + { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-3"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar5", + Status: metav1.ConditionStatus("test-status-5"), + ObservedGeneration: 123458, + LastTransitionTime: metav1.NewTime(testTime.Add(2 * time.Hour)), + Reason: "test reason 5", + Message: "test message 5", + }, + { + Type: "foobar6", + Status: metav1.ConditionStatus("test-status-6"), + ObservedGeneration: 123459, + LastTransitionTime: metav1.NewTime(testTime.Add(3 * time.Hour)), + Reason: "test reason 6", + Message: "test message 6", + }, + }, + }, + { + ParentRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-4"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar7", + Status: metav1.ConditionStatus("test-status-7"), + ObservedGeneration: 123458, + LastTransitionTime: metav1.NewTime(testTime.Add(2 * time.Hour)), + Reason: "test reason 7", + Message: "test message 7", + }, + { + Type: "foobar8", + Status: metav1.ConditionStatus("test-status-8"), + ObservedGeneration: 123459, + LastTransitionTime: metav1.NewTime(testTime.Add(3 * time.Hour)), + Reason: "test reason 8", + Message: "test message 8", + }, + }, + }, + }, + }, + }, + }, + }, + }, + resourceNamespaced: true, + resourceKind: gatewayapi.KindHTTPRoute, + quiet: false, + verbose: false, + allNamespaces: true, + typedName: false, + outputs: `NAMESPACE NAME PARENT TYPE STATUS REASON +default1 http1 gateway/test-1 foobar2 test-status-2 test reason 2 + foobar1 test-status-1 test reason 1 + gateway/test-2 foobar4 test-status-4 test reason 4 + foobar3 test-status-3 test reason 3 +default2 http2 gateway/test-3 foobar6 test-status-6 test reason 6 + foobar5 test-status-5 test reason 5 + gateway/test-4 foobar8 test-status-8 test reason 8 + foobar7 test-status-7 test reason 7 +`, + }, + { + name: "multiple backendtrafficpolicy with multiple ancestors", + resourceList: &egv1a1.BackendTrafficPolicyList{ + Items: []egv1a1.BackendTrafficPolicy{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "btp-1", + Namespace: "default", + }, + Status: gwv1a2.PolicyStatus{ + Ancestors: []gwv1a2.PolicyAncestorStatus{ + { + AncestorRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-1"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar1", + Status: metav1.ConditionStatus("test-status-1"), + ObservedGeneration: 123456, + LastTransitionTime: metav1.NewTime(testTime), + Reason: "test reason 1", + Message: "test message 1", + }, + { + Type: "foobar2", + Status: metav1.ConditionStatus("test-status-2"), + ObservedGeneration: 123457, + LastTransitionTime: metav1.NewTime(testTime.Add(1 * time.Hour)), + Reason: "test reason 2", + Message: "test message 2", + }, + }, + }, + { + AncestorRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindHTTPRoute), + Name: gwv1.ObjectName("test-2"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar3", + Status: metav1.ConditionStatus("test-status-3"), + ObservedGeneration: 123456, + LastTransitionTime: metav1.NewTime(testTime), + Reason: "test reason 3", + Message: "test message 3", + }, + { + Type: "foobar4", + Status: metav1.ConditionStatus("test-status-4"), + ObservedGeneration: 123457, + LastTransitionTime: metav1.NewTime(testTime.Add(1 * time.Hour)), + Reason: "test reason 4", + Message: "test message 4", + }, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "btp-2", + Namespace: "default", + }, + Status: gwv1a2.PolicyStatus{ + Ancestors: []gwv1a2.PolicyAncestorStatus{ + { + AncestorRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Name: gwv1.ObjectName("test-3"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar5", + Status: metav1.ConditionStatus("test-status-5"), + ObservedGeneration: 123456, + LastTransitionTime: metav1.NewTime(testTime), + Reason: "test reason 5", + Message: "test message 5", + }, + { + Type: "foobar6", + Status: metav1.ConditionStatus("test-status-6"), + ObservedGeneration: 123457, + LastTransitionTime: metav1.NewTime(testTime.Add(1 * time.Hour)), + Reason: "test reason 6", + Message: "test message 6", + }, + }, + }, + { + AncestorRef: gwv1.ParentReference{ + Kind: gatewayapi.KindPtr(gatewayapi.KindGRPCRoute), + Name: gwv1.ObjectName("test-4"), + }, + Conditions: []metav1.Condition{ + { + Type: "foobar7", + Status: metav1.ConditionStatus("test-status-7"), + ObservedGeneration: 123456, + LastTransitionTime: metav1.NewTime(testTime), + Reason: "test reason 7", + Message: "test message 7", + }, + { + Type: "foobar8", + Status: metav1.ConditionStatus("test-status-8"), + ObservedGeneration: 123457, + LastTransitionTime: metav1.NewTime(testTime.Add(1 * time.Hour)), + Reason: "test reason 8", + Message: "test message 8", + }, + }, + }, + }, + }, + }, + }, + }, + resourceNamespaced: true, + resourceKind: gatewayapi.KindBackendTrafficPolicy, + quiet: false, + verbose: false, + allNamespaces: false, + typedName: false, + outputs: `NAME ANCESTOR REFERENCE TYPE STATUS REASON +btp-1 gateway/test-1 foobar2 test-status-2 test reason 2 + foobar1 test-status-1 test reason 1 + httproute/test-2 foobar4 test-status-4 test reason 4 + foobar3 test-status-3 test reason 3 +btp-2 gateway/test-3 foobar6 test-status-6 test reason 6 + foobar5 test-status-5 test reason 5 + grpcroute/test-4 foobar8 test-status-8 test reason 8 + foobar7 test-status-7 test reason 7 `, - expect: true, }, - // TODO(sh2): add a policy status test for egctl x status cmd } for _, tc := range testCases { @@ -526,19 +819,13 @@ btls foobar2 test-status-2 test reason 2 tab := newStatusTableWriter(&out) needNamespace := tc.allNamespaces && tc.resourceNamespaced - headers := fetchStatusHeaders(tc.verbose, needNamespace) - bodies, err := fetchStatusBodies(tc.resourceList, tc.resourceType, tc.quiet, tc.verbose, needNamespace, tc.typedName) - if tc.expect { - require.NoError(t, err) - - writeStatusTable(tab, headers, bodies) - err = tab.Flush() - require.NoError(t, err) + header := fetchStatusHeader(tc.resourceKind, tc.verbose, needNamespace) + body := fetchStatusBody(tc.resourceList, tc.resourceKind, tc.quiet, tc.verbose, needNamespace, tc.typedName) + writeStatusTable(tab, header, body) + err := tab.Flush() + require.NoError(t, err) - require.Equal(t, tc.outputs, out.String()) - } else { - require.EqualError(t, err, tc.outputs) - } + require.Equal(t, tc.outputs, out.String()) }) } } diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index d0ea8244366..631357ff118 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -16,22 +16,24 @@ import ( ) const ( - KindConfigMap = "ConfigMap" - KindClientTrafficPolicy = "ClientTrafficPolicy" - KindBackendTLSPolicy = "BackendTLSPolicy" - KindEnvoyProxy = "EnvoyProxy" - KindGateway = "Gateway" - KindGatewayClass = "GatewayClass" - KindGRPCRoute = "GRPCRoute" - KindHTTPRoute = "HTTPRoute" - KindNamespace = "Namespace" - KindTLSRoute = "TLSRoute" - KindTCPRoute = "TCPRoute" - KindUDPRoute = "UDPRoute" - KindService = "Service" - KindServiceImport = "ServiceImport" - KindSecret = "Secret" - KindSecurityPolicy = "SecurityPolicy" + KindConfigMap = "ConfigMap" + KindClientTrafficPolicy = "ClientTrafficPolicy" + KindBackendTrafficPolicy = "BackendTrafficPolicy" + KindBackendTLSPolicy = "BackendTLSPolicy" + KindEnvoyPatchPolicy = "EnvoyPatchPolicy" + KindSecurityPolicy = "SecurityPolicy" + KindEnvoyProxy = "EnvoyProxy" + KindGateway = "Gateway" + KindGatewayClass = "GatewayClass" + KindGRPCRoute = "GRPCRoute" + KindHTTPRoute = "HTTPRoute" + KindNamespace = "Namespace" + KindTLSRoute = "TLSRoute" + KindTCPRoute = "TCPRoute" + KindUDPRoute = "UDPRoute" + KindService = "Service" + KindServiceImport = "ServiceImport" + KindSecret = "Secret" GroupMultiClusterService = "multicluster.x-k8s.io" // OwningGatewayNamespaceLabel is the owner reference label used for managed infra. diff --git a/site/content/en/latest/tasks/operations/egctl.md b/site/content/en/latest/tasks/operations/egctl.md index 3b25bc23456..ac1f13d7a61 100644 --- a/site/content/en/latest/tasks/operations/egctl.md +++ b/site/content/en/latest/tasks/operations/egctl.md @@ -768,9 +768,11 @@ display the latest condition, or add `--verbose` to display more details about c {{% alert title="Note" color="primary" %}} -Currently, this subcommand only supports: `GatewayClass`, `Gateway`, `HTTPRoute`, `GRPCRoute`, -`TLSRoute`, `TCPRoute`, `UDPRoute`, `BackendTLSPolicy`, -`BackendTrafficPolicy`, `ClientTrafficPolicy`, `EnvoyPatchPolicy`, `SecurityPolicy` resource types and `all`. +The resource types that this subcommand currently supports: + +- `xRoute`, `HTTPRoute`, `GRPCRoute`, `TLSRoute`, `TCPRoute`, `UDPRoute` +- `xPolicy`, `BackendTLSPolicy`, `BackendTrafficPolicy`, `ClientTrafficPolicy`, `EnvoyPatchPolicy`, `SecurityPolicy` +- `all`, `GatewayClass`, `Gateway` {{% /alert %}} @@ -801,11 +803,11 @@ marketing gateway/eg Programmed True Programmed product gateway/eg Programmed True Programmed Accepted True Accepted -NAMESPACE NAME TYPE STATUS REASON -marketing httproute/backend ResolvedRefs True ResolvedRefs - Accepted True Accepted -product httproute/backend ResolvedRefs True ResolvedRefs - Accepted True Accepted +NAMESPACE NAME PARENT TYPE STATUS REASON +marketing httproute/backend gateway/eg ResolvedRefs True ResolvedRefs + Accepted True Accepted +product httproute/backend gateway/eg ResolvedRefs True ResolvedRefs + Accepted True Accepted ``` - Show the summary of all the Gateways with details under all namespaces. @@ -820,7 +822,7 @@ product eg Programmed True Programmed Address assigned to th Accepted True Accepted The Gateway has been scheduled by Envoy Gateway 1 2024-02-01 17:52:42 +0800 CST ``` -- Show the summary of latest Gateways condition under `product` namespace. +- Show the summary of the latest Gateways condition under `product` namespace. ```console ~ egctl x status gateway --quiet -n product @@ -834,12 +836,11 @@ eg Programmed True Programmed ```console ~ egctl x status httproute --quiet --all-namespaces -NAMESPACE NAME TYPE STATUS REASON -marketing backend ResolvedRefs True ResolvedRefs -product backend ResolvedRefs True ResolvedRefs +NAMESPACE NAME PARENT TYPE STATUS REASON +marketing backend gateway/eg ResolvedRefs True ResolvedRefs +product backend gateway/eg ResolvedRefs True ResolvedRefs ``` - [Multi-tenancy]: ../deployment-mode#multi-tenancy [EnvoyProxy]: ../../../api/extension_types#envoyproxy From 6a28046210f1801afb9f2c186034c8cee111b4ce Mon Sep 17 00:00:00 2001 From: yaelSchechter <159942322+yaelSchechter@users.noreply.github.com> Date: Wed, 8 May 2024 13:41:21 +0300 Subject: [PATCH 14/17] docs: document buffer limit for client (#3324) * docs: document buffer limit for client Signed-off-by: Yael Shechter * add to latest Signed-off-by: Yael Shechter * fix pr comments Signed-off-by: Yael Shechter * close tab and fix lint issue Signed-off-by: Yael Shechter * close tab and fix lint issue Signed-off-by: Yael Shechter * remove from v1.0.1 Signed-off-by: Yael Shechter --------- Signed-off-by: Yael Shechter --- .../tasks/traffic/client-traffic-policy.md | 48 ++++++++++++- .../tasks/traffic/client-traffic-policy.md | 67 +------------------ 2 files changed, 48 insertions(+), 67 deletions(-) diff --git a/site/content/en/latest/tasks/traffic/client-traffic-policy.md b/site/content/en/latest/tasks/traffic/client-traffic-policy.md index b1782570796..37d85e5f8e1 100644 --- a/site/content/en/latest/tasks/traffic/client-traffic-policy.md +++ b/site/content/en/latest/tasks/traffic/client-traffic-policy.md @@ -495,7 +495,7 @@ Handling connection for 8888 ### Enable HTTP Request Received Timeout -This feature allows you to limit the take taken by the Envoy Proxy fleet to receive the entire request from the client, which is useful in preventing certain clients from consuming too much memory in Envoy +This feature allows you to limit the time taken by the Envoy Proxy fleet to receive the entire request from the client, which is useful in preventing certain clients from consuming too much memory in Envoy This example configures the HTTP request timeout for the client, please check out the details [here](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#stream-timeouts). {{< tabpane text=true >}} @@ -638,5 +638,51 @@ envoy_http_downstream_cx_idle_timeout{envoy_http_conn_manager_prefix="}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + [ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy [BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy diff --git a/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md b/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md index 3e75d98e239..51f9c65bf96 100644 --- a/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md +++ b/site/content/en/v1.0.1/tasks/traffic/client-traffic-policy.md @@ -412,7 +412,7 @@ Handling connection for 8888 ### Enable HTTP Request Received Timeout -This feature allows you to limit the take taken by the Envoy Proxy fleet to receive the entire request from the client, which is useful in preventing certain clients from consuming too much memory in Envoy +This feature allows you to limit the time taken by the Envoy Proxy fleet to receive the entire request from the client, which is useful in preventing certain clients from consuming too much memory in Envoy This example configures the HTTP request timeout for the client, please check out the details [here](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#stream-timeouts). ```shell @@ -464,70 +464,5 @@ curl -v http://$GATEWAY_HOST/get \ request timeout ``` -### Configure Client HTTP Idle Timeout - -The idle timeout is defined as the period in which there are no active requests. When the idle timeout is reached the connection will be closed. -For more details see [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout:~:text=...%7D%0A%7D-,idle_timeout,-(Duration)%20The). - -{{< tabpane text=true >}} -{{% tab header="Apply from stdin" %}} - -```shell -cat <}} - -Curl the example app through Envoy proxy: - -```shell -openssl s_client -crlf -connect $GATEWAY_HOST:443 -``` - -You should expect the connection to be closed after 5s. - -You can also check the number of connections closed due to idle timeout by using the following query: - -```shell -envoy_http_downstream_cx_idle_timeout{envoy_http_conn_manager_prefix=""} -``` - -The number of connections closed due to idle timeout should be increased by 1. - - [ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy [BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy From c8f12204d2cb434fc2193d81a4a4eefaeee648fb Mon Sep 17 00:00:00 2001 From: sh2 Date: Wed, 8 May 2024 18:42:51 +0800 Subject: [PATCH 15/17] fix: sort gateways by creation timestamp before translate (#3344) sort gateways by creation timestamp before translate Signed-off-by: shawnh2 Co-authored-by: zirain --- internal/gatewayapi/translator.go | 7 +++++++ test/e2e/tests/merge_gateways.go | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 631357ff118..d6c5283930f 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -6,6 +6,8 @@ package gatewayapi import ( + "sort" + "golang.org/x/exp/maps" "k8s.io/apimachinery/pkg/runtime/schema" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -156,6 +158,11 @@ func (t *Translator) Translate(resources *Resources) *TranslateResult { // Get Gateways belonging to our GatewayClass. gateways := t.GetRelevantGateways(resources.Gateways) + // Sort gateways based on timestamp. + sort.Slice(gateways, func(i, j int) bool { + return gateways[i].CreationTimestamp.Before(&(gateways[j].CreationTimestamp)) + }) + // Build IR maps. xdsIR, infraIR := t.InitIRs(gateways, resources) diff --git a/test/e2e/tests/merge_gateways.go b/test/e2e/tests/merge_gateways.go index fa8665dbc1d..900c305485e 100644 --- a/test/e2e/tests/merge_gateways.go +++ b/test/e2e/tests/merge_gateways.go @@ -240,13 +240,13 @@ var MergeGatewaysTest = suite.ConformanceTest{ }) }) - t.Run("clean-up conflicted gateway", func(t *testing.T) { + // Clean-up the conflicted gateway and route resources. + t.Cleanup(func() { conflictedGateway := new(gwapiv1.Gateway) conflictedHTTPRoute := new(gwapiv1.HTTPRoute) if err := suite.Client.Get(ctx, gw4NN, conflictedGateway); err != nil { t.Errorf("failed to get conflicted gateway: %v", err) - t.FailNow() } if err := suite.Client.Delete(ctx, conflictedGateway); err != nil { t.Errorf("failed to delete conflicted gateway: %v", err) @@ -254,7 +254,6 @@ var MergeGatewaysTest = suite.ConformanceTest{ if err := suite.Client.Get(ctx, route4NN, conflictedHTTPRoute); err != nil { t.Errorf("failed to get conflicted httproute: %v", err) - t.FailNow() } if err := suite.Client.Delete(ctx, conflictedHTTPRoute); err != nil { t.Errorf("failed to delete conflicted httproute: %v", err) From 04fb089b0c0c4f7c4b48f97f05006c0e13ec071b Mon Sep 17 00:00:00 2001 From: sh2 Date: Wed, 8 May 2024 23:57:44 +0800 Subject: [PATCH 16/17] chore: correct typos in comments and code (#3349) * fix typos in comment and code Signed-off-by: shawnh2 * fix tmpl file Signed-off-by: shawnh2 --------- Signed-off-by: shawnh2 --- .../kubernetes/proxy/resource.go | 8 ++++---- internal/xds/bootstrap/bootstrap.go | 18 +++++++++--------- internal/xds/bootstrap/bootstrap.yaml.tpl | 4 ++-- internal/xds/bootstrap/bootstrap_test.go | 16 ++++++++-------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go index dd9f7a90ff9..c4da07d893d 100644 --- a/internal/infrastructure/kubernetes/proxy/resource.go +++ b/internal/infrastructure/kubernetes/proxy/resource.go @@ -143,10 +143,10 @@ func expectedProxyContainers(infra *ir.ProxyInfra, proxyMetrics = infra.Config.Spec.Telemetry.Metrics } - maxHeapSizeBytes := caclulateMaxHeapSizeBytes(containerSpec.Resources) + maxHeapSizeBytes := calculateMaxHeapSizeBytes(containerSpec.Resources) // Get the default Bootstrap - bootstrapConfigurations, err := bootstrap.GetRenderedBootstrapConfig(&bootstrap.RenderBootsrapConfigOptions{ + bootstrapConfigurations, err := bootstrap.GetRenderedBootstrapConfig(&bootstrap.RenderBootstrapConfigOptions{ ProxyMetrics: proxyMetrics, MaxHeapSizeBytes: maxHeapSizeBytes, }) @@ -395,9 +395,9 @@ func expectedContainerEnv(containerSpec *egv1a1.KubernetesContainerSpec) []corev } } -// caclulateMaxHeapSizeBytes calculates the maximum heap size in bytes as 80% of Envoy container memory limits. +// calculateMaxHeapSizeBytes calculates the maximum heap size in bytes as 80% of Envoy container memory limits. // In case no limits are defined '0' is returned, which means no heap size limit is set. -func caclulateMaxHeapSizeBytes(envoyResourceRequirements *corev1.ResourceRequirements) uint64 { +func calculateMaxHeapSizeBytes(envoyResourceRequirements *corev1.ResourceRequirements) uint64 { if envoyResourceRequirements == nil || envoyResourceRequirements.Limits == nil { return 0 } diff --git a/internal/xds/bootstrap/bootstrap.go b/internal/xds/bootstrap/bootstrap.go index 68146e2ddaf..eb5e4398dc5 100644 --- a/internal/xds/bootstrap/bootstrap.go +++ b/internal/xds/bootstrap/bootstrap.go @@ -45,7 +45,7 @@ var bootstrapTmplStr string var bootstrapTmpl = template.Must(template.New(envoyCfgFileName).Parse(bootstrapTmplStr)) -// envoyBootstrap defines the envoy Bootstrap configuration. +// bootstrapConfig defines the envoy Bootstrap configuration. type bootstrapConfig struct { // parameters defines configurable bootstrap configuration parameters. parameters bootstrapParameters @@ -53,7 +53,7 @@ type bootstrapConfig struct { rendered string } -// envoyBootstrap defines the envoy Bootstrap configuration. +// bootstrapParameters defines the envoy Bootstrap configuration. type bootstrapParameters struct { // XdsServer defines the configuration of the XDS server. XdsServer xdsServerParameters @@ -70,7 +70,7 @@ type bootstrapParameters struct { // OtelMetricSinks defines the configuration of the OpenTelemetry sinks. OtelMetricSinks []metricSink - // EnableStatConfig defines whether to to customize the Envoy proxy stats. + // EnableStatConfig defines whether to customize the Envoy proxy stats. EnableStatConfig bool // StatsMatcher is to control creation of custom Envoy stats with prefix, // suffix, and regex expressions match on the name of the stats. @@ -113,8 +113,8 @@ type readyServerParameters struct { type StatsMatcherParameters struct { Exacts []string - Prefixs []string - Suffixs []string + Prefixes []string + Suffixes []string RegularExpressions []string } @@ -122,7 +122,7 @@ type overloadManagerParameters struct { MaxHeapSizeBytes uint64 } -type RenderBootsrapConfigOptions struct { +type RenderBootstrapConfigOptions struct { ProxyMetrics *egv1a1.ProxyMetrics MaxHeapSizeBytes uint64 } @@ -139,7 +139,7 @@ func (b *bootstrapConfig) render() error { } // GetRenderedBootstrapConfig renders the bootstrap YAML string -func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, error) { +func GetRenderedBootstrapConfig(opts *RenderBootstrapConfigOptions) (string, error) { var ( enablePrometheus = true enablePrometheusCompression = false @@ -199,9 +199,9 @@ func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, erro case egv1a1.StringMatchExact: StatsMatcher.Exacts = append(StatsMatcher.Exacts, match.Value) case egv1a1.StringMatchPrefix: - StatsMatcher.Prefixs = append(StatsMatcher.Prefixs, match.Value) + StatsMatcher.Prefixes = append(StatsMatcher.Prefixes, match.Value) case egv1a1.StringMatchSuffix: - StatsMatcher.Suffixs = append(StatsMatcher.Suffixs, match.Value) + StatsMatcher.Suffixes = append(StatsMatcher.Suffixes, match.Value) case egv1a1.StringMatchRegularExpression: if err := regex.Validate(match.Value); err != nil { return "", err diff --git a/internal/xds/bootstrap/bootstrap.yaml.tpl b/internal/xds/bootstrap/bootstrap.yaml.tpl index cc59b913862..af05d9752a5 100644 --- a/internal/xds/bootstrap/bootstrap.yaml.tpl +++ b/internal/xds/bootstrap/bootstrap.yaml.tpl @@ -16,10 +16,10 @@ stats_config: {{- range $_, $item := .StatsMatcher.Exacts }} - exact: {{$item}} {{- end}} - {{- range $_, $item := .StatsMatcher.Prefixs }} + {{- range $_, $item := .StatsMatcher.Prefixes }} - prefix: {{$item}} {{- end}} - {{- range $_, $item := .StatsMatcher.Suffixs }} + {{- range $_, $item := .StatsMatcher.Suffixes }} - suffix: {{$item}} {{- end}} {{- range $_, $item := .StatsMatcher.RegularExpressions }} diff --git a/internal/xds/bootstrap/bootstrap_test.go b/internal/xds/bootstrap/bootstrap_test.go index 54ee52f3d4e..19e020c499e 100644 --- a/internal/xds/bootstrap/bootstrap_test.go +++ b/internal/xds/bootstrap/bootstrap_test.go @@ -22,11 +22,11 @@ import ( func TestGetRenderedBootstrapConfig(t *testing.T) { cases := []struct { name string - opts *RenderBootsrapConfigOptions + opts *RenderBootstrapConfigOptions }{ { name: "disable-prometheus", - opts: &RenderBootsrapConfigOptions{ + opts: &RenderBootstrapConfigOptions{ ProxyMetrics: &egv1a1.ProxyMetrics{ Prometheus: &egv1a1.ProxyPrometheusProvider{ Disable: true, @@ -36,7 +36,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, { name: "enable-prometheus", - opts: &RenderBootsrapConfigOptions{ + opts: &RenderBootstrapConfigOptions{ ProxyMetrics: &egv1a1.ProxyMetrics{ Prometheus: &egv1a1.ProxyPrometheusProvider{}, }, @@ -44,7 +44,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, { name: "enable-prometheus-gzip-compression", - opts: &RenderBootsrapConfigOptions{ + opts: &RenderBootstrapConfigOptions{ ProxyMetrics: &egv1a1.ProxyMetrics{ Prometheus: &egv1a1.ProxyPrometheusProvider{ Compression: &egv1a1.Compression{ @@ -56,7 +56,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, { name: "otel-metrics", - opts: &RenderBootsrapConfigOptions{ + opts: &RenderBootstrapConfigOptions{ ProxyMetrics: &egv1a1.ProxyMetrics{ Prometheus: &egv1a1.ProxyPrometheusProvider{ Disable: true, @@ -75,7 +75,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, { name: "otel-metrics-backendref", - opts: &RenderBootsrapConfigOptions{ + opts: &RenderBootstrapConfigOptions{ ProxyMetrics: &egv1a1.ProxyMetrics{ Prometheus: &egv1a1.ProxyPrometheusProvider{ Disable: true, @@ -103,7 +103,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, { name: "custom-stats-matcher", - opts: &RenderBootsrapConfigOptions{ + opts: &RenderBootstrapConfigOptions{ ProxyMetrics: &egv1a1.ProxyMetrics{ Matches: []egv1a1.StringMatch{ { @@ -132,7 +132,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, { name: "with-max-heap-size-bytes", - opts: &RenderBootsrapConfigOptions{ + opts: &RenderBootstrapConfigOptions{ MaxHeapSizeBytes: 1073741824, }, }, From 0457ee7417288159eaa4422ee243b808a1696604 Mon Sep 17 00:00:00 2001 From: Dingkang Li Date: Thu, 9 May 2024 03:18:58 +0800 Subject: [PATCH 17/17] feat: support access log formatters (#3303) * Support access log formatters in EnvoyProxy Signed-off-by: Dingkang Li * Configure access log formatters based on command operators automatically Signed-off-by: Dingkang Li * Use ToAny function in protocov package Signed-off-by: Dingkang Li --------- Signed-off-by: Dingkang Li Co-authored-by: zirain --- internal/xds/translator/accesslog.go | 97 +++++++++ .../in/xds-ir/accesslog-formatters.yaml | 52 +++++ .../xds-ir/accesslog-formatters.clusters.yaml | 49 +++++ .../accesslog-formatters.endpoints.yaml | 12 ++ .../accesslog-formatters.listeners.yaml | 196 ++++++++++++++++++ .../xds-ir/accesslog-formatters.routes.yaml | 14 ++ 6 files changed, 420 insertions(+) create mode 100644 internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml diff --git a/internal/xds/translator/accesslog.go b/internal/xds/translator/accesslog.go index 9f1f17a09d9..446dc7d3fba 100644 --- a/internal/xds/translator/accesslog.go +++ b/internal/xds/translator/accesslog.go @@ -8,12 +8,16 @@ package translator import ( "errors" "sort" + "strings" accesslog "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v3" cfgcore "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" fileaccesslog "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/file/v3" grpcaccesslog "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/grpc/v3" otelaccesslog "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/open_telemetry/v3" + celformatter "github.com/envoyproxy/go-control-plane/envoy/extensions/formatter/cel/v3" + metadataformatter "github.com/envoyproxy/go-control-plane/envoy/extensions/formatter/metadata/v3" + reqwithoutqueryformatter "github.com/envoyproxy/go-control-plane/envoy/extensions/formatter/req_without_query/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" otlpcommonv1 "go.opentelemetry.io/proto/otlp/common/v1" "golang.org/x/exp/maps" @@ -22,6 +26,7 @@ import ( "k8s.io/utils/ptr" "github.com/envoyproxy/gateway/internal/ir" + "github.com/envoyproxy/gateway/internal/utils/protocov" "github.com/envoyproxy/gateway/internal/xds/types" ) @@ -46,6 +51,10 @@ const ( otelLogName = "otel_envoy_accesslog" otelAccessLog = "envoy.access_loggers.open_telemetry" + + reqWithoutQueryCommandOperator = "%REQ_WITHOUT_QUERY" + metadataCommandOperator = "%METADATA" + celCommandOperator = "%CEL" ) // for the case when a route does not exist to upstream, hcm logs will not be present @@ -55,6 +64,28 @@ var listenerAccessLogFilter = &accesslog.AccessLogFilter{ }, } +var ( + // reqWithoutQueryFormatter configures additional formatters needed for some of the format strings like "REQ_WITHOUT_QUERY" + reqWithoutQueryFormatter = &cfgcore.TypedExtensionConfig{ + Name: "envoy.formatter.req_without_query", + TypedConfig: protocov.ToAny(&reqwithoutqueryformatter.ReqWithoutQuery{}), + } + + // metadataFormatter configures additional formatters needed for some of the format strings like "METADATA" + // for more information, see https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/formatter/metadata/v3/metadata.proto + metadataFormatter = &cfgcore.TypedExtensionConfig{ + Name: "envoy.formatter.metadata", + TypedConfig: protocov.ToAny(&metadataformatter.Metadata{}), + } + + // celFormatter configures additional formatters needed for some of the format strings like "CEL" + // for more information, see https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/formatter/cel/v3/cel.proto + celFormatter = &cfgcore.TypedExtensionConfig{ + Name: "envoy.formatter.cel", + TypedConfig: protocov.ToAny(&celformatter.Cel{}), + } +) + func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLog { if al == nil { return nil @@ -84,6 +115,11 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo }, } + formatters := accessLogTextFormatters(format) + if len(formatters) != 0 { + filelog.GetLogFormat().Formatters = formatters + } + // TODO: find a better way to handle this accesslogAny, _ := anypb.New(filelog) accessLogs = append(accessLogs, &accesslog.AccessLog{ @@ -122,6 +158,11 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo }, } + formatters := accessLogJSONFormatters(json.JSON) + if len(formatters) != 0 { + filelog.GetLogFormat().Formatters = formatters + } + accesslogAny, _ := anypb.New(filelog) accessLogs = append(accessLogs, &accesslog.AccessLog{ Name: wellknown.FileAccessLog, @@ -182,6 +223,62 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo return accessLogs } +func accessLogTextFormatters(text string) []*cfgcore.TypedExtensionConfig { + formatters := make([]*cfgcore.TypedExtensionConfig, 0, 3) + + if strings.Contains(text, reqWithoutQueryCommandOperator) { + formatters = append(formatters, reqWithoutQueryFormatter) + } + + if strings.Contains(text, metadataCommandOperator) { + formatters = append(formatters, metadataFormatter) + } + + if strings.Contains(text, celCommandOperator) { + formatters = append(formatters, celFormatter) + } + + return formatters +} + +func accessLogJSONFormatters(json map[string]string) []*cfgcore.TypedExtensionConfig { + reqWithoutQuery, metadata, cel := false, false, false + + for _, value := range json { + if reqWithoutQuery && metadata && cel { + break + } + + if strings.Contains(value, reqWithoutQueryCommandOperator) { + reqWithoutQuery = true + } + + if strings.Contains(value, metadataCommandOperator) { + metadata = true + } + + if strings.Contains(value, celCommandOperator) { + cel = true + } + } + + formatters := make([]*cfgcore.TypedExtensionConfig, 0, 3) + + if reqWithoutQuery { + formatters = append(formatters, reqWithoutQueryFormatter) + } + + if metadata { + formatters = append(formatters, metadataFormatter) + } + + if cel { + formatters = append(formatters, celFormatter) + } + + return formatters +} + // read more here: https://opentelemetry.io/docs/specs/otel/resource/semantic_conventions/k8s/ const ( k8sNamespaceNameKey = "k8s.namespace.name" diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml new file mode 100644 index 00000000000..4dc9c30bf1a --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml @@ -0,0 +1,52 @@ +name: "accesslog" +accesslog: + text: + - path: "/dev/stdout" + format: | + [%START_TIME%] "%CEL(request.method)% %CEL(request.path)% %CEL(request.protocol)%" %CEL(response.code)% %CEL(response.flags)% %CEL(request.total_size)% %CEL(response.total_size)% %CEL(request.duration)% %CEL(response.headers['X-ENVOY-UPSTREAM-SERVICE-TIME'])% "%CEL(request.headers['X-FORWARDED-FOR'])%" "%CEL(request.useragent)%" "%CEL(request.id)%" "%CEL(request.host)%" "%CEL(upstream.address)%" + json: + - path: "/dev/stdout" + json: + start_time: "%START_TIME%" + method: "%REQ(:METHOD)%" + path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" + protocol: "%PROTOCOL%" + response_code: "%RESPONSE_CODE%" + test_key: "%METADATA(DYNAMIC:com.test.my_filter:test_key)%" + - path: "/dev/stdout" + json: + start_time: "%START_TIME%" + method: "%REQ(:METHOD)%" + path_without_query: "%REQ_WITHOUT_QUERY(X-ENVOY-ORIGINAL-PATH?:PATH)%" + protocol: "%PROTOCOL%" + response_code: "%RESPONSE_CODE%" + openTelemetry: + - text: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + attributes: + "response_code": "%RESPONSE_CODE%" + resources: + "cluster_name": "cluster1" + host: otel-collector.default.svc.cluster.local + port: 4317 +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + directResponse: + body: "Unknown custom filter type: UnsupportedType" + statusCode: 500 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml new file mode 100644 index 00000000000..7168156486d --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml @@ -0,0 +1,49 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: direct-route-dest + lbPolicy: LEAST_REQUEST + name: direct-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: otel-collector.default.svc.cluster.local + portValue: 4317 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: accesslog|otel-collector.default.svc.cluster.local|4317/backend/0 + name: accesslog|otel-collector.default.svc.cluster.local|4317 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + type: STRICT_DNS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.endpoints.yaml new file mode 100644 index 00000000000..20c80b3aaaa --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: direct-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: direct-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml new file mode 100644 index 00000000000..3407a6549c7 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.listeners.yaml @@ -0,0 +1,196 @@ +- accessLog: + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + formatters: + - name: envoy.formatter.cel + typedConfig: + '@type': type.googleapis.com/envoy.extensions.formatter.cel.v3.Cel + textFormatSource: + inlineString: | + [%START_TIME%] "%CEL(request.method)% %CEL(request.path)% %CEL(request.protocol)%" %CEL(response.code)% %CEL(response.flags)% %CEL(request.total_size)% %CEL(response.total_size)% %CEL(request.duration)% %CEL(response.headers['X-ENVOY-UPSTREAM-SERVICE-TIME'])% "%CEL(request.headers['X-FORWARDED-FOR'])%" "%CEL(request.useragent)%" "%CEL(request.id)%" "%CEL(request.host)%" "%CEL(upstream.address)%" + path: /dev/stdout + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + formatters: + - name: envoy.formatter.metadata + typedConfig: + '@type': type.googleapis.com/envoy.extensions.formatter.metadata.v3.Metadata + jsonFormat: + method: '%REQ(:METHOD)%' + path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%' + protocol: '%PROTOCOL%' + response_code: '%RESPONSE_CODE%' + start_time: '%START_TIME%' + test_key: '%METADATA(DYNAMIC:com.test.my_filter:test_key)%' + path: /dev/stdout + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + formatters: + - name: envoy.formatter.req_without_query + typedConfig: + '@type': type.googleapis.com/envoy.extensions.formatter.req_without_query.v3.ReqWithoutQuery + jsonFormat: + method: '%REQ(:METHOD)%' + path_without_query: '%REQ_WITHOUT_QUERY(X-ENVOY-ORIGINAL-PATH?:PATH)%' + protocol: '%PROTOCOL%' + response_code: '%RESPONSE_CODE%' + start_time: '%START_TIME%' + path: /dev/stdout + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.open_telemetry + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig + attributes: + values: + - key: k8s.namespace.name + value: + stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%' + - key: k8s.pod.name + value: + stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%' + - key: response_code + value: + stringValue: '%RESPONSE_CODE%' + body: + stringValue: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + commonConfig: + grpcService: + envoyGrpc: + authority: otel-collector.default.svc.cluster.local + clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + logName: otel_envoy_accesslog + transportApiVersion: V3 + resourceAttributes: + values: + - key: cluster_name + value: + stringValue: cluster1 + address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + formatters: + - name: envoy.formatter.cel + typedConfig: + '@type': type.googleapis.com/envoy.extensions.formatter.cel.v3.Cel + textFormatSource: + inlineString: | + [%START_TIME%] "%CEL(request.method)% %CEL(request.path)% %CEL(request.protocol)%" %CEL(response.code)% %CEL(response.flags)% %CEL(request.total_size)% %CEL(response.total_size)% %CEL(request.duration)% %CEL(response.headers['X-ENVOY-UPSTREAM-SERVICE-TIME'])% "%CEL(request.headers['X-FORWARDED-FOR'])%" "%CEL(request.useragent)%" "%CEL(request.id)%" "%CEL(request.host)%" "%CEL(upstream.address)%" + path: /dev/stdout + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + formatters: + - name: envoy.formatter.metadata + typedConfig: + '@type': type.googleapis.com/envoy.extensions.formatter.metadata.v3.Metadata + jsonFormat: + method: '%REQ(:METHOD)%' + path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%' + protocol: '%PROTOCOL%' + response_code: '%RESPONSE_CODE%' + start_time: '%START_TIME%' + test_key: '%METADATA(DYNAMIC:com.test.my_filter:test_key)%' + path: /dev/stdout + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + formatters: + - name: envoy.formatter.req_without_query + typedConfig: + '@type': type.googleapis.com/envoy.extensions.formatter.req_without_query.v3.ReqWithoutQuery + jsonFormat: + method: '%REQ(:METHOD)%' + path_without_query: '%REQ_WITHOUT_QUERY(X-ENVOY-ORIGINAL-PATH?:PATH)%' + protocol: '%PROTOCOL%' + response_code: '%RESPONSE_CODE%' + start_time: '%START_TIME%' + path: /dev/stdout + - name: envoy.access_loggers.open_telemetry + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig + attributes: + values: + - key: k8s.namespace.name + value: + stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%' + - key: k8s.pod.name + value: + stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%' + - key: response_code + value: + stringValue: '%RESPONSE_CODE%' + body: + stringValue: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + commonConfig: + grpcService: + envoyGrpc: + authority: otel-collector.default.svc.cluster.local + clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + logName: otel_envoy_accesslog + transportApiVersion: V3 + resourceAttributes: + values: + - key: cluster_name + value: + stringValue: cluster1 + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml new file mode 100644 index 00000000000..d4a7fa5ae20 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - directResponse: + body: + inlineString: 'Unknown custom filter type: UnsupportedType' + status: 500 + match: + prefix: / + name: direct-route