diff --git a/config/config-gateway.yaml b/config/config-gateway.yaml index 47d133807..5d217f82d 100644 --- a/config/config-gateway.yaml +++ b/config/config-gateway.yaml @@ -50,9 +50,13 @@ data: - class: istio gateway: istio-system/knative-gateway service: istio-system/istio-ingressgateway + supported-features: + - HTTPRouteRequestTimeout # local-gateways defines the Gateway to be used for cluster local traffic local-gateways: | - class: istio gateway: istio-system/knative-local-gateway service: istio-system/knative-local-gateway + supported-features: + - HTTPRouteRequestTimeout diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 22875be51..1fc9c9bde 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -36,14 +36,16 @@ EXTERNAL_INFORMER_PKG="sigs.k8s.io/gateway-api/pkg/client/informers/externalvers "apis:v1beta1,v1" \ --go-header-file "${boilerplate}" +# Deepcopy is broken for fields that use generics - so we generate the code +# ignore failures and then clean it up ourselves with sed until k8s upstream +# fixes the issue group "Deepcopy Gen" go run k8s.io/code-generator/cmd/deepcopy-gen \ -O zz_generated.deepcopy \ --go-header-file "${boilerplate}" \ --input-dirs knative.dev/net-gateway-api/pkg/reconciler/ingress/config -group "Update deps post-codegen" - +# group "Update deps post-codegen" # Make sure our dependencies are up-to-date "${REPO_ROOT_DIR}"/hack/update-deps.sh group "Update tested version docs" diff --git a/pkg/reconciler/ingress/config/doc.go b/pkg/reconciler/ingress/config/doc.go index a21d3f0e2..56f5c7fa6 100644 --- a/pkg/reconciler/ingress/config/doc.go +++ b/pkg/reconciler/ingress/config/doc.go @@ -14,6 +14,4 @@ See the License for the specific language governing permissions and limitations under the License. */ -// +k8s:deepcopy-gen=package - package config diff --git a/pkg/reconciler/ingress/config/gateway.go b/pkg/reconciler/ingress/config/gateway.go index 8f5adaffe..82cdc58d2 100644 --- a/pkg/reconciler/ingress/config/gateway.go +++ b/pkg/reconciler/ingress/config/gateway.go @@ -22,12 +22,12 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" "knative.dev/pkg/configmap" + "sigs.k8s.io/gateway-api/pkg/features" "sigs.k8s.io/yaml" ) -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - const ( // GatewayConfigName is the config map name for the gateway configuration. GatewayConfigName = "config-gateway" @@ -42,12 +42,14 @@ func defaultExternalGateways() []Gateway { Name: "knative-gateway", Namespace: "istio-system", }, - Class: "istio", Service: &types.NamespacedName{ Name: "istio-ingressgateway", Namespace: "istio-system", }, + SupportedFeatures: sets.New( + features.SupportHTTPRouteRequestTimeout, + ), }} } @@ -62,6 +64,9 @@ func defaultLocalGateways() []Gateway { Name: "knative-local-gateway", Namespace: "istio-system", }, + SupportedFeatures: sets.New( + features.SupportHTTPRouteRequestTimeout, + ), }} } @@ -79,11 +84,14 @@ func (g *GatewayPlugin) LocalGateway() Gateway { return g.LocalGateways[0] } +// Note deepcopy gen is broken for sets.Set[features.SupportedFeatures] +// So I've disabled the generator in this package for now type Gateway struct { types.NamespacedName - Class string - Service *types.NamespacedName + Class string + Service *types.NamespacedName + SupportedFeatures sets.Set[features.SupportedFeature] } // FromConfigMap creates a GatewayPlugin config from the supplied ConfigMap @@ -126,27 +134,43 @@ func FromConfigMap(cm *corev1.ConfigMap) (*GatewayPlugin, error) { return config, nil } +type gatewayEntry struct { + Gateway string `json:"gateway"` + Service *string `json:"service"` + Class string `json:"class"` + SupportedFeatures []features.SupportedFeature `json:"supported-features"` +} + func parseGatewayConfig(data string) ([]Gateway, error) { - var entries []map[string]string + var entries []gatewayEntry if err := yaml.Unmarshal([]byte(data), &entries); err != nil { return nil, err } gws := make([]Gateway, 0, len(entries)) - for i, entry := range entries { - gw := Gateway{} + gw := Gateway{ + Class: entry.Class, + SupportedFeatures: sets.New(entry.SupportedFeatures...), + } - err := configmap.Parse(entry, - configmap.AsString("class", &gw.Class), + names := map[string]string{ + "gateway": entry.Gateway, + } + + if entry.Service != nil { + names["service"] = *entry.Service + } + + err := configmap.Parse(names, configmap.AsNamespacedName("gateway", &gw.NamespacedName), configmap.AsOptionalNamespacedName("service", &gw.Service), ) + if err != nil { return nil, err } - if len(strings.TrimSpace(gw.Class)) == 0 { return nil, fmt.Errorf(`entry [%d] field "class" is required`, i) } diff --git a/pkg/reconciler/ingress/config/gateway_test.go b/pkg/reconciler/ingress/config/gateway_test.go index 601c3192d..3cc9dc275 100644 --- a/pkg/reconciler/ingress/config/gateway_test.go +++ b/pkg/reconciler/ingress/config/gateway_test.go @@ -56,13 +56,25 @@ func TestFromConfigMapErrors(t *testing.T) { }, { name: "external-gateways multiple entries", data: map[string]string{ - "external-gateways": `[{"class":"boo"},{"class":"boo"}]`, + "external-gateways": `[{ + "class":"boo", + "gateway": "ns/n" + },{ + "class":"boo", + "gateway": "ns/n" + }]`, }, want: `only a single external gateway is supported`, }, { name: "local-gateways multiple entries", data: map[string]string{ - "local-gateways": `[{"class":"boo"},{"class":"boo"}]`, + "local-gateways": `[{ + "class":"boo", + "gateway": "ns/n" + },{ + "class":"boo", + "gateway": "ns/n" + }]`, }, want: `only a single local gateway is supported`, }, { diff --git a/pkg/reconciler/ingress/config/zz_generated.deepcopy.go b/pkg/reconciler/ingress/config/zz_generated.deepcopy.go index 79cab0492..ee88720b4 100644 --- a/pkg/reconciler/ingress/config/zz_generated.deepcopy.go +++ b/pkg/reconciler/ingress/config/zz_generated.deepcopy.go @@ -23,7 +23,9 @@ package config import ( types "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" pkgconfig "knative.dev/networking/pkg/config" + "sigs.k8s.io/gateway-api/pkg/features" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -61,6 +63,13 @@ func (in *Gateway) DeepCopyInto(out *Gateway) { *out = new(types.NamespacedName) **out = **in } + if in.SupportedFeatures != nil { + in, out := &in.SupportedFeatures, &out.SupportedFeatures + *out = make(sets.Set[features.SupportedFeature], len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } diff --git a/pkg/reconciler/ingress/resources/httproute.go b/pkg/reconciler/ingress/resources/httproute.go index 31d2ffc2f..ad0d99380 100644 --- a/pkg/reconciler/ingress/resources/httproute.go +++ b/pkg/reconciler/ingress/resources/httproute.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" gatewayapi "sigs.k8s.io/gateway-api/apis/v1" + "sigs.k8s.io/gateway-api/pkg/features" "knative.dev/net-gateway-api/pkg/reconciler/ingress/config" "knative.dev/networking/pkg/apis/networking" @@ -225,8 +226,6 @@ func makeHTTPRouteSpec( hostnames = append(hostnames, gatewayapi.Hostname(hostname)) } - rules := makeHTTPRouteRule(rule) - pluginConfig := config.FromContext(ctx).GatewayPlugin var gateway config.Gateway @@ -237,6 +236,8 @@ func makeHTTPRouteSpec( gateway = pluginConfig.ExternalGateway() } + rules := makeHTTPRouteRule(gateway, rule) + gatewayRef := gatewayapi.ParentReference{ Group: (*gatewayapi.Group)(&gatewayapi.GroupVersion.Group), Kind: (*gatewayapi.Kind)(ptr.To("Gateway")), @@ -253,10 +254,11 @@ func makeHTTPRouteSpec( } } -func makeHTTPRouteRule(rule *netv1alpha1.IngressRule) []gatewayapi.HTTPRouteRule { +func makeHTTPRouteRule(gw config.Gateway, rule *netv1alpha1.IngressRule) []gatewayapi.HTTPRouteRule { rules := []gatewayapi.HTTPRouteRule{} for _, path := range rule.HTTP.Paths { + path := path backendRefs := make([]gatewayapi.HTTPBackendRef, 0, len(path.Splits)) var preFilters []gatewayapi.HTTPRouteFilter @@ -351,6 +353,13 @@ func makeHTTPRouteRule(rule *netv1alpha1.IngressRule) []gatewayapi.HTTPRouteRule Filters: preFilters, Matches: matches, } + + if gw.SupportedFeatures.Has(features.SupportHTTPRouteRequestTimeout) { + rule.Timeouts = &gatewayapi.HTTPRouteTimeouts{ + Request: ptr.To[gatewayapi.Duration]("0s"), + } + } + rules = append(rules, rule) } return rules diff --git a/pkg/reconciler/ingress/resources/httproute_test.go b/pkg/reconciler/ingress/resources/httproute_test.go index 8441a3569..2a59a6f23 100644 --- a/pkg/reconciler/ingress/resources/httproute_test.go +++ b/pkg/reconciler/ingress/resources/httproute_test.go @@ -18,12 +18,14 @@ package resources import ( "context" + "fmt" "testing" "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" "knative.dev/net-gateway-api/pkg/reconciler/ingress/config" "knative.dev/networking/pkg/apis/networking" @@ -32,6 +34,7 @@ import ( "knative.dev/pkg/kmeta" "knative.dev/pkg/reconciler" gatewayapi "sigs.k8s.io/gateway-api/apis/v1" + "sigs.k8s.io/gateway-api/pkg/features" ) const ( @@ -102,9 +105,10 @@ var ( func TestMakeHTTPRoute(t *testing.T) { for _, tc := range []struct { - name string - ing *v1alpha1.Ingress - expected []*gatewayapi.HTTPRoute + name string + ing *v1alpha1.Ingress + expected []*gatewayapi.HTTPRoute + changeConfig func(gw *config.Config) }{ { name: "single external domain with split and cluster local", @@ -535,11 +539,78 @@ func TestMakeHTTPRoute(t *testing.T) { }, }, }}, + }, { + name: "gateway supports HTTPRouteRequestTimeout", + changeConfig: func(c *config.Config) { + gateways := c.GatewayPlugin.ExternalGateways + + for _, gateway := range gateways { + gateway.SupportedFeatures.Insert(features.SupportHTTPRouteRequestTimeout) + } + }, + ing: &v1alpha1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: testIngressName, + Namespace: testNamespace, + Labels: map[string]string{ + networking.IngressLabelKey: testIngressName, + }, + }, + Spec: v1alpha1.IngressSpec{Rules: []v1alpha1.IngressRule{{ + Hosts: testHosts, + Visibility: v1alpha1.IngressVisibilityExternalIP, + HTTP: &v1alpha1.HTTPIngressRuleValue{ + Paths: []v1alpha1.HTTPIngressPath{{ + Path: "/", + }}, + }, + }}}, + }, + expected: []*gatewayapi.HTTPRoute{{ + ObjectMeta: metav1.ObjectMeta{ + Name: LongestHost(testHosts), + Namespace: testNamespace, + Labels: map[string]string{ + networking.IngressLabelKey: testIngressName, + "networking.knative.dev/visibility": "", + }, + Annotations: map[string]string{}, + }, + Spec: gatewayapi.HTTPRouteSpec{ + Hostnames: []gatewayapi.Hostname{externalHost}, + Rules: []gatewayapi.HTTPRouteRule{{ + Timeouts: &gatewayapi.HTTPRouteTimeouts{ + Request: ptr.To[gatewayapi.Duration]("0s"), + }, + BackendRefs: []gatewayapi.HTTPBackendRef{}, + Matches: []gatewayapi.HTTPRouteMatch{{ + Path: &gatewayapi.HTTPPathMatch{ + Type: ptr.To(gatewayapi.PathMatchPathPrefix), + Value: ptr.To("/"), + }, + }}}, + }, + CommonRouteSpec: gatewayapi.CommonRouteSpec{ + ParentRefs: []gatewayapi.ParentReference{{ + Group: (*gatewayapi.Group)(ptr.To("gateway.networking.k8s.io")), + Kind: (*gatewayapi.Kind)(ptr.To("Gateway")), + Namespace: ptr.To[gatewayapi.Namespace]("test-ns"), + Name: gatewayapi.ObjectName("foo"), + }}, + }, + }, + }}, }} { t.Run(tc.name, func(t *testing.T) { for i, rule := range tc.ing.Spec.Rules { rule := rule - tcs := &testConfigStore{config: testConfig} + cfg := testConfig.DeepCopy() + if tc.changeConfig != nil { + tc.changeConfig(cfg) + + fmt.Printf("%#v", cfg.GatewayPlugin.ExternalGateways) + } + tcs := &testConfigStore{config: cfg} ctx := tcs.ToContext(context.Background()) route, err := MakeHTTPRoute(ctx, tc.ing, &rule) @@ -1125,12 +1196,14 @@ func (t *testConfigStore) ToContext(ctx context.Context) context.Context { var testConfig = &config.Config{ GatewayPlugin: &config.GatewayPlugin{ ExternalGateways: []config.Gateway{{ - NamespacedName: types.NamespacedName{Namespace: "test-ns", Name: "foo"}, - Class: testGatewayClass, + NamespacedName: types.NamespacedName{Namespace: "test-ns", Name: "foo"}, + Class: testGatewayClass, + SupportedFeatures: sets.New[features.SupportedFeature](), }}, LocalGateways: []config.Gateway{{ - NamespacedName: types.NamespacedName{Namespace: "test-ns", Name: "foo-local"}, - Class: testGatewayClass, + NamespacedName: types.NamespacedName{Namespace: "test-ns", Name: "foo-local"}, + Class: testGatewayClass, + SupportedFeatures: sets.New[features.SupportedFeature](), }}, }, } diff --git a/test/e2e/testdata/contour-no-service-vis.yaml b/test/e2e/testdata/contour-no-service-vis.yaml index 8a6ce8551..83879d565 100644 --- a/test/e2e/testdata/contour-no-service-vis.yaml +++ b/test/e2e/testdata/contour-no-service-vis.yaml @@ -25,9 +25,13 @@ metadata: serving.knative.dev/release: devel data: external-gateways: | - - class: contour + - class: contour-external gateway: contour-external/knative-external + supported-features: + - HTTPRouteRequestTimeout local-gateways: | - - class: contour + - class: contour-internal gateway: contour-internal/knative-local service: contour-internal/envoy-knative-local + supported-features: + - HTTPRouteRequestTimeout diff --git a/test/e2e/testdata/istio-no-service-vis.yaml b/test/e2e/testdata/istio-no-service-vis.yaml index c934762ca..60a08f930 100644 --- a/test/e2e/testdata/istio-no-service-vis.yaml +++ b/test/e2e/testdata/istio-no-service-vis.yaml @@ -23,6 +23,10 @@ data: external-gateways: | - class: istio gateway: istio-system/knative-gateway + supported-features: + - HTTPRouteRequestTimeout local-gateways: | - class: istio gateway: istio-system/knative-local-gateway + supported-features: + - HTTPRouteRequestTimeout diff --git a/third_party/contour/config-gateway.yaml b/third_party/contour/config-gateway.yaml index 4505d9c34..7c4343920 100644 --- a/third_party/contour/config-gateway.yaml +++ b/third_party/contour/config-gateway.yaml @@ -23,12 +23,16 @@ metadata: serving.knative.dev/release: devel data: external-gateways: | - - class: contour + - class: contour-external gateway: contour-external/knative-external service: contour-external/envoy-knative-external + supported-features: + - HTTPRouteRequestTimeout # local-gateways defines the Gateway to be used for cluster local traffic local-gateways: | - - class: contour + - class: contour-internal gateway: contour-internal/knative-local service: contour-internal/envoy-knative-local + supported-features: + - HTTPRouteRequestTimeout diff --git a/third_party/contour/config_test.go b/third_party/contour/config_test.go new file mode 100644 index 000000000..9628c24b5 --- /dev/null +++ b/third_party/contour/config_test.go @@ -0,0 +1,44 @@ +/* +Copyright 2024 The Knative 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. +*/ + +package main + +import ( + "os" + "testing" + + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" + + "knative.dev/net-gateway-api/pkg/reconciler/ingress/config" +) + +func TestFromConfigMap(t *testing.T) { + bytes, err := os.ReadFile(config.GatewayConfigName + ".yaml") + if err != nil { + t.Fatalf("failed to read %q: %s", config.GatewayConfigName, err) + } + + cm := &corev1.ConfigMap{} + err = yaml.Unmarshal(bytes, cm) + if err != nil { + t.Fatalf("failed to unmarshal %q: %s", config.GatewayConfigName, err) + } + + if _, err := config.FromConfigMap(cm); err != nil { + t.Error("FromConfigMap(actual) =", err) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 76f611ca6..ad1d6bb08 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1037,6 +1037,7 @@ sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1 sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1alpha2 sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1alpha3 sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1beta1 +sigs.k8s.io/gateway-api/pkg/features # sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd ## explicit; go 1.18 sigs.k8s.io/json diff --git a/vendor/sigs.k8s.io/gateway-api/pkg/features/features.go b/vendor/sigs.k8s.io/gateway-api/pkg/features/features.go new file mode 100644 index 000000000..fcb6d2801 --- /dev/null +++ b/vendor/sigs.k8s.io/gateway-api/pkg/features/features.go @@ -0,0 +1,265 @@ +/* +Copyright 2022 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. +*/ + +package features + +import "k8s.io/apimachinery/pkg/util/sets" + +// ----------------------------------------------------------------------------- +// Features - Types +// ----------------------------------------------------------------------------- + +// SupportedFeature allows opting in to additional conformance tests at an +// individual feature granularity. +type SupportedFeature string + +// ----------------------------------------------------------------------------- +// Features - Gateway Conformance (Core) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates support for Gateway. + // Opting out of this is allowed only for GAMMA-only implementations + SupportGateway SupportedFeature = "Gateway" +) + +// GatewayCoreFeatures are the features that are required to be conformant with +// the Gateway resource. +var GatewayCoreFeatures = sets.New( + SupportGateway, +) + +// ----------------------------------------------------------------------------- +// Features - Gateway Conformance (Extended) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates that the Gateway can also use port 8080 + SupportGatewayPort8080 SupportedFeature = "GatewayPort8080" + + // SupportGatewayStaticAddresses option indicates that the Gateway is capable + // of allocating pre-determined addresses, rather than dynamically having + // addresses allocated for it. + SupportGatewayStaticAddresses SupportedFeature = "GatewayStaticAddresses" +) + +// GatewayExtendedFeatures are extra generic features that implementations may +// choose to support as an opt-in. This does not include any Core Features. +var GatewayExtendedFeatures = sets.New( + SupportGatewayPort8080, + SupportGatewayStaticAddresses, +) + +// ----------------------------------------------------------------------------- +// Features - ReferenceGrant Conformance (Core) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates support for ReferenceGrant. + SupportReferenceGrant SupportedFeature = "ReferenceGrant" +) + +// ReferenceGrantCoreFeatures includes all SupportedFeatures needed to be +// conformant with the ReferenceGrant resource. +var ReferenceGrantCoreFeatures = sets.New( + SupportReferenceGrant, +) + +// ----------------------------------------------------------------------------- +// Features - HTTPRoute Conformance (Core) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates support for HTTPRoute + SupportHTTPRoute SupportedFeature = "HTTPRoute" +) + +// HTTPRouteCoreFeatures includes all SupportedFeatures needed to be conformant with +// the HTTPRoute resource. +var HTTPRouteCoreFeatures = sets.New( + SupportHTTPRoute, +) + +// ----------------------------------------------------------------------------- +// Features - HTTPRoute Conformance (Extended) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates support for HTTPRoute backend request header modification + SupportHTTPRouteBackendRequestHeaderModification SupportedFeature = "HTTPRouteBackendRequestHeaderModification" + + // This option indicates support for HTTPRoute query param matching (extended conformance). + SupportHTTPRouteQueryParamMatching SupportedFeature = "HTTPRouteQueryParamMatching" + + // This option indicates support for HTTPRoute method matching (extended conformance). + SupportHTTPRouteMethodMatching SupportedFeature = "HTTPRouteMethodMatching" + + // This option indicates support for HTTPRoute response header modification (extended conformance). + SupportHTTPRouteResponseHeaderModification SupportedFeature = "HTTPRouteResponseHeaderModification" + + // This option indicates support for HTTPRoute port redirect (extended conformance). + SupportHTTPRoutePortRedirect SupportedFeature = "HTTPRoutePortRedirect" + + // This option indicates support for HTTPRoute scheme redirect (extended conformance). + SupportHTTPRouteSchemeRedirect SupportedFeature = "HTTPRouteSchemeRedirect" + + // This option indicates support for HTTPRoute path redirect (extended conformance). + SupportHTTPRoutePathRedirect SupportedFeature = "HTTPRoutePathRedirect" + + // This option indicates support for HTTPRoute host rewrite (extended conformance) + SupportHTTPRouteHostRewrite SupportedFeature = "HTTPRouteHostRewrite" + + // This option indicates support for HTTPRoute path rewrite (extended conformance) + SupportHTTPRoutePathRewrite SupportedFeature = "HTTPRoutePathRewrite" + + // This option indicates support for HTTPRoute request mirror (extended conformance). + SupportHTTPRouteRequestMirror SupportedFeature = "HTTPRouteRequestMirror" + + // This option indicates support for multiple RequestMirror filters within the same HTTPRoute rule (extended conformance). + SupportHTTPRouteRequestMultipleMirrors SupportedFeature = "HTTPRouteRequestMultipleMirrors" + + // This option indicates support for HTTPRoute request timeouts (extended conformance). + SupportHTTPRouteRequestTimeout SupportedFeature = "HTTPRouteRequestTimeout" + + // This option indicates support for HTTPRoute backendRequest timeouts (extended conformance). + SupportHTTPRouteBackendTimeout SupportedFeature = "HTTPRouteBackendTimeout" + + // This option indicates support for HTTPRoute parentRef port (extended conformance). + SupportHTTPRouteParentRefPort SupportedFeature = "HTTPRouteParentRefPort" +) + +// HTTPRouteExtendedFeatures includes all extended features for HTTPRoute +// conformance and can be used to opt-in to run all HTTPRoute extended features tests. +// This does not include any Core Features. +var HTTPRouteExtendedFeatures = sets.New( + SupportHTTPRouteQueryParamMatching, + SupportHTTPRouteMethodMatching, + SupportHTTPRouteResponseHeaderModification, + SupportHTTPRoutePortRedirect, + SupportHTTPRouteSchemeRedirect, + SupportHTTPRoutePathRedirect, + SupportHTTPRouteHostRewrite, + SupportHTTPRoutePathRewrite, + SupportHTTPRouteRequestMirror, + SupportHTTPRouteRequestMultipleMirrors, + SupportHTTPRouteRequestTimeout, + SupportHTTPRouteBackendTimeout, + SupportHTTPRouteParentRefPort, + SupportHTTPRouteBackendRequestHeaderModification, +) + +// ----------------------------------------------------------------------------- +// Features - HTTPRoute Conformance (Experimental) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates support for Destination Port matching. + SupportHTTPRouteDestinationPortMatching SupportedFeature = "HTTPRouteDestinationPortMatching" + + // This option indicates support for HTTPRoute with a backendref with an appProtocol 'kubernetes.io/h2c' + SupportHTTPRouteBackendProtocolH2C SupportedFeature = "HTTPRouteBackendProtocolH2C" + + // This option indicates support for HTTPRoute with a backendref with an appProtoocol 'kubernetes.io/ws' + SupportHTTPRouteBackendProtocolWebSocket SupportedFeature = "HTTPRouteBackendProtocolWebSocket" +) + +// HTTPRouteExperimentalFeatures includes all the supported experimental features, currently only +// available in our experimental release channel. +// Implementations have the flexibility to opt-in for either specific features or the entire set. +var HTTPRouteExperimentalFeatures = sets.New( + SupportHTTPRouteDestinationPortMatching, + SupportHTTPRouteBackendProtocolH2C, + SupportHTTPRouteBackendProtocolWebSocket, +) + +// ----------------------------------------------------------------------------- +// Features - TLSRoute Conformance (Core) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates support for TLSRoute + SupportTLSRoute SupportedFeature = "TLSRoute" +) + +// TLSCoreFeatures includes all the supported features for the TLSRoute API at +// a Core level of support. +var TLSRouteCoreFeatures = sets.New( + SupportTLSRoute, +) + +// ----------------------------------------------------------------------------- +// Features - UDPRoute Conformance (Core) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates support for UDPRoute + SupportUDPRoute SupportedFeature = "UDPRoute" +) + +// UDPRouteCoreFeatures includes all SupportedFeatures needed to be conformant with +// the UDPRoute resource. +var UDPRouteFeatures = sets.New( + SupportUDPRoute, +) + +// ----------------------------------------------------------------------------- +// Features - Mesh Conformance (Core) +// ----------------------------------------------------------------------------- + +const ( + // This option indicates general support for service mesh + SupportMesh SupportedFeature = "Mesh" +) + +// MeshCoreFeatures includes all the supported features for the service mesh at +// a Core level of support. +var MeshCoreFeatures = sets.New( + SupportMesh, +) + +// ----------------------------------------------------------------------------- +// Features - GRPCRoute Conformance +// ----------------------------------------------------------------------------- + +const ( + // This option indicates general support for service mesh + SupportGRPCRoute SupportedFeature = "GRPCRoute" +) + +// GRPCRouteCoreFeatures includes all the supported features for GRPCRoute at +// a Core level of support. +var GRPCRouteCoreFeatures = sets.New( + SupportGRPCRoute, +) + +// ----------------------------------------------------------------------------- +// Features - Compilations +// ----------------------------------------------------------------------------- + +// AllFeatures contains all the supported features and can be used to run all +// conformance tests with `all-features` flag. +// +// NOTE: as new feature sets are added they should be inserted into this set. +var AllFeatures = sets.New[SupportedFeature](). + Insert(GatewayCoreFeatures.UnsortedList()...). + Insert(GatewayExtendedFeatures.UnsortedList()...). + Insert(ReferenceGrantCoreFeatures.UnsortedList()...). + Insert(HTTPRouteCoreFeatures.UnsortedList()...). + Insert(HTTPRouteExtendedFeatures.UnsortedList()...). + Insert(HTTPRouteExperimentalFeatures.UnsortedList()...). + Insert(TLSRouteCoreFeatures.UnsortedList()...). + Insert(MeshCoreFeatures.UnsortedList()...). + Insert(GRPCRouteCoreFeatures.UnsortedList()...)