From 3136ed961c704275338aa83ee6c9490efbd5590f Mon Sep 17 00:00:00 2001 From: Adam Cattermole Date: Tue, 14 Nov 2023 12:11:36 +0000 Subject: [PATCH] Update gatewayapi to v1.0.0 (#286) --- .github/workflows/build-images-base.yaml | 8 +- .github/workflows/code-style.yaml | 8 +- .github/workflows/test.yaml | 20 +- Dockerfile | 2 +- README.md | 36 +- api/v1beta2/authpolicy_types.go | 14 +- api/v1beta2/authpolicy_types_test.go | 36 +- api/v1beta2/ratelimitpolicy_types.go | 12 +- api/v1beta2/ratelimitpolicy_types_test.go | 14 +- api/v1beta2/route_selectors.go | 21 +- api/v1beta2/route_selectors_test.go | 120 ++--- api/v1beta2/zz_generated.deepcopy.go | 6 +- .../manifests/kuadrant.io_authpolicies.yaml | 421 +++++++++++++++++- .../kuadrant.io_ratelimitpolicies.yaml | 59 ++- .../crd/bases/kuadrant.io_authpolicies.yaml | 421 +++++++++++++++++- .../bases/kuadrant.io_ratelimitpolicies.yaml | 59 ++- .../gateway-api/gateway/gateway.yaml | 2 +- .../gateway-api/kustomization.yaml | 2 +- controllers/authpolicy_authconfig.go | 48 +- controllers/authpolicy_authconfig_test.go | 146 +++--- controllers/authpolicy_controller.go | 10 +- controllers/authpolicy_controller_test.go | 54 +-- .../authpolicy_istio_authorizationpolicy.go | 32 +- ...thpolicy_istio_authorizationpolicy_test.go | 110 ++--- controllers/gateway_eventmapper.go | 6 +- controllers/gateway_kuadrant_controller.go | 10 +- .../gateway_kuadrant_controller_test.go | 10 +- controllers/helper_test.go | 68 +-- .../httprouteparentrefs_eventmapper.go | 10 +- controllers/kuadrant_controller.go | 6 +- ...imitador_cluster_envoyfilter_controller.go | 10 +- ...dor_cluster_envoyfilter_controller_test.go | 8 +- controllers/ratelimitpolicy_controller.go | 6 +- .../ratelimitpolicy_controller_test.go | 66 +-- .../ratelimitpolicy_istio_wasmplugin.go | 12 +- controllers/suite_test.go | 4 +- doc/auth.md | 2 +- doc/development.md | 2 +- doc/rate-limiting.md | 2 +- doc/reference/route-selectors.md | 6 +- ...uth-for-app-devs-and-platform-engineers.md | 4 +- .../authenticated-rl-for-app-developers.md | 2 +- .../gateway-rl-for-cluster-operators.md | 6 +- .../simple-rl-for-app-developers.md | 2 +- examples/toystore/httproute.yaml | 2 +- go.mod | 66 +-- go.sum | 254 ++++++++--- main.go | 4 +- pkg/common/common.go | 16 +- pkg/common/common_test.go | 50 +-- pkg/common/gatewayapi_utils.go | 82 ++-- pkg/common/gatewayapi_utils_test.go | 400 ++++++++--------- pkg/common/istio_utils.go | 4 +- pkg/common/istio_utils_test.go | 16 +- pkg/reconcilers/targetref_reconciler.go | 24 +- pkg/reconcilers/targetref_reconciler_test.go | 122 ++--- pkg/rlptools/wasm/types.go | 10 +- pkg/rlptools/wasm_utils.go | 18 +- pkg/rlptools/wasm_utils_test.go | 46 +- 59 files changed, 2002 insertions(+), 1015 deletions(-) diff --git a/.github/workflows/build-images-base.yaml b/.github/workflows/build-images-base.yaml index a6f88eded..ae6221d5e 100644 --- a/.github/workflows/build-images-base.yaml +++ b/.github/workflows/build-images-base.yaml @@ -108,10 +108,10 @@ jobs: name: Build Bundle runs-on: ubuntu-latest steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code uses: actions/checkout@v3 @@ -156,10 +156,10 @@ jobs: needs: [build, build-bundle] runs-on: ubuntu-latest steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code uses: actions/checkout@v3 diff --git a/.github/workflows/code-style.yaml b/.github/workflows/code-style.yaml index 5e12fc45c..10f9b1fc2 100644 --- a/.github/workflows/code-style.yaml +++ b/.github/workflows/code-style.yaml @@ -40,10 +40,10 @@ jobs: importpath: golang.org/x/tools/cmd/goimports@latest steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code @@ -90,10 +90,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 26e814e2e..25b777d0f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,7 +18,7 @@ jobs: name: Unit Tests strategy: matrix: - go-version: [ 1.20.x ] + go-version: [ 1.21.x ] platform: [ ubuntu-latest ] runs-on: ${{ matrix.platform }} defaults: @@ -53,10 +53,10 @@ jobs: run: shell: bash steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code uses: actions/checkout@v3 @@ -94,10 +94,10 @@ jobs: name: Verify manifests runs-on: ubuntu-latest steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code uses: actions/checkout@v3 @@ -109,10 +109,10 @@ jobs: name: Verify bundle runs-on: ubuntu-latest steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code uses: actions/checkout@v3 @@ -124,10 +124,10 @@ jobs: name: Verify fmt runs-on: ubuntu-latest steps: - - name: Set up Go 1.20.x + - name: Set up Go 1.21.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x id: go - name: Check out code uses: actions/checkout@v3 @@ -139,7 +139,7 @@ jobs: name: Test Scripts strategy: matrix: - go-version: [ 1.20.x ] + go-version: [ 1.21.x ] platform: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.platform }} defaults: diff --git a/Dockerfile b/Dockerfile index 7782a3b87..541c670a9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM golang:1.20 as builder +FROM golang:1.21 as builder WORKDIR /workspace # Copy the Go Modules manifests diff --git a/README.md b/README.md index c8dd8694b..e793a8ef9 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,23 @@ The Operator to install and manage the lifecycle of the [Kuadrant](https://github.com/Kuadrant/) components deployments. -* [Overview](#overview) -* [Architecture](#architecture) - * [Kuadrant components](#kuadrant-components) - * [Provided APIs](#provided-apis) -* [Getting started](#getting-started) - * [Pre-requisites](#pre-requisites) - * [Installing Kuadrant](#installing-kuadrant) - * [Protect Your Service](#protect-your-service) - * [If you are an API Provider](#if-you-are-an-api-provider) - * [If you are a Cluster Operator](#if-you-are-a-cluster-operator) -* [User guides](#user-guides) -* [Kuadrant Rate Limiting](#kuadrant-rate-limiting) -* [Documentation](#documentation) -* [Contributing](#contributing) -* [Licensing](#licensing) +- [Overview](#overview) +- [Architecture](#architecture) + - [Kuadrant components](#kuadrant-components) + - [Provided APIs](#provided-apis) +- [Getting started](#getting-started) + - [Pre-requisites](#pre-requisites) + - [Installing Kuadrant](#installing-kuadrant) + - [1. Install the Kuadrant Operator](#1-install-the-kuadrant-operator) + - [2. Request a Kuadrant instance](#2-request-a-kuadrant-instance) + - [Protect your service](#protect-your-service) + - [If you are an *API Provider*](#if-you-are-an-api-provider) + - [If you are a *Cluster Operator*](#if-you-are-a-cluster-operator) +- [User guides](#user-guides) +- [Kuadrant Rate Limiting](#kuadrant-rate-limiting) +- [Documentation](#documentation) +- [Contributing](#contributing) +- [Licensing](#licensing) @@ -144,7 +146,7 @@ EOF * Deploy the service/API to be protected ("Upstream") * Expose the service/API using the kubernetes Gateway API, ie - [HTTPRoute](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRoute) object. + [HTTPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute) object. * Write and apply the Kuadrant's [RateLimitPolicy](doc/rate-limiting.md) and/or [AuthPolicy](doc/auth.md) custom resources targeting the HTTPRoute resource to have your API protected. @@ -152,7 +154,7 @@ EOF #### If you are a *Cluster Operator* * (Optionally) deploy istio ingress gateway using the - [Gateway](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.Gateway) resource. + [Gateway](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway) resource. * Write and apply the Kuadrant's [RateLimitPolicy](doc/rate-limiting.md) and/or [AuthPolicy](doc/auth.md) custom resources targeting the Gateway resource to have your gateway traffic protected. diff --git a/api/v1beta2/authpolicy_types.go b/api/v1beta2/authpolicy_types.go index af7287341..c2fa14b34 100644 --- a/api/v1beta2/authpolicy_types.go +++ b/api/v1beta2/authpolicy_types.go @@ -7,8 +7,8 @@ import ( "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" authorinoapi "github.com/kuadrant/authorino/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -18,16 +18,19 @@ type AuthSchemeSpec struct { // Authentication configs. // At least one config MUST evaluate to a valid identity object for the auth request to be successful. // +optional + // +kubebuilder:validation:MaxProperties=14 Authentication map[string]AuthenticationSpec `json:"authentication,omitempty"` // Metadata sources. // Authorino fetches auth metadata as JSON from sources specified in this config. // +optional + // +kubebuilder:validation:MaxProperties=14 Metadata map[string]MetadataSpec `json:"metadata,omitempty"` // Authorization policies. // All policies MUST evaluate to "allowed = true" for the auth request be successful. // +optional + // +kubebuilder:validation:MaxProperties=14 Authorization map[string]AuthorizationSpec `json:"authorization,omitempty"` // Response items. @@ -38,6 +41,7 @@ type AuthSchemeSpec struct { // Callback functions. // Authorino sends callbacks at the end of the auth pipeline to the endpoints specified in this config. // +optional + // +kubebuilder:validation:MaxProperties=14 Callbacks map[string]CallbackSpec `json:"callbacks,omitempty"` } @@ -47,6 +51,7 @@ type CommonAuthRuleSpec struct { // At least one selected HTTPRoute rule must match to trigger the auth rule. // If no route selectors are specified, the auth rule will be evaluated at all requests to the protected routes. // +optional + // +kubebuilder:validation:MaxItems=15 RouteSelectors []RouteSelector `json:"routeSelectors,omitempty"` } @@ -93,11 +98,13 @@ type ResponseSpec struct { type WrappedSuccessResponseSpec struct { // Custom success response items wrapped as HTTP headers. // For integration of Authorino via proxy, the proxy must use these settings to inject data in the request. + // +kubebuilder:validation:MaxProperties=14 Headers map[string]HeaderSuccessResponseSpec `json:"headers,omitempty"` // Custom success response items wrapped as HTTP headers. // For integration of Authorino via proxy, the proxy must use these settings to propagate dynamic metadata. // See https://www.envoyproxy.io/docs/envoy/latest/configuration/advanced/well_known_dynamic_metadata + // +kubebuilder:validation:MaxProperties=14 DynamicMetadata map[string]SuccessResponseSpec `json:"dynamicMetadata,omitempty"` } @@ -133,6 +140,7 @@ type AuthPolicySpec struct { // At least one selected HTTPRoute rule must match to trigger the AuthPolicy. // If no route selectors are specified, the AuthPolicy will be enforced at all requests to the protected routes. // +optional + // +kubebuilder:validation:MaxItems=15 RouteSelectors []RouteSelector `json:"routeSelectors,omitempty"` // Named sets of patterns that can be referred in `when` conditions and in pattern-matching authorization policy rules. @@ -266,8 +274,8 @@ func (ap *AuthPolicy) GetTargetRef() gatewayapiv1alpha2.PolicyTargetReference { return ap.Spec.TargetRef } -func (ap *AuthPolicy) GetWrappedNamespace() gatewayapiv1beta1.Namespace { - return gatewayapiv1beta1.Namespace(ap.Namespace) +func (ap *AuthPolicy) GetWrappedNamespace() gatewayapiv1.Namespace { + return gatewayapiv1.Namespace(ap.Namespace) } // GetRulesHostnames returns all hostnames referenced in the route selectors of the policy. diff --git a/api/v1beta2/authpolicy_types_test.go b/api/v1beta2/authpolicy_types_test.go index 9e5bb6b6f..5f11f3f86 100644 --- a/api/v1beta2/authpolicy_types_test.go +++ b/api/v1beta2/authpolicy_types_test.go @@ -8,8 +8,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" authorinoapi "github.com/kuadrant/authorino/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -68,7 +68,7 @@ func TestAuthPolicyTargetKey(t *testing.T) { } // targetRef with namespace - policy.Spec.TargetRef.Namespace = ptr.To(gatewayapiv1beta1.Namespace("route-namespace")) + policy.Spec.TargetRef.Namespace = ptr.To(gatewayapiv1.Namespace("route-namespace")) expected = "route-namespace/my-route" if result := policy.TargetKey().String(); result != expected { t.Errorf("Expected target key %s, got %s", expected, result) @@ -113,7 +113,7 @@ func TestAuthPolicyGetRulesHostnames(t *testing.T) { } policy.Spec.RouteSelectors = []RouteSelector{ { - Hostnames: []gatewayapiv1beta1.Hostname{"*.kuadrant.io", "toystore.kuadrant.io"}, + Hostnames: []gatewayapiv1.Hostname{"*.kuadrant.io", "toystore.kuadrant.io"}, }, } // 1 top-level route selectors with 2 hostnames @@ -190,7 +190,7 @@ func TestAuthPolicyGetRulesHostnames(t *testing.T) { CommonAuthRuleSpec: CommonAuthRuleSpec{ RouteSelectors: []RouteSelector{ { - Hostnames: []gatewayapiv1beta1.Hostname{"*.kuadrant.io", "toystore.kuadrant.io"}, + Hostnames: []gatewayapiv1.Hostname{"*.kuadrant.io", "toystore.kuadrant.io"}, }, }, }, @@ -202,7 +202,7 @@ func TestAuthPolicyGetRulesHostnames(t *testing.T) { CommonAuthRuleSpec: CommonAuthRuleSpec{ RouteSelectors: []RouteSelector{ { - Hostnames: []gatewayapiv1beta1.Hostname{"*.kuadrant.io"}, + Hostnames: []gatewayapiv1.Hostname{"*.kuadrant.io"}, }, }, }, @@ -330,10 +330,10 @@ func TestAuthPolicyValidate(t *testing.T) { }, RouteSelectors: []RouteSelector{ { - Hostnames: []gatewayapiv1beta1.Hostname{"*.foo.io"}, - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Hostnames: []gatewayapiv1.Hostname{"*.foo.io"}, + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ + Path: &gatewayapiv1.HTTPPathMatch{ Value: ptr.To("/foo"), }, }, @@ -368,10 +368,10 @@ func TestAuthPolicyValidate(t *testing.T) { CommonAuthRuleSpec: CommonAuthRuleSpec{ RouteSelectors: []RouteSelector{ { - Hostnames: []gatewayapiv1beta1.Hostname{"*.foo.io"}, - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Hostnames: []gatewayapiv1.Hostname{"*.foo.io"}, + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ + Path: &gatewayapiv1.HTTPPathMatch{ Value: ptr.To("/foo"), }, }, @@ -398,7 +398,7 @@ func TestAuthPolicyValidate(t *testing.T) { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: "my-route", - Namespace: ptr.To(gatewayapiv1beta1.Namespace("other-namespace")), + Namespace: ptr.To(gatewayapiv1.Namespace("other-namespace")), }, AuthScheme: AuthSchemeSpec{ Authentication: map[string]AuthenticationSpec{ @@ -411,10 +411,10 @@ func TestAuthPolicyValidate(t *testing.T) { CommonAuthRuleSpec: CommonAuthRuleSpec{ RouteSelectors: []RouteSelector{ { - Hostnames: []gatewayapiv1beta1.Hostname{"*.foo.io"}, - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Hostnames: []gatewayapiv1.Hostname{"*.foo.io"}, + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ + Path: &gatewayapiv1.HTTPPathMatch{ Value: ptr.To("/foo"), }, }, @@ -445,10 +445,10 @@ func TestAuthPolicyValidate(t *testing.T) { func testBuildRouteSelector() RouteSelector { return RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"}, - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io"}, + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ + Path: &gatewayapiv1.HTTPPathMatch{ Value: ptr.To("/toy"), }, }, diff --git a/api/v1beta2/ratelimitpolicy_types.go b/api/v1beta2/ratelimitpolicy_types.go index 1ba25a4a2..16b13578c 100644 --- a/api/v1beta2/ratelimitpolicy_types.go +++ b/api/v1beta2/ratelimitpolicy_types.go @@ -24,8 +24,8 @@ import ( "github.com/kuadrant/kuadrant-operator/pkg/common" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" ) // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! @@ -70,7 +70,7 @@ type Rate struct { } // RouteSelector defines semantics for matching an HTTP request based on conditions -// https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec +// https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec type WhenCondition struct { // Selector defines one item from the well known selectors // TODO Document properly "Well-known selector" https://github.com/Kuadrant/architecture/blob/main/rfcs/0001-rlp-v2.md#well-known-selectors @@ -88,6 +88,7 @@ type WhenCondition struct { type Limit struct { // RouteSelectors defines semantics for matching an HTTP request based on conditions // +optional + // +kubebuilder:validation:MaxItems=15 RouteSelectors []RouteSelector `json:"routeSelectors,omitempty"` // When holds the list of conditions for the policy to be enforced. @@ -119,6 +120,7 @@ type RateLimitPolicySpec struct { // Limits holds the struct of limits indexed by a unique name // +optional + // +kubebuilder:validation:MaxProperties=14 Limits map[string]Limit `json:"limits,omitempty"` } @@ -226,15 +228,15 @@ func (r *RateLimitPolicy) GetTargetRef() gatewayapiv1alpha2.PolicyTargetReferenc return r.Spec.TargetRef } -func (r *RateLimitPolicy) GetWrappedNamespace() gatewayapiv1beta1.Namespace { - return gatewayapiv1beta1.Namespace(r.Namespace) +func (r *RateLimitPolicy) GetWrappedNamespace() gatewayapiv1.Namespace { + return gatewayapiv1.Namespace(r.Namespace) } func (r *RateLimitPolicy) GetRulesHostnames() (ruleHosts []string) { ruleHosts = make([]string, 0) for _, limit := range r.Spec.Limits { for _, routeSelector := range limit.RouteSelectors { - convertHostnamesToString := func(gwHostnames []gatewayapiv1beta1.Hostname) []string { + convertHostnamesToString := func(gwHostnames []gatewayapiv1.Hostname) []string { hostnames := make([]string, 0, len(gwHostnames)) for _, gwHostName := range gwHostnames { hostnames = append(hostnames, string(gwHostName)) diff --git a/api/v1beta2/ratelimitpolicy_types_test.go b/api/v1beta2/ratelimitpolicy_types_test.go index 140e82e13..b1fec0b24 100644 --- a/api/v1beta2/ratelimitpolicy_types_test.go +++ b/api/v1beta2/ratelimitpolicy_types_test.go @@ -7,13 +7,13 @@ import ( "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/kuadrant/kuadrant-operator/pkg/common" ) -func testBuildBasicRLP(name string, kind gatewayapiv1beta1.Kind) *RateLimitPolicy { +func testBuildBasicRLP(name string, kind gatewayapiv1.Kind) *RateLimitPolicy { return &RateLimitPolicy{ TypeMeta: metav1.TypeMeta{ Kind: "RateLimitPolicy", @@ -34,11 +34,11 @@ func testBuildBasicRLP(name string, kind gatewayapiv1beta1.Kind) *RateLimitPolic } func testBuildBasicGatewayRLP(name string) *RateLimitPolicy { - return testBuildBasicRLP(name, gatewayapiv1beta1.Kind("Gateway")) + return testBuildBasicRLP(name, gatewayapiv1.Kind("Gateway")) } func testBuildBasicHTTPRouteRLP(name string) *RateLimitPolicy { - return testBuildBasicRLP(name, gatewayapiv1beta1.Kind("HTTPRoute")) + return testBuildBasicRLP(name, gatewayapiv1.Kind("HTTPRoute")) } // TestRateLimitPolicyValidation calls rlp.Validate() @@ -62,7 +62,7 @@ func TestRateLimitPolicyValidation(t *testing.T) { // invalid group rlp = testBuildBasicHTTPRouteRLP(name) - rlp.Spec.TargetRef.Group = gatewayapiv1beta1.Group("foo.example.com") + rlp.Spec.TargetRef.Group = gatewayapiv1.Group("foo.example.com") err = rlp.Validate() if err == nil { t.Fatal(`rlp.Validate() did not return error and should`) @@ -73,7 +73,7 @@ func TestRateLimitPolicyValidation(t *testing.T) { // invalid kind rlp = testBuildBasicHTTPRouteRLP(name) - rlp.Spec.TargetRef.Kind = gatewayapiv1beta1.Kind("Foo") + rlp.Spec.TargetRef.Kind = gatewayapiv1.Kind("Foo") err = rlp.Validate() if err == nil { t.Fatal(`rlp.Validate() did not return error and should`) @@ -84,7 +84,7 @@ func TestRateLimitPolicyValidation(t *testing.T) { // Different namespace rlp = testBuildBasicHTTPRouteRLP(name) - otherNS := gatewayapiv1beta1.Namespace(rlp.GetNamespace() + "other") + otherNS := gatewayapiv1.Namespace(rlp.GetNamespace() + "other") rlp.Spec.TargetRef.Namespace = &otherNS err = rlp.Validate() if err == nil { diff --git a/api/v1beta2/route_selectors.go b/api/v1beta2/route_selectors.go index a40af94f2..880ae16be 100644 --- a/api/v1beta2/route_selectors.go +++ b/api/v1beta2/route_selectors.go @@ -1,7 +1,7 @@ package v1beta2 import ( - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" orderedmap "github.com/elliotchance/orderedmap/v2" @@ -9,17 +9,18 @@ import ( ) // RouteSelector defines semantics for matching an HTTP request based on conditions -// https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec +// https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec type RouteSelector struct { // Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process the request - // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + // https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec // +optional - Hostnames []gatewayapiv1beta1.Hostname `json:"hostnames,omitempty"` + Hostnames []gatewayapiv1.Hostname `json:"hostnames,omitempty"` // Matches define conditions used for matching the rule against incoming HTTP requests. - // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + // https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec // +optional - Matches []gatewayapiv1beta1.HTTPRouteMatch `json:"matches,omitempty"` + // +kubebuilder:validation:MaxItems=8 + Matches []gatewayapiv1.HTTPRouteMatch `json:"matches,omitempty"` } // SelectRules returns, from a HTTPRoute, all HTTPRouteRules that either specify no HTTRouteMatches or that contain at @@ -29,8 +30,8 @@ type RouteSelector struct { // Additionally, if the selector specifies a non-empty list of hostnames, a non-empty intersection between the literal // hostnames of the selector and set of hostnames specified in the HTTPRoute must exist. Otherwise, the function // returns nil. -func (s *RouteSelector) SelectRules(route *gatewayapiv1beta1.HTTPRoute) (rules []gatewayapiv1beta1.HTTPRouteRule) { - rulesIndices := orderedmap.NewOrderedMap[int, gatewayapiv1beta1.HTTPRouteRule]() +func (s *RouteSelector) SelectRules(route *gatewayapiv1.HTTPRoute) (rules []gatewayapiv1.HTTPRouteRule) { + rulesIndices := orderedmap.NewOrderedMap[int, gatewayapiv1.HTTPRouteRule]() if len(s.Hostnames) > 0 && !common.Intersect(s.Hostnames, route.Spec.Hostnames) { return nil } @@ -54,7 +55,7 @@ func (s *RouteSelector) SelectRules(route *gatewayapiv1beta1.HTTPRoute) (rules [ // HostnamesForConditions allows avoiding building conditions for hostnames that are excluded by the selector // or when the hostname is irrelevant (i.e. matches all hostnames) -func (s *RouteSelector) HostnamesForConditions(route *gatewayapiv1beta1.HTTPRoute) []gatewayapiv1beta1.Hostname { +func (s *RouteSelector) HostnamesForConditions(route *gatewayapiv1.HTTPRoute) []gatewayapiv1.Hostname { hostnames := route.Spec.Hostnames if len(s.Hostnames) > 0 { @@ -62,7 +63,7 @@ func (s *RouteSelector) HostnamesForConditions(route *gatewayapiv1beta1.HTTPRout } if common.SameElements(hostnames, route.Spec.Hostnames) { - return []gatewayapiv1beta1.Hostname{"*"} + return []gatewayapiv1.Hostname{"*"} } return hostnames diff --git a/api/v1beta2/route_selectors_test.go b/api/v1beta2/route_selectors_test.go index ee2cf9095..7e061ab8e 100644 --- a/api/v1beta2/route_selectors_test.go +++ b/api/v1beta2/route_selectors_test.go @@ -9,7 +9,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/kuadrant/kuadrant-operator/pkg/common" ) @@ -20,8 +20,8 @@ func TestRouteSelectors(t *testing.T) { testCases := []struct { name string routeSelector RouteSelector - route *gatewayapiv1beta1.HTTPRoute - expected []gatewayapiv1beta1.HTTPRouteRule + route *gatewayapiv1.HTTPRoute + expected []gatewayapiv1.HTTPRouteRule }{ { name: "empty route selector selects all HTTPRouteRules", @@ -32,56 +32,56 @@ func TestRouteSelectors(t *testing.T) { { name: "route selector selects the HTTPRouteRules whose set of HTTPRouteMatch is a perfect match", routeSelector: RouteSelector{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/assets"}[0], }, }, }, }, route: route, - expected: []gatewayapiv1beta1.HTTPRouteRule{route.Spec.Rules[1]}, + expected: []gatewayapiv1.HTTPRouteRule{route.Spec.Rules[1]}, }, { name: "route selector selects the HTTPRouteRules whose set of HTTPRouteMatch contains at least one match", routeSelector: RouteSelector{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethod("POST")}[0], + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethod("POST")}[0], }, }, }, route: route, - expected: []gatewayapiv1beta1.HTTPRouteRule{route.Spec.Rules[0]}, + expected: []gatewayapiv1.HTTPRouteRule{route.Spec.Rules[0]}, }, { name: "route selector with missing part of a HTTPRouteMatch still selects the HTTPRouteRules that match", routeSelector: RouteSelector{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, }, }, }, route: route, - expected: []gatewayapiv1beta1.HTTPRouteRule{route.Spec.Rules[0]}, + expected: []gatewayapiv1.HTTPRouteRule{route.Spec.Rules[0]}, }, { name: "route selector selects no HTTPRouteRule when no criterion matches", routeSelector: RouteSelector{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchExact}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchExact}[0], Value: &[]string{"/toy"}[0], }, }, @@ -93,7 +93,7 @@ func TestRouteSelectors(t *testing.T) { { name: "route selector selects the HTTPRouteRules whose HTTPRoute's hostnames match the selector", routeSelector: RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"api.toystore.com"}, + Hostnames: []gatewayapiv1.Hostname{"api.toystore.com"}, }, route: route, expected: route.Spec.Rules, @@ -101,23 +101,23 @@ func TestRouteSelectors(t *testing.T) { { name: "route selector selects the HTTPRouteRules whose HTTPRoute's hostnames match the selector additionally to other criteria", routeSelector: RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"api.toystore.com"}, - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Hostnames: []gatewayapiv1.Hostname{"api.toystore.com"}, + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, }, }, }, route: route, - expected: []gatewayapiv1beta1.HTTPRouteRule{route.Spec.Rules[0]}, + expected: []gatewayapiv1.HTTPRouteRule{route.Spec.Rules[0]}, }, { name: "route selector does not select HTTPRouteRules whose HTTPRoute's hostnames do not match the selector", routeSelector: RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"www.toystore.com"}, + Hostnames: []gatewayapiv1.Hostname{"www.toystore.com"}, }, route: route, expected: nil, @@ -125,11 +125,11 @@ func TestRouteSelectors(t *testing.T) { { name: "route selector does not select HTTPRouteRules whose HTTPRoute's hostnames do not match the selector even when other criteria match", routeSelector: RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"www.toystore.com"}, - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Hostnames: []gatewayapiv1.Hostname{"www.toystore.com"}, + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, }, @@ -143,7 +143,7 @@ func TestRouteSelectors(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { rules := tc.routeSelector.SelectRules(tc.route) - rulesToStringSlice := func(rules []gatewayapiv1beta1.HTTPRouteRule) []string { + rulesToStringSlice := func(rules []gatewayapiv1.HTTPRouteRule) []string { return common.Map(common.Map(rules, common.HTTPRouteRuleToString), func(r string) string { return fmt.Sprintf("{%s}", r) }) } if !reflect.DeepEqual(rules, tc.expected) { @@ -155,11 +155,11 @@ func TestRouteSelectors(t *testing.T) { func TestRouteSelectorsHostnamesForConditions(t *testing.T) { route := testBuildHttpRoute(testBuildGateway()) - route.Spec.Hostnames = append(route.Spec.Hostnames, gatewayapiv1beta1.Hostname("www.toystore.com")) + route.Spec.Hostnames = append(route.Spec.Hostnames, gatewayapiv1.Hostname("www.toystore.com")) // route and selector with exact same hostnames selector := RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"api.toystore.com", "www.toystore.com"}, + Hostnames: []gatewayapiv1.Hostname{"api.toystore.com", "www.toystore.com"}, } result := selector.HostnamesForConditions(route) if expected := 1; len(result) != expected { @@ -171,7 +171,7 @@ func TestRouteSelectorsHostnamesForConditions(t *testing.T) { // route and selector with some overlapping hostnames selector = RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"api.toystore.com", "other.io"}, + Hostnames: []gatewayapiv1.Hostname{"api.toystore.com", "other.io"}, } result = selector.HostnamesForConditions(route) if expected := 1; len(result) != expected { @@ -183,7 +183,7 @@ func TestRouteSelectorsHostnamesForConditions(t *testing.T) { // route and selector with no overlapping hostnames selector = RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"other.io"}, + Hostnames: []gatewayapiv1.Hostname{"other.io"}, } result = selector.HostnamesForConditions(route) if expected := 0; len(result) != expected { @@ -201,9 +201,9 @@ func TestRouteSelectorsHostnamesForConditions(t *testing.T) { } // route without hostnames and selector with hostnames - route.Spec.Hostnames = []gatewayapiv1beta1.Hostname{} + route.Spec.Hostnames = []gatewayapiv1.Hostname{} selector = RouteSelector{ - Hostnames: []gatewayapiv1beta1.Hostname{"api.toystore.com"}, + Hostnames: []gatewayapiv1.Hostname{"api.toystore.com"}, } result = selector.HostnamesForConditions(route) if expected := 1; len(result) != expected { @@ -221,59 +221,59 @@ func TestRouteSelectorsHostnamesForConditions(t *testing.T) { } } -func testBuildGateway() *gatewayapiv1beta1.Gateway { - return &gatewayapiv1beta1.Gateway{ +func testBuildGateway() *gatewayapiv1.Gateway { + return &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "my-gateway", }, - Spec: gatewayapiv1beta1.GatewaySpec{ - Listeners: []gatewayapiv1beta1.Listener{ + Spec: gatewayapiv1.GatewaySpec{ + Listeners: []gatewayapiv1.Listener{ { - Hostname: ptr.To(gatewayapiv1beta1.Hostname("*.toystore.com")), + Hostname: ptr.To(gatewayapiv1.Hostname("*.toystore.com")), }, }, }, } } -func testBuildHttpRoute(parentGateway *gatewayapiv1beta1.Gateway) *gatewayapiv1beta1.HTTPRoute { - return &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ +func testBuildHttpRoute(parentGateway *gatewayapiv1.Gateway) *gatewayapiv1.HTTPRoute { + return &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { - Name: gatewayapiv1beta1.ObjectName(parentGateway.Name), + Name: gatewayapiv1.ObjectName(parentGateway.Name), }, }, }, - Hostnames: []gatewayapiv1beta1.Hostname{"api.toystore.com"}, - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + Hostnames: []gatewayapiv1.Hostname{"api.toystore.com"}, + Rules: []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ // get /toys* { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethod("GET")}[0], + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethod("GET")}[0], }, // post /toys* { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethod("POST")}[0], + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethod("POST")}[0], }, }, }, { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ // /assets* { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/assets"}[0], }, }, diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index e34640951..e7df27649 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -24,7 +24,7 @@ import ( apiv1beta2 "github.com/kuadrant/authorino/api/v1beta2" "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/gateway-api/apis/v1beta1" + apisv1 "sigs.k8s.io/gateway-api/apis/v1" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -496,12 +496,12 @@ func (in *RouteSelector) DeepCopyInto(out *RouteSelector) { *out = *in if in.Hostnames != nil { in, out := &in.Hostnames, &out.Hostnames - *out = make([]v1beta1.Hostname, len(*in)) + *out = make([]apisv1.Hostname, len(*in)) copy(*out, *in) } if in.Matches != nil { in, out := &in.Matches, &out.Matches - *out = make([]v1beta1.HTTPRouteMatch, len(*in)) + *out = make([]apisv1.HTTPRouteMatch, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/bundle/manifests/kuadrant.io_authpolicies.yaml b/bundle/manifests/kuadrant.io_authpolicies.yaml index 90fcd5de0..55b4f2927 100644 --- a/bundle/manifests/kuadrant.io_authpolicies.yaml +++ b/bundle/manifests/kuadrant.io_authpolicies.yaml @@ -78,12 +78,12 @@ spec: the protected routes. items: description: RouteSelector defines semantics for matching an HTTP - request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to - process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition @@ -105,7 +105,7 @@ spec: type: array matches: description: Matches define conditions used for matching the - rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple match types are @@ -213,6 +213,52 @@ spec: 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, @@ -243,6 +289,7 @@ spec: differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -275,8 +322,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array rules: description: The auth rules of the policy. See Authorino's AuthConfig @@ -565,12 +614,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -594,7 +643,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -711,6 +760,54 @@ spec: 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 @@ -747,6 +844,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -780,8 +878,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce this config. @@ -906,6 +1006,7 @@ spec: description: Authentication configs. At least one config MUST evaluate to a valid identity object for the auth request to be successful. + maxProperties: 14 type: object authorization: additionalProperties: @@ -1422,12 +1523,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -1451,7 +1552,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -1568,6 +1669,54 @@ spec: 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 @@ -1604,6 +1753,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -1637,8 +1787,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array spicedb: description: Authorization decision delegated to external @@ -1828,6 +1980,7 @@ spec: type: object description: Authorization policies. All policies MUST evaluate to "allowed = true" for the auth request be successful. + maxProperties: 14 type: object callbacks: additionalProperties: @@ -2091,12 +2244,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -2120,7 +2273,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -2237,6 +2390,54 @@ spec: 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 @@ -2273,6 +2474,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -2306,8 +2508,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce this config. @@ -2368,6 +2572,7 @@ spec: description: Callback functions. Authorino sends callbacks at the end of the auth pipeline to the endpoints specified in this config. + maxProperties: 14 type: object metadata: additionalProperties: @@ -2631,12 +2836,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -2660,7 +2865,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -2777,6 +2982,54 @@ spec: 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 @@ -2813,6 +3066,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -2846,8 +3100,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array uma: description: User-Managed Access (UMA) source of resource @@ -2942,6 +3198,7 @@ spec: type: object description: Metadata sources. Authorino fetches auth metadata as JSON from sources specified in this config. + maxProperties: 14 type: object response: description: Response items. Authorino builds custom responses @@ -3068,13 +3325,13 @@ spec: items: description: RouteSelector defines semantics for matching an HTTP request based on conditions - https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process - the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches @@ -3102,7 +3359,7 @@ spec: matches: description: Matches define conditions used for matching the rule against incoming HTTP - requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a @@ -3233,6 +3490,63 @@ spec: 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 @@ -3276,6 +3590,7 @@ spec: implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -3312,8 +3627,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce @@ -3448,6 +3765,7 @@ spec: HTTP headers. For integration of Authorino via proxy, the proxy must use these settings to propagate dynamic metadata. See https://www.envoyproxy.io/docs/envoy/latest/configuration/advanced/well_known_dynamic_metadata + maxProperties: 14 type: object headers: additionalProperties: @@ -3563,13 +3881,13 @@ spec: items: description: RouteSelector defines semantics for matching an HTTP request based on conditions - https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process - the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches @@ -3597,7 +3915,7 @@ spec: matches: description: Matches define conditions used for matching the rule against incoming HTTP - requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a @@ -3728,6 +4046,63 @@ spec: 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 @@ -3771,6 +4146,7 @@ spec: implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -3807,8 +4183,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce @@ -3943,6 +4321,7 @@ spec: HTTP headers. For integration of Authorino via proxy, the proxy must use these settings to inject data in the request. + maxProperties: 14 type: object type: object unauthenticated: diff --git a/bundle/manifests/kuadrant.io_ratelimitpolicies.yaml b/bundle/manifests/kuadrant.io_ratelimitpolicies.yaml index a221ac1c9..6e7b9cd52 100644 --- a/bundle/manifests/kuadrant.io_ratelimitpolicies.yaml +++ b/bundle/manifests/kuadrant.io_ratelimitpolicies.yaml @@ -88,12 +88,12 @@ spec: HTTP request based on conditions items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -116,7 +116,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple match @@ -232,6 +232,53 @@ spec: 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, @@ -266,6 +313,7 @@ spec: in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -299,8 +347,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: When holds the list of conditions for the policy @@ -308,7 +358,7 @@ spec: must also match items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: operator: description: 'The binary operator to be applied to the @@ -342,6 +392,7 @@ spec: type: object description: Limits holds the struct of limits indexed by a unique name + maxProperties: 14 type: object targetRef: description: TargetRef identifies an API object to apply policy to. diff --git a/config/crd/bases/kuadrant.io_authpolicies.yaml b/config/crd/bases/kuadrant.io_authpolicies.yaml index eda23f8bf..c90305e57 100644 --- a/config/crd/bases/kuadrant.io_authpolicies.yaml +++ b/config/crd/bases/kuadrant.io_authpolicies.yaml @@ -77,12 +77,12 @@ spec: the protected routes. items: description: RouteSelector defines semantics for matching an HTTP - request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to - process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition @@ -104,7 +104,7 @@ spec: type: array matches: description: Matches define conditions used for matching the - rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple match types are @@ -212,6 +212,52 @@ spec: 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, @@ -242,6 +288,7 @@ spec: differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -274,8 +321,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array rules: description: The auth rules of the policy. See Authorino's AuthConfig @@ -564,12 +613,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -593,7 +642,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -710,6 +759,54 @@ spec: 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 @@ -746,6 +843,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -779,8 +877,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce this config. @@ -905,6 +1005,7 @@ spec: description: Authentication configs. At least one config MUST evaluate to a valid identity object for the auth request to be successful. + maxProperties: 14 type: object authorization: additionalProperties: @@ -1421,12 +1522,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -1450,7 +1551,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -1567,6 +1668,54 @@ spec: 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 @@ -1603,6 +1752,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -1636,8 +1786,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array spicedb: description: Authorization decision delegated to external @@ -1827,6 +1979,7 @@ spec: type: object description: Authorization policies. All policies MUST evaluate to "allowed = true" for the auth request be successful. + maxProperties: 14 type: object callbacks: additionalProperties: @@ -2090,12 +2243,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -2119,7 +2272,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -2236,6 +2389,54 @@ spec: 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 @@ -2272,6 +2473,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -2305,8 +2507,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce this config. @@ -2367,6 +2571,7 @@ spec: description: Callback functions. Authorino sends callbacks at the end of the auth pipeline to the endpoints specified in this config. + maxProperties: 14 type: object metadata: additionalProperties: @@ -2630,12 +2835,12 @@ spec: evaluated at all requests to the protected routes. items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -2659,7 +2864,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple @@ -2776,6 +2981,54 @@ spec: 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 @@ -2812,6 +3065,7 @@ spec: potential differences in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -2845,8 +3099,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array uma: description: User-Managed Access (UMA) source of resource @@ -2941,6 +3197,7 @@ spec: type: object description: Metadata sources. Authorino fetches auth metadata as JSON from sources specified in this config. + maxProperties: 14 type: object response: description: Response items. Authorino builds custom responses @@ -3067,13 +3324,13 @@ spec: items: description: RouteSelector defines semantics for matching an HTTP request based on conditions - https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process - the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches @@ -3101,7 +3358,7 @@ spec: matches: description: Matches define conditions used for matching the rule against incoming HTTP - requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a @@ -3232,6 +3489,63 @@ spec: 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 @@ -3275,6 +3589,7 @@ spec: implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -3311,8 +3626,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce @@ -3447,6 +3764,7 @@ spec: HTTP headers. For integration of Authorino via proxy, the proxy must use these settings to propagate dynamic metadata. See https://www.envoyproxy.io/docs/envoy/latest/configuration/advanced/well_known_dynamic_metadata + maxProperties: 14 type: object headers: additionalProperties: @@ -3562,13 +3880,13 @@ spec: items: description: RouteSelector defines semantics for matching an HTTP request based on conditions - https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process - the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches @@ -3596,7 +3914,7 @@ spec: matches: description: Matches define conditions used for matching the rule against incoming HTTP - requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a @@ -3727,6 +4045,63 @@ spec: 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 @@ -3770,6 +4145,7 @@ spec: implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -3806,8 +4182,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: Conditions for Authorino to enforce @@ -3942,6 +4320,7 @@ spec: HTTP headers. For integration of Authorino via proxy, the proxy must use these settings to inject data in the request. + maxProperties: 14 type: object type: object unauthenticated: diff --git a/config/crd/bases/kuadrant.io_ratelimitpolicies.yaml b/config/crd/bases/kuadrant.io_ratelimitpolicies.yaml index e49cada84..b1000cb17 100644 --- a/config/crd/bases/kuadrant.io_ratelimitpolicies.yaml +++ b/config/crd/bases/kuadrant.io_ratelimitpolicies.yaml @@ -86,12 +86,12 @@ spec: HTTP request based on conditions items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: hostnames: description: Hostnames defines a set of hostname that should match against the HTTP Host header to select - a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 @@ -114,7 +114,7 @@ spec: type: array matches: description: Matches define conditions used for matching - the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec items: description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple match @@ -230,6 +230,53 @@ spec: 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, @@ -264,6 +311,7 @@ spec: in the implementations." maxLength: 256 minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact @@ -297,8 +345,10 @@ spec: - name x-kubernetes-list-type: map type: object + maxItems: 8 type: array type: object + maxItems: 15 type: array when: description: When holds the list of conditions for the policy @@ -306,7 +356,7 @@ spec: must also match items: description: RouteSelector defines semantics for matching - an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteSpec properties: operator: description: 'The binary operator to be applied to the @@ -340,6 +390,7 @@ spec: type: object description: Limits holds the struct of limits indexed by a unique name + maxProperties: 14 type: object targetRef: description: TargetRef identifies an API object to apply policy to. diff --git a/config/dependencies/gateway-api/gateway/gateway.yaml b/config/dependencies/gateway-api/gateway/gateway.yaml index 7886c7a77..c9c22f3e4 100644 --- a/config/dependencies/gateway-api/gateway/gateway.yaml +++ b/config/dependencies/gateway-api/gateway/gateway.yaml @@ -1,5 +1,5 @@ --- -apiVersion: gateway.networking.k8s.io/v1beta1 +apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: labels: diff --git a/config/dependencies/gateway-api/kustomization.yaml b/config/dependencies/gateway-api/kustomization.yaml index 0e67b0fa9..2ebe6d402 100644 --- a/config/dependencies/gateway-api/kustomization.yaml +++ b/config/dependencies/gateway-api/kustomization.yaml @@ -1,3 +1,3 @@ --- resources: -- github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.6.2 +- github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.0.0 diff --git a/controllers/authpolicy_authconfig.go b/controllers/authpolicy_authconfig.go index a0fbe65cb..478ae54bd 100644 --- a/controllers/authpolicy_authconfig.go +++ b/controllers/authpolicy_authconfig.go @@ -11,7 +11,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" authorinoapi "github.com/kuadrant/authorino/api/v1beta2" api "github.com/kuadrant/kuadrant-operator/api/v1beta2" @@ -79,28 +79,28 @@ func (r *AuthPolicyReconciler) desiredAuthConfig(ctx context.Context, ap *api.Au Spec: authorinoapi.AuthConfigSpec{}, } - var route *gatewayapiv1beta1.HTTPRoute + var route *gatewayapiv1.HTTPRoute var hosts []string switch obj := targetNetworkObject.(type) { - case *gatewayapiv1beta1.HTTPRoute: + case *gatewayapiv1.HTTPRoute: route = obj var err error hosts, err = common.HostnamesFromHTTPRoute(ctx, obj, r.Client()) if err != nil { return nil, err } - case *gatewayapiv1beta1.Gateway: + case *gatewayapiv1.Gateway: // fake a single httproute with all rules from all httproutes accepted by the gateway, // that do not have an authpolicy of its own, so we can generate wasm rules for those cases gw := common.GatewayWrapper{Gateway: obj} gwHostnames := gw.Hostnames() if len(hosts) == 0 { - gwHostnames = []gatewayapiv1beta1.Hostname{"*"} + gwHostnames = []gatewayapiv1.Hostname{"*"} } hosts = common.HostnamesToStrings(gwHostnames) - rules := make([]gatewayapiv1beta1.HTTPRouteRule, 0) + rules := make([]gatewayapiv1.HTTPRouteRule, 0) routes := r.FetchAcceptedGatewayHTTPRoutes(ctx, ap.TargetKey()) for idx := range routes { route := routes[idx] @@ -115,8 +115,8 @@ func (r *AuthPolicyReconciler) desiredAuthConfig(ctx context.Context, ap *api.Au common.TagObjectToDelete(authConfig) return authConfig, nil } - route = &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ + route = &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ Hostnames: gwHostnames, Rules: rules, }, @@ -196,7 +196,7 @@ func authorinoSpecsFromConfigs[T, U any](configs map[string]U, extractAuthorinoS return specs } -func mergeConditionsFromRouteSelectorsIntoConfigs(ap *api.AuthPolicy, route *gatewayapiv1beta1.HTTPRoute, authConfig *authorinoapi.AuthConfig) (*authorinoapi.AuthConfig, error) { +func mergeConditionsFromRouteSelectorsIntoConfigs(ap *api.AuthPolicy, route *gatewayapiv1.HTTPRoute, authConfig *authorinoapi.AuthConfig) (*authorinoapi.AuthConfig, error) { // authentication for name, config := range ap.Spec.AuthScheme.Authentication { conditions, err := authorinoConditionsFromRouteSelectors(route, config) @@ -288,7 +288,7 @@ func mergeConditionsFromRouteSelectorsIntoConfigs(ap *api.AuthPolicy, route *gat } // authorinoConditionFromRouteSelectors builds a list of Authorino conditions from a config that may specify route selectors -func authorinoConditionsFromRouteSelectors(route *gatewayapiv1beta1.HTTPRoute, config api.RouteSelectorsGetter) ([]authorinoapi.PatternExpressionOrRef, error) { +func authorinoConditionsFromRouteSelectors(route *gatewayapiv1.HTTPRoute, config api.RouteSelectorsGetter) ([]authorinoapi.PatternExpressionOrRef, error) { routeSelectors := config.GetRouteSelectors() if len(routeSelectors) == 0 { @@ -311,7 +311,7 @@ func authorinoConditionsFromRouteSelectors(route *gatewayapiv1beta1.HTTPRoute, c } // authorinoConditionsFromHTTPRoute builds a list of Authorino conditions from an HTTPRoute, without using route selectors. -func authorinoConditionsFromHTTPRoute(route *gatewayapiv1beta1.HTTPRoute) []authorinoapi.PatternExpressionOrRef { +func authorinoConditionsFromHTTPRoute(route *gatewayapiv1.HTTPRoute) []authorinoapi.PatternExpressionOrRef { conditions := []authorinoapi.PatternExpressionOrRef{} hostnamesForConditions := (&api.RouteSelector{}).HostnamesForConditions(route) for _, rule := range route.Spec.Rules { @@ -324,7 +324,7 @@ func authorinoConditionsFromHTTPRoute(route *gatewayapiv1beta1.HTTPRoute) []auth // * Each combination of HTTPRouteMatch and hostname yields one condition. // * Rules that specify no explicit HTTPRouteMatch are assumed to match all requests (i.e. implicit catch-all rule.) // * Empty list of hostnames yields a condition without a hostname pattern expression. -func authorinoConditionsFromHTTPRouteRule(rule gatewayapiv1beta1.HTTPRouteRule, hostnames []gatewayapiv1beta1.Hostname) []authorinoapi.PatternExpressionOrRef { +func authorinoConditionsFromHTTPRouteRule(rule gatewayapiv1.HTTPRouteRule, hostnames []gatewayapiv1.Hostname) []authorinoapi.PatternExpressionOrRef { hosts := []string{} for _, hostname := range hostnames { if hostname == "*" { @@ -397,7 +397,7 @@ func hostnamesToRegex(hostnames []string) string { }), "|") } -func httpMethodRuleToAuthorinoCondition(method gatewayapiv1beta1.HTTPMethod) authorinoapi.PatternExpressionOrRef { +func httpMethodRuleToAuthorinoCondition(method gatewayapiv1.HTTPMethod) authorinoapi.PatternExpressionOrRef { return authorinoapi.PatternExpressionOrRef{ PatternExpression: authorinoapi.PatternExpression{ Selector: "request.method", @@ -407,7 +407,7 @@ func httpMethodRuleToAuthorinoCondition(method gatewayapiv1beta1.HTTPMethod) aut } } -func httpPathRuleToAuthorinoCondition(path gatewayapiv1beta1.HTTPPathMatch) authorinoapi.PatternExpressionOrRef { +func httpPathRuleToAuthorinoCondition(path gatewayapiv1.HTTPPathMatch) authorinoapi.PatternExpressionOrRef { value := "/" if path.Value != nil { value = *path.Value @@ -416,17 +416,17 @@ func httpPathRuleToAuthorinoCondition(path gatewayapiv1beta1.HTTPPathMatch) auth matchType := path.Type if matchType == nil { - p := gatewayapiv1beta1.PathMatchPathPrefix + p := gatewayapiv1.PathMatchPathPrefix matchType = &p // gateway api defaults to PathMatchPathPrefix } switch *matchType { - case gatewayapiv1beta1.PathMatchExact: + case gatewayapiv1.PathMatchExact: operator = "eq" - case gatewayapiv1beta1.PathMatchPathPrefix: + case gatewayapiv1.PathMatchPathPrefix: operator = "matches" value += ".*" - case gatewayapiv1beta1.PathMatchRegularExpression: + case gatewayapiv1.PathMatchRegularExpression: operator = "matches" } @@ -439,7 +439,7 @@ func httpPathRuleToAuthorinoCondition(path gatewayapiv1beta1.HTTPPathMatch) auth } } -func httpHeadersRuleToAuthorinoConditions(headers []gatewayapiv1beta1.HTTPHeaderMatch) []authorinoapi.PatternExpressionOrRef { +func httpHeadersRuleToAuthorinoConditions(headers []gatewayapiv1.HTTPHeaderMatch) []authorinoapi.PatternExpressionOrRef { conditions := make([]authorinoapi.PatternExpressionOrRef, 0, len(headers)) for _, header := range headers { condition := httpHeaderRuleToAuthorinoCondition(header) @@ -448,9 +448,9 @@ func httpHeadersRuleToAuthorinoConditions(headers []gatewayapiv1beta1.HTTPHeader return conditions } -func httpHeaderRuleToAuthorinoCondition(header gatewayapiv1beta1.HTTPHeaderMatch) authorinoapi.PatternExpressionOrRef { +func httpHeaderRuleToAuthorinoCondition(header gatewayapiv1.HTTPHeaderMatch) authorinoapi.PatternExpressionOrRef { operator := "eq" // gateway api defaults to HeaderMatchExact - if header.Type != nil && *header.Type == gatewayapiv1beta1.HeaderMatchRegularExpression { + if header.Type != nil && *header.Type == gatewayapiv1.HeaderMatchRegularExpression { operator = "matches" } return authorinoapi.PatternExpressionOrRef{ @@ -462,7 +462,7 @@ func httpHeaderRuleToAuthorinoCondition(header gatewayapiv1beta1.HTTPHeaderMatch } } -func httpQueryParamsRuleToAuthorinoConditions(queryParams []gatewayapiv1beta1.HTTPQueryParamMatch) []authorinoapi.PatternExpressionOrRef { +func httpQueryParamsRuleToAuthorinoConditions(queryParams []gatewayapiv1.HTTPQueryParamMatch) []authorinoapi.PatternExpressionOrRef { conditions := make([]authorinoapi.PatternExpressionOrRef, 0, len(queryParams)) for _, queryParam := range queryParams { condition := httpQueryParamRuleToAuthorinoCondition(queryParam) @@ -471,9 +471,9 @@ func httpQueryParamsRuleToAuthorinoConditions(queryParams []gatewayapiv1beta1.HT return conditions } -func httpQueryParamRuleToAuthorinoCondition(queryParam gatewayapiv1beta1.HTTPQueryParamMatch) authorinoapi.PatternExpressionOrRef { +func httpQueryParamRuleToAuthorinoCondition(queryParam gatewayapiv1.HTTPQueryParamMatch) authorinoapi.PatternExpressionOrRef { operator := "eq" // gateway api defaults to QueryParamMatchExact - if queryParam.Type != nil && *queryParam.Type == gatewayapiv1beta1.QueryParamMatchRegularExpression { + if queryParam.Type != nil && *queryParam.Type == gatewayapiv1.QueryParamMatchRegularExpression { operator = "matches" } return authorinoapi.PatternExpressionOrRef{ diff --git a/controllers/authpolicy_authconfig_test.go b/controllers/authpolicy_authconfig_test.go index bef86f20b..37784cd66 100644 --- a/controllers/authpolicy_authconfig_test.go +++ b/controllers/authpolicy_authconfig_test.go @@ -8,20 +8,20 @@ import ( authorinoapi "github.com/kuadrant/authorino/api/v1beta2" "k8s.io/utils/ptr" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { testCases := []struct { name string - hostnames []gatewayapiv1beta1.Hostname - rule gatewayapiv1beta1.HTTPRouteRule + hostnames []gatewayapiv1.Hostname + rule gatewayapiv1.HTTPRouteRule expected []authorinoapi.PatternExpressionOrRef }{ { name: "No HTTPRouteMatch", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{}, + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{}, expected: []authorinoapi.PatternExpressionOrRef{ { PatternExpression: authorinoapi.PatternExpression{ @@ -34,12 +34,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Single HTTPRouteMatch", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -78,18 +78,18 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Multiple HTTPRouteMatches", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("Exact")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("Exact")), Value: ptr.To("/foo"), }, }, @@ -152,12 +152,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Multiple hosts", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io", "gamestore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io", "gamestore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -196,12 +196,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Host wildcard", - hostnames: []gatewayapiv1beta1.Hostname{"*.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"*.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -240,12 +240,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Catch-all host is ignored", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io", "*"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io", "*"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -284,10 +284,10 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Method", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("GET")), + Method: ptr.To(gatewayapiv1.HTTPMethod("GET")), }, }, }, @@ -315,11 +315,11 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "PathMatchExact", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("Exact")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("Exact")), Value: ptr.To("/toy"), }, }, @@ -349,11 +349,11 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "PathMatchPrefix", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -383,11 +383,11 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "PathMatchRegularExpression", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("RegularExpression")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("RegularExpression")), Value: ptr.To("^/(dolls|cars)"), }, }, @@ -417,12 +417,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Single header match", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("Exact")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("Exact")), Name: "X-Foo", Value: "a-value", }, @@ -454,17 +454,17 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Multiple header matches", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("Exact")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("Exact")), Name: "x-foo", Value: "a-value", }, { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("Exact")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("Exact")), Name: "x-bar", Value: "other-value", }, @@ -505,12 +505,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "HeaderMatchRegularExpression", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("RegularExpression")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("RegularExpression")), Name: "x-foo", Value: "^a+.*$", }, @@ -542,12 +542,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Single query param match", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - QueryParams: []gatewayapiv1beta1.HTTPQueryParamMatch{ + QueryParams: []gatewayapiv1.HTTPQueryParamMatch{ { - Type: ptr.To(gatewayapiv1beta1.QueryParamMatchType("Exact")), + Type: ptr.To(gatewayapiv1.QueryParamMatchType("Exact")), Name: "x-foo", Value: "a-value", }, @@ -594,17 +594,17 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "Multiple query param matches", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - QueryParams: []gatewayapiv1beta1.HTTPQueryParamMatch{ + QueryParams: []gatewayapiv1.HTTPQueryParamMatch{ { - Type: ptr.To(gatewayapiv1beta1.QueryParamMatchType("Exact")), + Type: ptr.To(gatewayapiv1.QueryParamMatchType("Exact")), Name: "x-foo", Value: "a-value", }, { - Type: ptr.To(gatewayapiv1beta1.QueryParamMatchType("Exact")), + Type: ptr.To(gatewayapiv1.QueryParamMatchType("Exact")), Name: "x-bar", Value: "other-value", }, @@ -675,12 +675,12 @@ func TestAuthorinoConditionsFromHTTPRouteRule(t *testing.T) { }, { name: "QueryParamMatchRegularExpression", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - QueryParams: []gatewayapiv1beta1.HTTPQueryParamMatch{ + QueryParams: []gatewayapiv1.HTTPQueryParamMatch{ { - Type: ptr.To(gatewayapiv1beta1.QueryParamMatchType("RegularExpression")), + Type: ptr.To(gatewayapiv1.QueryParamMatchType("RegularExpression")), Name: "x-foo", Value: "^a+.*$", }, diff --git a/controllers/authpolicy_controller.go b/controllers/authpolicy_controller.go index 0ff208ed2..490ab653f 100644 --- a/controllers/authpolicy_controller.go +++ b/controllers/authpolicy_controller.go @@ -10,7 +10,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/handler" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" api "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -119,7 +119,7 @@ func (r *AuthPolicyReconciler) Reconcile(eventCtx context.Context, req ctrl.Requ // trigger concurrent reconciliations of possibly affected gateway policies switch route := targetNetworkObject.(type) { - case *gatewayapiv1beta1.HTTPRoute: + case *gatewayapiv1.HTTPRoute: if err := r.reconcileRouteParentGatewayPolicies(ctx, route); err != nil { return ctrl.Result{}, err } @@ -198,7 +198,7 @@ func (r *AuthPolicyReconciler) deleteNetworkResourceDirectBackReference(ctx cont } // reconcileRouteParentGatewayPolicies triggers the concurrent reconciliation of all policies that target gateways that are parents of a route -func (r *AuthPolicyReconciler) reconcileRouteParentGatewayPolicies(ctx context.Context, route *gatewayapiv1beta1.HTTPRoute) error { +func (r *AuthPolicyReconciler) reconcileRouteParentGatewayPolicies(ctx context.Context, route *gatewayapiv1.HTTPRoute) error { logger, err := logr.FromContext(ctx) if err != nil { return err @@ -227,10 +227,10 @@ func (r *AuthPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&api.AuthPolicy{}). Watches( - &gatewayapiv1beta1.HTTPRoute{}, + &gatewayapiv1.HTTPRoute{}, handler.EnqueueRequestsFromMapFunc(httpRouteEventMapper.MapToAuthPolicy), ). - Watches(&gatewayapiv1beta1.Gateway{}, + Watches(&gatewayapiv1.Gateway{}, handler.EnqueueRequestsFromMapFunc(gatewayEventMapper.MapToAuthPolicy)). Complete(r) } diff --git a/controllers/authpolicy_controller_test.go b/controllers/authpolicy_controller_test.go index fbe3a39f4..3d1fd7d28 100644 --- a/controllers/authpolicy_controller_test.go +++ b/controllers/authpolicy_controller_test.go @@ -20,8 +20,8 @@ import ( "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" authorinoapi "github.com/kuadrant/authorino/api/v1beta2" api "github.com/kuadrant/kuadrant-operator/api/v1beta2" @@ -44,7 +44,7 @@ var _ = Describe("AuthPolicy controller", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func() bool { - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) return err == nil && meta.IsStatusConditionTrue(existingGateway.Status.Conditions, common.GatewayProgrammedConditionType) }, 15*time.Second, 5*time.Second).Should(BeTrue()) @@ -64,7 +64,7 @@ var _ = Describe("AuthPolicy controller", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func() bool { - existingRoute := &gatewayapiv1beta1.HTTPRoute{} + existingRoute := &gatewayapiv1.HTTPRoute{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(route), existingRoute) return err == nil && common.IsHTTPRouteAccepted(existingRoute) }, 15*time.Second, 5*time.Second).Should(BeTrue()) @@ -81,7 +81,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: testGatewayName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -143,7 +143,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -203,7 +203,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -218,11 +218,11 @@ var _ = Describe("AuthPolicy controller", func() { // create second (policyless) httproute otherRoute := testBuildBasicHttpRoute("policyless-route", testGatewayName, testNamespace, []string{"*.other"}) - otherRoute.Spec.Rules = []gatewayapiv1beta1.HTTPRouteRule{ + otherRoute.Spec.Rules = []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("POST")), + Method: ptr.To(gatewayapiv1.HTTPMethod("POST")), }, }, }, @@ -241,7 +241,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: testGatewayName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -302,7 +302,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -326,7 +326,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "Gateway", Name: testGatewayName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -374,7 +374,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, RouteSelectors: []api.RouteSelector{ { // does not select any HTTPRouteRule @@ -431,7 +431,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -496,7 +496,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -540,7 +540,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, NamedPatterns: map[string]authorinoapi.PatternExpressions{ "internal-source": []authorinoapi.PatternExpression{ @@ -784,7 +784,7 @@ var _ = Describe("AuthPolicy controller", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func() bool { - existingRoute := &gatewayapiv1beta1.HTTPRoute{} + existingRoute := &gatewayapiv1.HTTPRoute{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(route), existingRoute) return err == nil && common.IsHTTPRouteAccepted(existingRoute) }, 15*time.Second, 5*time.Second).Should(BeTrue()) @@ -801,7 +801,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -886,7 +886,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, RouteSelectors: []api.RouteSelector{ { // Selects: POST|DELETE *.admin.toystore.com/admin* @@ -898,7 +898,7 @@ var _ = Describe("AuthPolicy controller", func() { }, }, }, - Hostnames: []gatewayapiv1beta1.Hostname{"*.admin.toystore.com"}, + Hostnames: []gatewayapiv1.Hostname{"*.admin.toystore.com"}, }, { // Selects: GET /private* Matches: []gatewayapiv1alpha2.HTTPRouteMatch{ @@ -1003,7 +1003,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -1019,7 +1019,7 @@ var _ = Describe("AuthPolicy controller", func() { }, }, }, - Hostnames: []gatewayapiv1beta1.Hostname{"*.admin.toystore.com"}, + Hostnames: []gatewayapiv1.Hostname{"*.admin.toystore.com"}, }, } policy.Spec.AuthScheme.Authentication["apiKey"] = config @@ -1130,7 +1130,7 @@ var _ = Describe("AuthPolicy controller", func() { Group: "gateway.networking.k8s.io", Kind: "HTTPRoute", Name: testHTTPRouteName, - Namespace: ptr.To(gatewayapiv1beta1.Namespace(testNamespace)), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), }, AuthScheme: testBasicAuthScheme(), }, @@ -1138,13 +1138,13 @@ var _ = Describe("AuthPolicy controller", func() { config := policy.Spec.AuthScheme.Authentication["apiKey"] config.RouteSelectors = []api.RouteSelector{ { // Selects: GET /private* - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/private"), }, - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("GET")), + Method: ptr.To(gatewayapiv1.HTTPMethod("GET")), }, }, }, diff --git a/controllers/authpolicy_istio_authorizationpolicy.go b/controllers/authpolicy_istio_authorizationpolicy.go index 4a498aa14..b4fdfe92c 100644 --- a/controllers/authpolicy_istio_authorizationpolicy.go +++ b/controllers/authpolicy_istio_authorizationpolicy.go @@ -11,8 +11,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" istiosecurity "istio.io/api/security/v1beta1" istio "istio.io/client-go/pkg/apis/security/v1beta1" @@ -101,26 +101,26 @@ func (r *AuthPolicyReconciler) istioAuthorizationPolicy(ctx context.Context, ap }, } - var route *gatewayapiv1beta1.HTTPRoute + var route *gatewayapiv1.HTTPRoute gwHostnames := gw.Hostnames() if len(gwHostnames) == 0 { - gwHostnames = []gatewayapiv1beta1.Hostname{"*"} + gwHostnames = []gatewayapiv1.Hostname{"*"} } - var routeHostnames []gatewayapiv1beta1.Hostname + var routeHostnames []gatewayapiv1.Hostname switch obj := targetNetworkObject.(type) { - case *gatewayapiv1beta1.HTTPRoute: + case *gatewayapiv1.HTTPRoute: route = obj if len(route.Spec.Hostnames) > 0 { routeHostnames = common.FilterValidSubdomains(gwHostnames, route.Spec.Hostnames) } else { routeHostnames = gwHostnames } - case *gatewayapiv1beta1.Gateway: + case *gatewayapiv1.Gateway: // fake a single httproute with all rules from all httproutes accepted by the gateway, // that do not have an authpolicy of its own, so we can generate wasm rules for those cases - rules := make([]gatewayapiv1beta1.HTTPRouteRule, 0) + rules := make([]gatewayapiv1.HTTPRouteRule, 0) routes := r.FetchAcceptedGatewayHTTPRoutes(ctx, ap.TargetKey()) for idx := range routes { route := routes[idx] @@ -135,8 +135,8 @@ func (r *AuthPolicyReconciler) istioAuthorizationPolicy(ctx context.Context, ap common.TagObjectToDelete(iap) return iap, nil } - route = &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ + route = &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ Hostnames: gwHostnames, Rules: rules, }, @@ -190,7 +190,7 @@ func istioAuthorizationPolicyLabels(gwKey, apKey client.ObjectKey) map[string]st // These rules are the conditions that, when matched, will make the gateway to call external authorization. // If no rules are specified, the gateway will call external authorization for all requests. // If the route selectors specified in the policy do not match any route rules, an error is returned. -func istioAuthorizationPolicyRules(ap *api.AuthPolicy, route *gatewayapiv1beta1.HTTPRoute) ([]*istiosecurity.Rule, error) { +func istioAuthorizationPolicyRules(ap *api.AuthPolicy, route *gatewayapiv1.HTTPRoute) ([]*istiosecurity.Rule, error) { // use only the top level route selectors if defined if topLevelRouteSelectors := ap.Spec.RouteSelectors; len(topLevelRouteSelectors) > 0 { return istioAuthorizationPolicyRulesFromRouteSelectors(route, topLevelRouteSelectors) @@ -200,7 +200,7 @@ func istioAuthorizationPolicyRules(ap *api.AuthPolicy, route *gatewayapiv1beta1. // istioAuthorizationPolicyRulesFromRouteSelectors builds a list of Istio AuthorizationPolicy rules from an HTTPRoute, // filtered to the HTTPRouteRules and hostnames selected by the route selectors. -func istioAuthorizationPolicyRulesFromRouteSelectors(route *gatewayapiv1beta1.HTTPRoute, routeSelectors []api.RouteSelector) ([]*istiosecurity.Rule, error) { +func istioAuthorizationPolicyRulesFromRouteSelectors(route *gatewayapiv1.HTTPRoute, routeSelectors []api.RouteSelector) ([]*istiosecurity.Rule, error) { istioRules := []*istiosecurity.Rule{} if len(routeSelectors) > 0 { @@ -223,7 +223,7 @@ func istioAuthorizationPolicyRulesFromRouteSelectors(route *gatewayapiv1beta1.HT // istioAuthorizationPolicyRulesFromHTTPRoute builds a list of Istio AuthorizationPolicy rules from an HTTPRoute, // without using route selectors. -func istioAuthorizationPolicyRulesFromHTTPRoute(route *gatewayapiv1beta1.HTTPRoute) []*istiosecurity.Rule { +func istioAuthorizationPolicyRulesFromHTTPRoute(route *gatewayapiv1.HTTPRoute) []*istiosecurity.Rule { istioRules := []*istiosecurity.Rule{} hostnamesForConditions := (&api.RouteSelector{}).HostnamesForConditions(route) @@ -239,7 +239,7 @@ func istioAuthorizationPolicyRulesFromHTTPRoute(route *gatewayapiv1beta1.HTTPRou // * Each combination of HTTPRouteMatch and hostname yields one condition. // * Rules that specify no explicit HTTPRouteMatch are assumed to match all requests (i.e. implicit catch-all rule.) // * Empty list of hostnames yields a condition without a hostname pattern expression. -func istioAuthorizationPolicyRulesFromHTTPRouteRule(rule gatewayapiv1beta1.HTTPRouteRule, hostnames []gatewayapiv1beta1.Hostname) (istioRules []*istiosecurity.Rule) { +func istioAuthorizationPolicyRulesFromHTTPRouteRule(rule gatewayapiv1.HTTPRouteRule, hostnames []gatewayapiv1.Hostname) (istioRules []*istiosecurity.Rule) { hosts := []string{} for _, hostname := range hostnames { if hostname == "*" { @@ -294,9 +294,9 @@ func istioAuthorizationPolicyRulesFromHTTPRouteRule(rule gatewayapiv1beta1.HTTPR skip := false if path.Type != nil { switch *path.Type { - case gatewayapiv1beta1.PathMatchExact: + case gatewayapiv1.PathMatchExact: operator = "" - case gatewayapiv1beta1.PathMatchRegularExpression: + case gatewayapiv1.PathMatchRegularExpression: // ignore this rule as it is not supported by Istio - Authorino will check it anyway skip = true } @@ -322,7 +322,7 @@ func istioAuthorizationPolicyRulesFromHTTPRouteRule(rule gatewayapiv1beta1.HTTPR for idx := range match.Headers { header := match.Headers[idx] - if header.Type != nil && *header.Type == gatewayapiv1beta1.HeaderMatchRegularExpression { + if header.Type != nil && *header.Type == gatewayapiv1.HeaderMatchRegularExpression { // skip this rule as it is not supported by Istio - Authorino will check it anyway continue } diff --git a/controllers/authpolicy_istio_authorizationpolicy_test.go b/controllers/authpolicy_istio_authorizationpolicy_test.go index 9c300569f..a64baf5d7 100644 --- a/controllers/authpolicy_istio_authorizationpolicy_test.go +++ b/controllers/authpolicy_istio_authorizationpolicy_test.go @@ -8,20 +8,20 @@ import ( istiosecurity "istio.io/api/security/v1beta1" "k8s.io/utils/ptr" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { testCases := []struct { name string - hostnames []gatewayapiv1beta1.Hostname - rule gatewayapiv1beta1.HTTPRouteRule + hostnames []gatewayapiv1.Hostname + rule gatewayapiv1.HTTPRouteRule expected []*istiosecurity.Rule }{ { name: "No HTTPRouteMatch", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{}, + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{}, expected: []*istiosecurity.Rule{ { To: []*istiosecurity.Rule_To{ @@ -36,12 +36,12 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "Single HTTPRouteMatch", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -62,18 +62,18 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "Multiple HTTPRouteMatches", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("Exact")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("Exact")), Value: ptr.To("/foo"), }, }, @@ -104,12 +104,12 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "Multiple hosts", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io", "gamestore.kuadrant.io"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io", "gamestore.kuadrant.io"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -130,12 +130,12 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "Catch-all host is ignored", - hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io", "*"}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + hostnames: []gatewayapiv1.Hostname{"toystore.kuadrant.io", "*"}, + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -156,10 +156,10 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "Method", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("GET")), + Method: ptr.To(gatewayapiv1.HTTPMethod("GET")), }, }, }, @@ -177,11 +177,11 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "PathMatchExact", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("Exact")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("Exact")), Value: ptr.To("/toy"), }, }, @@ -201,11 +201,11 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "PathMatchPrefix", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/toy"), }, }, @@ -225,11 +225,11 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "PathMatchRegularExpression", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("RegularExpression")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("RegularExpression")), Value: ptr.To("/toy"), }, }, @@ -247,12 +247,12 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "Single header match", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("Exact")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("Exact")), Name: "x-foo", Value: "a-value", }, @@ -273,17 +273,17 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "Multiple header matches", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("Exact")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("Exact")), Name: "x-foo", Value: "a-value", }, { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("Exact")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("Exact")), Name: "x-bar", Value: "other-value", }, @@ -308,12 +308,12 @@ func TestIstioAuthorizationPolicyRulesFromHTTPRouteRule(t *testing.T) { }, { name: "HeaderMatchRegularExpression", - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: ptr.To(gatewayapiv1beta1.HeaderMatchType("RegularExpression")), + Type: ptr.To(gatewayapiv1.HeaderMatchType("RegularExpression")), Name: "x-foo", Value: "^a+.*$", }, diff --git a/controllers/gateway_eventmapper.go b/controllers/gateway_eventmapper.go index 0708ee3b8..bd9e7a8f1 100644 --- a/controllers/gateway_eventmapper.go +++ b/controllers/gateway_eventmapper.go @@ -7,7 +7,7 @@ import ( "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/kuadrant/kuadrant-operator/pkg/common" ) @@ -28,9 +28,9 @@ func (m *GatewayEventMapper) MapToAuthPolicy(_ context.Context, obj client.Objec func (m *GatewayEventMapper) mapToPolicyRequest(obj client.Object, policyKind string, policyRefsConfig common.PolicyRefsConfig) []reconcile.Request { logger := m.Logger.V(1).WithValues("object", client.ObjectKeyFromObject(obj)) - gateway, ok := obj.(*gatewayapiv1beta1.Gateway) + gateway, ok := obj.(*gatewayapiv1.Gateway) if !ok { - logger.Info("mapToPolicyRequest:", "error", fmt.Sprintf("%T is not a *gatewayapiv1beta1.Gateway", obj)) + logger.Info("mapToPolicyRequest:", "error", fmt.Sprintf("%T is not a *gatewayapiv1.Gateway", obj)) return []reconcile.Request{} } diff --git a/controllers/gateway_kuadrant_controller.go b/controllers/gateway_kuadrant_controller.go index 9f39c529a..21a5cd919 100644 --- a/controllers/gateway_kuadrant_controller.go +++ b/controllers/gateway_kuadrant_controller.go @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/predicate" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -49,7 +49,7 @@ func (r *GatewayKuadrantReconciler) Reconcile(eventCtx context.Context, req ctrl logger.Info("Reconciling Kuadrant annotations") ctx := logr.NewContext(eventCtx, logger) - gw := &gatewayapiv1beta1.Gateway{} + gw := &gatewayapiv1.Gateway{} if err := r.Client().Get(ctx, req.NamespacedName, gw); err != nil { if apierrors.IsNotFound(err) { logger.Info("no gateway found") @@ -77,7 +77,7 @@ func (r *GatewayKuadrantReconciler) Reconcile(eventCtx context.Context, req ctrl return ctrl.Result{}, nil } -func (r *GatewayKuadrantReconciler) reconcileGatewayKuadrantMetadata(ctx context.Context, gw *gatewayapiv1beta1.Gateway) error { +func (r *GatewayKuadrantReconciler) reconcileGatewayKuadrantMetadata(ctx context.Context, gw *gatewayapiv1.Gateway) error { updated, err := r.reconcileKuadrantNamespaceAnnotation(ctx, gw) if err != nil { return err @@ -92,7 +92,7 @@ func (r *GatewayKuadrantReconciler) reconcileGatewayKuadrantMetadata(ctx context return nil } -func (r *GatewayKuadrantReconciler) reconcileKuadrantNamespaceAnnotation(ctx context.Context, gw *gatewayapiv1beta1.Gateway) (bool, error) { +func (r *GatewayKuadrantReconciler) reconcileKuadrantNamespaceAnnotation(ctx context.Context, gw *gatewayapiv1.Gateway) (bool, error) { logger, err := logr.FromContext(ctx) if err != nil { return false, err @@ -131,6 +131,6 @@ func (r *GatewayKuadrantReconciler) reconcileKuadrantNamespaceAnnotation(ctx con func (r *GatewayKuadrantReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). // Gateway Kuadrant controller only cares about the annotations - For(&gatewayapiv1beta1.Gateway{}, builder.WithPredicates(predicate.AnnotationChangedPredicate{})). + For(&gatewayapiv1.Gateway{}, builder.WithPredicates(predicate.AnnotationChangedPredicate{})). Complete(r) } diff --git a/controllers/gateway_kuadrant_controller_test.go b/controllers/gateway_kuadrant_controller_test.go index 443ec7b50..374395856 100644 --- a/controllers/gateway_kuadrant_controller_test.go +++ b/controllers/gateway_kuadrant_controller_test.go @@ -12,7 +12,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -40,7 +40,7 @@ var _ = Describe("Kuadrant Gateway controller", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func() bool { - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) if err != nil { logf.Log.V(1).Info("[WARN] Getting gateway failed", "error", err) @@ -57,7 +57,7 @@ var _ = Describe("Kuadrant Gateway controller", func() { // Check gateway is annotated with kuadrant annotation Eventually(func() bool { - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) if err != nil { logf.Log.V(1).Info("[WARN] Getting gateway failed", "error", err) @@ -98,7 +98,7 @@ var _ = Describe("Kuadrant Gateway controller", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func() bool { - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) if err != nil { logf.Log.V(1).Info("[WARN] Getting gateway failed", "error", err) @@ -115,7 +115,7 @@ var _ = Describe("Kuadrant Gateway controller", func() { // Check gateway is not annotated with kuadrant annotation Eventually(func() bool { - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) if err != nil { logf.Log.V(1).Info("[WARN] Getting gateway failed", "error", err) diff --git a/controllers/helper_test.go b/controllers/helper_test.go index 92799c556..3dcd62805 100644 --- a/controllers/helper_test.go +++ b/controllers/helper_test.go @@ -29,7 +29,7 @@ import ( "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) func ApplyKuadrantCR(namespace string) { @@ -182,11 +182,11 @@ func CreateOrUpdateK8SObject(obj runtime.Object, k8sClient client.Client) error return k8sClient.Update(context.Background(), k8sObjCopy) } -func testBuildBasicGateway(gwName, ns string) *gatewayapiv1beta1.Gateway { - return &gatewayapiv1beta1.Gateway{ +func testBuildBasicGateway(gwName, ns string) *gatewayapiv1.Gateway { + return &gatewayapiv1.Gateway{ TypeMeta: metav1.TypeMeta{ Kind: "Gateway", - APIVersion: gatewayapiv1beta1.GroupVersion.String(), + APIVersion: gatewayapiv1.GroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ Name: gwName, @@ -194,12 +194,12 @@ func testBuildBasicGateway(gwName, ns string) *gatewayapiv1beta1.Gateway { Labels: map[string]string{"app": "rlptest"}, Annotations: map[string]string{"networking.istio.io/service-type": string(corev1.ServiceTypeClusterIP)}, }, - Spec: gatewayapiv1beta1.GatewaySpec{ + Spec: gatewayapiv1.GatewaySpec{ GatewayClassName: "istio", - Listeners: []gatewayapiv1beta1.Listener{ + Listeners: []gatewayapiv1.Listener{ { Name: "default", - Port: gatewayapiv1beta1.PortNumber(80), + Port: gatewayapiv1.PortNumber(80), Protocol: "HTTP", }, }, @@ -207,36 +207,36 @@ func testBuildBasicGateway(gwName, ns string) *gatewayapiv1beta1.Gateway { } } -func testBuildBasicHttpRoute(routeName, gwName, ns string, hostnames []string) *gatewayapiv1beta1.HTTPRoute { - return &gatewayapiv1beta1.HTTPRoute{ +func testBuildBasicHttpRoute(routeName, gwName, ns string, hostnames []string) *gatewayapiv1.HTTPRoute { + return &gatewayapiv1.HTTPRoute{ TypeMeta: metav1.TypeMeta{ Kind: "HTTPRoute", - APIVersion: gatewayapiv1beta1.GroupVersion.String(), + APIVersion: gatewayapiv1.GroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ Name: routeName, Namespace: ns, Labels: map[string]string{"app": "rlptest"}, }, - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { - Name: gatewayapiv1beta1.ObjectName(gwName), - Namespace: ptr.To(gatewayapiv1beta1.Namespace(ns)), + Name: gatewayapiv1.ObjectName(gwName), + Namespace: ptr.To(gatewayapiv1.Namespace(ns)), }, }, }, - Hostnames: common.Map(hostnames, func(hostname string) gatewayapiv1beta1.Hostname { return gatewayapiv1beta1.Hostname(hostname) }), - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + Hostnames: common.Map(hostnames, func(hostname string) gatewayapiv1.Hostname { return gatewayapiv1.Hostname(hostname) }), + Rules: []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchPathPrefix), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchPathPrefix), Value: ptr.To("/toy"), }, - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("GET")), + Method: ptr.To(gatewayapiv1.HTTPMethod("GET")), }, }, }, @@ -245,35 +245,35 @@ func testBuildBasicHttpRoute(routeName, gwName, ns string, hostnames []string) * } } -func testBuildMultipleRulesHttpRoute(routeName, gwName, ns string, hostnames []string) *gatewayapiv1beta1.HTTPRoute { +func testBuildMultipleRulesHttpRoute(routeName, gwName, ns string, hostnames []string) *gatewayapiv1.HTTPRoute { route := testBuildBasicHttpRoute(routeName, gwName, ns, hostnames) - route.Spec.Rules = []gatewayapiv1beta1.HTTPRouteRule{ + route.Spec.Rules = []gatewayapiv1.HTTPRouteRule{ { // POST|DELETE /admin* - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/admin"), }, - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("POST")), + Method: ptr.To(gatewayapiv1.HTTPMethod("POST")), }, { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/admin"), }, - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("DELETE")), + Method: ptr.To(gatewayapiv1.HTTPMethod("DELETE")), }, }, }, { // GET /private* - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchType("PathPrefix")), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchType("PathPrefix")), Value: ptr.To("/private"), }, - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("GET")), + Method: ptr.To(gatewayapiv1.HTTPMethod("GET")), }, }, }, diff --git a/controllers/httprouteparentrefs_eventmapper.go b/controllers/httprouteparentrefs_eventmapper.go index 0fcebcddb..70bbed511 100644 --- a/controllers/httprouteparentrefs_eventmapper.go +++ b/controllers/httprouteparentrefs_eventmapper.go @@ -7,7 +7,7 @@ import ( "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" api "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -35,9 +35,9 @@ func (m *HTTPRouteParentRefsEventMapper) mapToPolicyRequest(obj client.Object, p "policyKind", policyKind, ) - route, ok := obj.(*gatewayapiv1beta1.HTTPRoute) + route, ok := obj.(*gatewayapiv1.HTTPRoute) if !ok { - logger.Info("mapToPolicyRequest:", "error", fmt.Sprintf("%T is not a *gatewayapiv1beta1.HTTPRoute", obj)) + logger.Info("mapToPolicyRequest:", "error", fmt.Sprintf("%T is not a *gatewayapiv1.HTTPRoute", obj)) return []reconcile.Request{} } @@ -51,7 +51,7 @@ func (m *HTTPRouteParentRefsEventMapper) mapToPolicyRequest(obj client.Object, p // list policies in the same namespace as the parent gateway of the route parentRefNamespace := parentRef.Namespace if parentRefNamespace == nil { - ns := gatewayapiv1beta1.Namespace(route.GetNamespace()) + ns := gatewayapiv1.Namespace(route.GetNamespace()) parentRefNamespace = &ns } if err := m.Client.List(context.Background(), policyList, &client.ListOptions{Namespace: string(*parentRefNamespace)}); err != nil { @@ -70,7 +70,7 @@ func (m *HTTPRouteParentRefsEventMapper) mapToPolicyRequest(obj client.Object, p } targetRefNamespace := targetRef.Namespace if targetRefNamespace == nil { - ns := gatewayapiv1beta1.Namespace(policy.GetNamespace()) + ns := gatewayapiv1.Namespace(policy.GetNamespace()) targetRefNamespace = &ns } if *parentRefNamespace == *targetRefNamespace && parentRef.Name == targetRef.Name { diff --git a/controllers/kuadrant_controller.go b/controllers/kuadrant_controller.go index 5798a3f11..3aa126ac7 100644 --- a/controllers/kuadrant_controller.go +++ b/controllers/kuadrant_controller.go @@ -38,7 +38,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -398,7 +398,7 @@ func buildServiceMeshMember(kObj *kuadrantv1beta1.Kuadrant) *maistrav1.ServiceMe func (r *KuadrantReconciler) reconcileClusterGateways(ctx context.Context, kObj *kuadrantv1beta1.Kuadrant) error { // TODO: After the RFC defined, we might want to get the gw to label/annotate from Kuadrant.Spec or manual labeling/annotation - gwList := &gatewayapiv1beta1.GatewayList{} + gwList := &gatewayapiv1.GatewayList{} if err := r.Client().List(ctx, gwList); err != nil { return err } @@ -427,7 +427,7 @@ func (r *KuadrantReconciler) reconcileClusterGateways(ctx context.Context, kObj } func (r *KuadrantReconciler) removeAnnotationFromGateways(ctx context.Context, kObj *kuadrantv1beta1.Kuadrant) error { - gwList := &gatewayapiv1beta1.GatewayList{} + gwList := &gatewayapiv1.GatewayList{} if err := r.Client().List(ctx, gwList); err != nil { return err } diff --git a/controllers/limitador_cluster_envoyfilter_controller.go b/controllers/limitador_cluster_envoyfilter_controller.go index dafdc5f14..6f6a5cc20 100644 --- a/controllers/limitador_cluster_envoyfilter_controller.go +++ b/controllers/limitador_cluster_envoyfilter_controller.go @@ -32,7 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/predicate" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/kuadrant/kuadrant-operator/pkg/common" kuadrantistioutils "github.com/kuadrant/kuadrant-operator/pkg/istio" @@ -55,7 +55,7 @@ func (r *LimitadorClusterEnvoyFilterReconciler) Reconcile(eventCtx context.Conte logger.Info("Reconciling EnvoyFilter") ctx := logr.NewContext(eventCtx, logger) - gw := &gatewayapiv1beta1.Gateway{} + gw := &gatewayapiv1.Gateway{} if err := r.Client().Get(ctx, req.NamespacedName, gw); err != nil { if apierrors.IsNotFound(err) { logger.Info("no gateway found") @@ -83,7 +83,7 @@ func (r *LimitadorClusterEnvoyFilterReconciler) Reconcile(eventCtx context.Conte return ctrl.Result{}, nil } -func (r *LimitadorClusterEnvoyFilterReconciler) reconcileRateLimitingClusterEnvoyFilter(ctx context.Context, gw *gatewayapiv1beta1.Gateway) error { +func (r *LimitadorClusterEnvoyFilterReconciler) reconcileRateLimitingClusterEnvoyFilter(ctx context.Context, gw *gatewayapiv1.Gateway) error { desired, err := r.desiredRateLimitingClusterEnvoyFilter(ctx, gw) if err != nil { return err @@ -97,7 +97,7 @@ func (r *LimitadorClusterEnvoyFilterReconciler) reconcileRateLimitingClusterEnvo return nil } -func (r *LimitadorClusterEnvoyFilterReconciler) desiredRateLimitingClusterEnvoyFilter(ctx context.Context, gw *gatewayapiv1beta1.Gateway) (*istioclientnetworkingv1alpha3.EnvoyFilter, error) { +func (r *LimitadorClusterEnvoyFilterReconciler) desiredRateLimitingClusterEnvoyFilter(ctx context.Context, gw *gatewayapiv1.Gateway) (*istioclientnetworkingv1alpha3.EnvoyFilter, error) { logger, err := logr.FromContext(ctx) if err != nil { return nil, err @@ -166,7 +166,7 @@ func (r *LimitadorClusterEnvoyFilterReconciler) SetupWithManager(mgr ctrl.Manage // Limitador cluster EnvoyFilter controller only cares about // the annotation having references to RLP's // kuadrant.io/ratelimitpolicies - For(&gatewayapiv1beta1.Gateway{}, builder.WithPredicates(predicate.AnnotationChangedPredicate{})). + For(&gatewayapiv1.Gateway{}, builder.WithPredicates(predicate.AnnotationChangedPredicate{})). Owns(&istioclientnetworkingv1alpha3.EnvoyFilter{}). Complete(r) } diff --git a/controllers/limitador_cluster_envoyfilter_controller_test.go b/controllers/limitador_cluster_envoyfilter_controller_test.go index 217ce8d59..be2cec803 100644 --- a/controllers/limitador_cluster_envoyfilter_controller_test.go +++ b/controllers/limitador_cluster_envoyfilter_controller_test.go @@ -15,8 +15,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -38,7 +38,7 @@ var _ = Describe("Limitador Cluster EnvoyFilter controller", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func() bool { - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) if err != nil { logf.Log.V(1).Info("[WARN] Creating gateway failed", "error", err) @@ -86,9 +86,9 @@ var _ = Describe("Limitador Cluster EnvoyFilter controller", func() { }, Spec: kuadrantv1beta2.RateLimitPolicySpec{ TargetRef: gatewayapiv1alpha2.PolicyTargetReference{ - Group: gatewayapiv1beta1.Group("gateway.networking.k8s.io"), + Group: gatewayapiv1.Group("gateway.networking.k8s.io"), Kind: "Gateway", - Name: gatewayapiv1beta1.ObjectName(gwName), + Name: gatewayapiv1.ObjectName(gwName), }, Limits: map[string]kuadrantv1beta2.Limit{ "l1": { diff --git a/controllers/ratelimitpolicy_controller.go b/controllers/ratelimitpolicy_controller.go index e01b30dd0..83d22affe 100644 --- a/controllers/ratelimitpolicy_controller.go +++ b/controllers/ratelimitpolicy_controller.go @@ -26,7 +26,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/handler" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -230,13 +230,13 @@ func (r *RateLimitPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&kuadrantv1beta2.RateLimitPolicy{}). Watches( - &gatewayapiv1beta1.HTTPRoute{}, + &gatewayapiv1.HTTPRoute{}, handler.EnqueueRequestsFromMapFunc(httpRouteEventMapper.MapToRateLimitPolicy), ). // Currently the purpose is to generate events when rlp references change in gateways // so the status of the rlps targeting a route can be keep in sync Watches( - &gatewayapiv1beta1.Gateway{}, + &gatewayapiv1.Gateway{}, handler.EnqueueRequestsFromMapFunc(gatewayEventMapper.MapToRateLimitPolicy), ). Complete(r) diff --git a/controllers/ratelimitpolicy_controller_test.go b/controllers/ratelimitpolicy_controller_test.go index 54e711508..228070dac 100644 --- a/controllers/ratelimitpolicy_controller_test.go +++ b/controllers/ratelimitpolicy_controller_test.go @@ -16,8 +16,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -33,7 +33,7 @@ var _ = Describe("RateLimitPolicy controller", func() { routeName = "toystore-route" gwName = "toystore-gw" rlpName = "toystore-rlp" - gateway *gatewayapiv1beta1.Gateway + gateway *gatewayapiv1.Gateway ) beforeEachCallback := func() { @@ -43,7 +43,7 @@ var _ = Describe("RateLimitPolicy controller", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func() bool { - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) if err != nil { logf.Log.V(1).Info("[WARN] Creating gateway failed", "error", err) @@ -96,9 +96,9 @@ var _ = Describe("RateLimitPolicy controller", func() { }, Spec: kuadrantv1beta2.RateLimitPolicySpec{ TargetRef: gatewayapiv1alpha2.PolicyTargetReference{ - Group: gatewayapiv1beta1.Group("gateway.networking.k8s.io"), + Group: gatewayapiv1.Group("gateway.networking.k8s.io"), Kind: "HTTPRoute", - Name: gatewayapiv1beta1.ObjectName(routeName), + Name: gatewayapiv1.ObjectName(routeName), }, Limits: map[string]kuadrantv1beta2.Limit{ "l1": { @@ -120,7 +120,7 @@ var _ = Describe("RateLimitPolicy controller", func() { // Check HTTPRoute direct back reference routeKey := client.ObjectKey{Name: routeName, Namespace: testNamespace} - existingRoute := &gatewayapiv1beta1.HTTPRoute{} + existingRoute := &gatewayapiv1.HTTPRoute{} err = k8sClient.Get(context.Background(), routeKey, existingRoute) // must exist Expect(err).ToNot(HaveOccurred()) @@ -192,7 +192,7 @@ var _ = Describe("RateLimitPolicy controller", func() { // Check gateway back references gwKey := client.ObjectKey{Name: gwName, Namespace: testNamespace} - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err = k8sClient.Get(context.Background(), gwKey, existingGateway) // must exist Expect(err).ToNot(HaveOccurred()) @@ -206,30 +206,30 @@ var _ = Describe("RateLimitPolicy controller", func() { It("Creates the correct WasmPlugin for a complex HTTPRoute and a RateLimitPolicy", func() { // create httproute httpRoute := testBuildBasicHttpRoute(routeName, gwName, testNamespace, []string{"*.toystore.acme.com", "api.toystore.io"}) - httpRoute.Spec.Rules = []gatewayapiv1beta1.HTTPRouteRule{ + httpRoute.Spec.Rules = []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { // get /toys* - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchPathPrefix), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchPathPrefix), Value: ptr.To("/toys"), }, - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("GET")), + Method: ptr.To(gatewayapiv1.HTTPMethod("GET")), }, { // post /toys* - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchPathPrefix), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchPathPrefix), Value: ptr.To("/toys"), }, - Method: ptr.To(gatewayapiv1beta1.HTTPMethod("POST")), + Method: ptr.To(gatewayapiv1.HTTPMethod("POST")), }, }, }, { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { // /assets* - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchPathPrefix), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchPathPrefix), Value: ptr.To("/assets"), }, }, @@ -251,9 +251,9 @@ var _ = Describe("RateLimitPolicy controller", func() { }, Spec: kuadrantv1beta2.RateLimitPolicySpec{ TargetRef: gatewayapiv1alpha2.PolicyTargetReference{ - Group: gatewayapiv1beta1.Group("gateway.networking.k8s.io"), + Group: gatewayapiv1.Group("gateway.networking.k8s.io"), Kind: "HTTPRoute", - Name: gatewayapiv1beta1.ObjectName(routeName), + Name: gatewayapiv1.ObjectName(routeName), }, Limits: map[string]kuadrantv1beta2.Limit{ "toys": { @@ -263,15 +263,15 @@ var _ = Describe("RateLimitPolicy controller", func() { Counters: []kuadrantv1beta2.ContextSelector{"auth.identity.username"}, RouteSelectors: []kuadrantv1beta2.RouteSelector{ { // selects the 1st HTTPRouteRule (i.e. get|post /toys*) for one of the hostnames - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchPathPrefix), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchPathPrefix), Value: ptr.To("/toys"), }, }, }, - Hostnames: []gatewayapiv1beta1.Hostname{"*.toystore.acme.com"}, + Hostnames: []gatewayapiv1.Hostname{"*.toystore.acme.com"}, }, }, When: []kuadrantv1beta2.WhenCondition{ @@ -289,10 +289,10 @@ var _ = Describe("RateLimitPolicy controller", func() { }, RouteSelectors: []kuadrantv1beta2.RouteSelector{ { // selects the 2nd HTTPRouteRule (i.e. /assets*) for all hostnames - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: ptr.To(gatewayapiv1beta1.PathMatchPathPrefix), + Path: &gatewayapiv1.HTTPPathMatch{ + Type: ptr.To(gatewayapiv1.PathMatchPathPrefix), Value: ptr.To("/assets"), }, }, @@ -434,9 +434,9 @@ var _ = Describe("RateLimitPolicy controller", func() { }, Spec: kuadrantv1beta2.RateLimitPolicySpec{ TargetRef: gatewayapiv1alpha2.PolicyTargetReference{ - Group: gatewayapiv1beta1.Group("gateway.networking.k8s.io"), + Group: gatewayapiv1.Group("gateway.networking.k8s.io"), Kind: "Gateway", - Name: gatewayapiv1beta1.ObjectName(gwName), + Name: gatewayapiv1.ObjectName(gwName), }, Limits: map[string]kuadrantv1beta2.Limit{ "l1": { @@ -458,7 +458,7 @@ var _ = Describe("RateLimitPolicy controller", func() { // Check Gateway direct back reference gwKey := client.ObjectKeyFromObject(gateway) - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err = k8sClient.Get(context.Background(), gwKey, existingGateway) // must exist Expect(err).ToNot(HaveOccurred()) @@ -551,9 +551,9 @@ var _ = Describe("RateLimitPolicy controller", func() { }, Spec: kuadrantv1beta2.RateLimitPolicySpec{ TargetRef: gatewayapiv1alpha2.PolicyTargetReference{ - Group: gatewayapiv1beta1.Group("gateway.networking.k8s.io"), + Group: gatewayapiv1.Group("gateway.networking.k8s.io"), Kind: "Gateway", - Name: gatewayapiv1beta1.ObjectName(gwName), + Name: gatewayapiv1.ObjectName(gwName), }, Limits: map[string]kuadrantv1beta2.Limit{ "l1": { @@ -575,7 +575,7 @@ var _ = Describe("RateLimitPolicy controller", func() { // Check Gateway direct back reference gwKey := client.ObjectKeyFromObject(gateway) - existingGateway := &gatewayapiv1beta1.Gateway{} + existingGateway := &gatewayapiv1.Gateway{} err = k8sClient.Get(context.Background(), gwKey, existingGateway) // must exist Expect(err).ToNot(HaveOccurred()) diff --git a/controllers/ratelimitpolicy_istio_wasmplugin.go b/controllers/ratelimitpolicy_istio_wasmplugin.go index 093e24826..0781efe44 100644 --- a/controllers/ratelimitpolicy_istio_wasmplugin.go +++ b/controllers/ratelimitpolicy_istio_wasmplugin.go @@ -10,7 +10,7 @@ import ( istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/common" @@ -127,7 +127,7 @@ func (r *RateLimitPolicyReconciler) wasmPluginConfig(ctx context.Context, gw com type store struct { rlp kuadrantv1beta2.RateLimitPolicy - route gatewayapiv1beta1.HTTPRoute + route gatewayapiv1.HTTPRoute skip bool } rlps := make(map[string]*store, len(rlpRefs)) @@ -164,13 +164,13 @@ func (r *RateLimitPolicyReconciler) wasmPluginConfig(ctx context.Context, gw com gwHostnames := gw.Hostnames() if len(gwHostnames) == 0 { - gwHostnames = []gatewayapiv1beta1.Hostname{"*"} + gwHostnames = []gatewayapiv1.Hostname{"*"} } // if there is a gateway rlp, fake a single httproute with all rules from all httproutes accepted by the gateway, // that do not have a rlp of its own, so we can generate wasm rules for those cases if gwRLPKey != "" { - rules := make([]gatewayapiv1beta1.HTTPRouteRule, 0) + rules := make([]gatewayapiv1.HTTPRouteRule, 0) routes := r.FetchAcceptedGatewayHTTPRoutes(ctx, rlps[gwRLPKey].rlp.TargetKey()) for idx := range routes { route := routes[idx] @@ -184,8 +184,8 @@ func (r *RateLimitPolicyReconciler) wasmPluginConfig(ctx context.Context, gw com logger.V(1).Info("no httproutes attached to the targeted gateway, skipping wasm config for the gateway rlp", "ratelimitpolicy", gwRLPKey) rlps[gwRLPKey].skip = true } else { - rlps[gwRLPKey].route = gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ + rlps[gwRLPKey].route = gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ Hostnames: gwHostnames, Rules: rules, }, diff --git a/controllers/suite_test.go b/controllers/suite_test.go index a842045fb..ab11764af 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -37,7 +37,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/kuadrant/kuadrant-operator/pkg/log" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -83,7 +83,7 @@ var _ = BeforeSuite(func() { err = kuadrantv1beta2.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = gatewayapiv1beta1.AddToScheme(scheme.Scheme) + err = gatewayapiv1.Install(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = authorinoopapi.AddToScheme(scheme.Scheme) diff --git a/doc/auth.md b/doc/auth.md index ae2796287..92934b1bd 100644 --- a/doc/auth.md +++ b/doc/auth.md @@ -2,7 +2,7 @@ A Kuadrant AuthPolicy custom resource: -1. Targets Gateway API networking resources such as [HTTPRoutes](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRoute) and [Gateways](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.Gateway), using these resources to obtain additional context, i.e., which traffic workload (HTTP attributes, hostnames, user attributes, etc) to enforce auth. +1. Targets Gateway API networking resources such as [HTTPRoutes](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute) and [Gateways](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway), using these resources to obtain additional context, i.e., which traffic workload (HTTP attributes, hostnames, user attributes, etc) to enforce auth. 2. Supports targeting subsets (sections) of a network resource to apply the auth rules to. 3. Abstracts the details of the underlying external authorization protocol and configuration resources, that have a much broader remit and surface area. 4. Enables cluster operators to set defaults that govern behavior at the lower levels of the network, until a more specific policy is applied. diff --git a/doc/development.md b/doc/development.md index 4582ce6f3..fa0994d7a 100644 --- a/doc/development.md +++ b/doc/development.md @@ -26,7 +26,7 @@ * [operator-sdk] version v1.28.1 * [kind] version v0.20.0 * [git][git_tool] -* [go] version 1.20+ +* [go] version 1.21+ * [kubernetes] version v1.19+ * [kubectl] version v1.19+ diff --git a/doc/rate-limiting.md b/doc/rate-limiting.md index 25aa329d5..24db2c435 100644 --- a/doc/rate-limiting.md +++ b/doc/rate-limiting.md @@ -2,7 +2,7 @@ A Kuadrant RateLimitPolicy custom resource, often abbreviated "RLP": -1. Targets Gateway API networking resources such as [HTTPRoutes](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRoute) and [Gateways](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.Gateway), using these resources to obtain additional context, i.e., which traffic workload (HTTP attributes, hostnames, user attributes, etc) to rate limit. +1. Targets Gateway API networking resources such as [HTTPRoutes](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute) and [Gateways](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway), using these resources to obtain additional context, i.e., which traffic workload (HTTP attributes, hostnames, user attributes, etc) to rate limit. 2. Supports targeting subsets (sections) of a network resource to apply the limits to. 3. Abstracts the details of the underlying Rate Limit protocol and configuration resources, that have a much broader remit and surface area. 4. Enables cluster operators to set defaults that govern behavior at the lower levels of the network, until a more specific policy is applied. diff --git a/doc/reference/route-selectors.md b/doc/reference/route-selectors.md index 45f499611..66a38b134 100644 --- a/doc/reference/route-selectors.md +++ b/doc/reference/route-selectors.md @@ -12,12 +12,12 @@ The `routeSelectors` field can be found in policy specs and policy rules (limit ### RouteSelector -Each `RouteSelector` is an object composed of a set of [HTTPRouteMatch](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPPathMatch) objects (from Gateway API), and an additional `hostnames` field. +Each `RouteSelector` is an object composed of a set of [HTTPRouteMatch](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPPathMatch) objects (from Gateway API), and an additional `hostnames` field. | **Field** | **Type** | **Required** | **Description** | |-------------|--------------------------------------------------------------------------------------------------------------------------------|:------------:|---------------------------------------------------------------------------------------------| -| `matches` | [][HTTPRouteMatch](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteMatch) | No | List of selectors of HTTPRouteRules whose matching rules activate the policy or policy rule | -| `hostnames` | [][Hostname](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.Hostname) | No | List of hostnames of the HTTPRoute that activate the policy or policy rule | +| `matches` | [][HTTPRouteMatch](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteMatch) | No | List of selectors of HTTPRouteRules whose matching rules activate the policy or policy rule | +| `hostnames` | [][Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) | No | List of hostnames of the HTTPRoute that activate the policy or policy rule | ## Mechanics of the route selectors diff --git a/doc/user-guides/auth-for-app-devs-and-platform-engineers.md b/doc/user-guides/auth-for-app-devs-and-platform-engineers.md index 4e1b13551..3e736a00e 100644 --- a/doc/user-guides/auth-for-app-devs-and-platform-engineers.md +++ b/doc/user-guides/auth-for-app-devs-and-platform-engineers.md @@ -77,7 +77,7 @@ EOF kubectl apply -f examples/toystore/toystore.yaml kubectl apply -f - < 0 { return RouteHostnames(route), nil } @@ -552,7 +552,7 @@ func HostnamesFromHTTPRoute(ctx context.Context, route *gatewayapiv1beta1.HTTPRo if (ref.Kind != nil && *ref.Kind != "Gateway") || (ref.Group != nil && *ref.Group != "gateway.networking.k8s.io") { continue } - gw := &gatewayapiv1beta1.Gateway{} + gw := &gatewayapiv1.Gateway{} ns := route.Namespace if ref.Namespace != nil { ns = string(*ref.Namespace) @@ -587,11 +587,11 @@ func ValidateHierarchicalRules(policy KuadrantPolicy, targetNetworkObject client return nil } -func GetGatewayWorkloadSelector(ctx context.Context, cli client.Client, gateway *gatewayapiv1beta1.Gateway) (map[string]string, error) { +func GetGatewayWorkloadSelector(ctx context.Context, cli client.Client, gateway *gatewayapiv1.Gateway) (map[string]string, error) { address, found := Find( gateway.Status.Addresses, - func(address gatewayapiv1beta1.GatewayAddress) bool { - return address.Type != nil && *address.Type == gatewayapiv1beta1.HostnameAddressType + func(address gatewayapiv1.GatewayStatusAddress) bool { + return address.Type != nil && *address.Type == gatewayapiv1.HostnameAddressType }, ) if !found { @@ -605,7 +605,7 @@ func GetGatewayWorkloadSelector(ctx context.Context, cli client.Client, gateway return GetServiceWorkloadSelector(ctx, cli, serviceKey) } -func IsHTTPRouteAccepted(httpRoute *gatewayapiv1beta1.HTTPRoute) bool { +func IsHTTPRouteAccepted(httpRoute *gatewayapiv1.HTTPRoute) bool { if httpRoute == nil { return false } @@ -617,7 +617,7 @@ func IsHTTPRouteAccepted(httpRoute *gatewayapiv1beta1.HTTPRoute) bool { // Check HTTProute parents (gateways) in the status object // if any of the current parent gateways reports not "Admitted", return false for _, parentRef := range httpRoute.Spec.CommonRouteSpec.ParentRefs { - routeParentStatus := func(pRef gatewayapiv1beta1.ParentReference) *gatewayapiv1beta1.RouteParentStatus { + routeParentStatus := func(pRef gatewayapiv1.ParentReference) *gatewayapiv1.RouteParentStatus { for idx := range httpRoute.Status.RouteStatus.Parents { if reflect.DeepEqual(pRef, httpRoute.Status.RouteStatus.Parents[idx].ParentRef) { return &httpRoute.Status.RouteStatus.Parents[idx] diff --git a/pkg/common/gatewayapi_utils_test.go b/pkg/common/gatewayapi_utils_test.go index 5309baeba..b0e976a78 100644 --- a/pkg/common/gatewayapi_utils_test.go +++ b/pkg/common/gatewayapi_utils_test.go @@ -15,14 +15,14 @@ import ( k8stypes "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" ) func TestRouteHostnames(t *testing.T) { testCases := []struct { name string - route *gatewayapiv1beta1.HTTPRoute + route *gatewayapiv1.HTTPRoute expected []string }{ { @@ -32,8 +32,8 @@ func TestRouteHostnames(t *testing.T) { }, { "nil hostname", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ Hostnames: nil, }, }, @@ -41,9 +41,9 @@ func TestRouteHostnames(t *testing.T) { }, { "basic", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Hostnames: []gatewayapiv1beta1.Hostname{"*.com", "example.net", "test.example.net"}, + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Hostnames: []gatewayapiv1.Hostname{"*.com", "example.net", "test.example.net"}, }, }, []string{"*.com", "example.net", "test.example.net"}, @@ -61,30 +61,30 @@ func TestRouteHostnames(t *testing.T) { func TestRulesFromHTTPRoute(t *testing.T) { var ( - getMethod = "GET" - catsPath = "/cats" - dogsPath = "/dogs" - rabbitsPath = "/rabbits" - getHTTPMethod gatewayapiv1beta1.HTTPMethod = "GET" - postHTTPMethod gatewayapiv1beta1.HTTPMethod = "POST" - pathPrefix = gatewayapiv1beta1.PathMatchPathPrefix - pathExact = gatewayapiv1beta1.PathMatchExact - catsPrefixPatchMatch = gatewayapiv1beta1.HTTPPathMatch{ + getMethod = "GET" + catsPath = "/cats" + dogsPath = "/dogs" + rabbitsPath = "/rabbits" + getHTTPMethod gatewayapiv1.HTTPMethod = "GET" + postHTTPMethod gatewayapiv1.HTTPMethod = "POST" + pathPrefix = gatewayapiv1.PathMatchPathPrefix + pathExact = gatewayapiv1.PathMatchExact + catsPrefixPatchMatch = gatewayapiv1.HTTPPathMatch{ Type: &pathPrefix, Value: &catsPath, } - dogsExactPatchMatch = gatewayapiv1beta1.HTTPPathMatch{ + dogsExactPatchMatch = gatewayapiv1.HTTPPathMatch{ Type: &pathExact, Value: &dogsPath, } - rabbitsPrefixPatchMatch = gatewayapiv1beta1.HTTPPathMatch{ + rabbitsPrefixPatchMatch = gatewayapiv1.HTTPPathMatch{ Value: &rabbitsPath, } ) testCases := []struct { name string - route *gatewayapiv1beta1.HTTPRoute + route *gatewayapiv1.HTTPRoute expected []HTTPRouteRule }{ { @@ -94,31 +94,31 @@ func TestRulesFromHTTPRoute(t *testing.T) { }, { "nil rules", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ Rules: nil, - Hostnames: []gatewayapiv1beta1.Hostname{"*.com"}, + Hostnames: []gatewayapiv1.Hostname{"*.com"}, }, }, []HTTPRouteRule{{Hosts: []string{"*.com"}}}, }, { "empty rules", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Rules: make([]gatewayapiv1beta1.HTTPRouteRule, 0), - Hostnames: []gatewayapiv1beta1.Hostname{"*.com"}, + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Rules: make([]gatewayapiv1.HTTPRouteRule, 0), + Hostnames: []gatewayapiv1.Hostname{"*.com"}, }, }, []HTTPRouteRule{{Hosts: []string{"*.com"}}}, }, { "with method", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Rules: []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { Method: &getHTTPMethod, }, @@ -134,11 +134,11 @@ func TestRulesFromHTTPRoute(t *testing.T) { }, { "with path", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Rules: []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { Path: &catsPrefixPatchMatch, }, @@ -154,11 +154,11 @@ func TestRulesFromHTTPRoute(t *testing.T) { }, { "with path and default path match type", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Rules: []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { Path: &rabbitsPrefixPatchMatch, }, @@ -174,13 +174,13 @@ func TestRulesFromHTTPRoute(t *testing.T) { }, { "no paths or methods", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Rules: []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Headers: []gatewayapiv1.HTTPHeaderMatch{ { Name: "someheader", Value: "somevalue", @@ -190,21 +190,21 @@ func TestRulesFromHTTPRoute(t *testing.T) { }, }, }, - Hostnames: []gatewayapiv1beta1.Hostname{"*.com"}, + Hostnames: []gatewayapiv1.Hostname{"*.com"}, }, }, []HTTPRouteRule{{Hosts: []string{"*.com"}}}, }, { "basic", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Hostnames: []gatewayapiv1beta1.Hostname{"*.com"}, - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Hostnames: []gatewayapiv1.Hostname{"*.com"}, + Rules: []gatewayapiv1.HTTPRouteRule{ { // GET /cats* // POST /dogs - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { Path: &catsPrefixPatchMatch, Method: &getHTTPMethod, @@ -246,30 +246,30 @@ func TestHTTPRouteRuleSelectorSelects(t *testing.T) { testCases := []struct { name string selector HTTPRouteRuleSelector - rule gatewayapiv1beta1.HTTPRouteRule + rule gatewayapiv1.HTTPRouteRule expected bool }{ { name: "when the httproutrule contains the exact match then return true", selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1beta1.HTTPRouteMatch{ - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, }, }, }, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, @@ -282,17 +282,17 @@ func TestHTTPRouteRuleSelectorSelects(t *testing.T) { { name: "when the httproutrule contains the exact match and more then return true", selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1beta1.HTTPRouteMatch{ - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], + HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], }, }, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, @@ -305,29 +305,29 @@ func TestHTTPRouteRuleSelectorSelects(t *testing.T) { { name: "when the httproutrule contains all the matching headers and more then return true", selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1beta1.HTTPRouteMatch{ - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, }, }, }, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchRegularExpression}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchRegularExpression}[0], Name: "someotherheader", Value: "someregex.*", }, @@ -340,24 +340,24 @@ func TestHTTPRouteRuleSelectorSelects(t *testing.T) { { name: "when the httproutrule contains an inexact match then return false", selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1beta1.HTTPRouteMatch{ - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, }, }, }, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodPost}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPost}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, @@ -369,10 +369,10 @@ func TestHTTPRouteRuleSelectorSelects(t *testing.T) { }, { name: "when the httproutrule is empty then return false", - rule: gatewayapiv1beta1.HTTPRouteRule{}, + rule: gatewayapiv1.HTTPRouteRule{}, selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1beta1.HTTPRouteMatch{ - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], + HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], }, }, expected: false, @@ -380,13 +380,13 @@ func TestHTTPRouteRuleSelectorSelects(t *testing.T) { { name: "when the selector is empty then return true", selector: HTTPRouteRuleSelector{}, - rule: gatewayapiv1beta1.HTTPRouteRule{ - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + rule: gatewayapiv1.HTTPRouteRule{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - Headers: []gatewayapiv1beta1.HTTPHeaderMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + Headers: []gatewayapiv1.HTTPHeaderMatch{ { - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "someheader", Value: "somevalue", }, @@ -416,14 +416,14 @@ func TestHTTPRouteRuleSelectorSelects(t *testing.T) { func TestHTTPPathMatchToString(t *testing.T) { testCases := []struct { name string - input *gatewayapiv1beta1.HTTPPathMatch + input *gatewayapiv1.HTTPPathMatch expected string }{ { name: "exact path match", - input: &[]gatewayapiv1beta1.HTTPPathMatch{ + input: &[]gatewayapiv1.HTTPPathMatch{ { - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchExact}[0], + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchExact}[0], Value: &[]string{"/foo"}[0], }, }[0], @@ -431,9 +431,9 @@ func TestHTTPPathMatchToString(t *testing.T) { }, { name: "regex path match", - input: &[]gatewayapiv1beta1.HTTPPathMatch{ + input: &[]gatewayapiv1.HTTPPathMatch{ { - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchRegularExpression}[0], + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchRegularExpression}[0], Value: &[]string{"^\\/foo.*"}[0], }, }[0], @@ -441,9 +441,9 @@ func TestHTTPPathMatchToString(t *testing.T) { }, { name: "path prefix match", - input: &[]gatewayapiv1beta1.HTTPPathMatch{ + input: &[]gatewayapiv1.HTTPPathMatch{ { - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/foo"}[0], }, }[0], @@ -451,7 +451,7 @@ func TestHTTPPathMatchToString(t *testing.T) { }, { name: "path match with default type", - input: &[]gatewayapiv1beta1.HTTPPathMatch{ + input: &[]gatewayapiv1.HTTPPathMatch{ { Value: &[]string{"/foo"}[0], }, @@ -476,13 +476,13 @@ func TestHTTPPathMatchToString(t *testing.T) { func TestHTTPHeaderMatchToString(t *testing.T) { testCases := []struct { name string - input gatewayapiv1beta1.HTTPHeaderMatch + input gatewayapiv1.HTTPHeaderMatch expected string }{ { name: "exact header match", - input: gatewayapiv1beta1.HTTPHeaderMatch{ - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchExact}[0], + input: gatewayapiv1.HTTPHeaderMatch{ + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], Name: "some-header", Value: "foo", }, @@ -490,8 +490,8 @@ func TestHTTPHeaderMatchToString(t *testing.T) { }, { name: "regex header match", - input: gatewayapiv1beta1.HTTPHeaderMatch{ - Type: &[]gatewayapiv1beta1.HeaderMatchType{gatewayapiv1beta1.HeaderMatchRegularExpression}[0], + input: gatewayapiv1.HTTPHeaderMatch{ + Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchRegularExpression}[0], Name: "some-header", Value: "^foo.*", }, @@ -499,7 +499,7 @@ func TestHTTPHeaderMatchToString(t *testing.T) { }, { name: "header match with default type", - input: gatewayapiv1beta1.HTTPHeaderMatch{ + input: gatewayapiv1.HTTPHeaderMatch{ Name: "some-header", Value: "foo", }, @@ -518,13 +518,13 @@ func TestHTTPHeaderMatchToString(t *testing.T) { func TestHTTPQueryParamMatchToString(t *testing.T) { testCases := []struct { name string - input gatewayapiv1beta1.HTTPQueryParamMatch + input gatewayapiv1.HTTPQueryParamMatch expected string }{ { name: "exact query param match", - input: gatewayapiv1beta1.HTTPQueryParamMatch{ - Type: &[]gatewayapiv1beta1.QueryParamMatchType{gatewayapiv1beta1.QueryParamMatchExact}[0], + input: gatewayapiv1.HTTPQueryParamMatch{ + Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchExact}[0], Name: "some-param", Value: "foo", }, @@ -532,8 +532,8 @@ func TestHTTPQueryParamMatchToString(t *testing.T) { }, { name: "regex query param match", - input: gatewayapiv1beta1.HTTPQueryParamMatch{ - Type: &[]gatewayapiv1beta1.QueryParamMatchType{gatewayapiv1beta1.QueryParamMatchRegularExpression}[0], + input: gatewayapiv1.HTTPQueryParamMatch{ + Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchRegularExpression}[0], Name: "some-param", Value: "^foo.*", }, @@ -541,7 +541,7 @@ func TestHTTPQueryParamMatchToString(t *testing.T) { }, { name: "query param match with default type", - input: gatewayapiv1beta1.HTTPQueryParamMatch{ + input: gatewayapiv1.HTTPQueryParamMatch{ Name: "some-param", Value: "foo", }, @@ -559,43 +559,43 @@ func TestHTTPQueryParamMatchToString(t *testing.T) { func TestHTTPMethodToString(t *testing.T) { testCases := []struct { - input *gatewayapiv1beta1.HTTPMethod + input *gatewayapiv1.HTTPMethod expected string }{ { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], expected: "GET", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodHead}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodHead}[0], expected: "HEAD", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodPost}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPost}[0], expected: "POST", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodPut}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPut}[0], expected: "PUT", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodPatch}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPatch}[0], expected: "PATCH", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodDelete}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodDelete}[0], expected: "DELETE", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodConnect}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodConnect}[0], expected: "CONNECT", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodOptions}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodOptions}[0], expected: "OPTIONS", }, { - input: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodTrace}[0], + input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodTrace}[0], expected: "TRACE", }, { @@ -611,15 +611,15 @@ func TestHTTPMethodToString(t *testing.T) { } func TestHTTPRouteMatchToString(t *testing.T) { - match := gatewayapiv1beta1.HTTPRouteMatch{ - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchExact}[0], + match := gatewayapiv1.HTTPRouteMatch{ + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchExact}[0], Value: &[]string{"/foo"}[0], }, - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - QueryParams: []gatewayapiv1beta1.HTTPQueryParamMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + QueryParams: []gatewayapiv1.HTTPQueryParamMatch{ { - Type: &[]gatewayapiv1beta1.QueryParamMatchType{gatewayapiv1beta1.QueryParamMatchRegularExpression}[0], + Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchRegularExpression}[0], Name: "page", Value: "\\d+", }, @@ -632,7 +632,7 @@ func TestHTTPRouteMatchToString(t *testing.T) { t.Errorf("expected: %s, got: %s", expected, r) } - match.Headers = []gatewayapiv1beta1.HTTPHeaderMatch{ + match.Headers = []gatewayapiv1.HTTPHeaderMatch{ { Name: "x-foo", Value: "bar", @@ -647,7 +647,7 @@ func TestHTTPRouteMatchToString(t *testing.T) { } func TestHTTPRouteRuleToString(t *testing.T) { - rule := gatewayapiv1beta1.HTTPRouteRule{} + rule := gatewayapiv1.HTTPRouteRule{} expected := "{matches:[]}" @@ -655,16 +655,16 @@ func TestHTTPRouteRuleToString(t *testing.T) { t.Errorf("expected: %s, got: %s", expected, r) } - rule.Matches = []gatewayapiv1beta1.HTTPRouteMatch{ + rule.Matches = []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchExact}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchExact}[0], Value: &[]string{"/foo"}[0], }, - Method: &[]gatewayapiv1beta1.HTTPMethod{gatewayapiv1beta1.HTTPMethodGet}[0], - QueryParams: []gatewayapiv1beta1.HTTPQueryParamMatch{ + Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], + QueryParams: []gatewayapiv1.HTTPQueryParamMatch{ { - Type: &[]gatewayapiv1beta1.QueryParamMatchType{gatewayapiv1beta1.QueryParamMatchRegularExpression}[0], + Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchRegularExpression}[0], Name: "page", Value: "\\d+", }, @@ -680,8 +680,8 @@ func TestHTTPRouteRuleToString(t *testing.T) { } func TestGatewaysMissingPolicyRef(t *testing.T) { - gwList := &gatewayapiv1beta1.GatewayList{ - Items: []gatewayapiv1beta1.Gateway{ + gwList := &gatewayapiv1.GatewayList{ + Items: []gatewayapiv1.Gateway{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", @@ -755,8 +755,8 @@ func TestGatewaysMissingPolicyRef(t *testing.T) { } func TestGatewaysWithValidPolicyRef(t *testing.T) { - gwList := &gatewayapiv1beta1.GatewayList{ - Items: []gatewayapiv1beta1.Gateway{ + gwList := &gatewayapiv1.GatewayList{ + Items: []gatewayapiv1.Gateway{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", @@ -830,8 +830,8 @@ func TestGatewaysWithValidPolicyRef(t *testing.T) { } func TestGatewaysWithInvalidPolicyRef(t *testing.T) { - gwList := &gatewayapiv1beta1.GatewayList{ - Items: []gatewayapiv1beta1.Gateway{ + gwList := &gatewayapiv1.GatewayList{ + Items: []gatewayapiv1.Gateway{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", @@ -906,7 +906,7 @@ func TestGatewaysWithInvalidPolicyRef(t *testing.T) { func TestGatewayWrapperKey(t *testing.T) { gw := GatewayWrapper{ - Gateway: &gatewayapiv1beta1.Gateway{ + Gateway: &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", Name: "gw-1", @@ -922,7 +922,7 @@ func TestGatewayWrapperKey(t *testing.T) { func TestGatewayWrapperPolicyRefs(t *testing.T) { gw := GatewayWrapper{ - Gateway: &gatewayapiv1beta1.Gateway{ + Gateway: &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", Name: "gw-1", @@ -945,7 +945,7 @@ func TestGatewayWrapperPolicyRefs(t *testing.T) { func TestGatewayWrapperContainsPolicy(t *testing.T) { gw := GatewayWrapper{ - Gateway: &gatewayapiv1beta1.Gateway{ + Gateway: &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", Name: "gw-1", @@ -966,7 +966,7 @@ func TestGatewayWrapperContainsPolicy(t *testing.T) { } func TestGatewayWrapperAddPolicy(t *testing.T) { - gateway := gatewayapiv1beta1.Gateway{ + gateway := gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", Name: "gw-1", @@ -989,7 +989,7 @@ func TestGatewayWrapperAddPolicy(t *testing.T) { } func TestGatewayDeletePolicy(t *testing.T) { - gateway := gatewayapiv1beta1.Gateway{ + gateway := gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", Name: "gw-1", @@ -1012,15 +1012,15 @@ func TestGatewayDeletePolicy(t *testing.T) { } func TestGatewayHostnames(t *testing.T) { - hostname := gatewayapiv1beta1.Hostname("toystore.com") - gateway := gatewayapiv1beta1.Gateway{ + hostname := gatewayapiv1.Hostname("toystore.com") + gateway := gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", Name: "gw-1", Annotations: map[string]string{"kuadrant.io/ratelimitpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, }, - Spec: gatewayapiv1beta1.GatewaySpec{ - Listeners: []gatewayapiv1beta1.Listener{ + Spec: gatewayapiv1.GatewaySpec{ + Listeners: []gatewayapiv1.Listener{ { Name: "my-listener", Hostname: &hostname, @@ -1043,7 +1043,7 @@ func TestGatewayHostnames(t *testing.T) { func TestGatewayWrapperPolicyRefsAnnotation(t *testing.T) { gw := GatewayWrapper{ - Gateway: &gatewayapiv1beta1.Gateway{ + Gateway: &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gw-ns", Name: "gw-1", @@ -1058,8 +1058,8 @@ func TestGatewayWrapperPolicyRefsAnnotation(t *testing.T) { } func TestGetGatewayWorkloadSelector(t *testing.T) { - hostnameAddress := gatewayapiv1beta1.AddressType("Hostname") - gateway := &gatewayapiv1beta1.Gateway{ + hostnameAddress := gatewayapiv1.AddressType("Hostname") + gateway := &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "my-ns", Name: "my-gw", @@ -1068,8 +1068,8 @@ func TestGetGatewayWorkloadSelector(t *testing.T) { "control-plane": "kuadrant", }, }, - Status: gatewayapiv1beta1.GatewayStatus{ - Addresses: []gatewayapiv1beta1.GatewayAddress{ + Status: gatewayapiv1.GatewayStatus{ + Addresses: []gatewayapiv1.GatewayStatusAddress{ { Type: &hostnameAddress, Value: "my-gw-svc.my-ns.svc.cluster.local:80", @@ -1095,7 +1095,7 @@ func TestGetGatewayWorkloadSelector(t *testing.T) { scheme := runtime.NewScheme() _ = corev1.AddToScheme(scheme) - _ = gatewayapiv1beta1.AddToScheme(scheme) + _ = gatewayapiv1.AddToScheme(scheme) k8sClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(gateway, service).Build() var selector map[string]string @@ -1108,7 +1108,7 @@ func TestGetGatewayWorkloadSelector(t *testing.T) { } func TestGetGatewayWorkloadSelectorWithoutHostnameAddress(t *testing.T) { - gateway := &gatewayapiv1beta1.Gateway{ + gateway := &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "my-ns", Name: "my-gw", @@ -1136,7 +1136,7 @@ func TestGetGatewayWorkloadSelectorWithoutHostnameAddress(t *testing.T) { scheme := runtime.NewScheme() _ = corev1.AddToScheme(scheme) - _ = gatewayapiv1beta1.AddToScheme(scheme) + _ = gatewayapiv1.AddToScheme(scheme) k8sClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(gateway, service).Build() var selector map[string]string @@ -1157,7 +1157,7 @@ func (p *FakePolicy) GetTargetRef() gatewayapiv1alpha2.PolicyTargetReference { return gatewayapiv1alpha2.PolicyTargetReference{} } -func (p *FakePolicy) GetWrappedNamespace() gatewayapiv1beta1.Namespace { +func (p *FakePolicy) GetWrappedNamespace() gatewayapiv1.Namespace { return "" } @@ -1166,13 +1166,13 @@ func (p *FakePolicy) GetRulesHostnames() []string { } func TestValidateHierarchicalRules(t *testing.T) { - hostname := gatewayapiv1beta1.Hostname("*.example.com") - gateway := &gatewayapiv1beta1.Gateway{ + hostname := gatewayapiv1.Hostname("*.example.com") + gateway := &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "cool-namespace", Name: "cool-gateway", }, - Spec: gatewayapiv1beta1.GatewaySpec{Listeners: []gatewayapiv1beta1.Listener{ + Spec: gatewayapiv1.GatewaySpec{Listeners: []gatewayapiv1.Listener{ { Hostname: &hostname, }, @@ -1202,7 +1202,7 @@ func TestValidateHierarchicalRules(t *testing.T) { func TestIsHTTPRouteAccepted(t *testing.T) { testCases := []struct { name string - route *gatewayapiv1beta1.HTTPRoute + route *gatewayapiv1.HTTPRoute expected bool }{ { @@ -1212,28 +1212,28 @@ func TestIsHTTPRouteAccepted(t *testing.T) { }, { "empty parent refs", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{}, + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{}, }, false, }, { "single parent accepted", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "a", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "a", }, Conditions: []metav1.Condition{ @@ -1251,21 +1251,21 @@ func TestIsHTTPRouteAccepted(t *testing.T) { }, { "single parent not accepted", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "a", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "a", }, Conditions: []metav1.Condition{ @@ -1283,21 +1283,21 @@ func TestIsHTTPRouteAccepted(t *testing.T) { }, { "wrong parent is accepted", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "a", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "b", }, Conditions: []metav1.Condition{ @@ -1315,10 +1315,10 @@ func TestIsHTTPRouteAccepted(t *testing.T) { }, { "multiple parents only one is accepted", - &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "a", }, @@ -1328,11 +1328,11 @@ func TestIsHTTPRouteAccepted(t *testing.T) { }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "a", }, Conditions: []metav1.Condition{ @@ -1343,7 +1343,7 @@ func TestIsHTTPRouteAccepted(t *testing.T) { }, }, { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "b", }, Conditions: []metav1.Condition{ diff --git a/pkg/common/istio_utils.go b/pkg/common/istio_utils.go index 6c69d89c0..d263f401d 100644 --- a/pkg/common/istio_utils.go +++ b/pkg/common/istio_utils.go @@ -6,10 +6,10 @@ import ( "github.com/go-logr/logr" istiocommon "istio.io/api/type/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) -func IstioWorkloadSelectorFromGateway(ctx context.Context, k8sClient client.Client, gateway *gatewayapiv1beta1.Gateway) *istiocommon.WorkloadSelector { +func IstioWorkloadSelectorFromGateway(ctx context.Context, k8sClient client.Client, gateway *gatewayapiv1.Gateway) *istiocommon.WorkloadSelector { logger, _ := logr.FromContext(ctx) gatewayWorkloadSelector, err := GetGatewayWorkloadSelector(ctx, k8sClient, gateway) if err != nil { diff --git a/pkg/common/istio_utils_test.go b/pkg/common/istio_utils_test.go index a35a8677c..a4261d0b4 100644 --- a/pkg/common/istio_utils_test.go +++ b/pkg/common/istio_utils_test.go @@ -12,14 +12,14 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/kuadrant/kuadrant-operator/pkg/log" ) func TestIstioWorkloadSelectorFromGateway(t *testing.T) { - hostnameAddress := gatewayapiv1beta1.AddressType("Hostname") - gateway := &gatewayapiv1beta1.Gateway{ + hostnameAddress := gatewayapiv1.AddressType("Hostname") + gateway := &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "my-ns", Name: "my-gw", @@ -28,8 +28,8 @@ func TestIstioWorkloadSelectorFromGateway(t *testing.T) { "control-plane": "kuadrant", }, }, - Status: gatewayapiv1beta1.GatewayStatus{ - Addresses: []gatewayapiv1beta1.GatewayAddress{ + Status: gatewayapiv1.GatewayStatus{ + Addresses: []gatewayapiv1.GatewayStatusAddress{ { Type: &hostnameAddress, Value: "my-gw-svc.my-ns.svc.cluster.local:80", @@ -55,7 +55,7 @@ func TestIstioWorkloadSelectorFromGateway(t *testing.T) { scheme := runtime.NewScheme() _ = corev1.AddToScheme(scheme) - _ = gatewayapiv1beta1.AddToScheme(scheme) + _ = gatewayapiv1.AddToScheme(scheme) k8sClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(gateway, service).Build() var selector *istiocommon.WorkloadSelector @@ -67,7 +67,7 @@ func TestIstioWorkloadSelectorFromGateway(t *testing.T) { } func TestIstioWorkloadSelectorFromGatewayMissingHostnameAddress(t *testing.T) { - gateway := &gatewayapiv1beta1.Gateway{ + gateway := &gatewayapiv1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "my-ns", Name: "my-gw", @@ -95,7 +95,7 @@ func TestIstioWorkloadSelectorFromGatewayMissingHostnameAddress(t *testing.T) { scheme := runtime.NewScheme() _ = corev1.AddToScheme(scheme) - _ = gatewayapiv1beta1.AddToScheme(scheme) + _ = gatewayapiv1.AddToScheme(scheme) k8sClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(gateway, service).Build() var selector *istiocommon.WorkloadSelector diff --git a/pkg/reconcilers/targetref_reconciler.go b/pkg/reconcilers/targetref_reconciler.go index 004371891..fd605c4ab 100644 --- a/pkg/reconcilers/targetref_reconciler.go +++ b/pkg/reconcilers/targetref_reconciler.go @@ -26,8 +26,8 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/kuadrant/kuadrant-operator/pkg/common" ) @@ -43,10 +43,10 @@ func (r *TargetRefReconciler) Reconcile(context.Context, ctrl.Request) (ctrl.Res return reconcile.Result{}, nil } -func (r *TargetRefReconciler) FetchValidGateway(ctx context.Context, key client.ObjectKey) (*gatewayapiv1beta1.Gateway, error) { +func (r *TargetRefReconciler) FetchValidGateway(ctx context.Context, key client.ObjectKey) (*gatewayapiv1.Gateway, error) { logger, _ := logr.FromContext(ctx) - gw := &gatewayapiv1beta1.Gateway{} + gw := &gatewayapiv1.Gateway{} err := r.Client().Get(ctx, key, gw) logger.V(1).Info("FetchValidGateway", "gateway", key, "err", err) if err != nil { @@ -60,10 +60,10 @@ func (r *TargetRefReconciler) FetchValidGateway(ctx context.Context, key client. return gw, nil } -func (r *TargetRefReconciler) FetchValidHTTPRoute(ctx context.Context, key client.ObjectKey) (*gatewayapiv1beta1.HTTPRoute, error) { +func (r *TargetRefReconciler) FetchValidHTTPRoute(ctx context.Context, key client.ObjectKey) (*gatewayapiv1.HTTPRoute, error) { logger, _ := logr.FromContext(ctx) - httpRoute := &gatewayapiv1beta1.HTTPRoute{} + httpRoute := &gatewayapiv1.HTTPRoute{} err := r.Client().Get(ctx, key, httpRoute) logger.V(1).Info("FetchValidHTTPRoute", "httpRoute", key, "err", err) if err != nil { @@ -96,11 +96,11 @@ func (r *TargetRefReconciler) FetchValidTargetRef(ctx context.Context, targetRef } // FetchAcceptedGatewayHTTPRoutes returns the list of HTTPRoutes that have been accepted as children of a gateway. -func (r *TargetRefReconciler) FetchAcceptedGatewayHTTPRoutes(ctx context.Context, gwKey client.ObjectKey) (routes []gatewayapiv1beta1.HTTPRoute) { +func (r *TargetRefReconciler) FetchAcceptedGatewayHTTPRoutes(ctx context.Context, gwKey client.ObjectKey) (routes []gatewayapiv1.HTTPRoute) { logger, _ := logr.FromContext(ctx) logger = logger.WithName("FetchAcceptedGatewayHTTPRoutes").WithValues("gateway", gwKey) - routeList := &gatewayapiv1beta1.HTTPRouteList{} + routeList := &gatewayapiv1.HTTPRouteList{} err := r.Client().List(ctx, routeList) if err != nil { logger.V(1).Info("failed to list httproutes", "err", err) @@ -109,7 +109,7 @@ func (r *TargetRefReconciler) FetchAcceptedGatewayHTTPRoutes(ctx context.Context for idx := range routeList.Items { route := routeList.Items[idx] - routeParentStatus, found := common.Find(route.Status.RouteStatus.Parents, func(p gatewayapiv1beta1.RouteParentStatus) bool { + routeParentStatus, found := common.Find(route.Status.RouteStatus.Parents, func(p gatewayapiv1.RouteParentStatus) bool { return *p.ParentRef.Kind == ("Gateway") && ((p.ParentRef.Namespace == nil && route.GetNamespace() == gwKey.Namespace) || string(*p.ParentRef.Namespace) == gwKey.Namespace) && string(p.ParentRef.Name) == gwKey.Name @@ -128,7 +128,7 @@ func (r *TargetRefReconciler) FetchAcceptedGatewayHTTPRoutes(ctx context.Context // TargetedGatewayKeys returns the list of gateways that are being referenced from the target. func (r *TargetRefReconciler) TargetedGatewayKeys(_ context.Context, targetNetworkObject client.Object) []client.ObjectKey { switch obj := targetNetworkObject.(type) { - case *gatewayapiv1beta1.HTTPRoute: + case *gatewayapiv1.HTTPRoute: gwKeys := make([]client.ObjectKey, 0) for _, parentRef := range obj.Spec.CommonRouteSpec.ParentRefs { gwKey := client.ObjectKey{Name: string(parentRef.Name), Namespace: obj.Namespace} @@ -139,7 +139,7 @@ func (r *TargetRefReconciler) TargetedGatewayKeys(_ context.Context, targetNetwo } return gwKeys - case *gatewayapiv1beta1.Gateway: + case *gatewayapiv1.Gateway: return []client.ObjectKey{client.ObjectKeyFromObject(targetNetworkObject)} // If the targetNetworkObject is nil, we don't fail; instead, we return an empty slice of gateway keys. @@ -207,7 +207,7 @@ func (r *TargetRefReconciler) GetAllGatewayPolicyRefs(ctx context.Context, polic var uniquePolicyRefs map[string]struct{} var policyRefs []client.ObjectKey - gwList := &gatewayapiv1beta1.GatewayList{} + gwList := &gatewayapiv1.GatewayList{} if err := r.Client().List(ctx, gwList); err != nil { return nil, err } @@ -249,7 +249,7 @@ func (r *TargetRefReconciler) ComputeGatewayDiffs(ctx context.Context, policy co } // TODO(rahulanand16nov): maybe think about optimizing it with a label later - allGwList := &gatewayapiv1beta1.GatewayList{} + allGwList := &gatewayapiv1.GatewayList{} err := r.Client().List(ctx, allGwList) if err != nil { return nil, err diff --git a/pkg/reconcilers/targetref_reconciler_test.go b/pkg/reconcilers/targetref_reconciler_test.go index 46cff300e..c39fce7d1 100644 --- a/pkg/reconcilers/targetref_reconciler_test.go +++ b/pkg/reconcilers/targetref_reconciler_test.go @@ -31,8 +31,8 @@ import ( "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/kuadrant/kuadrant-operator/pkg/log" ) @@ -50,24 +50,24 @@ func TestFetchValidGateway(t *testing.T) { if err != nil { t.Fatal(err) } - err = gatewayapiv1beta1.AddToScheme(s) + err = gatewayapiv1.AddToScheme(s) if err != nil { t.Fatal(err) } - existingGateway := &gatewayapiv1beta1.Gateway{ + existingGateway := &gatewayapiv1.Gateway{ TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1beta1", + APIVersion: gatewayapiv1.GroupName, Kind: "Gateway", }, ObjectMeta: metav1.ObjectMeta{ Name: gwName, Namespace: namespace, }, - Spec: gatewayapiv1beta1.GatewaySpec{ + Spec: gatewayapiv1.GatewaySpec{ GatewayClassName: "istio", }, - Status: gatewayapiv1beta1.GatewayStatus{ + Status: gatewayapiv1.GatewayStatus{ Conditions: []metav1.Condition{ { Type: "Ready", @@ -119,34 +119,34 @@ func TestFetchValidHTTPRoute(t *testing.T) { if err != nil { t.Fatal(err) } - err = gatewayapiv1beta1.AddToScheme(s) + err = gatewayapiv1.AddToScheme(s) if err != nil { t.Fatal(err) } - existingRoute := &gatewayapiv1beta1.HTTPRoute{ + existingRoute := &gatewayapiv1.HTTPRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1beta1", + APIVersion: gatewayapiv1.GroupName, Kind: "HTTPRoute", }, ObjectMeta: metav1.ObjectMeta{ Name: routeName, Namespace: namespace, }, - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "gwName", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "gwName", }, Conditions: []metav1.Condition{ @@ -203,40 +203,40 @@ func TestFetchValidTargetRef(t *testing.T) { if err != nil { t.Fatal(err) } - err = gatewayapiv1beta1.AddToScheme(s) + err = gatewayapiv1.AddToScheme(s) if err != nil { t.Fatal(err) } targetRef := gatewayapiv1alpha2.PolicyTargetReference{ - Group: "gateway.networking.k8s.io", + Group: gatewayapiv1.GroupName, Kind: "HTTPRoute", - Name: gatewayapiv1beta1.ObjectName(routeName), + Name: gatewayapiv1.ObjectName(routeName), } - existingRoute := &gatewayapiv1beta1.HTTPRoute{ + existingRoute := &gatewayapiv1.HTTPRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1beta1", + APIVersion: gatewayapiv1.GroupName, Kind: "HTTPRoute", }, ObjectMeta: metav1.ObjectMeta{ Name: routeName, Namespace: namespace, }, - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "gwName", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "gwName", }, Conditions: []metav1.Condition{ @@ -274,7 +274,7 @@ func TestFetchValidTargetRef(t *testing.T) { } switch obj := res.(type) { - case *gatewayapiv1beta1.HTTPRoute: + case *gatewayapiv1.HTTPRoute: if !reflect.DeepEqual(obj.Spec, existingRoute.Spec) { t.Fatal("res spec not as expected") } @@ -297,36 +297,36 @@ func TestReconcileTargetBackReference(t *testing.T) { if err != nil { t.Fatal(err) } - err = gatewayapiv1beta1.AddToScheme(s) + err = gatewayapiv1.AddToScheme(s) if err != nil { t.Fatal(err) } policyKey := client.ObjectKey{Name: "someName", Namespace: "someNamespace"} - existingRoute := &gatewayapiv1beta1.HTTPRoute{ + existingRoute := &gatewayapiv1.HTTPRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1beta1", + APIVersion: gatewayapiv1.GroupName, Kind: "HTTPRoute", }, ObjectMeta: metav1.ObjectMeta{ Name: routeName, Namespace: namespace, }, - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "gwName", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "gwName", }, Conditions: []metav1.Condition{ @@ -359,7 +359,7 @@ func TestReconcileTargetBackReference(t *testing.T) { t.Fatal(err) } - res := &gatewayapiv1beta1.HTTPRoute{} + res := &gatewayapiv1.HTTPRoute{} err = cl.Get(ctx, client.ObjectKey{Name: routeName, Namespace: namespace}, res) if err != nil { t.Fatal(err) @@ -396,34 +396,34 @@ func TestTargetedGatewayKeys(t *testing.T) { if err != nil { t.Fatal(err) } - err = gatewayapiv1beta1.AddToScheme(s) + err = gatewayapiv1.AddToScheme(s) if err != nil { t.Fatal(err) } - existingRoute := &gatewayapiv1beta1.HTTPRoute{ + existingRoute := &gatewayapiv1.HTTPRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1beta1", + APIVersion: gatewayapiv1.GroupName, Kind: "HTTPRoute", }, ObjectMeta: metav1.ObjectMeta{ Name: routeName, Namespace: namespace, }, - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "gwName", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "gwName", }, Conditions: []metav1.Condition{ @@ -478,14 +478,14 @@ func TestDeleteTargetBackReference(t *testing.T) { if err != nil { t.Fatal(err) } - err = gatewayapiv1beta1.AddToScheme(s) + err = gatewayapiv1.AddToScheme(s) if err != nil { t.Fatal(err) } - existingRoute := &gatewayapiv1beta1.HTTPRoute{ + existingRoute := &gatewayapiv1.HTTPRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1beta1", + APIVersion: gatewayapiv1.GroupName, Kind: "HTTPRoute", }, ObjectMeta: metav1.ObjectMeta{ @@ -495,20 +495,20 @@ func TestDeleteTargetBackReference(t *testing.T) { annotationName: "annotationValue", }, }, - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1beta1.ParentReference{ + Spec: gatewayapiv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ + ParentRefs: []gatewayapiv1.ParentReference{ { Name: "gwName", }, }, }, }, - Status: gatewayapiv1beta1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1beta1.RouteStatus{ - Parents: []gatewayapiv1beta1.RouteParentStatus{ + Status: gatewayapiv1.HTTPRouteStatus{ + RouteStatus: gatewayapiv1.RouteStatus{ + Parents: []gatewayapiv1.RouteParentStatus{ { - ParentRef: gatewayapiv1beta1.ParentReference{ + ParentRef: gatewayapiv1.ParentReference{ Name: "gwName", }, Conditions: []metav1.Condition{ @@ -541,7 +541,7 @@ func TestDeleteTargetBackReference(t *testing.T) { t.Fatal(err) } - res := &gatewayapiv1beta1.HTTPRoute{} + res := &gatewayapiv1.HTTPRoute{} err = cl.Get(ctx, client.ObjectKey{Name: routeName, Namespace: namespace}, res) if err != nil { t.Fatal(err) diff --git a/pkg/rlptools/wasm/types.go b/pkg/rlptools/wasm/types.go index 98f184895..52deee790 100644 --- a/pkg/rlptools/wasm/types.go +++ b/pkg/rlptools/wasm/types.go @@ -4,16 +4,16 @@ import ( "encoding/json" _struct "google.golang.org/protobuf/types/known/structpb" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" ) var ( - PathMatchTypeMap = map[gatewayapiv1beta1.PathMatchType]PatternOperator{ - gatewayapiv1beta1.PathMatchExact: PatternOperator(kuadrantv1beta2.EqualOperator), - gatewayapiv1beta1.PathMatchPathPrefix: PatternOperator(kuadrantv1beta2.StartsWithOperator), - gatewayapiv1beta1.PathMatchRegularExpression: PatternOperator(kuadrantv1beta2.MatchesOperator), + PathMatchTypeMap = map[gatewayapiv1.PathMatchType]PatternOperator{ + gatewayapiv1.PathMatchExact: PatternOperator(kuadrantv1beta2.EqualOperator), + gatewayapiv1.PathMatchPathPrefix: PatternOperator(kuadrantv1beta2.StartsWithOperator), + gatewayapiv1.PathMatchRegularExpression: PatternOperator(kuadrantv1beta2.MatchesOperator), } ) diff --git a/pkg/rlptools/wasm_utils.go b/pkg/rlptools/wasm_utils.go index ea3c5e59d..0072985da 100644 --- a/pkg/rlptools/wasm_utils.go +++ b/pkg/rlptools/wasm_utils.go @@ -11,7 +11,7 @@ import ( istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" "k8s.io/utils/env" "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/rlptools/wasm" @@ -24,7 +24,7 @@ var ( // WasmRules computes WASM rules from the policy and the targeted route. // It returns an empty list of wasm rules if the policy specifies no limits or if all limits specified in the policy // fail to match any route rule according to the limits route selectors. -func WasmRules(rlp *kuadrantv1beta2.RateLimitPolicy, route *gatewayapiv1beta1.HTTPRoute) []wasm.Rule { +func WasmRules(rlp *kuadrantv1beta2.RateLimitPolicy, route *gatewayapiv1.HTTPRoute) []wasm.Rule { rules := make([]wasm.Rule, 0) if rlp == nil { return rules @@ -43,7 +43,7 @@ func WasmRules(rlp *kuadrantv1beta2.RateLimitPolicy, route *gatewayapiv1beta1.HT return rules } -func ruleFromLimit(limitIdentifier string, limit *kuadrantv1beta2.Limit, route *gatewayapiv1beta1.HTTPRoute) (wasm.Rule, error) { +func ruleFromLimit(limitIdentifier string, limit *kuadrantv1beta2.Limit, route *gatewayapiv1.HTTPRoute) (wasm.Rule, error) { rule := wasm.Rule{} conditions, err := conditionsFromLimit(limit, route) @@ -60,7 +60,7 @@ func ruleFromLimit(limitIdentifier string, limit *kuadrantv1beta2.Limit, route * return rule, nil } -func conditionsFromLimit(limit *kuadrantv1beta2.Limit, route *gatewayapiv1beta1.HTTPRoute) ([]wasm.Condition, error) { +func conditionsFromLimit(limit *kuadrantv1beta2.Limit, route *gatewayapiv1.HTTPRoute) ([]wasm.Condition, error) { if limit == nil { return nil, errors.New("limit should not be nil") } @@ -119,7 +119,7 @@ func conditionsFromLimit(limit *kuadrantv1beta2.Limit, route *gatewayapiv1beta1. // each combination of a rule match and hostname yields one condition // rules that specify no explicit match are assumed to match all request (i.e. implicit catch-all rule) // empty list of hostnames yields a condition without a hostname pattern expression -func conditionsFromRule(rule gatewayapiv1beta1.HTTPRouteRule, hostnames []gatewayapiv1beta1.Hostname) (conditions []wasm.Condition) { +func conditionsFromRule(rule gatewayapiv1.HTTPRouteRule, hostnames []gatewayapiv1.Hostname) (conditions []wasm.Condition) { if len(rule.Matches) == 0 { for _, hostname := range hostnames { if hostname == "*" { @@ -152,7 +152,7 @@ func conditionsFromRule(rule gatewayapiv1beta1.HTTPRouteRule, hostnames []gatewa return } -func patternExpresionsFromMatch(match gatewayapiv1beta1.HTTPRouteMatch) []wasm.PatternExpression { +func patternExpresionsFromMatch(match gatewayapiv1.HTTPRouteMatch) []wasm.PatternExpression { expressions := make([]wasm.PatternExpression, 0) if match.Path != nil { @@ -168,7 +168,7 @@ func patternExpresionsFromMatch(match gatewayapiv1beta1.HTTPRouteMatch) []wasm.P return expressions } -func patternExpresionFromPathMatch(pathMatch gatewayapiv1beta1.HTTPPathMatch) wasm.PatternExpression { +func patternExpresionFromPathMatch(pathMatch gatewayapiv1.HTTPPathMatch) wasm.PatternExpression { var ( operator = wasm.PatternOperator(kuadrantv1beta2.StartsWithOperator) // default value value = "/" // default value @@ -191,7 +191,7 @@ func patternExpresionFromPathMatch(pathMatch gatewayapiv1beta1.HTTPPathMatch) wa } } -func patternExpresionFromMethod(method gatewayapiv1beta1.HTTPMethod) wasm.PatternExpression { +func patternExpresionFromMethod(method gatewayapiv1.HTTPMethod) wasm.PatternExpression { return wasm.PatternExpression{ Selector: "request.method", Operator: wasm.PatternOperator(kuadrantv1beta2.EqualOperator), @@ -199,7 +199,7 @@ func patternExpresionFromMethod(method gatewayapiv1beta1.HTTPMethod) wasm.Patter } } -func patternExpresionFromHostname(hostname gatewayapiv1beta1.Hostname) wasm.PatternExpression { +func patternExpresionFromHostname(hostname gatewayapiv1.Hostname) wasm.PatternExpression { value := string(hostname) operator := "eq" if strings.HasPrefix(value, "*.") { diff --git a/pkg/rlptools/wasm_utils_test.go b/pkg/rlptools/wasm_utils_test.go index 89e6a5fbe..ad728fa90 100644 --- a/pkg/rlptools/wasm_utils_test.go +++ b/pkg/rlptools/wasm_utils_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" "github.com/kuadrant/kuadrant-operator/pkg/rlptools/wasm" @@ -16,21 +16,21 @@ import ( // TODO(eastizle): missing WASMPluginMutator tests // TODO(eastizle): missing TestWasmRules use cases tests. Only happy path func TestWasmRules(t *testing.T) { - httpRoute := &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Hostnames: []gatewayapiv1beta1.Hostname{ + httpRoute := &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Hostnames: []gatewayapiv1.Hostname{ "*.example.com", "*.apps.example.internal", }, - Rules: []gatewayapiv1beta1.HTTPRouteRule{ + Rules: []gatewayapiv1.HTTPRouteRule{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, - Method: &[]gatewayapiv1beta1.HTTPMethod{"GET"}[0], + Method: &[]gatewayapiv1.HTTPMethod{"GET"}[0], }, }, }, @@ -38,9 +38,9 @@ func TestWasmRules(t *testing.T) { }, } - catchAllHTTPRoute := &gatewayapiv1beta1.HTTPRoute{ - Spec: gatewayapiv1beta1.HTTPRouteSpec{ - Hostnames: []gatewayapiv1beta1.Hostname{"*"}, + catchAllHTTPRoute := &gatewayapiv1.HTTPRoute{ + Spec: gatewayapiv1.HTTPRouteSpec{ + Hostnames: []gatewayapiv1.Hostname{"*"}, }, } @@ -66,7 +66,7 @@ func TestWasmRules(t *testing.T) { testCases := []struct { name string rlp *kuadrantv1beta2.RateLimitPolicy - route *gatewayapiv1beta1.HTTPRoute + route *gatewayapiv1.HTTPRoute expectedRules []wasm.Rule }{ { @@ -113,7 +113,7 @@ func TestWasmRules(t *testing.T) { Rates: []kuadrantv1beta2.Rate{counter50rps}, RouteSelectors: []kuadrantv1beta2.RouteSelector{ { - Hostnames: []gatewayapiv1beta1.Hostname{ + Hostnames: []gatewayapiv1.Hostname{ "*.example.com", "myapp.apps.example.com", // ignored }, @@ -163,13 +163,13 @@ func TestWasmRules(t *testing.T) { Rates: []kuadrantv1beta2.Rate{counter50rps}, RouteSelectors: []kuadrantv1beta2.RouteSelector{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, - Method: &[]gatewayapiv1beta1.HTTPMethod{"GET"}[0], + Method: &[]gatewayapiv1.HTTPMethod{"GET"}[0], }, }, }, @@ -213,10 +213,10 @@ func TestWasmRules(t *testing.T) { Rates: []kuadrantv1beta2.Rate{counter50rps}, RouteSelectors: []kuadrantv1beta2.RouteSelector{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Path: &gatewayapiv1beta1.HTTPPathMatch{ - Type: &[]gatewayapiv1beta1.PathMatchType{gatewayapiv1beta1.PathMatchPathPrefix}[0], + Path: &gatewayapiv1.HTTPPathMatch{ + Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], Value: &[]string{"/toy"}[0], }, }, @@ -262,9 +262,9 @@ func TestWasmRules(t *testing.T) { Rates: []kuadrantv1beta2.Rate{counter50rps}, RouteSelectors: []kuadrantv1beta2.RouteSelector{ { - Matches: []gatewayapiv1beta1.HTTPRouteMatch{ + Matches: []gatewayapiv1.HTTPRouteMatch{ { - Method: &[]gatewayapiv1beta1.HTTPMethod{"POST"}[0], + Method: &[]gatewayapiv1.HTTPMethod{"POST"}[0], }, }, },