diff --git a/docs/content/getting-started/quick-start-with-kubernetes.md b/docs/content/getting-started/quick-start-with-kubernetes.md index 30530522d..ddd714b8f 100644 --- a/docs/content/getting-started/quick-start-with-kubernetes.md +++ b/docs/content/getting-started/quick-start-with-kubernetes.md @@ -35,12 +35,18 @@ rules: - "" resources: - services - - endpoints - secrets verbs: - get - list - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch - apiGroups: - extensions - networking.k8s.io diff --git a/docs/content/migration/v3.md b/docs/content/migration/v3.md new file mode 100644 index 000000000..4529a89a4 --- /dev/null +++ b/docs/content/migration/v3.md @@ -0,0 +1,53 @@ +--- +title: "Traefik Migration Documentation" +description: "Learn the steps needed to migrate to new Traefik Proxy v3 versions. Read the technical documentation." +--- + +# Migration: Steps needed between the versions + +## v3.0 to v3.1 + +### Kubernetes Provider RBACs + +Starting with v3.1, the Kubernetes Providers now use the [EndpointSlices API](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/) (Kubernetes >=v1.21) to discover service endpoint addresses. + +Therefore, in the corresponding RBACs (see [KubernetesIngress](../routing/providers/kubernetes-ingress.md#configuration-example), [KubernetesCRD](../reference/dynamic-configuration/kubernetes-crd.md#rbac), and [KubernetesGateway](../reference/dynamic-configuration/kubernetes-gateway.md#rbac) provider RBACs), +the `endpoints` right has to be removed and the following `endpointslices` right has to be added. + +```yaml + ... + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch + ... +``` + +#### Gateway API: KubernetesGateway Provider + +In v3.1, the KubernetesGateway Provider is no longer an experimental feature. +It can be enabled without the associated `experimental.kubernetesgateway` option, which is now deprecated. + +??? example "An example of the experimental `kubernetesgateway` option" + + ```yaml tab="File (YAML)" + experimental: + kubernetesgateway: true + ``` + + ```toml tab="File (TOML)" + [experimental] + kubernetesgateway=true + ``` + + ```bash tab="CLI" + --experimental.kubernetesgateway=true + ``` + +##### Remediation + +The `kubernetesgateway` option should be removed from the experimental section of the static configuration. +To configure `kubernetesgateway`, please check out the [KubernetesGateway Provider documentation](../providers/kubernetes-gateway.md). diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index eaefb45a1..6e7c83605 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -183,7 +183,7 @@ _Optional, Default: ""_ A label selector can be defined to filter on specific resource objects only, this applies only to Traefik [Custom Resources](../routing/providers/kubernetes-crd.md#custom-resource-definition-crd) -and has no effect on Kubernetes `Secrets`, `Endpoints` and `Services`. +and has no effect on Kubernetes `Secrets`, `EndpointSlices` and `Services`. If left empty, Traefik processes all resource objects in the configured namespaces. See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details. diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml index 6d0afb7a3..ef6dcab97 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml @@ -8,13 +8,19 @@ rules: - "" resources: - services - - endpoints - secrets - nodes verbs: - get - list - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch - apiGroups: - extensions - networking.k8s.io diff --git a/docs/content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml b/docs/content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml index 52e719f1b..4f54608e7 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml @@ -15,12 +15,18 @@ rules: - "" resources: - services - - endpoints - secrets verbs: - get - list - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch - apiGroups: - gateway.networking.k8s.io resources: diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index 136f8dc8e..951bf43ed 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -211,7 +211,7 @@ WriteTimeout is the maximum duration before timing out writes of the response. I Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```) `--experimental.kubernetesgateway`: -Allow the Kubernetes gateway api provider usage. (Default: ```false```) +(Deprecated) Allow the Kubernetes gateway api provider usage. (Default: ```false```) `--experimental.localplugins.`: Local plugins configuration. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 12636602c..5f3327d82 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -211,7 +211,7 @@ WriteTimeout is the maximum duration before timing out writes of the response. I Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```) `TRAEFIK_EXPERIMENTAL_KUBERNETESGATEWAY`: -Allow the Kubernetes gateway api provider usage. (Default: ```false```) +(Deprecated) Allow the Kubernetes gateway api provider usage. (Default: ```false```) `TRAEFIK_EXPERIMENTAL_LOCALPLUGINS_`: Local plugins configuration. (Default: ```false```) diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index 796569470..6c21d76ba 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -29,12 +29,18 @@ which in turn will create the resulting routers, services, handlers, etc. - "" resources: - services - - endpoints - secrets verbs: - get - list - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch - apiGroups: - extensions - networking.k8s.io @@ -427,12 +433,19 @@ This way, any Ingress attached to this Entrypoint will have TLS termination by d - "" resources: - services - - endpoints - secrets verbs: - get - list - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch - apiGroups: - extensions - networking.k8s.io @@ -612,12 +625,19 @@ For more options, please refer to the available [annotations](#on-ingress). - "" resources: - services - - endpoints - secrets verbs: - get - list - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch - apiGroups: - extensions - networking.k8s.io diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 5cac2369f..17a4bfefc 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -172,6 +172,7 @@ nav: - 'HTTP Challenge': 'user-guides/docker-compose/acme-http/index.md' - 'DNS Challenge': 'user-guides/docker-compose/acme-dns/index.md' - 'Migration': + - 'Traefik v3 minor migrations': 'migration/v3.md' - 'Traefik v2 to v3': - 'Migration guide': 'migration/v2-to-v3.md' - 'Configuration changes for v3': 'migration/v2-to-v3-details.md' diff --git a/go.mod b/go.mod index 09301931d..8a2f2fded 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/traefik/traefik/v3 -go 1.22 +go 1.22.4 require ( github.com/BurntSushi/toml v1.4.0 @@ -22,7 +22,7 @@ require ( github.com/golang/protobuf v1.5.4 github.com/google/go-github/v28 v28.1.1 github.com/gorilla/mux v1.8.0 - github.com/gorilla/websocket v1.5.0 + github.com/gorilla/websocket v1.5.1 github.com/hashicorp/consul/api v1.26.1 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-multierror v1.1.1 @@ -79,7 +79,7 @@ require ( go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 - golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f golang.org/x/mod v0.18.0 golang.org/x/net v0.26.0 golang.org/x/sys v0.21.0 @@ -88,14 +88,14 @@ require ( golang.org/x/tools v0.22.0 google.golang.org/grpc v1.64.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.29.2 - k8s.io/apiextensions-apiserver v0.28.3 - k8s.io/apimachinery v0.29.2 - k8s.io/client-go v0.29.2 - k8s.io/utils v0.0.0-20230726121419-3b25d923346b + k8s.io/api v0.30.0 + k8s.io/apiextensions-apiserver v0.30.0 + k8s.io/apimachinery v0.30.0 + k8s.io/client-go v0.30.0 + k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 mvdan.cc/xurls/v2 v2.5.0 - sigs.k8s.io/controller-runtime v0.16.3 - sigs.k8s.io/gateway-api v1.0.0 + sigs.k8s.io/controller-runtime v0.18.0 + sigs.k8s.io/gateway-api v1.1.0 ) require ( @@ -165,9 +165,9 @@ require ( github.com/distribution/reference v0.5.0 // indirect github.com/dnsimple/dnsimple-go v1.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.7.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/exoscale/egoscale v0.102.3 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -178,11 +178,11 @@ require ( github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-logr/zapr v1.2.4 // indirect + github.com/go-logr/zapr v1.3.0 // indirect github.com/go-ole/go-ole v1.2.6 // 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/go-resty/resty/v2 v2.11.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-viper/mapstructure/v2 v2.0.0 // indirect @@ -316,9 +316,9 @@ require ( github.com/yandex-cloud/go-sdk v0.0.0-20240318084659-dfa50323a0b4 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/zeebo/errs v1.2.2 // indirect - go.etcd.io/etcd/api/v3 v3.5.9 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect - go.etcd.io/etcd/client/v3 v3.5.9 // indirect + go.etcd.io/etcd/api/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/v3 v3.5.10 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/contrib/propagators/aws v1.27.0 // indirect @@ -347,8 +347,8 @@ require ( gopkg.in/ns1/ns1-go.v2 v2.9.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108 // indirect nhooyr.io/websocket v1.8.7 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/go.sum b/go.sum index 9e8011f42..80cb51429 100644 --- a/go.sum +++ b/go.sum @@ -151,7 +151,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 h1:M/1u4HBpwLuMtjlxuI2y6HoVLzF github.com/aws/aws-sdk-go-v2/service/sts v1.28.12/go.mod h1:kcfd+eTdEi/40FIbLq4Hif3XMXnl5b/+t/KTfLt9xIk= github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -282,8 +281,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -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.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -295,8 +294,8 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= -github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exoscale/egoscale v0.102.3 h1:DYqN2ipoLKpiFoprRGQkp2av/Ze7sUYYlGhi1N62tfY= github.com/exoscale/egoscale v0.102.3/go.mod h1:RPf2Gah6up+6kAEayHTQwqapzXlm93f0VQas/UEGU5c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -349,26 +348,22 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.5/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/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/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.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= 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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= @@ -519,8 +514,8 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 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/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf h1:C1GPyPJrOlJlIrcaBBiBpDsqZena2Ks8spa5xZqr1XQ= github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf/go.mod h1:zXqxTI6jXDdKnlf8s+nT+3c8LrwUEy3yNpO4XJL90lA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -874,8 +869,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= -github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -1168,12 +1163,12 @@ github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtC go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.9 h1:4wSsluwyTbGGmyjJktOf3wFQoTBIURXHnq9n/G/JQHs= -go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k= -go.etcd.io/etcd/client/pkg/v3 v3.5.9 h1:oidDC4+YEuSIQbsR94rY9gur91UPL6DnxDCIYd2IGsE= -go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4= -go.etcd.io/etcd/client/v3 v3.5.9 h1:r5xghnU7CwbUxD/fbUtRyJGaYNfDun8sp/gTr1hew6E= -go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA= +go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1221,18 +1216,15 @@ go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naR go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/ratelimit v0.3.0 h1:IdZd9wqvFXnvLvSEBo0KPcGfkoBGNkpTHlrE3Rcjkjw= @@ -1240,7 +1232,6 @@ go.uber.org/ratelimit v0.3.0/go.mod h1:So5LG7CV1zWpY1sHe+DXTJqQvOx+FFPFaAs2SnoyB go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -1280,8 +1271,8 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +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/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1507,7 +1498,6 @@ golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -1517,8 +1507,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= -gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= @@ -1650,20 +1638,20 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= -k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= -k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08= -k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc= -k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= -k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= -k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= -k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= +k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= +k8s.io/apiextensions-apiserver v0.30.0 h1:jcZFKMqnICJfRxTgnC4E+Hpcq8UEhT8B2lhBcQ+6uAs= +k8s.io/apiextensions-apiserver v0.30.0/go.mod h1:N9ogQFGcrbWqAY9p2mUAL5mGxsLqwgtUce127VtRX5Y= +k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= +k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= +k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= +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-20240423202451-8948a665c108 h1:Q8Z7VlGhcJgBHJHYugJ/K/7iB8a2eSxCyxdVjJp+lLY= +k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 h1:ao5hUqGhsqdm+bYbjH/pRkCs0unBGe9UyDahzs9zQzQ= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8= mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= @@ -1671,10 +1659,10 @@ nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0 nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= -sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= -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/controller-runtime v0.18.0 h1:Z7jKuX784TQSUL1TIyeuF7j8KXZ4RtSX0YgtjKcSTME= +sigs.k8s.io/controller-runtime v0.18.0/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM= +sigs.k8s.io/gateway-api v1.1.0/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/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/integration/fixtures/k8s-conformance/00-experimental-v1.0.0.yml b/integration/fixtures/k8s-conformance/00-experimental-v1.0.0.yml deleted file mode 100644 index bbb71f11f..000000000 --- a/integration/fixtures/k8s-conformance/00-experimental-v1.0.0.yml +++ /dev/null @@ -1,11763 +0,0 @@ -# Copyright 2023 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. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# Gateway API Experimental channel install -# ---- -# -# 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 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - labels: - gateway.networking.k8s.io/policy: Direct - name: backendtlspolicies.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: BackendTLSPolicy - listKind: BackendTLSPolicyList - plural: backendtlspolicies - shortNames: - - btlspolicy - singular: backendtlspolicy - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha2 - schema: - openAPIV3Schema: - 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' - 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 BackendTLSPolicy. - 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" - 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])?$ - 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])?)*$ - 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])?)*$ - 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\"" - enum: - - System - 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 != "") - required: - - targetRef - - tls - type: object - status: - description: Status defines the current state of BackendTLSPolicy. - 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." - 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." - properties: - ancestorRef: - description: AncestorRef corresponds with a ParentRef in the - spec that this PolicyAncestorStatus struct describes the status - of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, - \"gateway.networking.k8s.io\" is inferred. To set the - core API group (such as for a \"Service\" kind referent), - Group must be explicitly set to \"\" (empty string). \n - 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." - 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" - 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" - 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 " - 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" - 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. --- 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 - 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. \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." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - required: - - ancestorRef - - controllerName - type: object - maxItems: 16 - type: array - required: - - ancestors - 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_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 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: gatewayclasses.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: GatewayClass - listKind: GatewayClassList - plural: gatewayclasses - shortNames: - - gc - singular: gatewayclass - scope: Cluster - 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 - 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" - 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." - 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 - 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 - 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" - 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." - 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 - 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 - type: array - x-kubernetes-list-type: set - 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_gateways.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: 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. \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. - maxLength: 253 - minLength: 1 - type: string - infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " - 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: - - 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. - 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. - 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 - 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: {} - - 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. \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. - maxLength: 253 - minLength: 1 - type: string - infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " - 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: - - 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. - 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. - 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 - 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: {} -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 - 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\". - 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: \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`. - * 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" - 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." - 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. \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`. - * 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 - 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 " - 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." - 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" - 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." - 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" - 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" - 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 " - 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" - 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. \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" - 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 - 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 - " - 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.)" - 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. \n Support: Implementation-specific \n - 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. \n - 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" - 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." - 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). - \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" - 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" - 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." - 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. \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" - 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" - 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\". - \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)" - 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. \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 - 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. \n - 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" - 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." - 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). - \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" - 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" - 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." - 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: \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 " - 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\". \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)" - 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. \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 - 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. \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." - 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. \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 - 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" - 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. \n Support: Implementation-specific \n 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. \n 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" - 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." - 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). - \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" - 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" - 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." - 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. \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" - 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" - 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\". - \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)" - 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. \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 - 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. \n 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" - 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." - 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). - \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" - 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" - 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." - 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: \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 " - 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. \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." - 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 ```" - 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. \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." - 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. - \n 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." - 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)" - enum: - - Exact - - RegularExpression - type: string - type: object - 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 - type: object - maxItems: 16 - type: array - type: object - status: - 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." - items: - 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." - 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 - 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. \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." - 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. - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null ---- -# -# config/crd/experimental/gateway.networking.k8s.io_httproutes.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: httproutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: HTTPRoute - listKind: HTTPRouteList - plural: httproutes - singular: httproute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.hostnames - name: Hostnames - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - 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. - 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 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`. - * 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" - 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." - 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. \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`. - * 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 - 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 " - 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." - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - default: - - matches: - - path: - type: PathPrefix - 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). - 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" - 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 - 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 - " - 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.)" - 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. - 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" - 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. \n - 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" - 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." - 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). - \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" - 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" - 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." - 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. \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" - 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" - 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\". - \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)" - 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. \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 - 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 - requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n 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" - 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" - properties: - replaceFullPath: - 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 | / | /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified - when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? - has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when - replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type - == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified - when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' - ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' - when replacePrefixMatch is set - 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" - 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" - 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" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - 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" - 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." - 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). - \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" - 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" - 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." - 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: \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`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" - properties: - hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n 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" - properties: - replaceFullPath: - 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 | / | /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified - when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? - has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when - replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type - == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified - when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' - ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' - when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type - == ''ReplacePrefixMatch'' : true' - type: object - 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.requestRedirect must be nil if the - filter.type is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != - ''RequestRedirect'')' - - message: filter.requestRedirect must be specified - for RequestRedirect filter.type - rule: '!(!has(self.requestRedirect) && self.type == - ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type - is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite - filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - 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: May specify either httpRouteFilterRequestRedirect - or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') - && self.exists(f, f.type == ''URLRewrite''))' - - message: May specify either httpRouteFilterRequestRedirect - or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') - && self.exists(f, f.type == ''URLRewrite''))' - - 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 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() - <= 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').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\". \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)" - 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. \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 - 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. \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." - 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. \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 - 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" - 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. - 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" - 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. \n 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" - 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." - 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). - \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" - 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" - 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." - 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. \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" - 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" - 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\". - \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)" - 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. \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 - 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 - requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n 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" - 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" - properties: - replaceFullPath: - 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 | / | - /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when - type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) - : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath - is set - rule: 'has(self.replaceFullPath) ? self.type == - ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when - type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) - : true' - - message: type must be 'ReplacePrefixMatch' when - replacePrefixMatch is set - 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" - 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" - 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" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n 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" - 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." - 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). - \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" - 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" - 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." - 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: \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`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" - properties: - hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n 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" - properties: - replaceFullPath: - 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 | / | - /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when - type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) - : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath - is set - rule: 'has(self.replaceFullPath) ? self.type == - ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when - type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) - : true' - - message: type must be 'ReplacePrefixMatch' when - replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type - == ''ReplacePrefixMatch'' : true' - type: object - 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.requestRedirect must be nil if the filter.type - is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' - - message: filter.requestRedirect must be specified for RequestRedirect - filter.type - rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type - is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite - filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - 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: May specify either httpRouteFilterRequestRedirect - or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && - self.exists(f, f.type == ''URLRewrite''))' - - 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 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() <= - 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 - matches: - default: - - 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." - 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 ```" - 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. - items: - 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\"." - 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." - enum: - - Exact - - RegularExpression - 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 - 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" - enum: - - GET - - HEAD - - POST - - PUT - - DELETE - - CONNECT - - OPTIONS - - TRACE - - PATCH - type: string - path: - 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. - properties: - type: - default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" - enum: - - Exact - - PathPrefix - - RegularExpression - type: string - value: - default: / - description: Value of the HTTP path to match against. - maxLength: 1024 - type: string - type: object - x-kubernetes-validations: - - message: value must be an absolute path and start with - '/' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') - : true' - - message: must not contain '//' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') - : true' - - message: must not contain '/./' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') - : true' - - message: must not contain '/../' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') - : true' - - message: must not contain '%2f' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') - : true' - - message: must not contain '%2F' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') - : true' - - message: must not contain '#' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') - : true' - - message: must not end with '/..' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') - : true' - - message: must not end with '/.' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') - : true' - - message: type must be one of ['Exact', 'PathPrefix', - 'RegularExpression'] - rule: self.type in ['Exact','PathPrefix'] || self.type - == 'RegularExpression' - - message: must only contain valid characters (matching - ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) - for types ['Exact', 'PathPrefix'] - 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" - items: - 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." - 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." - enum: - - Exact - - RegularExpression - type: string - value: - description: Value is the value of HTTP query param - to be matched. - maxLength: 1024 - 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 - maxItems: 8 - type: array - timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " - 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" - 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" - pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ - type: string - type: object - x-kubernetes-validations: - - message: backendRequest timeout cannot be longer than request - timeout - rule: '!(has(self.request) && has(self.backendRequest) && - duration(self.request) != duration(''0s'') && duration(self.backendRequest) - > duration(self.request))' - type: object - x-kubernetes-validations: - - message: RequestRedirect filter must not be used together with - backendRefs - rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? - (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): - true' - - message: When using RequestRedirect filter with path.replacePrefixMatch, - exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) - && has(f.requestRedirect.path) && f.requestRedirect.path.type - == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) - ? ((size(self.matches) != 1 || !has(self.matches[0].path) || - self.matches[0].path.type != ''PathPrefix'') ? false : true) - : true' - - message: When using URLRewrite filter with path.replacePrefixMatch, - exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) - && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' - && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) - != 1 || !has(self.matches[0].path) || self.matches[0].path.type - != ''PathPrefix'') ? false : true) : true' - - message: Within backendRefs, when using RequestRedirect filter - with path.replacePrefixMatch, exactly one PathPrefix match must - be specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, - (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) - && has(f.requestRedirect.path) && f.requestRedirect.path.type - == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) - )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) - || self.matches[0].path.type != ''PathPrefix'') ? false : true) - : true' - - message: Within backendRefs, When using URLRewrite filter with - path.replacePrefixMatch, exactly one PathPrefix match must be - specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, - (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) - && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' - && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) - != 1 || !has(self.matches[0].path) || self.matches[0].path.type - != ''PathPrefix'') ? false : true) : true' - maxItems: 16 - type: array - type: object - status: - 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." - items: - 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." - 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 - 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. \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." - 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. - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.hostnames - name: Hostnames - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - 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. - 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 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`. - * 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" - 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." - 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. \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`. - * 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 - 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 " - 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." - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - default: - - matches: - - path: - type: PathPrefix - 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). - 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" - 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 - 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 - " - 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.)" - 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. - 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" - 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. \n - 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" - 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." - 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). - \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" - 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" - 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." - 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. \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" - 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" - 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\". - \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)" - 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. \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 - 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 - requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n 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" - 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" - properties: - replaceFullPath: - 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 | / | /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified - when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? - has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when - replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type - == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified - when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' - ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' - when replacePrefixMatch is set - 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" - 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" - 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" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - 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" - 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." - 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). - \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" - 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" - 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." - 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: \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`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" - properties: - hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n 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" - properties: - replaceFullPath: - 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 | / | /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified - when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? - has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when - replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type - == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified - when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' - ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' - when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type - == ''ReplacePrefixMatch'' : true' - type: object - 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.requestRedirect must be nil if the - filter.type is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != - ''RequestRedirect'')' - - message: filter.requestRedirect must be specified - for RequestRedirect filter.type - rule: '!(!has(self.requestRedirect) && self.type == - ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type - is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite - filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - 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: May specify either httpRouteFilterRequestRedirect - or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') - && self.exists(f, f.type == ''URLRewrite''))' - - message: May specify either httpRouteFilterRequestRedirect - or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') - && self.exists(f, f.type == ''URLRewrite''))' - - 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 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() - <= 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').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\". \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)" - 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. \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 - 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. \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." - 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. \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 - 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" - 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. - 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" - 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. \n 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" - 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." - 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). - \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" - 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" - 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." - 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. \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" - 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" - 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\". - \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)" - 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. \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 - 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 - requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n 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" - 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" - properties: - replaceFullPath: - 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 | / | - /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when - type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) - : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath - is set - rule: 'has(self.replaceFullPath) ? self.type == - ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when - type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) - : true' - - message: type must be 'ReplacePrefixMatch' when - replacePrefixMatch is set - 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" - 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" - 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" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n 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" - 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." - 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). - \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" - 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" - 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." - 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: \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`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" - properties: - hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n 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" - properties: - replaceFullPath: - 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 | / | - /" - 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`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when - type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) - : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath - is set - rule: 'has(self.replaceFullPath) ? self.type == - ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when - type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) - : true' - - message: type must be 'ReplacePrefixMatch' when - replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type - == ''ReplacePrefixMatch'' : true' - type: object - 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.requestRedirect must be nil if the filter.type - is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' - - message: filter.requestRedirect must be specified for RequestRedirect - filter.type - rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type - is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite - filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - 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: May specify either httpRouteFilterRequestRedirect - or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && - self.exists(f, f.type == ''URLRewrite''))' - - 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 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() <= - 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 - matches: - default: - - 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." - 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 ```" - 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. - items: - 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\"." - 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." - enum: - - Exact - - RegularExpression - 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 - 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" - enum: - - GET - - HEAD - - POST - - PUT - - DELETE - - CONNECT - - OPTIONS - - TRACE - - PATCH - type: string - path: - 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. - properties: - type: - default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" - enum: - - Exact - - PathPrefix - - RegularExpression - type: string - value: - default: / - description: Value of the HTTP path to match against. - maxLength: 1024 - type: string - type: object - x-kubernetes-validations: - - message: value must be an absolute path and start with - '/' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') - : true' - - message: must not contain '//' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') - : true' - - message: must not contain '/./' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') - : true' - - message: must not contain '/../' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') - : true' - - message: must not contain '%2f' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') - : true' - - message: must not contain '%2F' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') - : true' - - message: must not contain '#' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') - : true' - - message: must not end with '/..' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') - : true' - - message: must not end with '/.' when type one of ['Exact', - 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') - : true' - - message: type must be one of ['Exact', 'PathPrefix', - 'RegularExpression'] - rule: self.type in ['Exact','PathPrefix'] || self.type - == 'RegularExpression' - - message: must only contain valid characters (matching - ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) - for types ['Exact', 'PathPrefix'] - 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" - items: - 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." - 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." - enum: - - Exact - - RegularExpression - type: string - value: - description: Value is the value of HTTP query param - to be matched. - maxLength: 1024 - 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 - maxItems: 8 - type: array - timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " - 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" - 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" - pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ - type: string - type: object - x-kubernetes-validations: - - message: backendRequest timeout cannot be longer than request - timeout - rule: '!(has(self.request) && has(self.backendRequest) && - duration(self.request) != duration(''0s'') && duration(self.backendRequest) - > duration(self.request))' - type: object - x-kubernetes-validations: - - message: RequestRedirect filter must not be used together with - backendRefs - rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? - (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): - true' - - message: When using RequestRedirect filter with path.replacePrefixMatch, - exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) - && has(f.requestRedirect.path) && f.requestRedirect.path.type - == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) - ? ((size(self.matches) != 1 || !has(self.matches[0].path) || - self.matches[0].path.type != ''PathPrefix'') ? false : true) - : true' - - message: When using URLRewrite filter with path.replacePrefixMatch, - exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) - && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' - && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) - != 1 || !has(self.matches[0].path) || self.matches[0].path.type - != ''PathPrefix'') ? false : true) : true' - - message: Within backendRefs, when using RequestRedirect filter - with path.replacePrefixMatch, exactly one PathPrefix match must - be specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, - (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) - && has(f.requestRedirect.path) && f.requestRedirect.path.type - == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) - )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) - || self.matches[0].path.type != ''PathPrefix'') ? false : true) - : true' - - message: Within backendRefs, When using URLRewrite filter with - path.replacePrefixMatch, exactly one PathPrefix match must be - specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, - (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) - && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' - && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) - != 1 || !has(self.matches[0].path) || self.matches[0].path.type - != ''PathPrefix'') ? false : true) : true' - maxItems: 16 - type: array - type: object - status: - 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." - items: - 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." - 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 - 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. \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." - 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. - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - 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_referencegrants.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: referencegrants.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: ReferenceGrant - listKind: ReferenceGrantList - plural: referencegrants - shortNames: - - refgrant - singular: referencegrant - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - deprecated: true - deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated - and will be removed in a future release of the API. Please upgrade to v1beta1. - 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." - 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 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" - 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" - 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" - 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" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - namespace - type: object - maxItems: 16 - 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" - items: - 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" - 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" - 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. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - from - - to - type: object - type: object - served: true - storage: false - subresources: {} - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - 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." - 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 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" - 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" - 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" - 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" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - namespace - type: object - maxItems: 16 - 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" - items: - 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" - 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" - 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. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - from - - to - type: object - type: object - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null ---- -# -# config/crd/experimental/gateway.networking.k8s.io_tcproutes.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: tcproutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: TCPRoute - listKind: TCPRouteList - plural: tcproutes - singular: tcproute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - 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. - 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 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`. - * 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 - 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 " - 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." - 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" - 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." - 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" - 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" - 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 " - 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" - 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 TCP matchers and actions. - items: - 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 - 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" - 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." - 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\". \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)" - 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. \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 - 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. \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." - 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 - minItems: 1 - type: array - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - rules - type: object - status: - 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." - items: - 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." - 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 - 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. \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." - 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. - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - 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_tlsroutes.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: tlsroutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: TLSRoute - listKind: TLSRouteList - plural: tlsroutes - singular: tlsroute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - 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." - 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 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" - 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." - 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. \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`. - * 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 - 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 " - 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." - 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" - 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." - 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" - 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" - 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 " - 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" - 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 TLS matchers and actions. - items: - 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" - 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." - 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\". \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)" - 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. \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 - 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. \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." - 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 - minItems: 1 - type: array - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - rules - type: object - status: - 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." - items: - 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." - 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 - 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. \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." - 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. - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - 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_udproutes.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: udproutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: UDPRoute - listKind: UDPRouteList - plural: udproutes - singular: udproute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - 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. - 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 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`. - * 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 - 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 " - 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." - 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" - 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." - 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" - 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" - 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 " - 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" - 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 UDP matchers and actions. - items: - 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" - 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." - 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\". \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)" - 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. \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 - 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. \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." - 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 - minItems: 1 - type: array - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - rules - type: object - status: - 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." - items: - 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." - 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 - 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. \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." - 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. - 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" - 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." - 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" - 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" - 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 " - 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" - 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: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/integration/fixtures/k8s-conformance/00-experimental-v1.1.0.yml b/integration/fixtures/k8s-conformance/00-experimental-v1.1.0.yml new file mode 100644 index 000000000..1531a474c --- /dev/null +++ b/integration/fixtures/k8s-conformance/00-experimental-v1.1.0.yml @@ -0,0 +1,18317 @@ +# 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. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Gateway API Experimental channel install +# +--- +# +# 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/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: backendlbpolicies.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: BackendLBPolicy + listKind: BackendLBPolicyList + plural: backendlbpolicies + shortNames: + - blbpolicy + singular: backendlbpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + 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 + 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 BackendLBPolicy. + properties: + sessionPersistence: + description: |- + SessionPersistence defines and configures session persistence + for the backend. + + + 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)' + 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: + - targetRefs + type: object + status: + 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. + + + 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. + + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + items: + description: "Condition contains details for one aspect of + the current state of this API Resource.\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-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + 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_backendtlspolicies.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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + gateway.networking.k8s.io/policy: Direct + name: backendtlspolicies.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: BackendTLSPolicy + listKind: BackendTLSPolicyList + plural: backendtlspolicies + shortNames: + - btlspolicy + singular: backendtlspolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + 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 + 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 BackendTLSPolicy. + properties: + 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: |- + 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: + 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 + 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: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + validation: + description: Validation contains backend TLS validation configuration. + properties: + 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 + 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: + - 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: + - targetRefs + - validation + type: object + status: + description: Status defines the current state of BackendTLSPolicy. + 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. + + + 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. + + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + items: + description: "Condition contains details for one aspect of + the current state of this API Resource.\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-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + 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_gatewayclasses.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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + 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 + schema: + openAPIV3Schema: + 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 + 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. + + + 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 + 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: + 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. + + + 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: "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 + 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: true + 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. + + + 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 + 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. + + + 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 + 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: + 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. + + + 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: "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 + 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 + 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 + 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 + 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 + 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 + type: object + 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 + 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 + type: object + status: + 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. + + + 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. + 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. + + + 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.\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-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. + 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: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: true + storage: true + subresources: + status: {} + - 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. + + + 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 + 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 + 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 + type: object + 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 + 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 + type: object + status: + 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. + + + 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. + 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. + + + 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.\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-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. + 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: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: true + storage: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_httproutes.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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: httproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + 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. + 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 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. + + + 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. + + + 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: + + + 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: + default: + - matches: + - path: + type: PathPrefix + 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). + 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 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. + + + 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 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. + 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. + + + 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. + 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 + requestRedirect: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + 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. + + + 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. + + + 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. + + + 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. + + + 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 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 + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + 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.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - 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: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - 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 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').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. + + + 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. + + + 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. + 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. + + + 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. + 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 + requestRedirect: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + 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. + + + 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. + + + 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. + + + 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. + + + 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 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 + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + 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.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - 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: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - 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 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - 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. + + + 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\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. + items: + 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). + + + 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. + + + 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 + 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 + method: + 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 + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + 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. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + 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. + + + Support: Extended + items: + 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). + + + 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. + + + 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 + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + 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 + 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. + + + 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. + + + 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. + + + 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 + x-kubernetes-validations: + - message: backendRequest timeout cannot be longer than request + timeout + rule: '!(has(self.request) && has(self.backendRequest) && + duration(self.request) != duration(''0s'') && duration(self.backendRequest) + > duration(self.request))' + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + type: object + status: + 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. + + + 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. + 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. + + + 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.\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-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. + 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: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + 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. + 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 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. + + + 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. + + + 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: + + + 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: + default: + - matches: + - path: + type: PathPrefix + 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). + 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 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. + + + 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 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. + 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. + + + 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. + 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 + requestRedirect: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + 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. + + + 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. + + + 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. + + + 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. + + + 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 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 + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + 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.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - 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: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - 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 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').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. + + + 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. + + + 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. + 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. + + + 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. + 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 + requestRedirect: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + 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. + + + 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. + + + 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. + + + 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. + + + 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 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 + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + 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. + + + 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. + + + Support: Extended + properties: + replaceFullPath: + 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". + + + 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. + + + 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 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + 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.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - 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: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - 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 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - 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. + + + 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\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. + items: + 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). + + + 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. + + + 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 + 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 + method: + 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 + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + 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. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + 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. + + + Support: Extended + items: + 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). + + + 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. + + + 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 + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + 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 + 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. + + + 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. + + + 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. + + + 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 + x-kubernetes-validations: + - message: backendRequest timeout cannot be longer than request + timeout + rule: '!(has(self.request) && has(self.backendRequest) && + duration(self.request) != duration(''0s'') && duration(self.backendRequest) + > duration(self.request))' + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + type: object + status: + 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. + + + 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. + 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. + + + 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.\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-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. + 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: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + 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_referencegrants.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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: referencegrants.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: ReferenceGrant + listKind: ReferenceGrantList + plural: referencegrants + shortNames: + - refgrant + singular: referencegrant + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated + and will be removed in a future release of the API. Please upgrade to v1beta1. + 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. + + + 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 + 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 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. + + + 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. + + + 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. + + + 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. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + 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. + + + Support: Core + items: + 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. + + + 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: + + + * 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. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: false + subresources: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + 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. + + + 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 + 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 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. + + + 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. + + + 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. + + + 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. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + 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. + + + Support: Core + items: + 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. + + + 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: + + + * 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. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_tcproutes.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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: tcproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TCPRoute + listKind: TCPRouteList + plural: tcproutes + singular: tcproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + 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. + 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 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. + + + 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 TCP matchers and actions. + items: + 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 + connections, then 80% of connections 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. + + + 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. + 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 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + 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. + + + 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. + 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. + + + 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.\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-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. + 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: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + 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_tlsroutes.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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: tlsroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TLSRoute + listKind: TLSRouteList + plural: tlsroutes + singular: tlsroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + 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. + + + 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 + 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 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: + + + 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: + + + 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 TLS matchers and actions. + items: + 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. + + + 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. + + + 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. + 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 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + 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. + + + 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. + 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. + + + 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.\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-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. + 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: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + 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_udproutes.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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: udproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: UDPRoute + listKind: UDPRouteList + plural: udproutes + singular: udproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + 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. + 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 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. + + + 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 UDP matchers and actions. + items: + 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. + + + 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. + + + 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. + 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 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + 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. + + + 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. + 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. + + + 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.\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-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. + 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: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/integration/fixtures/k8s-conformance/01-rbac.yml b/integration/fixtures/k8s-conformance/01-rbac.yml index 004691004..3492bb453 100644 --- a/integration/fixtures/k8s-conformance/01-rbac.yml +++ b/integration/fixtures/k8s-conformance/01-rbac.yml @@ -15,12 +15,19 @@ rules: - "" resources: - services - - endpoints - secrets verbs: - get - list - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch - apiGroups: - gateway.networking.k8s.io resources: diff --git a/integration/k8s_conformance_test.go b/integration/k8s_conformance_test.go index 0e2b5e855..275ef6409 100644 --- a/integration/k8s_conformance_test.go +++ b/integration/k8s_conformance_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "io/fs" "os" "path/filepath" "slices" @@ -18,6 +19,7 @@ import ( "github.com/traefik/traefik/v3/integration/try" "github.com/traefik/traefik/v3/pkg/version" "gopkg.in/yaml.v3" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/util/sets" kclientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" @@ -27,10 +29,12 @@ import ( gatev1 "sigs.k8s.io/gateway-api/apis/v1" gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gatev1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - conformanceV1alpha1 "sigs.k8s.io/gateway-api/conformance/apis/v1alpha1" + "sigs.k8s.io/gateway-api/conformance" + v1 "sigs.k8s.io/gateway-api/conformance/apis/v1" "sigs.k8s.io/gateway-api/conformance/tests" "sigs.k8s.io/gateway-api/conformance/utils/config" ksuite "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/pkg/features" ) const ( @@ -84,7 +88,7 @@ func (s *K8sConformanceSuite) SetupSuite() { s.k3sContainer, err = k3s.RunContainer(ctx, testcontainers.WithImage(k3sImage), - k3s.WithManifest("./fixtures/k8s-conformance/00-experimental-v1.0.0.yml"), + k3s.WithManifest("./fixtures/k8s-conformance/00-experimental-v1.1.0.yml"), k3s.WithManifest("./fixtures/k8s-conformance/01-rbac.yml"), k3s.WithManifest("./fixtures/k8s-conformance/02-traefik.yml"), network.WithNetwork(nil, s.network), @@ -122,15 +126,19 @@ func (s *K8sConformanceSuite) SetupSuite() { s.T().Fatalf("Error initializing Kubernetes REST client: %v", err) } - if err = gatev1alpha2.AddToScheme(s.kubeClient.Scheme()); err != nil { + if err = gatev1alpha2.Install(s.kubeClient.Scheme()); err != nil { s.T().Fatal(err) } - if err = gatev1beta1.AddToScheme(s.kubeClient.Scheme()); err != nil { + if err = gatev1beta1.Install(s.kubeClient.Scheme()); err != nil { s.T().Fatal(err) } - if err = gatev1.AddToScheme(s.kubeClient.Scheme()); err != nil { + if err = gatev1.Install(s.kubeClient.Scheme()); err != nil { + s.T().Fatal(err) + } + + if err = apiextensionsv1.AddToScheme(s.kubeClient.Scheme()); err != nil { s.T().Fatal(err) } } @@ -169,81 +177,54 @@ func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() { err = try.GetRequest("http://"+k3sContainerIP+":9000/api/entrypoints", 10*time.Second, try.BodyContains(`"name":"web"`)) require.NoError(s.T(), err) - opts := ksuite.Options{ - Client: s.kubeClient, - Clientset: s.clientSet, - GatewayClassName: "traefik", - Debug: true, - CleanupBaseResources: true, - TimeoutConfig: config.TimeoutConfig{ - CreateTimeout: 5 * time.Second, - DeleteTimeout: 5 * time.Second, - GetTimeout: 5 * time.Second, - GatewayMustHaveAddress: 5 * time.Second, - GatewayMustHaveCondition: 5 * time.Second, - GatewayStatusMustHaveListeners: 10 * time.Second, - GatewayListenersMustHaveCondition: 5 * time.Second, - GWCMustBeAccepted: 60 * time.Second, // Pod creation in k3s cluster can be long. - HTTPRouteMustNotHaveParents: 5 * time.Second, - HTTPRouteMustHaveCondition: 5 * time.Second, - TLSRouteMustHaveCondition: 5 * time.Second, - RouteMustHaveParents: 5 * time.Second, - ManifestFetchTimeout: 5 * time.Second, - MaxTimeToConsistency: 5 * time.Second, - NamespacesMustBeReady: 60 * time.Second, // Pod creation in k3s cluster can be long. - RequestTimeout: 5 * time.Second, - LatestObservedGenerationSet: 5 * time.Second, - RequiredConsecutiveSuccesses: 0, - }, - SupportedFeatures: sets.New(ksuite.SupportGateway, - ksuite.SupportGatewayPort8080, - ksuite.SupportHTTPRoute, - ksuite.SupportHTTPRouteQueryParamMatching, - ksuite.SupportHTTPRouteMethodMatching, - ksuite.SupportHTTPRoutePortRedirect, - ksuite.SupportHTTPRouteSchemeRedirect, - ksuite.SupportHTTPRouteHostRewrite, - ksuite.SupportHTTPRoutePathRewrite, - ksuite.SupportHTTPRoutePathRedirect, - ), - ExemptFeatures: sets.New( - ksuite.SupportHTTPRouteRequestTimeout, - ksuite.SupportHTTPRouteBackendTimeout, - ksuite.SupportHTTPRouteResponseHeaderModification, - ksuite.SupportHTTPRouteRequestMirror, - ksuite.SupportHTTPRouteRequestMultipleMirrors, - ), + cSuite, err := ksuite.NewConformanceTestSuite(ksuite.ConformanceOptions{ + Client: s.kubeClient, + Clientset: s.clientSet, + GatewayClassName: "traefik", + Debug: true, + CleanupBaseResources: true, + TimeoutConfig: config.DefaultTimeoutConfig(), + ManifestFS: []fs.FS{&conformance.Manifests}, EnableAllSupportedFeatures: false, RunTest: *k8sConformanceRunTest, - // Until the feature are all supported, following tests are skipped. - SkipTests: []string{ - tests.HTTPRouteMethodMatching.ShortName, - tests.HTTPRouteQueryParamMatching.ShortName, - }, - } - - cSuite, err := ksuite.NewExperimentalConformanceTestSuite(ksuite.ExperimentalConformanceOptions{ - Options: opts, - Implementation: conformanceV1alpha1.Implementation{ + Implementation: v1.Implementation{ Organization: "traefik", Project: "traefik", URL: "https://traefik.io/", Version: version.Version, Contact: []string{"@traefik/maintainers"}, }, - ConformanceProfiles: sets.New(ksuite.HTTPConformanceProfileName), + ConformanceProfiles: sets.New(ksuite.GatewayHTTPConformanceProfileName), + SupportedFeatures: sets.New( + features.SupportGateway, + features.SupportGatewayPort8080, + features.SupportHTTPRoute, + features.SupportHTTPRouteQueryParamMatching, + features.SupportHTTPRouteMethodMatching, + features.SupportHTTPRoutePortRedirect, + features.SupportHTTPRouteSchemeRedirect, + features.SupportHTTPRouteHostRewrite, + features.SupportHTTPRoutePathRewrite, + features.SupportHTTPRoutePathRedirect, + ), + ExemptFeatures: sets.New( + features.SupportHTTPRouteRequestTimeout, + features.SupportHTTPRouteBackendTimeout, + features.SupportHTTPRouteResponseHeaderModification, + features.SupportHTTPRouteRequestMirror, + features.SupportHTTPRouteRequestMultipleMirrors, + ), }) require.NoError(s.T(), err) - cSuite.Setup(s.T()) + cSuite.Setup(s.T(), tests.ConformanceTests) + err = cSuite.Run(s.T(), tests.ConformanceTests) require.NoError(s.T(), err) report, err := cSuite.Report() require.NoError(s.T(), err, "failed generating conformance report") - report.GatewayAPIVersion = "1.0.0" - rawReport, err := yaml.Marshal(report) require.NoError(s.T(), err) s.T().Logf("Conformance report:\n%s", string(rawReport)) diff --git a/integration/resources/compose/k8s.yml b/integration/resources/compose/k8s.yml index a34f72bd7..f14b7abdb 100644 --- a/integration/resources/compose/k8s.yml +++ b/integration/resources/compose/k8s.yml @@ -1,7 +1,7 @@ version: "3.8" services: server: - image: rancher/k3s:v1.20.15-k3s1 + image: rancher/k3s:v1.21.14-k3s1 privileged: true command: - server @@ -26,7 +26,7 @@ services: - ./fixtures/k8s:/var/lib/rancher/k3s/server/manifests node: - image: rancher/k3s:v1.20.15-k3s1 + image: rancher/k3s:v1.21.14-k3s1 privileged: true environment: K3S_TOKEN: somethingtotallyrandom diff --git a/pkg/cli/deprecation.go b/pkg/cli/deprecation.go index 01fd64791..8cf52f7c6 100644 --- a/pkg/cli/deprecation.go +++ b/pkg/cli/deprecation.go @@ -458,7 +458,8 @@ func (h *http) deprecationNotice(logger zerolog.Logger) bool { } type experimental struct { - HTTP3 *bool `json:"http3,omitempty" toml:"http3,omitempty" yaml:"http3,omitempty"` + HTTP3 *bool `json:"http3,omitempty" toml:"http3,omitempty" yaml:"http3,omitempty"` + KubernetesGateway *bool `json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty"` } func (e *experimental) deprecationNotice(logger zerolog.Logger) bool { @@ -469,11 +470,17 @@ func (e *experimental) deprecationNotice(logger zerolog.Logger) bool { if e.HTTP3 != nil { logger.Error().Msg("HTTP3 is not an experimental feature in v3 and the associated enablement has been removed." + "Please remove its usage from the static configuration for Traefik to start." + - "For more information please read the migration guide: https://doc.traefik.io/traefik/v3.0/migration/v2-to-v3/#http3-experimental-configuration") + "For more information please read the migration guide: https://doc.traefik.io/traefik/v3.0/migration/v2-to-v3-details/#http3") return true } + if e.KubernetesGateway != nil { + logger.Error().Msg("KubernetesGateway provider is not an experimental feature starting with v3.1." + + "Please remove its usage from the static configuration." + + "For more information please read the migration guide: https://doc.traefik.io/traefik/v3.0/migration/v3/#gateway-api-kubernetesgateway-provider") + } + return false } diff --git a/pkg/cli/deprecation_test.go b/pkg/cli/deprecation_test.go index b33987024..556046b85 100644 --- a/pkg/cli/deprecation_test.go +++ b/pkg/cli/deprecation_test.go @@ -17,8 +17,9 @@ func ptr[T any](t T) *T { func TestDeprecationNotice(t *testing.T) { tests := []struct { - desc string - config configuration + desc string + config configuration + wantCompatible bool }{ { desc: "Docker provider swarmMode option is incompatible", @@ -196,6 +197,15 @@ func TestDeprecationNotice(t *testing.T) { }, }, }, + { + desc: "Experimental KubernetesGateway enablement configuration is compatible", + config: configuration{ + Experimental: &experimental{ + KubernetesGateway: ptr(true), + }, + }, + wantCompatible: true, + }, { desc: "Tracing SpanNameLimit option is incompatible", config: configuration{ @@ -278,7 +288,8 @@ func TestDeprecationNotice(t *testing.T) { }) logger := log.With().Logger().Hook(testHook) - assert.True(t, test.config.deprecationNotice(logger)) + + assert.Equal(t, !test.wantCompatible, test.config.deprecationNotice(logger)) assert.True(t, gotLog) assert.Equal(t, zerolog.ErrorLevel, gotLevel) }) diff --git a/pkg/config/static/experimental.go b/pkg/config/static/experimental.go index 7428f6a08..ecd18424d 100644 --- a/pkg/config/static/experimental.go +++ b/pkg/config/static/experimental.go @@ -7,5 +7,6 @@ type Experimental struct { Plugins map[string]plugins.Descriptor `description:"Plugins configuration." json:"plugins,omitempty" toml:"plugins,omitempty" yaml:"plugins,omitempty" export:"true"` LocalPlugins map[string]plugins.LocalDescriptor `description:"Local plugins configuration." json:"localPlugins,omitempty" toml:"localPlugins,omitempty" yaml:"localPlugins,omitempty" export:"true"` - KubernetesGateway bool `description:"Allow the Kubernetes gateway api provider usage." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true"` + // Deprecated: KubernetesGateway provider is not an experimental feature starting with v3.1. Please remove its usage from the static configuration. + KubernetesGateway bool `description:"(Deprecated) Allow the Kubernetes gateway api provider usage." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true"` } diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index 27bf10048..a52f76497 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -17,9 +17,11 @@ import ( "github.com/traefik/traefik/v3/pkg/types" "github.com/traefik/traefik/v3/pkg/version" corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" kinformers "k8s.io/client-go/informers" kclientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -46,7 +48,7 @@ type Client interface { GetTLSStores() []*traefikv1alpha1.TLSStore GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) - GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) + GetEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) GetNodes() ([]*corev1.Node, bool, error) } @@ -219,7 +221,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< if err != nil { return nil, err } - _, err = factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + _, err = factoryKube.Discovery().V1().EndpointSlices().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err } @@ -444,15 +446,20 @@ func (c *clientWrapper) GetService(namespace, name string) (*corev1.Service, boo return service, exist, err } -// GetEndpoints returns the named endpoints from the given namespace. -func (c *clientWrapper) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) { +// GetEndpointSlicesForService returns the EndpointSlices for the given service name in the given namespace. +func (c *clientWrapper) GetEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) { if !c.isWatchedNamespace(namespace) { - return nil, false, fmt.Errorf("failed to get endpoints %s/%s: namespace is not within watched namespaces", namespace, name) + return nil, fmt.Errorf("failed to get endpointslices for service %s/%s: namespace is not within watched namespaces", namespace, serviceName) } - endpoint, err := c.factoriesKube[c.lookupNamespace(namespace)].Core().V1().Endpoints().Lister().Endpoints(namespace).Get(name) - exist, err := translateNotFoundError(err) - return endpoint, exist, err + serviceLabelRequirement, err := labels.NewRequirement(discoveryv1.LabelServiceName, selection.Equals, []string{serviceName}) + if err != nil { + return nil, fmt.Errorf("failed to create service label selector requirement: %w", err) + } + serviceSelector := labels.NewSelector() + serviceSelector = serviceSelector.Add(*serviceLabelRequirement) + + return c.factoriesKube[c.lookupNamespace(namespace)].Discovery().V1().EndpointSlices().Lister().EndpointSlices(namespace).List(serviceSelector) } // GetSecret returns the named secret from the given namespace. diff --git a/pkg/provider/kubernetes/crd/fixtures/services.yml b/pkg/provider/kubernetes/crd/fixtures/services.yml index 825bb9106..86094ef8a 100644 --- a/pkg/provider/kubernetes/crd/fixtures/services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/services.yml @@ -13,19 +13,24 @@ spec: task: whoami --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami + name: whoami-abc namespace: default + labels: + kubernetes.io/service-name: whoami -subsets: +addressType: IPv4 +ports: + - name: web + port: 80 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 80 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 @@ -43,19 +48,24 @@ spec: task: whoami2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami2 + name: whoami2-abc namespace: default + labels: + kubernetes.io/service-name: whoami2 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 @@ -74,19 +84,24 @@ spec: task: whoami2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitls + name: whoamitls-abc namespace: default + labels: + kubernetes.io/service-name: whoamitls -subsets: +addressType: IPv4 +ports: + - name: websecure + port: 8443 +endpoints: - addresses: - - ip: 10.10.0.5 - - ip: 10.10.0.6 - ports: - - name: websecure - port: 8443 + - 10.10.0.5 + - 10.10.0.6 + conditions: + ready: true --- apiVersion: v1 @@ -99,25 +114,29 @@ spec: ports: - name: websecure2 port: 8443 - scheme: https selector: app: traefiklabs task: whoami3 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami3 + name: whoami3-abc namespace: default + labels: + kubernetes.io/service-name: whoami3 -subsets: +addressType: IPv4 +ports: + - name: websecure2 + port: 8443 +endpoints: - addresses: - - ip: 10.10.0.7 - - ip: 10.10.0.8 - ports: - - name: websecure2 - port: 8443 + - 10.10.0.7 + - 10.10.0.8 + conditions: + ready: true --- apiVersion: v1 @@ -135,18 +154,23 @@ spec: task: whoami-ipv6 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami-ipv6 + name: whoami-ipv6-abc namespace: default + labels: + kubernetes.io/service-name: whoami-ipv6 -subsets: +addressType: IPv6 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: "2001:db8:85a3:8d3:1319:8a2e:370:7348" - ports: - - name: web - port: 8080 + - "2001:db8:85a3:8d3:1319:8a2e:370:7348" + conditions: + ready: true --- apiVersion: v1 @@ -216,25 +240,30 @@ spec: task: whoami --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami-svc + name: whoami-svc-abc namespace: cross-ns + labels: + kubernetes.io/service-name: whoami-svc -subsets: +addressType: IPv4 +ports: + - name: web + port: 80 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 80 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 kind: Service metadata: - name: whoami-without-endpoints-subsets + name: whoami-without-endpointslice-endpoints namespace: default spec: @@ -247,11 +276,16 @@ spec: task: whoami --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami-without-endpoints-subsets + name: whoami-without-endpointslice-endpoints-abc namespace: default + labels: + kubernetes.io/service-name: whoami-without-endpointslice-endpoints + +addressType: IPv4 +endpoints: [] --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml index 40a2e90e5..8c29006e8 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml @@ -13,19 +13,24 @@ spec: task: whoamitcp --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp + name: whoamitcp-abc namespace: default + labels: + kubernetes.io/service-name: whoamitcp -subsets: +addressType: IPv4 +ports: + - name: myapp + port: 8000 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: myapp - port: 8000 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 @@ -43,19 +48,24 @@ spec: task: whoamitcp2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp2 + name: whoamitcp2-abc namespace: default + labels: + kubernetes.io/service-name: whoamitcp2 -subsets: +addressType: IPv4 +ports: + - name: myapp2 + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: myapp2 - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 @@ -73,19 +83,24 @@ spec: task: whoamitcptls2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcptls + name: whoamitcptls-abc namespace: default + labels: + kubernetes.io/service-name: whoamitcptls -subsets: +addressType: IPv4 +ports: + - name: websecure + port: 443 +endpoints: - addresses: - - ip: 10.10.0.5 - - ip: 10.10.0.6 - ports: - - name: websecure - port: 443 + - 10.10.0.5 + - 10.10.0.6 + conditions: + ready: true --- apiVersion: v1 @@ -103,34 +118,44 @@ spec: task: whoamitcp3 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp3 + name: whoamitcp3-abc namespace: ns3 + labels: + kubernetes.io/service-name: whoamitcp3 -subsets: +addressType: IPv4 +ports: + - name: myapp3 + port: 8083 +endpoints: - addresses: - - ip: 10.10.0.7 - - ip: 10.10.0.8 - ports: - - name: myapp3 - port: 8083 + - 10.10.0.7 + - 10.10.0.8 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp3 + name: whoamitcp3-abc namespace: ns4 + labels: + kubernetes.io/service-name: whoamitcp3 -subsets: +addressType: IPv4 +ports: + - name: myapp4 + port: 8084 +endpoints: - addresses: - - ip: 10.10.0.9 - - ip: 10.10.0.10 - ports: - - name: myapp4 - port: 8084 + - 10.10.0.9 + - 10.10.0.10 + conditions: + ready: true --- apiVersion: v1 @@ -148,19 +173,24 @@ spec: task: whoamitcp-ipv6 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp-ipv6 + name: whoamitcp-ipv6-abc namespace: default + labels: + kubernetes.io/service-name: whoamitcp-ipv6 -subsets: +addressType: IPv6 +ports: + - name: myapp-ipv6 + port: 8080 +endpoints: - addresses: - - ip: "fd00:10:244:0:1::3" - - ip: "2001:db8:85a3:8d3:1319:8a2e:370:7348" - ports: - - name: myapp-ipv6 - port: 8080 + - "fd00:10:244:0:1::3" + - "2001:db8:85a3:8d3:1319:8a2e:370:7348" + conditions: + ready: true --- apiVersion: v1 @@ -212,25 +242,30 @@ spec: task: whoamitcp --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp-cross-ns + name: whoamitcp-cross-ns-abc namespace: cross-ns + labels: + kubernetes.io/service-name: whoamitcp-cross-ns -subsets: +addressType: IPv4 +ports: + - name: myapp + port: 8000 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: myapp - port: 8000 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 kind: Service metadata: - name: whoamitcp-without-endpoints-subsets + name: whoamitcp-without-endpointslice-endpoints namespace: default spec: @@ -243,11 +278,16 @@ spec: task: whoamitcp --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp-without-endpoints-subsets + name: whoamitcp-without-endpointslice-endpoints-abc namespace: default + labels: + kubernetes.io/service-name: whoamitcp-without-endpointslice-endpoints + +addressType: IPv4 +endpoints: [] --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml index 55202d867..37daa91c1 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml @@ -11,5 +11,5 @@ spec: routes: - match: HostSNI(`foo.com`) services: - - name: whoamitcp-without-endpoints-subsets + - name: whoamitcp-without-endpointslice-endpoints port: 8000 diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/services.yml b/pkg/provider/kubernetes/crd/fixtures/udp/services.yml index 969281886..f77643d36 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/services.yml @@ -13,19 +13,24 @@ spec: task: whoamiudp --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamiudp + name: whoamiudp-abc namespace: default + labels: + kubernetes.io/service-name: whoamiudp -subsets: +addressType: IPv4 +ports: + - name: myapp + port: 8000 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: myapp - port: 8000 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 @@ -43,19 +48,24 @@ spec: task: whoamiudp2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamiudp2 + name: whoamiudp2-abc namespace: default + labels: + kubernetes.io/service-name: whoamiudp2 -subsets: +addressType: IPv4 +ports: + - name: myapp2 + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: myapp2 - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 @@ -73,34 +83,44 @@ spec: task: whoamiudp3 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamiudp3 + name: whoamiudp3-abc namespace: ns3 + labels: + kubernetes.io/service-name: whoamiudp3 -subsets: +addressType: IPv4 +ports: + - name: myapp3 + port: 8083 +endpoints: - addresses: - - ip: 10.10.0.7 - - ip: 10.10.0.8 - ports: - - name: myapp3 - port: 8083 + - 10.10.0.7 + - 10.10.0.8 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamiudp3 + name: whoamiudp3-abc namespace: ns4 + labels: + kubernetes.io/service-name: whoamiudp3 -subsets: +addressType: IPv4 +ports: + - name: myapp4 + port: 8084 +endpoints: - addresses: - - ip: 10.10.0.9 - - ip: 10.10.0.10 - ports: - - name: myapp4 - port: 8084 + - 10.10.0.9 + - 10.10.0.10 + conditions: + ready: true --- apiVersion: v1 @@ -118,18 +138,23 @@ spec: task: whoamiudp-ipv6 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamiudp-ipv6 + name: whoamiudp-ipv6-abc namespace: default + labels: + kubernetes.io/service-name: whoamiudp-ipv6 -subsets: +addressType: IPv6 +ports: + - name: myapp-ipv6 + port: 8080 +endpoints: - addresses: - - ip: "fd00:10:244:0:1::3" - ports: - - name: myapp-ipv6 - port: 8080 + - "fd00:10:244:0:1::3" + conditions: + ready: true --- apiVersion: v1 @@ -171,25 +196,30 @@ spec: port: 80 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamiudp-cross-ns + name: whoamiudp-cross-ns-abc namespace: cross-ns + labels: + kubernetes.io/service-name: whoamiudp-cross-ns -subsets: +addressType: IPv4 +ports: + - name: myapp + port: 8000 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: myapp - port: 8000 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 kind: Service metadata: - name: whoamiudp-without-endpoints-subsets + name: whoamiudp-without-endpointslice-endpoints namespace: default spec: @@ -202,11 +232,16 @@ spec: task: whoamiudp --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamiudp-without-endpoints-subsets + name: whoamiudp-without-endpointslice-endpoints-abc namespace: default + labels: + kubernetes.io/service-name: whoamiudp-without-endpointslice-endpoints + +addressType: IPv4 +endpoints: [] --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml index dc588d5e9..535d24b58 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml @@ -10,5 +10,5 @@ spec: routes: - services: - - name: whoamiudp-without-endpoints-subsets + - name: whoamiudp-without-endpointslice-endpoints port: 8000 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_duplicated_endpointaddresses.yml b/pkg/provider/kubernetes/crd/fixtures/with_duplicated_endpointaddresses.yml new file mode 100644 index 000000000..5054fc566 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_duplicated_endpointaddresses.yml @@ -0,0 +1,74 @@ +apiVersion: v1 +kind: Service +metadata: + name: whoami-svc-duplicated-endpointaddresses + namespace: default + +spec: + ports: + - name: web + port: 8080 + selector: + app: traefiklabs + task: whoami + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami-svc-duplicated-endpointaddresses-abc + namespace: default + labels: + kubernetes.io/service-name: whoami-svc-duplicated-endpointaddresses + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami-svc-duplicated-endpointaddresses-def + namespace: default + labels: + kubernetes.io/service-name: whoami-svc-duplicated-endpointaddresses + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.1 + - 10.10.0.2 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: Host(`foo.com`) && PathPrefix(`/bar`) + kind: Rule + priority: 12 + services: + - name: whoami-svc-duplicated-endpointaddresses + port: 8080 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml b/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml index b3ff215d1..6ccf7202b 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml @@ -13,5 +13,5 @@ spec: kind: Rule priority: 12 services: - - name: whoami-without-endpoints-subsets + - name: whoami-without-endpointslice-endpoints port: 80 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml index bc4f9626c..dbf8f366d 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml @@ -30,7 +30,7 @@ metadata: spec: weighted: services: - - name: whoami-without-endpoints-subsets + - name: whoami-without-endpointslice-endpoints weight: 1 port: 80 @@ -43,10 +43,10 @@ metadata: spec: mirroring: - name: whoami-without-endpoints-subsets + name: whoami-without-endpointslice-endpoints port: 80 mirrors: - - name: whoami-without-endpoints-subsets + - name: whoami-without-endpointslice-endpoints port: 80 - name: test-weighted kind: TraefikService @@ -61,5 +61,5 @@ metadata: spec: errors: service: - name: whoami-without-endpoints-subsets + name: whoami-without-endpointslice-endpoints port: 80 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml b/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml index a1ead36d8..015ed95d0 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml @@ -1,17 +1,22 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami4 + name: whoami4-abc namespace: default + labels: + kubernetes.io/service-name: whoami4 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 8080 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 @@ -28,20 +33,25 @@ spec: app: traefiklabs task: whoami4 ------- -kind: Endpoints -apiVersion: v1 +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: default + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml b/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml index 5f498a296..dc303e600 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml @@ -1,17 +1,22 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami4 + name: whoami4-abc namespace: default + labels: + kubernetes.io/service-name: whoami4 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 8080 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 @@ -28,20 +33,25 @@ spec: app: traefiklabs task: whoami4 ------- -kind: Endpoints -apiVersion: v1 +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: default + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_multiple_endpointaddresses.yml b/pkg/provider/kubernetes/crd/fixtures/with_multiple_endpointaddresses.yml new file mode 100644 index 000000000..6e7e8e70e --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_multiple_endpointaddresses.yml @@ -0,0 +1,63 @@ +apiVersion: v1 +kind: Service +metadata: + name: whoami-svc-multiple-endpointaddresses + namespace: default + +spec: + ports: + - name: web + port: 80 + selector: + app: traefiklabs + task: whoami + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami-svc-multiple-endpointaddresses-abc + namespace: default + labels: + kubernetes.io/service-name: whoami-svc-multiple-endpointaddresses + +addressType: IPv4 +ports: + - name: web + port: 80 +endpoints: + - addresses: + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true + - addresses: + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: false + serving: true + - addresses: + - 10.10.0.5 + - 10.10.0.6 + conditions: + ready: true + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: Host(`foo.com`) && PathPrefix(`/bar`) + kind: Rule + priority: 12 + services: + - name: whoami-svc-multiple-endpointaddresses + port: 80 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_multiple_endpointslices.yml b/pkg/provider/kubernetes/crd/fixtures/with_multiple_endpointslices.yml new file mode 100644 index 000000000..f1753c24f --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_multiple_endpointslices.yml @@ -0,0 +1,94 @@ +apiVersion: v1 +kind: Service +metadata: + name: whoami-svc-multiple-endpointslices + namespace: default + +spec: + ports: + - name: web + port: 80 + - name: web2 + port: 8080 + selector: + app: traefiklabs + task: whoami + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami-svc-multiple-endpointslices-abc + namespace: default + labels: + kubernetes.io/service-name: whoami-svc-multiple-endpointslices + +addressType: IPv4 +ports: + - name: web + port: 80 +endpoints: + - addresses: + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami-svc-multiple-endpointslices-def + namespace: default + labels: + kubernetes.io/service-name: whoami-svc-multiple-endpointslices + +addressType: IPv4 +ports: + - name: web2 + port: 8080 +endpoints: + - addresses: + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami-svc-multiple-endpointslices-ghi + namespace: default + labels: + kubernetes.io/service-name: whoami-svc-multiple-endpointslices + +addressType: IPv4 +ports: + - name: web2 + port: 8080 +endpoints: + - addresses: + - 10.10.0.5 + - 10.10.0.6 + conditions: + ready: true + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: Host(`foo.com`) && PathPrefix(`/bar`) + kind: Rule + priority: 12 + services: + - name: whoami-svc-multiple-endpointslices + port: 8080 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_multiple_subsets.yml b/pkg/provider/kubernetes/crd/fixtures/with_multiple_subsets.yml deleted file mode 100644 index 4d700d7ad..000000000 --- a/pkg/provider/kubernetes/crd/fixtures/with_multiple_subsets.yml +++ /dev/null @@ -1,54 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: whoami-svc-multiple-subsets - namespace: default - -spec: - ports: - - name: web - port: 80 - - name: web2 - port: 8080 - selector: - app: traefiklabs - task: whoami - ---- -kind: Endpoints -apiVersion: v1 -metadata: - name: whoami-svc-multiple-subsets - namespace: default - -subsets: - - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 80 - - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web2 - port: 8080 ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: test.route - namespace: default - -spec: - entryPoints: - - foo - - routes: - - match: Host(`foo.com`) && PathPrefix(`/bar`) - kind: Rule - priority: 12 - services: - - name: whoami-svc-multiple-subsets - port: 8080 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml b/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml index d8d4867e9..3d60d4fc7 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml @@ -1,47 +1,62 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami6 + name: whoami6-abc namespace: baz + labels: + kubernetes.io/service-name: whoami6 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.5 - - ip: 10.10.0.6 - ports: - - name: web - port: 8080 + - 10.10.0.5 + - 10.10.0.6 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: foo + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami4 + name: whoami4-abc namespace: foo + labels: + kubernetes.io/service-name: whoami4 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 8080 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml index d4f7b7d94..d45e91f5d 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml @@ -1,17 +1,22 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: default + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml index d863c3f1f..e981ee880 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml @@ -1,62 +1,82 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami4 + name: whoami4-abc namespace: default + labels: + kubernetes.io/service-name: whoami4 -subsets: +addressType: IPv4 +ports: + - name: web + port: 80 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 80 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: default + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami6 + name: whoami6-abc namespace: default + labels: + kubernetes.io/service-name: whoami6 -subsets: +addressType: IPv4 +ports: + - name: web + port: 80 +endpoints: - addresses: - - ip: 10.10.0.5 - - ip: 10.10.0.6 - ports: - - name: web - port: 80 + - 10.10.0.5 + - 10.10.0.6 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami7 + name: whoami7-abc namespace: default + labels: + kubernetes.io/service-name: whoami7 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.7 - - ip: 10.10.0.8 - ports: - - name: web - port: 8080 + - 10.10.0.7 + - 10.10.0.8 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml index c1732c18b..dfd7b5790 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml @@ -1,17 +1,22 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: default + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: traefik.io/v1alpha1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml index 8b15d9fd9..4a7eb19db 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml @@ -1,32 +1,42 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: default + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami4 + name: whoami4-abc namespace: default + labels: + kubernetes.io/service-name: whoami4 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 8080 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml index c98462ee9..0b7132681 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml @@ -1,17 +1,22 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami5 + name: whoami5-abc namespace: default + labels: + kubernetes.io/service-name: whoami5 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index 1d5eab777..85c9e0ab5 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -409,9 +409,8 @@ func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.L return nil, err } - var servers []dynamic.Server if service.Spec.Type != corev1.ServiceTypeExternalName && svc.HealthCheck != nil { - return nil, fmt.Errorf("HealthCheck allowed only for ExternalName services: %s/%s", namespace, sanitizedName) + return nil, fmt.Errorf("healthCheck allowed only for ExternalName services: %s/%s", namespace, sanitizedName) } if service.Spec.Type == corev1.ServiceTypeExternalName { @@ -426,9 +425,7 @@ func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.L hostPort := net.JoinHostPort(service.Spec.ExternalName, strconv.Itoa(int(svcPort.Port))) - return append(servers, dynamic.Server{ - URL: fmt.Sprintf("%s://%s", protocol, hostPort), - }), nil + return []dynamic.Server{{URL: fmt.Sprintf("%s://%s", protocol, hostPort)}}, nil } nativeLB := c.NativeLBByDefault @@ -449,6 +446,7 @@ func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.L return []dynamic.Server{{URL: fmt.Sprintf("%s://%s", protocol, address)}}, nil } + var servers []dynamic.Server if service.Spec.Type == corev1.ServiceTypeNodePort && svc.NodePortLB { nodes, nodesExists, nodesErr := c.client.GetNodes() if nodesErr != nil { @@ -482,27 +480,20 @@ func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.L return servers, nil } - endpoints, endpointsExists, endpointsErr := c.client.GetEndpoints(namespace, sanitizedName) - if endpointsErr != nil { - return nil, endpointsErr - } - if !endpointsExists { - return nil, fmt.Errorf("endpoints not found for %s/%s", namespace, sanitizedName) + endpointSlices, err := c.client.GetEndpointSlicesForService(namespace, sanitizedName) + if err != nil { + return nil, fmt.Errorf("getting endpointslices: %w", err) } - if len(endpoints.Subsets) == 0 && !c.allowEmptyServices { - return nil, fmt.Errorf("subset not found for %s/%s", namespace, sanitizedName) - } - - for _, subset := range endpoints.Subsets { + addresses := map[string]struct{}{} + for _, endpointSlice := range endpointSlices { var port int32 - for _, p := range subset.Ports { - if svcPort.Name == p.Name { - port = p.Port + for _, p := range endpointSlice.Ports { + if svcPort.Name == *p.Name { + port = *p.Port break } } - if port == 0 { continue } @@ -512,15 +503,28 @@ func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.L return nil, err } - for _, addr := range subset.Addresses { - hostPort := net.JoinHostPort(addr.IP, strconv.Itoa(int(port))) + for _, endpoint := range endpointSlice.Endpoints { + if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { + continue + } - servers = append(servers, dynamic.Server{ - URL: fmt.Sprintf("%s://%s", protocol, hostPort), - }) + for _, address := range endpoint.Addresses { + if _, ok := addresses[address]; ok { + continue + } + + addresses[address] = struct{}{} + servers = append(servers, dynamic.Server{ + URL: fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(address, strconv.Itoa(int(port)))), + }) + } } } + if len(servers) == 0 && !c.allowEmptyServices { + return nil, fmt.Errorf("no servers found for %s/%s", namespace, sanitizedName) + } + return servers, nil } diff --git a/pkg/provider/kubernetes/crd/kubernetes_tcp.go b/pkg/provider/kubernetes/crd/kubernetes_tcp.go index 20b0fe917..5cc35343d 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_tcp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_tcp.go @@ -238,7 +238,6 @@ func (p *Provider) loadTCPServers(client Client, namespace string, svc traefikv1 } var servers []dynamic.TCPServer - if service.Spec.Type == corev1.ServiceTypeNodePort && svc.NodePortLB { nodes, nodesExists, nodesErr := client.GetNodes() if nodesErr != nil { @@ -284,40 +283,47 @@ func (p *Provider) loadTCPServers(client Client, namespace string, svc traefikv1 return []dynamic.TCPServer{{Address: address}}, nil } - endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, svc.Name) - if endpointsErr != nil { - return nil, endpointsErr + endpointSlices, err := client.GetEndpointSlicesForService(namespace, svc.Name) + if err != nil { + return nil, fmt.Errorf("getting endpointslices: %w", err) } - if !endpointsExists { - return nil, errors.New("endpoints not found") - } - - if len(endpoints.Subsets) == 0 && !p.AllowEmptyServices { - return nil, errors.New("subset not found") - } - - var port int32 - for _, subset := range endpoints.Subsets { - for _, p := range subset.Ports { - if svcPort.Name == p.Name { - port = p.Port + addresses := map[string]struct{}{} + for _, endpointSlice := range endpointSlices { + var port int32 + for _, p := range endpointSlice.Ports { + if svcPort.Name == *p.Name { + port = *p.Port break } } - if port == 0 { - return nil, errors.New("cannot define a port") + continue } - for _, addr := range subset.Addresses { - servers = append(servers, dynamic.TCPServer{ - Address: net.JoinHostPort(addr.IP, strconv.Itoa(int(port))), - }) + for _, endpoint := range endpointSlice.Endpoints { + if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { + continue + } + + for _, address := range endpoint.Addresses { + if _, ok := addresses[address]; ok { + continue + } + + addresses[address] = struct{}{} + servers = append(servers, dynamic.TCPServer{ + Address: net.JoinHostPort(address, strconv.Itoa(int(port))), + }) + } } } } + if len(servers) == 0 && !p.AllowEmptyServices { + return nil, fmt.Errorf("no servers found for %s/%s", namespace, svc.Name) + } + return servers, nil } diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 4b886b7e8..8f53e1a0c 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -4620,9 +4620,9 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, { - desc: "IngressRoute, service with multiple subsets", + desc: "IngressRoute, service with multiple endpoint addresses on endpointslice", allowEmptyServices: true, - paths: []string{"services.yml", "with_multiple_subsets.yml"}, + paths: []string{"services.yml", "with_multiple_endpointaddresses.yml"}, expected: &dynamic.Configuration{ UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -4648,6 +4648,66 @@ func TestLoadIngressRoutes(t *testing.T) { "default-test-route-6b204d94623b3df4370c": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + { + URL: "http://10.10.0.5:80", + }, + { + URL: "http://10.10.0.6:80", + }, + }, + PassHostHeader: Bool(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "IngressRoute, service with duplicated endpointaddresses", + allowEmptyServices: true, + paths: []string{"services.yml", "with_duplicated_endpointaddresses.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-test-route-6b204d94623b3df4370c": { + EntryPoints: []string{"foo"}, + Service: "default-test-route-6b204d94623b3df4370c", + Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-test-route-6b204d94623b3df4370c": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + { + URL: "http://10.10.0.2:8080", + }, { URL: "http://10.10.0.3:8080", }, @@ -4726,7 +4786,7 @@ func TestLoadIngressRoutes(t *testing.T) { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-without-endpoints-subsets-80", + Name: "default-whoami-without-endpointslice-endpoints-80", Weight: func(i int) *int { return &i }(1), }, }, @@ -4734,10 +4794,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, "default-test-mirror": { Mirroring: &dynamic.Mirroring{ - Service: "default-whoami-without-endpoints-subsets-80", + Service: "default-whoami-without-endpointslice-endpoints-80", Mirrors: []dynamic.MirrorService{ { - Name: "default-whoami-without-endpoints-subsets-80", + Name: "default-whoami-without-endpointslice-endpoints-80", }, { Name: "default-test-weighted", @@ -4745,7 +4805,7 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, }, - "default-whoami-without-endpoints-subsets-80": { + "default-whoami-without-endpointslice-endpoints-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ PassHostHeader: Bool(true), ResponseForwarding: &dynamic.ResponseForwarding{ @@ -4799,6 +4859,87 @@ func TestLoadIngressRoutes(t *testing.T) { } } +func TestLoadIngressRoutes_multipleEndpointAddresses(t *testing.T) { + wantConf := &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-test-route-6b204d94623b3df4370c": { + EntryPoints: []string{"foo"}, + Service: "default-test-route-6b204d94623b3df4370c", + Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-test-route-6b204d94623b3df4370c": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + } + wantServers := []dynamic.Server{ + { + URL: "http://10.10.0.3:8080", + }, + { + URL: "http://10.10.0.4:8080", + }, + { + URL: "http://10.10.0.5:8080", + }, + { + URL: "http://10.10.0.6:8080", + }, + } + + k8sObjects, crdObjects := readResources(t, []string{"services.yml", "with_multiple_endpointslices.yml"}) + + kubeClient := kubefake.NewSimpleClientset(k8sObjects...) + crdClient := traefikcrdfake.NewSimpleClientset(crdObjects...) + + client := newClientImpl(kubeClient, crdClient) + + stopCh := make(chan struct{}) + + eventCh, err := client.WatchAll(nil, stopCh) + require.NoError(t, err) + + if k8sObjects != nil || crdObjects != nil { + // just wait for the first event + <-eventCh + } + + p := Provider{} + conf := p.loadConfigurationFromCRD(context.Background(), client) + + service, ok := conf.HTTP.Services["default-test-route-6b204d94623b3df4370c"] + require.True(t, ok) + require.NotNil(t, service) + require.NotNil(t, service.LoadBalancer) + assert.ElementsMatch(t, wantServers, service.LoadBalancer.Servers) + + service.LoadBalancer.Servers = nil + assert.Equal(t, wantConf, conf) +} + func TestLoadIngressRouteUDPs(t *testing.T) { testCases := []struct { desc string diff --git a/pkg/provider/kubernetes/crd/kubernetes_udp.go b/pkg/provider/kubernetes/crd/kubernetes_udp.go index 17a0ffaa5..8ab7a3838 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_udp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_udp.go @@ -122,7 +122,6 @@ func (p *Provider) loadUDPServers(client Client, namespace string, svc traefikv1 } var servers []dynamic.UDPServer - if service.Spec.Type == corev1.ServiceTypeNodePort && svc.NodePortLB { nodes, nodesExists, nodesErr := client.GetNodes() if nodesErr != nil { @@ -168,39 +167,46 @@ func (p *Provider) loadUDPServers(client Client, namespace string, svc traefikv1 return []dynamic.UDPServer{{Address: address}}, nil } - endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, svc.Name) - if endpointsErr != nil { - return nil, endpointsErr + endpointSlices, err := client.GetEndpointSlicesForService(namespace, svc.Name) + if err != nil { + return nil, fmt.Errorf("getting endpointslices: %w", err) } - if !endpointsExists { - return nil, errors.New("endpoints not found") - } - - if len(endpoints.Subsets) == 0 && !p.AllowEmptyServices { - return nil, errors.New("subset not found") - } - - var port int32 - for _, subset := range endpoints.Subsets { - for _, p := range subset.Ports { - if svcPort.Name == p.Name { - port = p.Port + addresses := map[string]struct{}{} + for _, endpointSlice := range endpointSlices { + var port int32 + for _, p := range endpointSlice.Ports { + if svcPort.Name == *p.Name { + port = *p.Port break } } - if port == 0 { - return nil, errors.New("cannot define a port") + continue } - for _, addr := range subset.Addresses { - servers = append(servers, dynamic.UDPServer{ - Address: net.JoinHostPort(addr.IP, strconv.Itoa(int(port))), - }) + for _, endpoint := range endpointSlice.Endpoints { + if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { + continue + } + + for _, address := range endpoint.Addresses { + if _, ok := addresses[address]; ok { + continue + } + + addresses[address] = struct{}{} + servers = append(servers, dynamic.UDPServer{ + Address: net.JoinHostPort(address, strconv.Itoa(int(port))), + }) + } } } } + if len(servers) == 0 && !p.AllowEmptyServices { + return nil, fmt.Errorf("no servers found for %s/%s", namespace, svc.Name) + } + return servers, nil } diff --git a/pkg/provider/kubernetes/gateway/client.go b/pkg/provider/kubernetes/gateway/client.go index 7c2756886..e91fc949f 100644 --- a/pkg/provider/kubernetes/gateway/client.go +++ b/pkg/provider/kubernetes/gateway/client.go @@ -11,9 +11,11 @@ import ( "github.com/rs/zerolog/log" "github.com/traefik/traefik/v3/pkg/types" corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" ktypes "k8s.io/apimachinery/pkg/types" kinformers "k8s.io/client-go/informers" kclientset "k8s.io/client-go/kubernetes" @@ -61,9 +63,9 @@ type Client interface { ListTLSRoutes() ([]*gatev1alpha2.TLSRoute, error) ListNamespaces(selector labels.Selector) ([]string, error) ListReferenceGrants(namespace string) ([]*gatev1beta1.ReferenceGrant, error) + ListEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) - GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) } type clientWrapper struct { @@ -222,7 +224,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< if err != nil { return nil, err } - _, err = factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + _, err = factoryKube.Discovery().V1().EndpointSlices().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err } @@ -543,16 +545,20 @@ func (c *clientWrapper) GetService(namespace, name string) (*corev1.Service, boo return service, exist, err } -// GetEndpoints returns the named endpoints from the given namespace. -func (c *clientWrapper) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) { +// ListEndpointSlicesForService returns the EndpointSlices for the given service name in the given namespace. +func (c *clientWrapper) ListEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) { if !c.isWatchedNamespace(namespace) { - return nil, false, fmt.Errorf("failed to get endpoints %s/%s: namespace is not within watched namespaces", namespace, name) + return nil, fmt.Errorf("failed to get endpointslices for service %s/%s: namespace is not within watched namespaces", namespace, serviceName) } - endpoint, err := c.factoriesKube[c.lookupNamespace(namespace)].Core().V1().Endpoints().Lister().Endpoints(namespace).Get(name) - exist, err := translateNotFoundError(err) + serviceLabelRequirement, err := labels.NewRequirement(discoveryv1.LabelServiceName, selection.Equals, []string{serviceName}) + if err != nil { + return nil, fmt.Errorf("failed to create service label selector requirement: %w", err) + } + serviceSelector := labels.NewSelector() + serviceSelector = serviceSelector.Add(*serviceLabelRequirement) - return endpoint, exist, err + return c.factoriesKube[c.lookupNamespace(namespace)].Discovery().V1().EndpointSlices().Lister().EndpointSlices(namespace).List(serviceSelector) } // GetSecret returns the named secret from the given namespace. diff --git a/pkg/provider/kubernetes/gateway/fixtures/httproute/with_method_matching.yml b/pkg/provider/kubernetes/gateway/fixtures/httproute/with_method_matching.yml new file mode 100644 index 000000000..759a961c6 --- /dev/null +++ b/pkg/provider/kubernetes/gateway/fixtures/httproute/with_method_matching.yml @@ -0,0 +1,50 @@ +--- +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: my-gateway-class +spec: + controllerName: traefik.io/gateway-controller + +--- +kind: Gateway +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: my-gateway + namespace: default +spec: + gatewayClassName: my-gateway-class + listeners: # Use GatewayClass defaults for listener definition. + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + +--- +kind: HTTPRoute +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: http-app-1 + namespace: default +spec: + parentRefs: + - name: my-gateway + kind: Gateway + group: gateway.networking.k8s.io + hostnames: + - "foo.com" + rules: + - matches: + - method: GET + path: + type: PathPrefix + value: /foo + + backendRefs: + - name: whoami + port: 80 + weight: 1 + kind: Service + group: "" diff --git a/pkg/provider/kubernetes/gateway/fixtures/httproute/with_query_param_matching.yml b/pkg/provider/kubernetes/gateway/fixtures/httproute/with_query_param_matching.yml new file mode 100644 index 000000000..b3039d43b --- /dev/null +++ b/pkg/provider/kubernetes/gateway/fixtures/httproute/with_query_param_matching.yml @@ -0,0 +1,56 @@ +--- +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: my-gateway-class +spec: + controllerName: traefik.io/gateway-controller + +--- +kind: Gateway +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: my-gateway + namespace: default +spec: + gatewayClassName: my-gateway-class + listeners: # Use GatewayClass defaults for listener definition. + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + +--- +kind: HTTPRoute +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: http-app-1 + namespace: default +spec: + parentRefs: + - name: my-gateway + kind: Gateway + group: gateway.networking.k8s.io + hostnames: + - "foo.com" + rules: + - matches: + - queryParams: + - type: Exact + name: foo + value: bar + - type: RegularExpression + name: baz + value: buz + path: + type: PathPrefix + value: /foo + + backendRefs: + - name: whoami + port: 80 + weight: 1 + kind: Service + group: "" diff --git a/pkg/provider/kubernetes/gateway/fixtures/services.yml b/pkg/provider/kubernetes/gateway/fixtures/services.yml index d9ebf1e6b..8a4cb3b72 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/services.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/services.yml @@ -17,21 +17,26 @@ spec: task: whoami --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami + name: whoami-abc namespace: default + labels: + kubernetes.io/service-name: whoami -subsets: +addressType: IPv4 +ports: + - name: web + port: 80 + - name: web2 + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: web - port: 80 - - name: web2 - port: 8000 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- apiVersion: v1 @@ -53,21 +58,26 @@ spec: task: whoami --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami-bar + name: whoami-bar-abc namespace: bar + labels: + kubernetes.io/service-name: whoami-bar -subsets: +addressType: IPv4 +ports: + - name: web + port: 80 + - name: web2 + port: 8000 +endpoints: - addresses: - - ip: 10.10.0.11 - - ip: 10.10.0.12 - ports: - - name: web - port: 80 - - name: web2 - port: 8000 + - 10.10.0.11 + - 10.10.0.12 + conditions: + ready: true --- apiVersion: v1 @@ -86,19 +96,24 @@ spec: task: whoami2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami2 + name: whoami2-abc namespace: default + labels: + kubernetes.io/service-name: whoami2 -subsets: +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: - addresses: - - ip: 10.10.0.3 - - ip: 10.10.0.4 - ports: - - name: web - port: 8080 + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true --- apiVersion: v1 @@ -117,19 +132,24 @@ spec: task: whoami2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitls + name: whoamitls-abc namespace: default + labels: + kubernetes.io/service-name: whoamitls -subsets: +addressType: IPv4 +ports: + - name: websecure + port: 8443 +endpoints: - addresses: - - ip: 10.10.0.5 - - ip: 10.10.0.6 - ports: - - name: websecure - port: 8443 + - 10.10.0.5 + - 10.10.0.6 + conditions: + ready: true --- apiVersion: v1 @@ -148,19 +168,24 @@ spec: task: whoami3 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoami3 + name: whoami3-abc namespace: default + labels: + kubernetes.io/service-name: whoami3 -subsets: +addressType: IPv4 +ports: + - name: websecure2 + port: 8443 +endpoints: - addresses: - - ip: 10.10.0.7 - - ip: 10.10.0.8 - ports: - - name: websecure2 - port: 8443 + - 10.10.0.7 + - 10.10.0.8 + conditions: + ready: true --- apiVersion: v1 @@ -201,23 +226,28 @@ spec: port: 443 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp + name: whoamitcp-abc namespace: default + labels: + kubernetes.io/service-name: whoamitcp -subsets: +addressType: IPv4 +ports: + - name: tcp-1 + protocol: TCP + port: 9000 + - name: tcp-2 + protocol: TCP + port: 10000 +endpoints: - addresses: - - ip: 10.10.0.9 - - ip: 10.10.0.10 - ports: - - name: tcp-1 - protocol: TCP - port: 9000 - - name: tcp-2 - protocol: TCP - port: 10000 + - 10.10.0.9 + - 10.10.0.10 + conditions: + ready: true --- apiVersion: v1 @@ -236,23 +266,28 @@ spec: name: tcp-2 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: whoamitcp-bar + name: whoamitcp-bar-abc namespace: bar + labels: + kubernetes.io/service-name: whoamitcp-bar -subsets: +addressType: IPv4 +ports: + - name: tcp-1 + protocol: TCP + port: 9000 + - name: tcp-2 + protocol: TCP + port: 10000 +endpoints: - addresses: - - ip: 10.10.0.13 - - ip: 10.10.0.14 - ports: - - name: tcp-1 - protocol: TCP - port: 9000 - - name: tcp-2 - protocol: TCP - port: 10000 + - 10.10.0.13 + - 10.10.0.14 + conditions: + ready: true --- apiVersion: v1 diff --git a/pkg/provider/kubernetes/gateway/httproute.go b/pkg/provider/kubernetes/gateway/httproute.go index 4d47869bf..535c4a1b7 100644 --- a/pkg/provider/kubernetes/gateway/httproute.go +++ b/pkg/provider/kubernetes/gateway/httproute.go @@ -370,6 +370,10 @@ func (p *Provider) loadHTTPRouteFilterExtensionRef(namespace string, extensionRe } func (p *Provider) loadHTTPServers(namespace string, backendRef gatev1.HTTPBackendRef) (*dynamic.ServersLoadBalancer, error) { + if backendRef.Port == nil { + return nil, errors.New("port is required for Kubernetes Service reference") + } + service, exists, err := p.client.GetService(namespace, string(backendRef.Name)) if err != nil { return nil, fmt.Errorf("getting service: %w", err) @@ -378,56 +382,58 @@ func (p *Provider) loadHTTPServers(namespace string, backendRef gatev1.HTTPBacke return nil, errors.New("service not found") } - var portSpec corev1.ServicePort - var match bool - + var svcPort *corev1.ServicePort for _, p := range service.Spec.Ports { - if backendRef.Port == nil || p.Port == int32(*backendRef.Port) { - portSpec = p - match = true + if p.Port == int32(*backendRef.Port) { + svcPort = &p break } } - if !match { - return nil, errors.New("service port not found") + if svcPort == nil { + return nil, fmt.Errorf("service port %d not found", *backendRef.Port) } - endpoints, endpointsExists, err := p.client.GetEndpoints(namespace, string(backendRef.Name)) + endpointSlices, err := p.client.ListEndpointSlicesForService(namespace, string(backendRef.Name)) if err != nil { - return nil, fmt.Errorf("getting endpoints: %w", err) + return nil, fmt.Errorf("getting endpointslices: %w", err) } - if !endpointsExists { - return nil, errors.New("endpoints not found") - } - - if len(endpoints.Subsets) == 0 { - return nil, errors.New("subset not found") + if len(endpointSlices) == 0 { + return nil, errors.New("endpointslices not found") } lb := &dynamic.ServersLoadBalancer{} lb.SetDefaults() - var port int32 - var portStr string - for _, subset := range endpoints.Subsets { - for _, p := range subset.Ports { - if portSpec.Name == p.Name { - port = p.Port + protocol := getProtocol(*svcPort) + + addresses := map[string]struct{}{} + for _, endpointSlice := range endpointSlices { + var port int32 + for _, p := range endpointSlice.Ports { + if svcPort.Name == *p.Name { + port = *p.Port break } } - if port == 0 { - return nil, errors.New("cannot define a port") + continue } - protocol := getProtocol(portSpec) + for _, endpoint := range endpointSlice.Endpoints { + if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { + continue + } - portStr = strconv.FormatInt(int64(port), 10) - for _, addr := range subset.Addresses { - lb.Servers = append(lb.Servers, dynamic.Server{ - URL: fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(addr.IP, portStr)), - }) + for _, address := range endpoint.Addresses { + if _, ok := addresses[address]; ok { + continue + } + + addresses[address] = struct{}{} + lb.Servers = append(lb.Servers, dynamic.Server{ + URL: fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(address, strconv.Itoa(int(port)))), + }) + } } } @@ -469,11 +475,11 @@ func buildHostRule(hostnames []gatev1.Hostname) (string, int) { // The current priority computing is rather naive but aims to fulfill Conformance tests suite requirement. // The priority is computed to match the following precedence order: // -// * "Exact" path match. (+100000) -// * "Prefix" path match with largest number of characters. (+10000) PathRegex (+1000) -// * Method match. (not implemented) -// * Largest number of header matches. (+100 each) or with PathRegex (+10 each) -// * Largest number of query param matches. (not implemented) +// * "Exact" path match (+100000). +// * "Prefix" path match with largest number of characters (+10000 + nb_characters*100). +// * Method match (+1000). +// * Largest number of header matches (+100 each). +// * Largest number of query param matches (+10 each). // // In case of multiple matches for a route, the maximum priority among all matches is retain. func buildMatchRule(hostnames []gatev1.Hostname, match gatev1.HTTPRouteMatch) (string, int) { @@ -489,10 +495,19 @@ func buildMatchRule(hostnames []gatev1.Hostname, match gatev1.HTTPRouteMatch) (s matchRules = append(matchRules, pathRule) priority += pathPriority + if match.Method != nil { + matchRules = append(matchRules, fmt.Sprintf("Method(`%s`)", *match.Method)) + priority += 1000 + } + headerRules, headersPriority := buildHeaderRules(match.Headers) matchRules = append(matchRules, headerRules...) priority += headersPriority + queryParamRules, queryParamsPriority := buildQueryParamRules(match.QueryParams) + matchRules = append(matchRules, queryParamRules...) + priority += queryParamsPriority + matchRulesStr := strings.Join(matchRules, " && ") hostRule, hostPriority := buildHostRule(hostnames) @@ -525,7 +540,7 @@ func buildPathRule(pathMatch gatev1.HTTPPathMatch) (string, int) { return fmt.Sprintf("(Path(`%[1]s`) || PathPrefix(`%[1]s/`))", pv), 10000 + len(pathValue)*100 case gatev1.PathMatchRegularExpression: - return fmt.Sprintf("PathRegexp(`%s`)", pathValue), 1000 + len(pathValue)*100 + return fmt.Sprintf("PathRegexp(`%s`)", pathValue), 10000 + len(pathValue)*100 default: return "PathPrefix(`/`)", 1 @@ -533,18 +548,38 @@ func buildPathRule(pathMatch gatev1.HTTPPathMatch) (string, int) { } func buildHeaderRules(headers []gatev1.HTTPHeaderMatch) ([]string, int) { - var rules []string - var priority int + var ( + rules []string + priority int + ) for _, header := range headers { typ := ptr.Deref(header.Type, gatev1.HeaderMatchExact) switch typ { case gatev1.HeaderMatchExact: rules = append(rules, fmt.Sprintf("Header(`%s`,`%s`)", header.Name, header.Value)) - priority += 100 case gatev1.HeaderMatchRegularExpression: rules = append(rules, fmt.Sprintf("HeaderRegexp(`%s`,`%s`)", header.Name, header.Value)) - priority += 10 } + priority += 100 + } + + return rules, priority +} + +func buildQueryParamRules(queryParams []gatev1.HTTPQueryParamMatch) ([]string, int) { + var ( + rules []string + priority int + ) + for _, qp := range queryParams { + typ := ptr.Deref(qp.Type, gatev1.QueryParamMatchExact) + switch typ { + case gatev1.QueryParamMatchExact: + rules = append(rules, fmt.Sprintf("Query(`%s`,`%s`)", qp.Name, qp.Value)) + case gatev1.QueryParamMatchRegularExpression: + rules = append(rules, fmt.Sprintf("QueryRegexp(`%s`,`%s`)", qp.Name, qp.Value)) + } + priority += 10 } return rules, priority diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index af87073df..28d1c9591 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -1288,7 +1288,7 @@ func TestLoadHTTPRoutes(t *testing.T) { "default-http-app-1-my-gateway-web-2-d23f7039bc8036fb918c": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && PathRegexp(`^/buzz/[0-9]+$`)", - Priority: 2408, + Priority: 11408, RuleSyntax: "v3", Service: "default-http-app-1-my-gateway-web-2-wrr", }, @@ -1354,6 +1354,128 @@ func TestLoadHTTPRoutes(t *testing.T) { TLS: &dynamic.TLSConfiguration{}, }, }, + { + desc: "Simple HTTPRoute, with method matching", + paths: []string{"services.yml", "httproute/with_method_matching.yml"}, + entryPoints: map[string]Entrypoint{"web": { + Address: ":80", + }}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-http-app-1-my-gateway-web-0-74ad70a7cf090becdd3c": { + EntryPoints: []string{"web"}, + Rule: "Host(`foo.com`) && (Path(`/foo`) || PathPrefix(`/foo/`)) && Method(`GET`)", + Priority: 11408, + RuleSyntax: "v3", + Service: "default-http-app-1-my-gateway-web-0-wrr", + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-http-app-1-my-gateway-web-0-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami-80", + Weight: ptr.To(1), + }, + }, + }, + }, + "default-whoami-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + }, + PassHostHeader: ptr.To(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "Simple HTTPRoute, with query param matching", + paths: []string{"services.yml", "httproute/with_query_param_matching.yml"}, + entryPoints: map[string]Entrypoint{"web": { + Address: ":80", + }}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-http-app-1-my-gateway-web-0-bb7b03c9610e982fd627": { + EntryPoints: []string{"web"}, + Rule: "Host(`foo.com`) && (Path(`/foo`) || PathPrefix(`/foo/`)) && Query(`foo`,`bar`) && QueryRegexp(`baz`,`buz`)", + Priority: 10428, + RuleSyntax: "v3", + Service: "default-http-app-1-my-gateway-web-0-wrr", + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-http-app-1-my-gateway-web-0-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami-80", + Weight: ptr.To(1), + }, + }, + }, + }, + "default-whoami-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + }, + PassHostHeader: ptr.To(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, { desc: "HTTPRoute with Same namespace selector", paths: []string{"services.yml", "httproute/with_namespace_same.yml"}, diff --git a/pkg/provider/kubernetes/gateway/tcproute.go b/pkg/provider/kubernetes/gateway/tcproute.go index cdbb155ff..c74355d6f 100644 --- a/pkg/provider/kubernetes/gateway/tcproute.go +++ b/pkg/provider/kubernetes/gateway/tcproute.go @@ -206,82 +206,71 @@ func (p *Provider) loadTCPServices(namespace string, backendRefs []gatev1.Backen return nil, nil, fmt.Errorf("unsupported BackendRef %s/%s/%s", *backendRef.Group, *backendRef.Kind, backendRef.Name) } - svc := dynamic.TCPService{ - LoadBalancer: &dynamic.TCPServersLoadBalancer{}, + if backendRef.Port == nil { + return nil, nil, errors.New("port is required for Kubernetes Service reference") } service, exists, err := p.client.GetService(namespace, string(backendRef.Name)) if err != nil { - return nil, nil, err + return nil, nil, fmt.Errorf("getting service: %w", err) } - if !exists { return nil, nil, errors.New("service not found") } - if len(service.Spec.Ports) > 1 && backendRef.Port == nil { - // If the port is unspecified and the backend is a Service - // object consisting of multiple port definitions, the route - // must be dropped from the Gateway. The controller should - // raise the "ResolvedRefs" condition on the Gateway with the - // "DroppedRoutes" reason. The gateway status for this route - // should be updated with a condition that describes the error - // more specifically. - log.Error().Msg("A multiple ports Kubernetes Service cannot be used if unspecified backendRef.Port") - continue - } - - var portSpec corev1.ServicePort - var match bool - + var svcPort *corev1.ServicePort for _, p := range service.Spec.Ports { - if backendRef.Port == nil || p.Port == int32(*backendRef.Port) { - portSpec = p - match = true + if p.Port == int32(*backendRef.Port) { + svcPort = &p break } } - - if !match { - return nil, nil, errors.New("service port not found") + if svcPort == nil { + return nil, nil, fmt.Errorf("service port %d not found", *backendRef.Port) } - endpoints, endpointsExists, endpointsErr := p.client.GetEndpoints(namespace, string(backendRef.Name)) - if endpointsErr != nil { - return nil, nil, endpointsErr + endpointSlices, err := p.client.ListEndpointSlicesForService(namespace, string(backendRef.Name)) + if err != nil { + return nil, nil, fmt.Errorf("getting endpointslices: %w", err) + } + if len(endpointSlices) == 0 { + return nil, nil, errors.New("endpointslices not found") } - if !endpointsExists { - return nil, nil, errors.New("endpoints not found") - } + svc := dynamic.TCPService{LoadBalancer: &dynamic.TCPServersLoadBalancer{}} - if len(endpoints.Subsets) == 0 { - return nil, nil, errors.New("subset not found") - } - - var port int32 - var portStr string - for _, subset := range endpoints.Subsets { - for _, p := range subset.Ports { - if portSpec.Name == p.Name { - port = p.Port + addresses := map[string]struct{}{} + for _, endpointSlice := range endpointSlices { + var port int32 + for _, p := range endpointSlice.Ports { + if svcPort.Name == *p.Name { + port = *p.Port break } } - if port == 0 { - return nil, nil, errors.New("cannot define a port") + continue } - portStr = strconv.FormatInt(int64(port), 10) - for _, addr := range subset.Addresses { - svc.LoadBalancer.Servers = append(svc.LoadBalancer.Servers, dynamic.TCPServer{ - Address: net.JoinHostPort(addr.IP, portStr), - }) + for _, endpoint := range endpointSlice.Endpoints { + if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { + continue + } + + for _, address := range endpoint.Addresses { + if _, ok := addresses[address]; ok { + continue + } + + addresses[address] = struct{}{} + svc.LoadBalancer.Servers = append(svc.LoadBalancer.Servers, dynamic.TCPServer{ + Address: net.JoinHostPort(address, strconv.Itoa(int(port))), + }) + } } } - serviceName := provider.Normalize(service.Namespace + "-" + service.Name + "-" + portStr) + serviceName := provider.Normalize(service.Namespace + "-" + service.Name + "-" + strconv.Itoa(int(svcPort.Port))) services[serviceName] = &svc wrrSvc.Weighted.Services = append(wrrSvc.Weighted.Services, dynamic.TCPWRRService{Name: serviceName, Weight: &weight}) diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index d7959d571..0e16aea9e 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -16,10 +16,12 @@ import ( "github.com/traefik/traefik/v3/pkg/types" traefikversion "github.com/traefik/traefik/v3/pkg/version" corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" netv1 "k8s.io/api/networking/v1" kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" kinformers "k8s.io/client-go/informers" kclientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -41,7 +43,7 @@ type Client interface { GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) GetNodes() ([]*corev1.Node, bool, error) - GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) + GetEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) UpdateIngressStatus(ing *netv1.Ingress, ingStatus []netv1.IngressLoadBalancerIngress) error } @@ -185,7 +187,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< if err != nil { return nil, err } - _, err = factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + _, err = factoryKube.Discovery().V1().EndpointSlices().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err } @@ -340,15 +342,20 @@ func (c *clientWrapper) GetService(namespace, name string) (*corev1.Service, boo return service, exist, err } -// GetEndpoints returns the named endpoints from the given namespace. -func (c *clientWrapper) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) { +// GetEndpointSlicesForService returns the EndpointSlices for the given service name in the given namespace. +func (c *clientWrapper) GetEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) { if !c.isWatchedNamespace(namespace) { - return nil, false, fmt.Errorf("failed to get endpoints %s/%s: namespace is not within watched namespaces", namespace, name) + return nil, fmt.Errorf("failed to get endpointslices for service %s/%s: namespace is not within watched namespaces", namespace, serviceName) } - endpoint, err := c.factoriesKube[c.lookupNamespace(namespace)].Core().V1().Endpoints().Lister().Endpoints(namespace).Get(name) - exist, err := translateNotFoundError(err) - return endpoint, exist, err + serviceLabelRequirement, err := labels.NewRequirement(discoveryv1.LabelServiceName, selection.Equals, []string{serviceName}) + if err != nil { + return nil, fmt.Errorf("failed to create service label selector requirement: %w", err) + } + serviceSelector := labels.NewSelector() + serviceSelector = serviceSelector.Add(*serviceLabelRequirement) + + return c.factoriesKube[c.lookupNamespace(namespace)].Discovery().V1().EndpointSlices().Lister().EndpointSlices(namespace).List(serviceSelector) } // GetSecret returns the named secret from the given namespace. diff --git a/pkg/provider/kubernetes/ingress/client_mock_test.go b/pkg/provider/kubernetes/ingress/client_mock_test.go index 02b8ec4c0..28b0a3501 100644 --- a/pkg/provider/kubernetes/ingress/client_mock_test.go +++ b/pkg/provider/kubernetes/ingress/client_mock_test.go @@ -6,6 +6,7 @@ import ( "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" netv1 "k8s.io/api/networking/v1" ) @@ -15,15 +16,15 @@ type clientMock struct { ingresses []*netv1.Ingress services []*corev1.Service secrets []*corev1.Secret - endpoints []*corev1.Endpoints + endpointSlices []*discoveryv1.EndpointSlice nodes []*corev1.Node ingressClasses []*netv1.IngressClass - apiServiceError error - apiSecretError error - apiEndpointsError error - apiNodesError error - apiIngressStatusError error + apiServiceError error + apiSecretError error + apiEndpointSlicesError error + apiNodesError error + apiIngressStatusError error watchChan chan interface{} } @@ -43,8 +44,8 @@ func newClientMock(path string) clientMock { c.services = append(c.services, o) case *corev1.Secret: c.secrets = append(c.secrets, o) - case *corev1.Endpoints: - c.endpoints = append(c.endpoints, o) + case *discoveryv1.EndpointSlice: + c.endpointSlices = append(c.endpointSlices, o) case *corev1.Node: c.nodes = append(c.nodes, o) case *netv1.Ingress: @@ -76,18 +77,19 @@ func (c clientMock) GetService(namespace, name string) (*corev1.Service, bool, e return nil, false, c.apiServiceError } -func (c clientMock) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) { - if c.apiEndpointsError != nil { - return nil, false, c.apiEndpointsError +func (c clientMock) GetEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) { + if c.apiEndpointSlicesError != nil { + return nil, c.apiEndpointSlicesError } - for _, endpoints := range c.endpoints { - if endpoints.Namespace == namespace && endpoints.Name == name { - return endpoints, true, nil + var result []*discoveryv1.EndpointSlice + for _, endpointSlice := range c.endpointSlices { + if endpointSlice.Namespace == namespace && endpointSlice.Labels[discoveryv1.LabelServiceName] == serviceName { + result = append(result, endpointSlice) } } - return &corev1.Endpoints{}, false, nil + return result, nil } func (c clientMock) GetNodes() ([]*corev1.Node, bool, error) { diff --git a/pkg/provider/kubernetes/ingress/client_test.go b/pkg/provider/kubernetes/ingress/client_test.go index 27e1bbd37..24240f277 100644 --- a/pkg/provider/kubernetes/ingress/client_test.go +++ b/pkg/provider/kubernetes/ingress/client_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" netv1 "k8s.io/api/networking/v1" kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -188,10 +189,10 @@ func TestClientIgnoresHelmOwnedSecrets(t *testing.T) { assert.False(t, found) } -func TestClientIgnoresEmptyEndpointUpdates(t *testing.T) { - emptyEndpoint := &corev1.Endpoints{ +func TestClientIgnoresEmptyEndpointSliceUpdates(t *testing.T) { + emptyEndpointSlice := &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ - Name: "empty-endpoint", + Name: "empty-endpointslice", Namespace: "test", ResourceVersion: "1244", Annotations: map[string]string{ @@ -200,25 +201,31 @@ func TestClientIgnoresEmptyEndpointUpdates(t *testing.T) { }, } - filledEndpoint := &corev1.Endpoints{ + samplePortName := "testing" + samplePortNumber := int32(1337) + samplePortProtocol := corev1.ProtocolTCP + sampleAddressReady := true + filledEndpointSlice := &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ - Name: "filled-endpoint", + Name: "filled-endpointslice", Namespace: "test", ResourceVersion: "1234", }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: "10.13.37.1", - }}, - Ports: []corev1.EndpointPort{{ - Name: "testing", - Port: 1337, - Protocol: "tcp", - }}, + AddressType: discoveryv1.AddressTypeIPv4, + Endpoints: []discoveryv1.Endpoint{{ + Addresses: []string{"10.13.37.1"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &sampleAddressReady, + }, + }}, + Ports: []discoveryv1.EndpointPort{{ + Name: &samplePortName, + Port: &samplePortNumber, + Protocol: &samplePortProtocol, }}, } - kubeClient := kubefake.NewSimpleClientset(emptyEndpoint, filledEndpoint) + kubeClient := kubefake.NewSimpleClientset(emptyEndpointSlice, filledEndpointSlice) discovery, _ := kubeClient.Discovery().(*discoveryfake.FakeDiscovery) discovery.FakedServerVersion = &kversion.Info{ @@ -234,50 +241,72 @@ func TestClientIgnoresEmptyEndpointUpdates(t *testing.T) { select { case event := <-eventCh: - ep, ok := event.(*corev1.Endpoints) + ep, ok := event.(*discoveryv1.EndpointSlice) require.True(t, ok) - assert.True(t, ep.Name == "empty-endpoint" || ep.Name == "filled-endpoint") + assert.True(t, ep.Name == "empty-endpointslice" || ep.Name == "filled-endpointslice") case <-time.After(50 * time.Millisecond): - assert.Fail(t, "expected to receive event for endpoints") + assert.Fail(t, "expected to receive event for endpointslices") } - emptyEndpoint, err = kubeClient.CoreV1().Endpoints("test").Get(context.TODO(), "empty-endpoint", metav1.GetOptions{}) + emptyEndpointSlice, err = kubeClient.DiscoveryV1().EndpointSlices("test").Get(context.TODO(), "empty-endpointslice", metav1.GetOptions{}) assert.NoError(t, err) // Update endpoint annotation and resource version (apparently not done by fake client itself) // to show an update that should not trigger an update event on our eventCh. // This reflects the behavior of kubernetes controllers which use endpoint annotations for leader election. - emptyEndpoint.Annotations["test-annotation"] = "___" - emptyEndpoint.ResourceVersion = "1245" - _, err = kubeClient.CoreV1().Endpoints("test").Update(context.TODO(), emptyEndpoint, metav1.UpdateOptions{}) + emptyEndpointSlice.Annotations["test-annotation"] = "___" + emptyEndpointSlice.ResourceVersion = "1245" + _, err = kubeClient.DiscoveryV1().EndpointSlices("test").Update(context.TODO(), emptyEndpointSlice, metav1.UpdateOptions{}) require.NoError(t, err) select { case event := <-eventCh: - ep, ok := event.(*corev1.Endpoints) + ep, ok := event.(*discoveryv1.EndpointSlice) require.True(t, ok) - assert.Fail(t, "didn't expect to receive event for empty endpoint update", ep.Name) + assert.Fail(t, "didn't expect to receive event for empty endpointslice update", ep.Name) case <-time.After(50 * time.Millisecond): } - filledEndpoint, err = kubeClient.CoreV1().Endpoints("test").Get(context.TODO(), "filled-endpoint", metav1.GetOptions{}) + filledEndpointSlice, err = kubeClient.DiscoveryV1().EndpointSlices("test").Get(context.TODO(), "filled-endpointslice", metav1.GetOptions{}) assert.NoError(t, err) - filledEndpoint.Subsets[0].Addresses[0].IP = "10.13.37.2" - filledEndpoint.ResourceVersion = "1235" - _, err = kubeClient.CoreV1().Endpoints("test").Update(context.TODO(), filledEndpoint, metav1.UpdateOptions{}) + filledEndpointSlice.Endpoints[0].Addresses[0] = "10.13.37.2" + filledEndpointSlice.ResourceVersion = "1235" + _, err = kubeClient.DiscoveryV1().EndpointSlices("test").Update(context.TODO(), filledEndpointSlice, metav1.UpdateOptions{}) require.NoError(t, err) select { case event := <-eventCh: - ep, ok := event.(*corev1.Endpoints) + ep, ok := event.(*discoveryv1.EndpointSlice) require.True(t, ok) - assert.Equal(t, "filled-endpoint", ep.Name) + assert.Equal(t, "filled-endpointslice", ep.Name) case <-time.After(50 * time.Millisecond): - assert.Fail(t, "expected to receive event for filled endpoint") + assert.Fail(t, "expected to receive event for filled endpointslice") + } + + select { + case <-eventCh: + assert.Fail(t, "received more than one event") + case <-time.After(50 * time.Millisecond): + } + + newPortNumber := int32(42) + filledEndpointSlice.Ports[0].Port = &newPortNumber + filledEndpointSlice.ResourceVersion = "1236" + _, err = kubeClient.DiscoveryV1().EndpointSlices("test").Update(context.TODO(), filledEndpointSlice, metav1.UpdateOptions{}) + require.NoError(t, err) + + select { + case event := <-eventCh: + ep, ok := event.(*discoveryv1.EndpointSlice) + require.True(t, ok) + + assert.Equal(t, "filled-endpointslice", ep.Name) + case <-time.After(50 * time.Millisecond): + assert.Fail(t, "expected to receive event for filled endpointslice") } select { diff --git a/pkg/provider/kubernetes/ingress/fixtures/2-ingresses-in-different-namespace-with-same-service-name.yml b/pkg/provider/kubernetes/ingress/fixtures/2-ingresses-in-different-namespace-with-same-service-name.yml index 616e2e3a8..afc2b3af3 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/2-ingresses-in-different-namespace-with-same-service-name.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/2-ingresses-in-different-namespace-with-same-service-name.yml @@ -1,32 +1,42 @@ --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: tchouk + port: 8089 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: tchouk - port: 8089 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: toto + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: tchouk + port: 8089 +endpoints: - addresses: - - ip: 10.11.0.1 - - ip: 10.11.0.2 - ports: - - name: tchouk - port: 8089 + - 10.11.0.1 + - 10.11.0.2 + conditions: + ready: true --- kind: Ingress diff --git a/pkg/provider/kubernetes/ingress/fixtures/Double-Single-Service-Ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/Double-Single-Service-Ingress.yml index b002d0fc5..95d47901a 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Double-Single-Service-Ingress.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Double-Single-Service-Ingress.yml @@ -50,35 +50,41 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiversion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.30.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.41.0.1 - ports: - - port: 8080 + - 10.30.0.1 + - 10.41.0.1 + conditions: + ready: true --- -kind: Endpoints -apiversion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service2 + name: service2-abc namespace: testing + labels: + kubernetes.io/service-name: service2 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-Two-rules-with-one-host-and-one-path.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-Two-rules-with-one-host-and-one-path.yml index 14b050fbd..c5dd091de 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-Two-rules-with-one-host-and-one-path.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-Two-rules-with-one-host-and-one-path.yml @@ -40,18 +40,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-host-and-two-paths.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-host-and-two-paths.yml index 675ddac66..def6f18a2 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-host-and-two-paths.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-host-and-two-paths.yml @@ -37,18 +37,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-path-and-one-host.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-path-and-one-host.yml index 2cb84cb33..fbddeff76 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-path-and-one-host.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-one-path-and-one-host.yml @@ -30,18 +30,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-two-paths.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-two-paths.yml index 8cd87d4c4..a7cbfe1d5 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-two-paths.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-with-two-paths.yml @@ -36,18 +36,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-IPv6-endpoints.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-IPv6-endpoints.yml index 340f79a60..aacdb0dbb 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-IPv6-endpoints.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-IPv6-endpoints.yml @@ -52,15 +52,20 @@ spec: externalName: "2001:0db8:3c4d:0015:0000:0000:1a2f:2a3b" --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service-bar + name: service-bar-abc namespace: testing + labels: + kubernetes.io/service-name: service-bar -subsets: +addressType: IPv6 +ports: + - name: http + port: 8080 +endpoints: - addresses: - - ip: "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b" - ports: - - name: http - port: 8080 + - "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b" + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(port-==-443).yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(port-==-443).yml index 0b3f020db..ec36dfbc5 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(port-==-443).yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(port-==-443).yml @@ -30,18 +30,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8443 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8443 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8443 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true \ No newline at end of file diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-==-https).yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-==-https).yml index 46227d191..659b70411 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-==-https).yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-==-https).yml @@ -31,20 +31,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: https + port: 8443 +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - name: https - port: 8443 - - addresses: - - ip: 10.21.0.1 - ports: - - name: https - port: 8443 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-starts-with-https).yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-starts-with-https).yml index 3cce7e424..6a5469730 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-starts-with-https).yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path-with-https-(portname-starts-with-https).yml @@ -31,20 +31,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: https-foo + port: 8443 +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - name: https-foo - port: 8443 - - addresses: - - ip: 10.21.0.1 - ports: - - name: https-foo - port: 8443 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path.yml index fcfbc08b1..1b64e2dbe 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-basic-rule-on-one-path.yml @@ -29,18 +29,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-named-port-matching-subset-of-service-pods.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-named-port-matching-subset-of-service-pods.yml index 8c65a2271..8e4a133e5 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-named-port-matching-subset-of-service-pods.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-a-named-port-matching-subset-of-service-pods.yml @@ -33,23 +33,42 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: tchouk + port: 8089 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: tchouk - port: 8089 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: service1-def + namespace: testing + labels: + kubernetes.io/service-name: service1 + +addressType: IPv4 +ports: + - name: carotte + port: 8090 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - - ip: 10.10.0.3 - ports: - - name: carotte - port: 8090 + - 10.10.0.1 + - 10.10.0.2 + - 10.10.0.3 + conditions: + ready: true \ No newline at end of file diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations.yml index 8acc12c2f..bf4679f30 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-annotations.yml @@ -53,18 +53,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-host.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-host.yml index b9d2b116d..655cdc26b 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-host.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-host.yml @@ -41,18 +41,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-path.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-path.yml index d0ef9b15d..f7f1459cf 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-path.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-conflicting-routers-on-path.yml @@ -37,18 +37,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-default-traefik-ingressClass.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-default-traefik-ingressClass.yml index 96ad4c8fd..42f94bf41 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-default-traefik-ingressClass.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-default-traefik-ingressClass.yml @@ -31,14 +31,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-defaultbackend.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-defaultbackend.yml index 7a9e31231..bcd8db9aa 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-defaultbackend.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-defaultbackend.yml @@ -36,27 +36,38 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 80 +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 80 + - 10.10.0.1 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: defaultservice + name: defaultservice-abc namespace: testing + labels: + kubernetes.io/service-name: defaultservice -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-empty-pathType.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-empty-pathType.yml index e4557b59b..f08124d72 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-empty-pathType.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-empty-pathType.yml @@ -30,14 +30,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-exact-pathType.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-exact-pathType.yml index cf33330da..b75c29d44 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-exact-pathType.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-exact-pathType.yml @@ -28,14 +28,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-implementationSpecific-pathType.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-implementationSpecific-pathType.yml index f410cd5f3..833b2878a 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-implementationSpecific-pathType.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-implementationSpecific-pathType.yml @@ -30,14 +30,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingress-annotation.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingress-annotation.yml index 3f9a500f5..1da2d0bfd 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingress-annotation.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingress-annotation.yml @@ -30,14 +30,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass-without-annotation.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass-without-annotation.yml index 96ad4c8fd..42f94bf41 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass-without-annotation.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass-without-annotation.yml @@ -31,14 +31,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass.yml index e272a505a..a954db81c 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClass.yml @@ -37,15 +37,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClasses-filter.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClasses-filter.yml index edc1b2a05..89aa5340b 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClasses-filter.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-ingressClasses-filter.yml @@ -64,14 +64,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-missing-ingressClass.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-missing-ingressClass.yml index 26473bbb3..2b8df5376 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-missing-ingressClass.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-missing-ingressClass.yml @@ -29,14 +29,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-multiple-ingressClasses.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-multiple-ingressClasses.yml index edc1b2a05..89aa5340b 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-multiple-ingressClasses.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-multiple-ingressClasses.yml @@ -64,14 +64,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-named-port.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-named-port.yml index 4d0394000..59c31a7cc 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-named-port.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-named-port.yml @@ -29,15 +29,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: foobar + port: 4711 +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - name: foobar - port: 4711 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-non-matching-provider-traefik-ingressClass-and-annotation.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-non-matching-provider-traefik-ingressClass-and-annotation.yml index 7c69c842b..6f571621f 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-non-matching-provider-traefik-ingressClass-and-annotation.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-non-matching-provider-traefik-ingressClass-and-annotation.yml @@ -31,14 +31,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-host-without-path.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-host-without-path.yml index 8de5910ad..52a370bbc 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-host-without-path.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-host-without-path.yml @@ -31,15 +31,20 @@ spec: type: ClusterIP --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: example-com + name: example-com-abc namespace: testing + labels: + kubernetes.io/service-name: example-com -subsets: +addressType: IPv4 +ports: + - name: http + port: 80 +endpoints: - addresses: - - ip: 10.11.0.1 - ports: - - name: http - port: 80 + - 10.11.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-service-without-endpoints-subset.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-service-without-endpoints-subset.yml index f0d9ffc8b..4cf788ea1 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-service-without-endpoints-subset.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-one-service-without-endpoints-subset.yml @@ -30,8 +30,14 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 + +addressType: IPv4 +ports: null +endpoints: [] diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-invalid-for-one-service.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-invalid-for-one-service.yml index ccf4c9557..cbfdf3b2f 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-invalid-for-one-service.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-invalid-for-one-service.yml @@ -40,24 +40,43 @@ spec: type: ClusterIP --- -apiVersion: v1 -kind: Endpoints +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing -subsets: + labels: + kubernetes.io/service-name: service1 + +addressType: IPv4 +ports: + - name: http-admin + port: 8079 + protocol: TCP +endpoints: - addresses: - - ip: 10.0.0.1 - nodeName: admin.whoami.service1 - ports: - - name: http-admin - port: 8079 - protocol: TCP + - 10.0.0.1 + conditions: + ready: true + nodeName: admin.whoami.service1 + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: service1-def + namespace: testing + labels: + kubernetes.io/service-name: service1 + +addressType: IPv4 +ports: + - name: http + port: 8080 + protocol: TCP +endpoints: - addresses: - - ip: 10.0.0.1 - nodeName: whoami.service1 - # targetRef: - ports: - - name: http - port: 8080 - protocol: TCP + - 10.0.0.1 + conditions: + ready: true + nodeName: whoami.service1 \ No newline at end of file diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-2-pod-replica.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-2-pod-replica.yml index 10216d602..79a3f892c 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-2-pod-replica.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-2-pod-replica.yml @@ -33,18 +33,23 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: carotte + port: 8090 + - name: tchouk + port: 8089 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: carotte - port: 8090 - - name: tchouk - port: 8089 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-no-pod-replica.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-no-pod-replica.yml index d9ea086f4..c263c46e4 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-no-pod-replica.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-name-in-backend-and-no-pod-replica.yml @@ -33,24 +33,23 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: carotte + port: 8090 + - name: tchouk + port: 8089 +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - name: carotte - port: 8090 - - name: tchouk - port: 8089 - - addresses: - - ip: 10.21.0.1 - ports: - - name: carotte - port: 8090 - - name: tchouk - port: 8089 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-value-in-backend-and-no-pod-replica.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-value-in-backend-and-no-pod-replica.yml index 073f5faa5..2c9db02e3 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-value-in-backend-and-no-pod-replica.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-port-value-in-backend-and-no-pod-replica.yml @@ -33,24 +33,23 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: carotte + port: 8090 + - name: tchouk + port: 8089 +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - name: carotte - port: 8090 - - name: tchouk - port: 8089 - - addresses: - - ip: 10.21.0.1 - ports: - - name: carotte - port: 8090 - - name: tchouk - port: 8089 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-prefix-pathType.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-prefix-pathType.yml index ca66982c8..c2d5fd6ba 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-prefix-pathType.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-prefix-pathType.yml @@ -28,14 +28,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-different-rules-with-one-path.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-different-rules-with-one-path.yml index 9f3a5d477..98fcb9307 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-different-rules-with-one-path.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-different-rules-with-one-path.yml @@ -38,18 +38,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-paths-using-same-service-and-different-port-name.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-paths-using-same-service-and-different-port-name.yml index 8474965be..495afdbd9 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-paths-using-same-service-and-different-port-name.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-paths-using-same-service-and-different-port-name.yml @@ -40,18 +40,23 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - name: carotte + port: 8090 + - name: tchouk + port: 8089 +endpoints: - addresses: - - ip: 10.10.0.1 - - ip: 10.10.0.2 - ports: - - name: carotte - port: 8090 - - name: tchouk - port: 8089 + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-services.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-services.yml index 55b9e4218..a11030881 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-services.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-two-services.yml @@ -52,35 +52,41 @@ spec: clusterIP: 10.1.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service2 + name: service2-abc namespace: testing + labels: + kubernetes.io/service-name: service2 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.2 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.2 - ports: - - port: 8080 + - 10.10.0.2 + - 10.21.0.2 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port-name.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port-name.yml index b22892ff5..c51486086 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port-name.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port-name.yml @@ -30,15 +30,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8089 + name: "" +endpoints: - addresses: - - ip: 10.11.0.1 - - ip: 10.11.0.2 - ports: - - port: 8089 + - 10.11.0.1 + - 10.11.0.2 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port.yml index 7ef564b1a..744ea812a 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-unknown-service-port.yml @@ -30,15 +30,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8089 + name: "" +endpoints: - addresses: - - ip: 10.11.0.1 - - ip: 10.11.0.2 - ports: - - port: 8089 + - 10.11.0.1 + - 10.11.0.2 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-wildcard-host.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-wildcard-host.yml index ff18bfd83..e0df96260 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-wildcard-host.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-wildcard-host.yml @@ -30,14 +30,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-without-provider-traefik-ingressClass-and-unknown-annotation.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-without-provider-traefik-ingressClass-and-unknown-annotation.yml index e2312d68e..aadced090 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Ingress-without-provider-traefik-ingressClass-and-unknown-annotation.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-without-provider-traefik-ingressClass-and-unknown-annotation.yml @@ -31,14 +31,20 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 + - 10.10.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/Single-Service-Ingress-(without-any-rules).yml b/pkg/provider/kubernetes/ingress/fixtures/Single-Service-Ingress-(without-any-rules).yml index 7ba4b0196..38b99a0d6 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/Single-Service-Ingress-(without-any-rules).yml +++ b/pkg/provider/kubernetes/ingress/fixtures/Single-Service-Ingress-(without-any-rules).yml @@ -24,18 +24,21 @@ spec: clusterIP: 10.0.0.1 --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: service1 + name: service1-abc namespace: testing + labels: + kubernetes.io/service-name: service1 -subsets: +addressType: IPv4 +ports: + - port: 8080 + name: "" +endpoints: - addresses: - - ip: 10.10.0.1 - ports: - - port: 8080 - - addresses: - - ip: 10.21.0.1 - ports: - - port: 8080 + - 10.10.0.1 + - 10.21.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/fixtures/TLS-support.yml b/pkg/provider/kubernetes/ingress/fixtures/TLS-support.yml index 6760730cd..c645ba44d 100644 --- a/pkg/provider/kubernetes/ingress/fixtures/TLS-support.yml +++ b/pkg/provider/kubernetes/ingress/fixtures/TLS-support.yml @@ -83,15 +83,20 @@ spec: type: ClusterIP --- -kind: Endpoints -apiVersion: v1 +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 metadata: - name: example-com + name: example-com-abc namespace: testing + labels: + kubernetes.io/service-name: example-com -subsets: +addressType: IPv4 +ports: + - name: http + port: 80 +endpoints: - addresses: - - ip: 10.11.0.1 - ports: - - name: http - port: 80 + - 10.11.0.1 + conditions: + ready: true diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index b952c32d7..7ae9c6b8b 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -651,36 +651,41 @@ func (p *Provider) loadService(client Client, namespace string, backend netv1.In return svc, nil } - endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, backend.Service.Name) - if endpointsErr != nil { - return nil, endpointsErr + endpointSlices, err := client.GetEndpointSlicesForService(namespace, backend.Service.Name) + if err != nil { + return nil, fmt.Errorf("getting endpointslices: %w", err) } - if !endpointsExists { - return nil, errors.New("endpoints not found") - } - - for _, subset := range endpoints.Subsets { + addresses := map[string]struct{}{} + for _, endpointSlice := range endpointSlices { var port int32 - for _, p := range subset.Ports { - if portName == p.Name { - port = p.Port + for _, p := range endpointSlice.Ports { + if portName == *p.Name { + port = *p.Port break } } - if port == 0 { continue } protocol := getProtocol(portSpec, portName, svcConfig) - for _, addr := range subset.Addresses { - hostPort := net.JoinHostPort(addr.IP, strconv.Itoa(int(port))) + for _, endpoint := range endpointSlice.Endpoints { + if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { + continue + } - svc.LoadBalancer.Servers = append(svc.LoadBalancer.Servers, dynamic.Server{ - URL: fmt.Sprintf("%s://%s", protocol, hostPort), - }) + for _, address := range endpoint.Addresses { + if _, ok := addresses[address]; ok { + continue + } + + addresses[address] = struct{}{} + svc.LoadBalancer.Servers = append(svc.LoadBalancer.Servers, dynamic.Server{ + URL: fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(address, strconv.Itoa(int(port)))), + }) + } } } diff --git a/pkg/provider/kubernetes/k8s/event_handler.go b/pkg/provider/kubernetes/k8s/event_handler.go index 14475c18c..1de67ec5e 100644 --- a/pkg/provider/kubernetes/k8s/event_handler.go +++ b/pkg/provider/kubernetes/k8s/event_handler.go @@ -1,7 +1,7 @@ package k8s import ( - corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -47,61 +47,54 @@ func objChanged(oldObj, newObj interface{}) bool { return false } - if _, ok := oldObj.(*corev1.Endpoints); ok { - return endpointsChanged(oldObj.(*corev1.Endpoints), newObj.(*corev1.Endpoints)) + if _, ok := oldObj.(*discoveryv1.EndpointSlice); ok { + return endpointSliceChanged(oldObj.(*discoveryv1.EndpointSlice), newObj.(*discoveryv1.EndpointSlice)) } return true } -func endpointsChanged(a, b *corev1.Endpoints) bool { - if len(a.Subsets) != len(b.Subsets) { +// In some Kubernetes versions leader election is done by updating an endpoint annotation every second, +// if there are no changes to the endpoints addresses, ports, and there are no addresses defined for an endpoint +// the event can safely be ignored and won't cause unnecessary config reloads. +// TODO: check if Kubernetes is still using EndpointSlice for leader election, which seems to not be the case anymore. +func endpointSliceChanged(a, b *discoveryv1.EndpointSlice) bool { + if len(a.Ports) != len(b.Ports) { return true } - for i, sa := range a.Subsets { - sb := b.Subsets[i] - if subsetsChanged(sa, sb) { - return true - } - } - - return false -} - -func subsetsChanged(sa, sb corev1.EndpointSubset) bool { - if len(sa.Addresses) != len(sb.Addresses) { - return true - } - - if len(sa.Ports) != len(sb.Ports) { - return true - } - - // in Addresses and Ports, we should be able to rely on - // these being sorted and able to be compared - // they are supposed to be in a canonical format - for addr, aaddr := range sa.Addresses { - baddr := sb.Addresses[addr] - if aaddr.IP != baddr.IP { - return true - } - - if aaddr.Hostname != baddr.Hostname { - return true - } - } - - for port, aport := range sa.Ports { - bport := sb.Ports[port] + for i, aport := range a.Ports { + bport := b.Ports[i] if aport.Name != bport.Name { return true } if aport.Port != bport.Port { return true } + } - if aport.Protocol != bport.Protocol { + if len(a.Endpoints) != len(b.Endpoints) { + return true + } + + for i, ea := range a.Endpoints { + eb := b.Endpoints[i] + if endpointChanged(ea, eb) { + return true + } + } + + return false +} + +func endpointChanged(a, b discoveryv1.Endpoint) bool { + if len(a.Addresses) != len(b.Addresses) { + return true + } + + for i, aaddr := range a.Addresses { + baddr := b.Addresses[i] + if aaddr != baddr { return true } } diff --git a/pkg/provider/kubernetes/k8s/event_handler_test.go b/pkg/provider/kubernetes/k8s/event_handler_test.go index 323b4f550..bcde5cc48 100644 --- a/pkg/provider/kubernetes/k8s/event_handler_test.go +++ b/pkg/provider/kubernetes/k8s/event_handler_test.go @@ -4,12 +4,14 @@ import ( "testing" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" netv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_detectChanges(t *testing.T) { + portA := int32(80) + portB := int32(8080) tests := []struct { name string oldObj interface{} @@ -21,28 +23,28 @@ func Test_detectChanges(t *testing.T) { want: true, }, { - name: "With empty endpoints", - oldObj: &corev1.Endpoints{}, - newObj: &corev1.Endpoints{}, + name: "With empty endpointslice", + oldObj: &discoveryv1.EndpointSlice{}, + newObj: &discoveryv1.EndpointSlice{}, }, { name: "With old nil", - newObj: &corev1.Endpoints{}, + newObj: &discoveryv1.EndpointSlice{}, want: true, }, { name: "With new nil", - oldObj: &corev1.Endpoints{}, + oldObj: &discoveryv1.EndpointSlice{}, want: true, }, { name: "With same version", - oldObj: &corev1.Endpoints{ + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, @@ -50,12 +52,12 @@ func Test_detectChanges(t *testing.T) { }, { name: "With different version", - oldObj: &corev1.Endpoints{ + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", }, @@ -90,7 +92,7 @@ func Test_detectChanges(t *testing.T) { }, { name: "With same annotations", - oldObj: &corev1.Endpoints{ + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", Annotations: map[string]string{ @@ -98,7 +100,7 @@ func Test_detectChanges(t *testing.T) { }, }, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", Annotations: map[string]string{ @@ -109,7 +111,7 @@ func Test_detectChanges(t *testing.T) { }, { name: "With different annotations", - oldObj: &corev1.Endpoints{ + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", Annotations: map[string]string{ @@ -117,7 +119,7 @@ func Test_detectChanges(t *testing.T) { }, }, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", Annotations: map[string]string{ @@ -127,384 +129,94 @@ func Test_detectChanges(t *testing.T) { }, }, { - name: "With same subsets", - oldObj: &corev1.Endpoints{ + name: "With same endpoints and ports", + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, - Subsets: []corev1.EndpointSubset{}, + Endpoints: []discoveryv1.Endpoint{}, + Ports: []discoveryv1.EndpointPort{}, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, - Subsets: []corev1.EndpointSubset{}, + Endpoints: []discoveryv1.Endpoint{}, + Ports: []discoveryv1.EndpointPort{}, }, }, { - name: "With different len of subsets", - oldObj: &corev1.Endpoints{ + name: "With different len of endpoints", + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, - Subsets: []corev1.EndpointSubset{}, + Endpoints: []discoveryv1.Endpoint{}, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", }, - Subsets: []corev1.EndpointSubset{{}}, + Endpoints: []discoveryv1.Endpoint{{}}, }, want: true, }, { - name: "With same subsets with same len of addresses", - oldObj: &corev1.Endpoints{ + name: "With different endpoints", + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{}, + Endpoints: []discoveryv1.Endpoint{{ + Addresses: []string{"10.10.10.10"}, }}, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{}, - }}, - }, - }, - { - name: "With same subsets with different len of addresses", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{}}, + Endpoints: []discoveryv1.Endpoint{{ + Addresses: []string{"10.10.10.11"}, }}, }, want: true, }, { - name: "With same subsets with same len of ports", - oldObj: &corev1.Endpoints{ + name: "With different len of ports", + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{}, - }}, + Ports: []discoveryv1.EndpointPort{}, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{}, - }}, - }, - }, - { - name: "With same subsets with different len of ports", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{}}, - }}, + Ports: []discoveryv1.EndpointPort{{}}, }, want: true, }, { - name: "With same subsets with same len of addresses with same ip", - oldObj: &corev1.Endpoints{ + name: "With different ports", + oldObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: "10.10.10.10", - }}, + Ports: []discoveryv1.EndpointPort{{ + Port: &portA, }}, }, - newObj: &corev1.Endpoints{ + newObj: &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: "10.10.10.10", - }}, - }}, - }, - }, - { - name: "With same subsets with same len of addresses with different ip", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: "10.10.10.10", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: "10.10.10.42", - }}, + Ports: []discoveryv1.EndpointPort{{ + Port: &portB, }}, }, want: true, }, - { - name: "With same subsets with same len of addresses with same hostname", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - Hostname: "foo", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - Hostname: "foo", - }}, - }}, - }, - }, - { - name: "With same subsets with same len of addresses with same hostname", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - Hostname: "foo", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - Hostname: "bar", - }}, - }}, - }, - want: true, - }, - { - name: "With same subsets with same len of port with same name", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Name: "foo", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Name: "foo", - }}, - }}, - }, - }, - { - name: "With same subsets with same len of port with different name", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Name: "foo", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Name: "bar", - }}, - }}, - }, - want: true, - }, - { - name: "With same subsets with same len of port with same port", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Port: 4242, - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Port: 4242, - }}, - }}, - }, - }, - { - name: "With same subsets with same len of port with different port", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Port: 4242, - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Port: 6969, - }}, - }}, - }, - want: true, - }, - { - name: "With same subsets with same len of port with same protocol", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Protocol: "HTTP", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Protocol: "HTTP", - }}, - }}, - }, - }, - { - name: "With same subsets with same len of port with different protocol", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Protocol: "HTTP", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Ports: []corev1.EndpointPort{{ - Protocol: "TCP", - }}, - }}, - }, - want: true, - }, - { - name: "With same subsets with same subset", - oldObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "1", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: "10.10.10.10", - Hostname: "foo", - }}, - Ports: []corev1.EndpointPort{{ - Name: "bar", - Port: 4242, - Protocol: "HTTP", - }}, - }}, - }, - newObj: &corev1.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: "2", - }, - Subsets: []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: "10.10.10.10", - Hostname: "foo", - }}, - Ports: []corev1.EndpointPort{{ - Name: "bar", - Port: 4242, - Protocol: "HTTP", - }}, - }}, - }, - }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/pkg/provider/kubernetes/k8s/parser.go b/pkg/provider/kubernetes/k8s/parser.go index 1f1a0d0e9..0c50ab61e 100644 --- a/pkg/provider/kubernetes/k8s/parser.go +++ b/pkg/provider/kubernetes/k8s/parser.go @@ -12,7 +12,7 @@ import ( // MustParseYaml parses a YAML to objects. func MustParseYaml(content []byte) []runtime.Object { - acceptedK8sTypes := regexp.MustCompile(`^(Namespace|Deployment|Endpoints|Node|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|ServersTransportTCP|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute|ReferenceGrant)$`) + acceptedK8sTypes := regexp.MustCompile(`^(Namespace|Deployment|EndpointSlice|Node|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|ServersTransportTCP|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute|ReferenceGrant)$`) files := strings.Split(string(content), "---\n") retVal := make([]runtime.Object, 0, len(files))