From 9c2bc19af62328c649ab55e83526a0385a689dd7 Mon Sep 17 00:00:00 2001 From: Travis Raines Date: Wed, 15 Dec 2021 11:02:08 -0800 Subject: [PATCH] feat(crd) migrate to Kubebuilder (#1971) * Add dedicated types for KongIngress subsections Add new KongIngressUpstream, KongIngressService, and KongIngressRoute types for the KongIngress subsections, rather than using the go-kong types directly. These allow for kubebuilder validation without much annotation of go-kong types, and avoid unwanted fields (ID, name, etc.) that aren't actually exposed by KongIngress. * Enable all-Kubebuilder CRD generation CRD manifests are now entirely generated using stock Kubebuilder tools and type annotations. * Remove unnecessary meta fields from ConfigSource types The ConfigSource types used in KongPlugin/KongClusterPlugin were previously full Kubernetes objects, with associated metadata. These resources are not actually Kubernetes objects (they are never created independent of plugins) and should not have included this metadata. * Add upgrade test Add a new E2E test that performs an upgrade from the previous minor version's latest patch, and ensures that routes work as expected both before and after the upgrade. --- CHANGELOG.md | 14 + Makefile | 7 +- ...uration.konghq.com_kongclusterplugins.yaml | 18 +- ...onfiguration.konghq.com_kongconsumers.yaml | 18 +- ...onfiguration.konghq.com_kongingresses.yaml | 47 ++- .../configuration.konghq.com_kongplugins.yaml | 21 +- ...configuration.konghq.com_tcpingresses.yaml | 3 +- ...configuration.konghq.com_udpingresses.yaml | 3 +- .../all-in-one-dbless-k4k8s-enterprise.yaml | 96 ++++-- deploy/single/all-in-one-dbless.yaml | 96 ++++-- .../all-in-one-postgres-enterprise.yaml | 96 ++++-- deploy/single/all-in-one-postgres.yaml | 96 ++++-- go.mod | 2 +- go.sum | 9 +- hack/generators/manifests/main.go | 168 --------- internal/admission/validator.go | 2 +- internal/kongstate/route.go | 4 +- internal/kongstate/route_test.go | 32 +- internal/kongstate/service_test.go | 26 +- internal/kongstate/upstream.go | 39 ++- internal/kongstate/upstream_test.go | 3 +- internal/kongstate/util.go | 17 +- internal/kongstate/util_test.go | 20 +- internal/parser/parser_test.go | 323 ++++++++++-------- internal/parser/translate.go | 70 ++-- internal/parser/translate_test.go | 32 +- internal/store/store.go | 2 - pkg/apis/configuration/v1/configsource.go | 24 +- .../v1/kongclusterplugin_types.go | 3 +- .../configuration/v1/kongingress_types.go | 59 +++- pkg/apis/configuration/v1/kongplugin_types.go | 3 +- .../configuration/v1/kongprotocol_types.go | 33 ++ .../configuration/v1/zz_generated.deepcopy.go | 254 +++++++++++--- test/e2e/all_in_one_test.go | 153 ++++++++- test/integration/knative_test.go | 1 - test/integration/kongingress_test.go | 2 +- 36 files changed, 1199 insertions(+), 597 deletions(-) delete mode 100644 hack/generators/manifests/main.go create mode 100644 pkg/apis/configuration/v1/kongprotocol_types.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 616731aea3..dac8e9fcdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,20 @@ you should edit it (`kubectl edit validatingwebhookconfiguration kong-validations`) and add `kongclusterplugins` under the `resources` block for the `configuration.konghq.com` API group. +#### Breaking changes + +- You must upgrade to 2.0.x before upgrading to 2.1.x to properly handle the + transition from apiextensions.k8s.io/v1beta1 CRDs to apiextensions.k8s.io/v1 + CRDSs. CRDs are now generated from their underlying Go structures to avoid + accidental mismatches between implementation and Kubernetes configuration. + KongIngresses previously included `healthchecks.passive.unhealthy.timeout` + and `healthchecks.active.unhealthy.timeout` fields that did not match the + corresponding Kong configuration and had no effect. These are now + `healthchecks.passive.unhealthy.timeouts` and + `healthchecks.active.unhealthy.timeouts`, respectively. If you use these + fields, you must rename them in your KongIngresses before upgrading. + [#1971](https://github.com/Kong/kubernetes-ingress-controller/pull/1971) + #### Added - Added validation for `Gateway` objects in the admission webhook diff --git a/Makefile b/Makefile index 5ed4e7dcdc..9a5617b32e 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ export GO111MODULE=on CONTROLLER_GEN = $(shell pwd)/bin/controller-gen controller-gen: ## Download controller-gen locally if necessary. - $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.6.2) + $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0) KUSTOMIZE = $(shell pwd)/bin/kustomize kustomize: ## Download kustomize locally if necessary. @@ -52,7 +52,7 @@ endef # Build # ------------------------------------------------------------------------------ -CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false,allowDangerousTypes=true" +CRD_OPTIONS ?= "+crd:allowDangerousTypes=true" # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) GOBIN=$(shell go env GOPATH)/bin @@ -119,8 +119,7 @@ manifests: manifests.crds manifests.single .PHONY: manifests.crds manifests.crds: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=kong-ingress webhook paths="./..." output:crd:artifacts:config=build/config/crd/bases - go run hack/generators/manifests/main.go --input-directory build/config/crd/bases/ --output-directory config/crd/bases + $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=kong-ingress webhook paths="./..." output:crd:artifacts:config=config/crd/bases .PHONY: manifests.single manifests.single: kustomize ## Compose single-file deployment manifests from building blocks diff --git a/config/crd/bases/configuration.konghq.com_kongclusterplugins.yaml b/config/crd/bases/configuration.konghq.com_kongclusterplugins.yaml index f197b5bcc5..ff88a536f3 100644 --- a/config/crd/bases/configuration.konghq.com_kongclusterplugins.yaml +++ b/config/crd/bases/configuration.konghq.com_kongclusterplugins.yaml @@ -1,6 +1,11 @@ + +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongclusterplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -11,7 +16,6 @@ spec: shortNames: - kcp singular: kongclusterplugin - preserveUnknownFields: false scope: Cluster versions: - additionalPrinterColumns: @@ -38,6 +42,11 @@ spec: openAPIV3Schema: description: KongClusterPlugin is the Schema for the kongclusterplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -70,6 +79,13 @@ spec: disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config diff --git a/config/crd/bases/configuration.konghq.com_kongconsumers.yaml b/config/crd/bases/configuration.konghq.com_kongconsumers.yaml index 1626375374..cc516ffeb4 100644 --- a/config/crd/bases/configuration.konghq.com_kongconsumers.yaml +++ b/config/crd/bases/configuration.konghq.com_kongconsumers.yaml @@ -1,6 +1,11 @@ + +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongconsumers.configuration.konghq.com spec: group: configuration.konghq.com @@ -11,7 +16,6 @@ spec: shortNames: - kc singular: kongconsumer - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -28,6 +32,11 @@ spec: openAPIV3Schema: description: KongConsumer is the Schema for the kongconsumers API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string credentials: description: Credentials are references to secrets containing a credential to be provisioned in Kong. @@ -38,6 +47,13 @@ spec: description: CustomID existing unique ID for the consumer - useful for mapping Kong with users in your existing database type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object username: description: Username unique username of the consumer. type: string diff --git a/config/crd/bases/configuration.konghq.com_kongingresses.yaml b/config/crd/bases/configuration.konghq.com_kongingresses.yaml index e4914b95a8..72d1d56805 100644 --- a/config/crd/bases/configuration.konghq.com_kongingresses.yaml +++ b/config/crd/bases/configuration.konghq.com_kongingresses.yaml @@ -1,6 +1,11 @@ + +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongingresses.configuration.konghq.com spec: group: configuration.konghq.com @@ -11,7 +16,6 @@ spec: shortNames: - ki singular: kongingress - preserveUnknownFields: false scope: Namespaced versions: - name: v1 @@ -19,14 +23,27 @@ spec: openAPIV3Schema: description: KongIngress is the Schema for the kongingresses API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object proxy: + description: KongIngressService contains KongIngress service configuration properties: - path: - type: string - pattern: ^/.*$ connect_timeout: minimum: 0 type: integer + path: + pattern: ^/.*$ + type: string protocol: enum: - http @@ -48,7 +65,7 @@ spec: type: integer type: object route: - description: Route represents a Route in Kong. Read https://getkong.org/docs/0.13.x/admin-api/#Route-object + description: KongIngressRoute contains KongIngress route configuration properties: headers: additionalProperties: @@ -84,12 +101,6 @@ spec: regex_priority: type: integer request_buffering: - description: "Kong buffers requests and responses by default. Buffering - is not always desired, for instance if large payloads are being - proxied using HTTP 1.1 chunked encoding. \n The request and response - route buffering options are enabled by default and allow the user - to disable buffering if desired for their use case. \n SEE ALSO: - - https://github.com/Kong/kong/pull/6057 - https://docs.konghq.com/2.2.x/admin-api/#route-object" type: boolean response_buffering: type: boolean @@ -101,7 +112,7 @@ spec: type: boolean type: object upstream: - description: Upstream represents an Upstream in Kong. + description: KongIngressUpstream contains KongIngress upstream configuration properties: algorithm: enum: @@ -150,6 +161,10 @@ spec: http_path: pattern: ^/.*$ type: string + https_sni: + type: string + https_verify_certificate: + type: boolean timeout: minimum: 0 type: integer @@ -172,7 +187,7 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object @@ -196,6 +211,8 @@ spec: minimum: 0 type: integer type: object + type: + type: string unhealthy: description: Unhealthy configures thresholds and HTTP status codes to mark targets unhealthy. @@ -213,13 +230,13 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object type: object threshold: - type: integer + type: number type: object host_header: type: string diff --git a/config/crd/bases/configuration.konghq.com_kongplugins.yaml b/config/crd/bases/configuration.konghq.com_kongplugins.yaml index d4aac76035..763f39b12b 100644 --- a/config/crd/bases/configuration.konghq.com_kongplugins.yaml +++ b/config/crd/bases/configuration.konghq.com_kongplugins.yaml @@ -1,6 +1,11 @@ + +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -11,7 +16,6 @@ spec: shortNames: - kp singular: kongplugin - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -38,6 +42,11 @@ spec: openAPIV3Schema: description: KongPlugin is the Schema for the kongplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -60,9 +69,19 @@ spec: - name type: object type: object + consumerRef: + description: ConsumerRef is a reference to a particular consumer + type: string disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config diff --git a/config/crd/bases/configuration.konghq.com_tcpingresses.yaml b/config/crd/bases/configuration.konghq.com_tcpingresses.yaml index 357c098b95..9e275b5c79 100644 --- a/config/crd/bases/configuration.konghq.com_tcpingresses.yaml +++ b/config/crd/bases/configuration.konghq.com_tcpingresses.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: tcpingresses.configuration.konghq.com spec: @@ -14,7 +14,6 @@ spec: listKind: TCPIngressList plural: tcpingresses singular: tcpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: diff --git a/config/crd/bases/configuration.konghq.com_udpingresses.yaml b/config/crd/bases/configuration.konghq.com_udpingresses.yaml index 33a41d73e2..10f7006bd9 100644 --- a/config/crd/bases/configuration.konghq.com_udpingresses.yaml +++ b/config/crd/bases/configuration.konghq.com_udpingresses.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: udpingresses.configuration.konghq.com spec: @@ -14,7 +14,6 @@ spec: listKind: UDPIngressList plural: udpingresses singular: udpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: diff --git a/deploy/single/all-in-one-dbless-k4k8s-enterprise.yaml b/deploy/single/all-in-one-dbless-k4k8s-enterprise.yaml index d4fc0365b0..0f7f988e9e 100644 --- a/deploy/single/all-in-one-dbless-k4k8s-enterprise.yaml +++ b/deploy/single/all-in-one-dbless-k4k8s-enterprise.yaml @@ -6,6 +6,9 @@ metadata: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongclusterplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -16,7 +19,6 @@ spec: shortNames: - kcp singular: kongclusterplugin - preserveUnknownFields: false scope: Cluster versions: - additionalPrinterColumns: @@ -43,6 +45,11 @@ spec: openAPIV3Schema: description: KongClusterPlugin is the Schema for the kongclusterplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -75,6 +82,13 @@ spec: disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -118,6 +132,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongconsumers.configuration.konghq.com spec: group: configuration.konghq.com @@ -128,7 +145,6 @@ spec: shortNames: - kc singular: kongconsumer - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -145,6 +161,11 @@ spec: openAPIV3Schema: description: KongConsumer is the Schema for the kongconsumers API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string credentials: description: Credentials are references to secrets containing a credential to be provisioned in Kong. @@ -155,6 +176,13 @@ spec: description: CustomID existing unique ID for the consumer - useful for mapping Kong with users in your existing database type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object username: description: Username unique username of the consumer. type: string @@ -173,6 +201,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongingresses.configuration.konghq.com spec: group: configuration.konghq.com @@ -183,7 +214,6 @@ spec: shortNames: - ki singular: kongingress - preserveUnknownFields: false scope: Namespaced versions: - name: v1 @@ -191,7 +221,20 @@ spec: openAPIV3Schema: description: KongIngress is the Schema for the kongingresses API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object proxy: + description: KongIngressService contains KongIngress service configuration properties: connect_timeout: minimum: 0 @@ -220,7 +263,7 @@ spec: type: integer type: object route: - description: Route represents a Route in Kong. Read https://getkong.org/docs/0.13.x/admin-api/#Route-object + description: KongIngressRoute contains KongIngress route configuration properties: headers: additionalProperties: @@ -256,12 +299,6 @@ spec: regex_priority: type: integer request_buffering: - description: "Kong buffers requests and responses by default. Buffering - is not always desired, for instance if large payloads are being - proxied using HTTP 1.1 chunked encoding. \n The request and response - route buffering options are enabled by default and allow the user - to disable buffering if desired for their use case. \n SEE ALSO: - - https://github.com/Kong/kong/pull/6057 - https://docs.konghq.com/2.2.x/admin-api/#route-object" type: boolean response_buffering: type: boolean @@ -273,7 +310,7 @@ spec: type: boolean type: object upstream: - description: Upstream represents an Upstream in Kong. + description: KongIngressUpstream contains KongIngress upstream configuration properties: algorithm: enum: @@ -322,6 +359,10 @@ spec: http_path: pattern: ^/.*$ type: string + https_sni: + type: string + https_verify_certificate: + type: boolean timeout: minimum: 0 type: integer @@ -344,7 +385,7 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object @@ -368,6 +409,8 @@ spec: minimum: 0 type: integer type: object + type: + type: string unhealthy: description: Unhealthy configures thresholds and HTTP status codes to mark targets unhealthy. @@ -385,13 +428,13 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object type: object threshold: - type: integer + type: number type: object host_header: type: string @@ -414,6 +457,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -424,7 +470,6 @@ spec: shortNames: - kp singular: kongplugin - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -451,6 +496,11 @@ spec: openAPIV3Schema: description: KongPlugin is the Schema for the kongplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -473,9 +523,19 @@ spec: - name type: object type: object + consumerRef: + description: ConsumerRef is a reference to a particular consumer + type: string disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -520,7 +580,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: tcpingresses.configuration.konghq.com spec: @@ -530,7 +590,6 @@ spec: listKind: TCPIngressList plural: tcpingresses singular: tcpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -707,7 +766,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: udpingresses.configuration.konghq.com spec: @@ -717,7 +776,6 @@ spec: listKind: UDPIngressList plural: udpingresses singular: udpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: diff --git a/deploy/single/all-in-one-dbless.yaml b/deploy/single/all-in-one-dbless.yaml index b0dfbec077..27b8d66256 100644 --- a/deploy/single/all-in-one-dbless.yaml +++ b/deploy/single/all-in-one-dbless.yaml @@ -6,6 +6,9 @@ metadata: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongclusterplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -16,7 +19,6 @@ spec: shortNames: - kcp singular: kongclusterplugin - preserveUnknownFields: false scope: Cluster versions: - additionalPrinterColumns: @@ -43,6 +45,11 @@ spec: openAPIV3Schema: description: KongClusterPlugin is the Schema for the kongclusterplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -75,6 +82,13 @@ spec: disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -118,6 +132,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongconsumers.configuration.konghq.com spec: group: configuration.konghq.com @@ -128,7 +145,6 @@ spec: shortNames: - kc singular: kongconsumer - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -145,6 +161,11 @@ spec: openAPIV3Schema: description: KongConsumer is the Schema for the kongconsumers API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string credentials: description: Credentials are references to secrets containing a credential to be provisioned in Kong. @@ -155,6 +176,13 @@ spec: description: CustomID existing unique ID for the consumer - useful for mapping Kong with users in your existing database type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object username: description: Username unique username of the consumer. type: string @@ -173,6 +201,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongingresses.configuration.konghq.com spec: group: configuration.konghq.com @@ -183,7 +214,6 @@ spec: shortNames: - ki singular: kongingress - preserveUnknownFields: false scope: Namespaced versions: - name: v1 @@ -191,7 +221,20 @@ spec: openAPIV3Schema: description: KongIngress is the Schema for the kongingresses API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object proxy: + description: KongIngressService contains KongIngress service configuration properties: connect_timeout: minimum: 0 @@ -220,7 +263,7 @@ spec: type: integer type: object route: - description: Route represents a Route in Kong. Read https://getkong.org/docs/0.13.x/admin-api/#Route-object + description: KongIngressRoute contains KongIngress route configuration properties: headers: additionalProperties: @@ -256,12 +299,6 @@ spec: regex_priority: type: integer request_buffering: - description: "Kong buffers requests and responses by default. Buffering - is not always desired, for instance if large payloads are being - proxied using HTTP 1.1 chunked encoding. \n The request and response - route buffering options are enabled by default and allow the user - to disable buffering if desired for their use case. \n SEE ALSO: - - https://github.com/Kong/kong/pull/6057 - https://docs.konghq.com/2.2.x/admin-api/#route-object" type: boolean response_buffering: type: boolean @@ -273,7 +310,7 @@ spec: type: boolean type: object upstream: - description: Upstream represents an Upstream in Kong. + description: KongIngressUpstream contains KongIngress upstream configuration properties: algorithm: enum: @@ -322,6 +359,10 @@ spec: http_path: pattern: ^/.*$ type: string + https_sni: + type: string + https_verify_certificate: + type: boolean timeout: minimum: 0 type: integer @@ -344,7 +385,7 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object @@ -368,6 +409,8 @@ spec: minimum: 0 type: integer type: object + type: + type: string unhealthy: description: Unhealthy configures thresholds and HTTP status codes to mark targets unhealthy. @@ -385,13 +428,13 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object type: object threshold: - type: integer + type: number type: object host_header: type: string @@ -414,6 +457,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -424,7 +470,6 @@ spec: shortNames: - kp singular: kongplugin - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -451,6 +496,11 @@ spec: openAPIV3Schema: description: KongPlugin is the Schema for the kongplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -473,9 +523,19 @@ spec: - name type: object type: object + consumerRef: + description: ConsumerRef is a reference to a particular consumer + type: string disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -520,7 +580,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: tcpingresses.configuration.konghq.com spec: @@ -530,7 +590,6 @@ spec: listKind: TCPIngressList plural: tcpingresses singular: tcpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -707,7 +766,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: udpingresses.configuration.konghq.com spec: @@ -717,7 +776,6 @@ spec: listKind: UDPIngressList plural: udpingresses singular: udpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: diff --git a/deploy/single/all-in-one-postgres-enterprise.yaml b/deploy/single/all-in-one-postgres-enterprise.yaml index 9643fc5998..e0be0adcad 100644 --- a/deploy/single/all-in-one-postgres-enterprise.yaml +++ b/deploy/single/all-in-one-postgres-enterprise.yaml @@ -6,6 +6,9 @@ metadata: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongclusterplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -16,7 +19,6 @@ spec: shortNames: - kcp singular: kongclusterplugin - preserveUnknownFields: false scope: Cluster versions: - additionalPrinterColumns: @@ -43,6 +45,11 @@ spec: openAPIV3Schema: description: KongClusterPlugin is the Schema for the kongclusterplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -75,6 +82,13 @@ spec: disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -118,6 +132,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongconsumers.configuration.konghq.com spec: group: configuration.konghq.com @@ -128,7 +145,6 @@ spec: shortNames: - kc singular: kongconsumer - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -145,6 +161,11 @@ spec: openAPIV3Schema: description: KongConsumer is the Schema for the kongconsumers API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string credentials: description: Credentials are references to secrets containing a credential to be provisioned in Kong. @@ -155,6 +176,13 @@ spec: description: CustomID existing unique ID for the consumer - useful for mapping Kong with users in your existing database type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object username: description: Username unique username of the consumer. type: string @@ -173,6 +201,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongingresses.configuration.konghq.com spec: group: configuration.konghq.com @@ -183,7 +214,6 @@ spec: shortNames: - ki singular: kongingress - preserveUnknownFields: false scope: Namespaced versions: - name: v1 @@ -191,7 +221,20 @@ spec: openAPIV3Schema: description: KongIngress is the Schema for the kongingresses API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object proxy: + description: KongIngressService contains KongIngress service configuration properties: connect_timeout: minimum: 0 @@ -220,7 +263,7 @@ spec: type: integer type: object route: - description: Route represents a Route in Kong. Read https://getkong.org/docs/0.13.x/admin-api/#Route-object + description: KongIngressRoute contains KongIngress route configuration properties: headers: additionalProperties: @@ -256,12 +299,6 @@ spec: regex_priority: type: integer request_buffering: - description: "Kong buffers requests and responses by default. Buffering - is not always desired, for instance if large payloads are being - proxied using HTTP 1.1 chunked encoding. \n The request and response - route buffering options are enabled by default and allow the user - to disable buffering if desired for their use case. \n SEE ALSO: - - https://github.com/Kong/kong/pull/6057 - https://docs.konghq.com/2.2.x/admin-api/#route-object" type: boolean response_buffering: type: boolean @@ -273,7 +310,7 @@ spec: type: boolean type: object upstream: - description: Upstream represents an Upstream in Kong. + description: KongIngressUpstream contains KongIngress upstream configuration properties: algorithm: enum: @@ -322,6 +359,10 @@ spec: http_path: pattern: ^/.*$ type: string + https_sni: + type: string + https_verify_certificate: + type: boolean timeout: minimum: 0 type: integer @@ -344,7 +385,7 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object @@ -368,6 +409,8 @@ spec: minimum: 0 type: integer type: object + type: + type: string unhealthy: description: Unhealthy configures thresholds and HTTP status codes to mark targets unhealthy. @@ -385,13 +428,13 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object type: object threshold: - type: integer + type: number type: object host_header: type: string @@ -414,6 +457,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -424,7 +470,6 @@ spec: shortNames: - kp singular: kongplugin - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -451,6 +496,11 @@ spec: openAPIV3Schema: description: KongPlugin is the Schema for the kongplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -473,9 +523,19 @@ spec: - name type: object type: object + consumerRef: + description: ConsumerRef is a reference to a particular consumer + type: string disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -520,7 +580,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: tcpingresses.configuration.konghq.com spec: @@ -530,7 +590,6 @@ spec: listKind: TCPIngressList plural: tcpingresses singular: tcpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -707,7 +766,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: udpingresses.configuration.konghq.com spec: @@ -717,7 +776,6 @@ spec: listKind: UDPIngressList plural: udpingresses singular: udpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: diff --git a/deploy/single/all-in-one-postgres.yaml b/deploy/single/all-in-one-postgres.yaml index 42668778c4..6d20874c8d 100644 --- a/deploy/single/all-in-one-postgres.yaml +++ b/deploy/single/all-in-one-postgres.yaml @@ -6,6 +6,9 @@ metadata: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongclusterplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -16,7 +19,6 @@ spec: shortNames: - kcp singular: kongclusterplugin - preserveUnknownFields: false scope: Cluster versions: - additionalPrinterColumns: @@ -43,6 +45,11 @@ spec: openAPIV3Schema: description: KongClusterPlugin is the Schema for the kongclusterplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -75,6 +82,13 @@ spec: disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -118,6 +132,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongconsumers.configuration.konghq.com spec: group: configuration.konghq.com @@ -128,7 +145,6 @@ spec: shortNames: - kc singular: kongconsumer - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -145,6 +161,11 @@ spec: openAPIV3Schema: description: KongConsumer is the Schema for the kongconsumers API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string credentials: description: Credentials are references to secrets containing a credential to be provisioned in Kong. @@ -155,6 +176,13 @@ spec: description: CustomID existing unique ID for the consumer - useful for mapping Kong with users in your existing database type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object username: description: Username unique username of the consumer. type: string @@ -173,6 +201,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongingresses.configuration.konghq.com spec: group: configuration.konghq.com @@ -183,7 +214,6 @@ spec: shortNames: - ki singular: kongingress - preserveUnknownFields: false scope: Namespaced versions: - name: v1 @@ -191,7 +221,20 @@ spec: openAPIV3Schema: description: KongIngress is the Schema for the kongingresses API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object proxy: + description: KongIngressService contains KongIngress service configuration properties: connect_timeout: minimum: 0 @@ -220,7 +263,7 @@ spec: type: integer type: object route: - description: Route represents a Route in Kong. Read https://getkong.org/docs/0.13.x/admin-api/#Route-object + description: KongIngressRoute contains KongIngress route configuration properties: headers: additionalProperties: @@ -256,12 +299,6 @@ spec: regex_priority: type: integer request_buffering: - description: "Kong buffers requests and responses by default. Buffering - is not always desired, for instance if large payloads are being - proxied using HTTP 1.1 chunked encoding. \n The request and response - route buffering options are enabled by default and allow the user - to disable buffering if desired for their use case. \n SEE ALSO: - - https://github.com/Kong/kong/pull/6057 - https://docs.konghq.com/2.2.x/admin-api/#route-object" type: boolean response_buffering: type: boolean @@ -273,7 +310,7 @@ spec: type: boolean type: object upstream: - description: Upstream represents an Upstream in Kong. + description: KongIngressUpstream contains KongIngress upstream configuration properties: algorithm: enum: @@ -322,6 +359,10 @@ spec: http_path: pattern: ^/.*$ type: string + https_sni: + type: string + https_verify_certificate: + type: boolean timeout: minimum: 0 type: integer @@ -344,7 +385,7 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object @@ -368,6 +409,8 @@ spec: minimum: 0 type: integer type: object + type: + type: string unhealthy: description: Unhealthy configures thresholds and HTTP status codes to mark targets unhealthy. @@ -385,13 +428,13 @@ spec: tcp_failures: minimum: 0 type: integer - timeout: + timeouts: minimum: 0 type: integer type: object type: object threshold: - type: integer + type: number type: object host_header: type: string @@ -414,6 +457,9 @@ status: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null name: kongplugins.configuration.konghq.com spec: group: configuration.konghq.com @@ -424,7 +470,6 @@ spec: shortNames: - kp singular: kongplugin - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -451,6 +496,11 @@ spec: openAPIV3Schema: description: KongPlugin is the Schema for the kongplugins API properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string config: description: Config contains the plugin configuration. type: object @@ -473,9 +523,19 @@ spec: - name type: object type: object + consumerRef: + description: ConsumerRef is a reference to a particular consumer + type: string disabled: description: Disabled set if the plugin is disabled or not type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object plugin: description: PluginName is the name of the plugin to which to apply the config @@ -520,7 +580,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: tcpingresses.configuration.konghq.com spec: @@ -530,7 +590,6 @@ spec: listKind: TCPIngressList plural: tcpingresses singular: tcpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: @@ -707,7 +766,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 + controller-gen.kubebuilder.io/version: v0.7.0 creationTimestamp: null name: udpingresses.configuration.konghq.com spec: @@ -717,7 +776,6 @@ spec: listKind: UDPIngressList plural: udpingresses singular: udpingress - preserveUnknownFields: false scope: Namespaced versions: - additionalPrinterColumns: diff --git a/go.mod b/go.mod index 13475a220b..f9d8ca77e1 100644 --- a/go.mod +++ b/go.mod @@ -140,7 +140,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect k8s.io/klog/v2 v2.10.0 // indirect - k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect + k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e // indirect sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect ) diff --git a/go.sum b/go.sum index bfb7f23d43..5188cee042 100644 --- a/go.sum +++ b/go.sum @@ -486,6 +486,7 @@ github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5 github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -885,6 +886,8 @@ github.com/kong/deck v1.7.0 h1:uo4NdcChHoM9sb2Z8YPAuFyobv8bxaQuayA00tzN5js= github.com/kong/deck v1.7.0/go.mod h1:o2letQaSpXVnDNoXehEibOF6q7v46qtbsKOCC+1owAw= github.com/kong/go-kong v0.19.0/go.mod h1:HyNtOxzh/tzmOV//ccO5NAdmrCnq8b86YUPjmdy5aog= github.com/kong/go-kong v0.25.1 h1:T3a4JvwQO//FVtj8F8xrOo689bb/ZmcvoLtBvrPaaj0= +github.com/kong/go-kong v0.25.1 h1:T3a4JvwQO//FVtj8F8xrOo689bb/ZmcvoLtBvrPaaj0= +github.com/kong/go-kong v0.25.1/go.mod h1:8Dl/eA8SVH3aJNOkS91J8CPf5oUHZ2+XSYvacrF5PBc= github.com/kong/go-kong v0.25.1/go.mod h1:8Dl/eA8SVH3aJNOkS91J8CPf5oUHZ2+XSYvacrF5PBc= github.com/kong/kubernetes-testing-framework v0.11.0 h1:7nvRLOqfvcWoHl2pZcODwXjGbbwX1MLnBvzc74CoR1U= github.com/kong/kubernetes-testing-framework v0.11.0/go.mod h1:xHb9zka61BSmm+Ptu23qTYal8xhItR1LNTtj6h9fvF4= @@ -2150,6 +2153,7 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201203183100-97869a43a9d9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -2169,8 +2173,10 @@ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAG k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kubectl v0.22.1/go.mod h1:mjAOgEbMNMtZWxnfM6jd+nPjPsaoLqO5xanc78WcSbw= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/legacy-cloud-providers v0.21.0/go.mod h1:bNxo7gDg+PGkBmT/MFZswLTWdSWK9kAlS1s8DJca5q4= @@ -2181,6 +2187,7 @@ k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20210305010621-2afb4311ab10/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e h1:ldQh+neBabomh7+89dTpiFAB8tGdfVmuIzAHbvtl+9I= k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= diff --git a/hack/generators/manifests/main.go b/hack/generators/manifests/main.go deleted file mode 100644 index 06ab3b5111..0000000000 --- a/hack/generators/manifests/main.go +++ /dev/null @@ -1,168 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - - v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "sigs.k8s.io/yaml" -) - -// ----------------------------------------------------------------------------- -// This script exists as a workaround for some problems which came up between -// v1 and v2 of the KIC regarding upgrading and generating CRDs: -// -// 1. upgrades from v1beta1 CRD to v1 needed a fix for a backwards incompatible -// change made in upstream that makes "preserveUnknownFields" no longer usable -// in the same form that it previously was -// 2. controller-gen automatic generation of CRDs did not work out of the box for -// some of our complex "Kong" resources, and so this script has a list -// of types to filter out as we're still manually managing those CRDs -// -// ----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------------- -// Details on CRD v1's "PreserveUnknownFields" -// -// In the v1beta1 version of the API a field called "preserveUnknownFields" was -// used to trigger pruning for API fields that are sent in the request payload -// but not a valid part of the API. In v1 this field is effectively deprecated -// and MUST be set to false: -// -// https://github.com/kubernetes/kubernetes/pull/93078 -// -// Problematically: even though validation enforces the "false" setting of this -// deprecated attribute for v1 CRDs, the previous default was "true" in v1beta1 -// and if you try to apply a v1 CRD that does NOT have this field set where a -// v1beta1 version of the CRD already exists on the cluster this can result in -// and error and fail to upgrade the CRD. -// -// This program accounts for this by applying "preserveUnknownFields: false" to -// any v1 CustomResourceDefinition to work around the upstream backwards -// incompatibility issue automatically. -// -// NOTE: When this was first written using controller-gen configuration options -// and kubebuilder flags on the API types was attempted but none of these -// things could produce the right result. -// -// The controller-gen CLI can't really do it (easily) because the default -// behavior of the marshaller in sigs.k8s.io/yaml is to not emit optional -// boolean fields to YAML if they're set to false. 😑 -// -// It's quite possible there's a better way to do this and if you find one -// we encourage you to put in a PR and replace this. -// -// ----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------------- -// Vars -// ----------------------------------------------------------------------------- - -var ( - // inputDir that will be used for walking the filesystem to find CRDs. - inputDir string - - // outputDir is where this script will emit completed CRDs - outputDir string - - // patchfile is the patch that will be used for each CRD file - patchfile = "config/crd/patches/upgrade_compat.yaml" - - // excludedTypes is the list of API types which we DON'T want to automatically - // generate CRDs for, as those CRDs are currently manually maintained. - excludedTypes = [4]string{ - "KongClusterPlugin", - "KongPlugin", - "KongConsumer", - "KongIngress", - } -) - -// ----------------------------------------------------------------------------- -// Main -// ----------------------------------------------------------------------------- - -func main() { - // handle arguments - flag.StringVar(&inputDir, "input-directory", ".", "which directory to find CRDs in") - flag.StringVar(&outputDir, "output-directory", ".", "which directory to emit completed CRDs to") - flag.Parse() - - // find all the YAML CRDs in the provided directory and patch them - if err := filepath.Walk(inputDir, processFile); err != nil { - fmt.Fprintf(os.Stderr, "Error processing files in %s: %s\n", inputDir, err) - os.Exit(1) - } -} - -func processFile(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if info.IsDir() { - return nil - } - - // filter out any files that don't identify themselves as YAML files via file extensions - if !strings.HasSuffix(info.Name(), ".yaml") && !strings.HasSuffix(info.Name(), ".yml") { - return nil - } - - // read in the file contents - b, err := os.ReadFile(path) - if err != nil { - return err - } - - // filter out any YAML files that don't contain a v1.CustomResourceDefinition - if !bytes.Contains(b, []byte(`kind: CustomResourceDefinition`)) || !bytes.Contains(b, []byte(`apiVersion: apiextensions.k8s.io/v1`)) { - return nil - } - - // don't allow files that contain multiple objects (controller-gen wont be configured to emit these anyway) - yamlCRDs := bytes.Split(b, []byte(`\n---\n`)) - if len(yamlCRDs) > 1 { - return fmt.Errorf("file %s contained multiple objects (%d) which this script doesn't yet support", path, len(yamlCRDs)) - } - - // filter out YAML files for CRDs we specifically want to exclude from automatic generation - for _, excludedType := range excludedTypes { - // check whether the excluded type is even present - if bytes.Contains(b, []byte(excludedType)) { - // the excluded type is present in this file, marshal it into YAML - crd := v1.CustomResourceDefinition{} - if err := yaml.Unmarshal(b, &crd); err != nil { - return err - } - if crd.Spec.Names.Kind == excludedType { - return nil - } - } - } - - // generate a patch command to ensure "preserveUnknownFields" is set to false - stdout, stderr := new(bytes.Buffer), new(bytes.Buffer) - patchCMD := exec.Command("kubectl", "patch", "--type", "merge", "--local", "-o", "yaml", "-f", path, "--patch-file", patchfile) - patchCMD.Stdout = stdout - patchCMD.Stderr = stderr - - // run the patcher and make sure there are no errors - if err := patchCMD.Run(); err != nil { - return fmt.Errorf("failed to patch crd in %s: %w; STDOUT=(%s) STDERR=(%s)", - path, err, strings.TrimSpace(stdout.String()), strings.TrimSpace(stderr.String()), - ) - } - - // controller-gen will add a YAML delimiter in the header, so we match that for consistency - patchedCRD := append([]byte("\n---\n"), stdout.Bytes()...) - - // write the patched CRD back to the original file - outputPath := fmt.Sprintf("%s/%s", outputDir, info.Name()) - return os.WriteFile(outputPath, patchedCRD, info.Mode().Perm()) -} diff --git a/internal/admission/validator.go b/internal/admission/validator.go index 7f536d30df..957545be10 100644 --- a/internal/admission/validator.go +++ b/internal/admission/validator.go @@ -229,7 +229,7 @@ func (validator KongHTTPValidator) ValidatePlugin( plugin.RunOn = kong.String(k8sPlugin.RunOn) } if len(k8sPlugin.Protocols) > 0 { - plugin.Protocols = kong.StringSlice(k8sPlugin.Protocols...) + plugin.Protocols = kong.StringSlice(kongv1.KongProtocolsToStrings(k8sPlugin.Protocols)...) } isValid, msg, err := validator.PluginSvc.Validate(ctx, &plugin) if err != nil { diff --git a/internal/kongstate/route.go b/internal/kongstate/route.go index 47b444148b..9f470f655a 100644 --- a/internal/kongstate/route.go +++ b/internal/kongstate/route.go @@ -279,7 +279,7 @@ func (r *Route) overrideByKongIngress(log logrus.FieldLogger, kongIngress *confi r.Headers = ir.Headers } if len(ir.Protocols) != 0 { - r.Protocols = cloneStringPointerSlice(ir.Protocols...) + r.Protocols = protocolPointersToStringPointers(ir.Protocols) } if ir.RegexPriority != nil { r.RegexPriority = kong.Int(*ir.RegexPriority) @@ -304,7 +304,7 @@ func (r *Route) overrideByKongIngress(log logrus.FieldLogger, kongIngress *confi SNIs = append(SNIs, kong.String(SNI)) } else { // SNI is not a valid hostname - log.WithField("kongroute", ir.Name).Errorf("invalid SNI: %v", unsanitizedSNI) + log.WithField("kongroute", r.Name).Errorf("invalid SNI: %v", unsanitizedSNI) return } } diff --git a/internal/kongstate/route_test.go b/internal/kongstate/route_test.go index ec4cda4b27..6ac09d14d0 100644 --- a/internal/kongstate/route_test.go +++ b/internal/kongstate/route_test.go @@ -40,7 +40,7 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ + Route: &configurationv1.KongIngressRoute{ Methods: kong.StringSlice("GET", "POST"), }, }, @@ -58,7 +58,7 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ + Route: &configurationv1.KongIngressRoute{ Methods: kong.StringSlice("GET ", "post"), }, }, @@ -76,7 +76,7 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ + Route: &configurationv1.KongIngressRoute{ Methods: kong.StringSlice("GET", "-1"), }, }, @@ -93,7 +93,7 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ + Route: &configurationv1.KongIngressRoute{ HTTPSRedirectStatusCode: kong.Int(302), }, }, @@ -113,8 +113,8 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ - Protocols: kong.StringSlice("http"), + Route: &configurationv1.KongIngressRoute{ + Protocols: configurationv1.ProtocolSlice("http"), PreserveHost: kong.Bool(false), StripPath: kong.Bool(false), RegexPriority: kong.Int(10), @@ -138,7 +138,7 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ + Route: &configurationv1.KongIngressRoute{ Headers: map[string][]string{ "foo-header": {"bar-value"}, }, @@ -161,8 +161,8 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ - Protocols: kong.StringSlice("grpc", "grpcs"), + Route: &configurationv1.KongIngressRoute{ + Protocols: configurationv1.ProtocolSlice("grpc", "grpcs"), }, }, Route{ @@ -180,7 +180,7 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ + Route: &configurationv1.KongIngressRoute{ PathHandling: kong.String("v1"), }, }, @@ -198,7 +198,7 @@ func TestOverrideRoute(t *testing.T) { }, }, configurationv1.KongIngress{ - Route: &kong.Route{ + Route: &configurationv1.KongIngressRoute{ RequestBuffering: kong.Bool(true), ResponseBuffering: kong.Bool(true), }, @@ -233,8 +233,8 @@ func TestOverrideRoutePriority(t *testing.T) { }, } kongIngress := configurationv1.KongIngress{ - Route: &kong.Route{ - Hosts: kong.StringSlice("foo.com", "bar.com"), + Route: &configurationv1.KongIngressRoute{ + Protocols: configurationv1.ProtocolSlice("http"), }, } @@ -263,13 +263,13 @@ func TestOverrideRouteByKongIngress(t *testing.T) { }, } kongIngress := configurationv1.KongIngress{ - Route: &kong.Route{ - Hosts: kong.StringSlice("foo.com", "bar.com"), + Route: &configurationv1.KongIngressRoute{ + Protocols: configurationv1.ProtocolSlice("http"), }, } route.overrideByKongIngress(logrus.New(), &kongIngress) - assert.Equal(route.Hosts, kong.StringSlice("foo.com", "bar.com")) + assert.Equal(route.Protocols, kong.StringSlice("http")) assert.NotPanics(func() { var nilRoute *Route nilRoute.override(logrus.New(), nil) diff --git a/internal/kongstate/service_test.go b/internal/kongstate/service_test.go index 6a17b41bcc..d4db2feb4d 100644 --- a/internal/kongstate/service_test.go +++ b/internal/kongstate/service_test.go @@ -30,7 +30,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{}, + Proxy: &configurationv1.KongIngressService{}, }, Service{ Service: kong.Service{ @@ -54,7 +54,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Protocol: kong.String("https"), }, }, @@ -80,7 +80,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Retries: kong.Int(0), }, }, @@ -107,7 +107,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Path: kong.String("/new-path"), }, }, @@ -133,7 +133,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Retries: kong.Int(1), }, }, @@ -160,7 +160,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ ConnectTimeout: kong.Int(100), ReadTimeout: kong.Int(100), WriteTimeout: kong.Int(100), @@ -191,7 +191,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Protocol: kong.String("grpc"), }, }, @@ -217,7 +217,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Protocol: kong.String("grpcs"), }, }, @@ -243,7 +243,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Protocol: kong.String("grpcs"), }, }, @@ -269,7 +269,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Protocol: kong.String("grpcs"), }, }, @@ -295,7 +295,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{}, + Proxy: &configurationv1.KongIngressService{}, }, Service{ Service: kong.Service{ @@ -319,7 +319,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{ + Proxy: &configurationv1.KongIngressService{ Protocol: kong.String("grpcs"), }, }, @@ -345,7 +345,7 @@ func TestOverrideService(t *testing.T) { }, }, configurationv1.KongIngress{ - Proxy: &kong.Service{}, + Proxy: &configurationv1.KongIngressService{}, }, Service{ Service: kong.Service{ diff --git a/internal/kongstate/upstream.go b/internal/kongstate/upstream.go index d0a89f7112..e4eea5945c 100644 --- a/internal/kongstate/upstream.go +++ b/internal/kongstate/upstream.go @@ -45,13 +45,38 @@ func (u *Upstream) overrideByKongIngress(kongIngress *configurationv1.KongIngres if kongIngress == nil || kongIngress.Upstream == nil { return } - - // The upstream within the KongIngress has no name. - // As this overwrites the entire upstream object, we must restore the - // original name after. - name := *u.Upstream.Name - u.Upstream = *kongIngress.Upstream.DeepCopy() - u.Name = &name + k := kongIngress.Upstream + if k.HostHeader != nil { + u.HostHeader = kong.String(*k.HostHeader) + } + if k.Algorithm != nil { + u.Algorithm = kong.String(*k.Algorithm) + } + if k.Slots != nil { + u.Slots = kong.Int(*k.Slots) + } + if k.Healthchecks != nil { + u.Healthchecks = k.Healthchecks + } + if k.HashOn != nil { + u.HashOn = kong.String(*k.HashOn) + } + if k.HashFallback != nil { + u.HashFallback = kong.String(*k.HashFallback) + } + if k.HashOnHeader != nil { + u.HashOnHeader = kong.String(*k.HashOnHeader) + } + if k.HashFallbackHeader != nil { + u.HashFallbackHeader = kong.String(*k.HashFallbackHeader) + } + if k.HashOnCookie != nil { + u.HashOnCookie = kong.String(*k.HashOnCookie) + } + if k.HashOnCookiePath != nil { + u.HashOnCookiePath = kong.String(*k.HashOnCookiePath) + } + // TODO https://github.com/Kong/kubernetes-ingress-controller/issues/2075 } // override sets Upstream fields by KongIngress first, then by annotation diff --git a/internal/kongstate/upstream_test.go b/internal/kongstate/upstream_test.go index edf1b45814..e6c90b6176 100644 --- a/internal/kongstate/upstream_test.go +++ b/internal/kongstate/upstream_test.go @@ -38,8 +38,7 @@ func TestOverrideUpstream(t *testing.T) { }, }, inKongIngresss: &configurationv1.KongIngress{ - Upstream: &kong.Upstream{ - Name: kong.String("wrong.com"), + Upstream: &configurationv1.KongIngressUpstream{ HashOn: kong.String("HashOn"), HashOnCookie: kong.String("HashOnCookie"), HashOnCookiePath: kong.String("HashOnCookiePath"), diff --git a/internal/kongstate/util.go b/internal/kongstate/util.go index e1a5eb9f47..4e2994c4b0 100644 --- a/internal/kongstate/util.go +++ b/internal/kongstate/util.go @@ -112,13 +112,22 @@ func kongPluginFromK8SClusterPlugin( RunOn: k8sPlugin.RunOn, Disabled: k8sPlugin.Disabled, - Protocols: k8sPlugin.Protocols, + Protocols: protocolsToStrings(k8sPlugin.Protocols), }.toKongPlugin() return kongPlugin, nil } -func cloneStringPointerSlice(array ...*string) (res []*string) { - res = append(res, array...) +func protocolPointersToStringPointers(protocols []*configurationv1.KongProtocol) (res []*string) { + for _, protocol := range protocols { + res = append(res, kong.String(string(*protocol))) + } + return +} + +func protocolsToStrings(protocols []configurationv1.KongProtocol) (res []string) { + for _, protocol := range protocols { + res = append(res, string(protocol)) + } return } @@ -153,7 +162,7 @@ func kongPluginFromK8SPlugin( RunOn: k8sPlugin.RunOn, Disabled: k8sPlugin.Disabled, - Protocols: k8sPlugin.Protocols, + Protocols: protocolsToStrings(k8sPlugin.Protocols), }.toKongPlugin() return kongPlugin, nil } diff --git a/internal/kongstate/util_test.go b/internal/kongstate/util_test.go index 30642fcea3..55b067ec82 100644 --- a/internal/kongstate/util_test.go +++ b/internal/kongstate/util_test.go @@ -41,7 +41,7 @@ func TestKongPluginFromK8SClusterPlugin(t *testing.T) { name: "basic configuration", args: args{ plugin: configurationv1.KongClusterPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", Config: apiextensionsv1.JSON{ Raw: []byte(`{"header_name": "foo"}`), @@ -61,7 +61,7 @@ func TestKongPluginFromK8SClusterPlugin(t *testing.T) { name: "secret configuration", args: args{ plugin: configurationv1.KongClusterPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -85,7 +85,7 @@ func TestKongPluginFromK8SClusterPlugin(t *testing.T) { name: "missing secret configuration", args: args{ plugin: configurationv1.KongClusterPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -103,7 +103,7 @@ func TestKongPluginFromK8SClusterPlugin(t *testing.T) { name: "non-JSON configuration", args: args{ plugin: configurationv1.KongClusterPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", Config: apiextensionsv1.JSON{ Raw: []byte(`{{}`), @@ -117,7 +117,7 @@ func TestKongPluginFromK8SClusterPlugin(t *testing.T) { name: "both Config and ConfigFrom set", args: args{ plugin: configurationv1.KongClusterPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", Config: apiextensionsv1.JSON{ Raw: []byte(`{"header_name": "foo"}`), @@ -175,7 +175,7 @@ func TestKongPluginFromK8SPlugin(t *testing.T) { name: "basic configuration", args: args{ plugin: configurationv1.KongPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", Config: apiextensionsv1.JSON{ Raw: []byte(`{"header_name": "foo"}`), @@ -199,7 +199,7 @@ func TestKongPluginFromK8SPlugin(t *testing.T) { Name: "foo", Namespace: "default", }, - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", ConfigFrom: &configurationv1.ConfigSource{ SecretValue: configurationv1.SecretValueFromSource{ @@ -226,7 +226,7 @@ func TestKongPluginFromK8SPlugin(t *testing.T) { Name: "foo", Namespace: "default", }, - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", ConfigFrom: &configurationv1.ConfigSource{ SecretValue: configurationv1.SecretValueFromSource{ @@ -243,7 +243,7 @@ func TestKongPluginFromK8SPlugin(t *testing.T) { name: "non-JSON configuration", args: args{ plugin: configurationv1.KongPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", Config: apiextensionsv1.JSON{ Raw: []byte(`{{}`), @@ -257,7 +257,7 @@ func TestKongPluginFromK8SPlugin(t *testing.T) { name: "both Config and ConfigFrom set", args: args{ plugin: configurationv1.KongPlugin{ - Protocols: []string{"http"}, + Protocols: []configurationv1.KongProtocol{"http"}, PluginName: "correlation-id", Config: apiextensionsv1.JSON{ Raw: []byte(`{"header_name": "foo"}`), diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go index 8b176003bf..5fde1adbd6 100644 --- a/internal/parser/parser_test.go +++ b/internal/parser/parser_test.go @@ -254,7 +254,7 @@ func TestGlobalPlugin(t *testing.T) { annotations.IngressClassKey: annotations.DefaultIngressClass, }, }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", Config: apiextensionsv1.JSON{ Raw: []byte(`{"foo1": "bar1"}`), @@ -383,7 +383,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { annotations.IngressClassKey: annotations.DefaultIngressClass, }, }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -403,7 +403,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { // explicitly none, this should not get rendered }, }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -417,7 +417,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "bar-plugin", }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -507,7 +507,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { "global": "true", }, }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -521,7 +521,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "bar-plugin", }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -602,7 +602,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { "global": "true", }, }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", Config: apiextensionsv1.JSON{ Raw: []byte(`{"fake": true}`), @@ -619,7 +619,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "bar-plugin", }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", Config: apiextensionsv1.JSON{ Raw: []byte(`{"fake": true}`), @@ -757,7 +757,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { "global": "true", }, }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -771,7 +771,7 @@ func TestSecretConfigurationPlugin(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "bar-plugin", }, - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), PluginName: "basic-auth", ConfigFrom: &configurationv1.NamespacedConfigSource{ SecretValue: configurationv1.NamespacedSecretValueFromSource{ @@ -1174,13 +1174,15 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(true), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(true), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) t.Run("strip-path annotation is correctly processed (false)", func(t *testing.T) { @@ -1251,13 +1253,15 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) t.Run("https-redirect-status-code annotation is correctly processed", @@ -1337,6 +1341,8 @@ func TestKongRouteAnnotations(t *testing.T) { Paths: kong.StringSlice("/"), Protocols: kong.StringSlice("http", "https"), RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) t.Run("bad https-redirect-status-code annotation is ignored", @@ -1408,13 +1414,15 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) t.Run("preserve-host annotation is correctly processed", @@ -1486,13 +1494,15 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(false), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(false), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) t.Run("preserve-host annotation with random string is correctly processed", @@ -1564,13 +1574,15 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) t.Run("regex-priority annotation is correctly processed", @@ -1642,13 +1654,15 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(10), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(10), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) t.Run("non-integer regex-priority annotation is ignored", @@ -1720,13 +1734,15 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), }, state.Services[0].Routes[0].Route) }) t.Run("route buffering options are processed (true)", func(t *testing.T) { @@ -1937,10 +1953,11 @@ func TestKongRouteAnnotations(t *testing.T) { assert.Nil(err) assert.NotNil(state) + kongTrue := kong.Bool(true) assert.Equal(1, len(state.Services), "expected one service to be rendered") assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") - assert.Empty(state.Services[0].Routes[0].Route.RequestBuffering) - assert.Empty(state.Services[0].Routes[0].Route.ResponseBuffering) + assert.Equal(kongTrue, state.Services[0].Routes[0].Route.RequestBuffering) + assert.Equal(kongTrue, state.Services[0].Routes[0].Route.ResponseBuffering) }) } @@ -2099,8 +2116,8 @@ func TestKnativeIngressAndPlugins(t *testing.T) { Name: "https-only", Namespace: "foo-ns", }, - Route: &kong.Route{ - Protocols: kong.StringSlice("https"), + Route: &configurationv1.KongIngressRoute{ + Protocols: configurationv1.ProtocolSlice("https"), HTTPSRedirectStatusCode: kong.Int(308), }, }, @@ -2177,8 +2194,8 @@ func TestKnativeIngressAndPlugins(t *testing.T) { Name: "https-only", Namespace: "foo-ns", }, - Route: &kong.Route{ - Protocols: kong.StringSlice("https"), + Route: &configurationv1.KongIngressRoute{ + Protocols: configurationv1.ProtocolSlice("https"), HTTPSRedirectStatusCode: kong.Int(308), }, }, @@ -2339,7 +2356,7 @@ func TestKnativeIngressAndPlugins(t *testing.T) { Namespace: "foo-ns", }, PluginName: "key-auth", - Protocols: []string{"http"}, + Protocols: configurationv1.StringsToKongProtocols([]string{"http"}), Config: apiextensionsv1.JSON{ Raw: []byte(`{"foo": "bar", "knative": "yo"}`), }, @@ -2384,13 +2401,15 @@ func TestKnativeIngressAndPlugins(t *testing.T) { assert.Equal(1, len(svc.Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("foo-ns.knative-ingress.00"), - StripPath: kong.Bool(false), - Hosts: kong.StringSlice("my-func.example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("foo-ns.knative-ingress.00"), + StripPath: kong.Bool(false), + Hosts: kong.StringSlice("my-func.example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, svc.Routes[0].Route) assert.Equal(1, len(state.Plugins), "expected one key-auth plugin") @@ -2480,13 +2499,15 @@ func TestKongServiceAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) @@ -2567,13 +2588,15 @@ func TestKongServiceAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, state.Services[0].Routes[0].Route) }) @@ -2646,14 +2669,16 @@ func TestKongServiceAnnotations(t *testing.T) { assert.Equal(1, len(state.Services[0].Routes), "expected one route to be rendered") assert.Equal(kong.Route{ - Name: kong.String("default.bar.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), - Methods: kong.StringSlice("POST", "GET"), + Name: kong.String("default.bar.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), + Methods: kong.StringSlice("POST", "GET"), }, state.Services[0].Routes[0].Route) }) } @@ -3073,23 +3098,27 @@ func TestParserSNI(t *testing.T) { assert.Nil(err) assert.NotNil(state) assert.Equal(kong.Route{ - Name: kong.String("default.foo.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.foo.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), }, state.Services[0].Routes[0].Route) assert.Equal(kong.Route{ - Name: kong.String("default.foo.10"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("*.example.com"), - SNIs: nil, - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.foo.10"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("*.example.com"), + SNIs: nil, + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), }, state.Services[0].Routes[1].Route) }) t.Run("route does not include SNI when TLS info absent", func(t *testing.T) { @@ -3133,14 +3162,16 @@ func TestParserSNI(t *testing.T) { assert.Nil(err) assert.NotNil(state) assert.Equal(kong.Route{ - Name: kong.String("default.foo.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("example.com"), - SNIs: nil, - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.foo.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("example.com"), + SNIs: nil, + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), }, state.Services[0].Routes[0].Route) }) } @@ -3190,13 +3221,15 @@ func TestParserHostAliases(t *testing.T) { assert.Nil(err) assert.NotNil(state) assert.Equal(kong.Route{ - Name: kong.String("default.foo.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("example.com", "*.example.com", "*.sample.com", "*.illustration.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.foo.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("example.com", "*.example.com", "*.sample.com", "*.illustration.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), }, state.Services[0].Routes[0].Route) }) t.Run("route Hosts remain unmodified when Host-Aliases are not present", func(t *testing.T) { @@ -3240,13 +3273,15 @@ func TestParserHostAliases(t *testing.T) { assert.Nil(err) assert.NotNil(state) assert.Equal(kong.Route{ - Name: kong.String("default.foo.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.foo.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), }, state.Services[0].Routes[0].Route) }) t.Run("route Hosts will not contain duplicates when Host-Aliases duplicates the host", func(t *testing.T) { @@ -3291,13 +3326,15 @@ func TestParserHostAliases(t *testing.T) { assert.Nil(err) assert.NotNil(state) assert.Equal(kong.Route{ - Name: kong.String("default.foo.00"), - StripPath: kong.Bool(false), - RegexPriority: kong.Int(0), - Hosts: kong.StringSlice("example.com", "*.example.com"), - PreserveHost: kong.Bool(true), - Paths: kong.StringSlice("/"), - Protocols: kong.StringSlice("http", "https"), + Name: kong.String("default.foo.00"), + StripPath: kong.Bool(false), + RegexPriority: kong.Int(0), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), + Hosts: kong.StringSlice("example.com", "*.example.com"), + PreserveHost: kong.Bool(true), + Paths: kong.StringSlice("/"), + Protocols: kong.StringSlice("http", "https"), }, state.Services[0].Routes[0].Route) }) } @@ -3353,7 +3390,7 @@ func TestPluginAnnotations(t *testing.T) { Namespace: "default", }, PluginName: "key-auth", - Protocols: []string{"grpc"}, + Protocols: []configurationv1.KongProtocol{"grpc"}, Config: apiextensionsv1.JSON{ Raw: []byte(`{ "foo": "bar", @@ -3444,7 +3481,7 @@ func TestPluginAnnotations(t *testing.T) { Namespace: "default", }, PluginName: "basic-auth", - Protocols: []string{"grpc"}, + Protocols: []configurationv1.KongProtocol{"grpc"}, Config: apiextensionsv1.JSON{ Raw: []byte(`{"foo": "bar"}`), }, @@ -3457,7 +3494,7 @@ func TestPluginAnnotations(t *testing.T) { Namespace: "default", }, PluginName: "key-auth", - Protocols: []string{"grpc"}, + Protocols: []configurationv1.KongProtocol{"grpc"}, Config: apiextensionsv1.JSON{ Raw: []byte(`{"foo": "bar"}`), }, @@ -3528,7 +3565,7 @@ func TestPluginAnnotations(t *testing.T) { Namespace: "default", }, PluginName: "basic-auth", - Protocols: []string{"grpc"}, + Protocols: []configurationv1.KongProtocol{"grpc"}, Config: apiextensionsv1.JSON{ Raw: []byte(`{"foo": "bar"}`), }, diff --git a/internal/parser/translate.go b/internal/parser/translate.go index 07dde507c9..f26bcbdb1a 100644 --- a/internal/parser/translate.go +++ b/internal/parser/translate.go @@ -74,12 +74,14 @@ func fromIngressV1beta1(log logrus.FieldLogger, ingressList []*networkingv1beta1 // 2. Is it guaranteed that the order is stable? // Meaning, the routes will always appear in the same // order? - Name: kong.String(fmt.Sprintf("%s.%s.%d%d", ingress.Namespace, ingress.Name, i, j)), - Paths: kong.StringSlice(path), - StripPath: kong.Bool(false), - PreserveHost: kong.Bool(true), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String(fmt.Sprintf("%s.%s.%d%d", ingress.Namespace, ingress.Name, i, j)), + Paths: kong.StringSlice(path), + StripPath: kong.Bool(false), + PreserveHost: kong.Bool(true), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + RequestBuffering: kong.Bool(true), + ResponseBuffering: kong.Bool(true), }, } if host != "" { @@ -155,12 +157,14 @@ func fromIngressV1beta1(log logrus.FieldLogger, ingressList []*networkingv1beta1 r := kongstate.Route{ Ingress: util.FromK8sObject(&ingress), Route: kong.Route{ - Name: kong.String(ingress.Namespace + "." + ingress.Name), - Paths: kong.StringSlice("/"), - StripPath: kong.Bool(false), - PreserveHost: kong.Bool(true), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String(ingress.Namespace + "." + ingress.Name), + Paths: kong.StringSlice("/"), + StripPath: kong.Bool(false), + PreserveHost: kong.Bool(true), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + RequestBuffering: kong.Bool(true), + ResponseBuffering: kong.Bool(true), }, } service.Routes = append(service.Routes, r) @@ -224,12 +228,14 @@ func fromIngressV1(log logrus.FieldLogger, ingressList []*networkingv1.Ingress) // 2. Is it guaranteed that the order is stable? // Meaning, the routes will always appear in the same // order? - Name: kong.String(fmt.Sprintf("%s.%s.%d%d", ingress.Namespace, ingress.Name, i, j)), - Paths: paths, - StripPath: kong.Bool(false), - PreserveHost: kong.Bool(true), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(priorityForPath[pathType]), + Name: kong.String(fmt.Sprintf("%s.%s.%d%d", ingress.Namespace, ingress.Name, i, j)), + Paths: paths, + StripPath: kong.Bool(false), + PreserveHost: kong.Bool(true), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(priorityForPath[pathType]), + RequestBuffering: kong.Bool(true), + ResponseBuffering: kong.Bool(true), }, } if rule.Host != "" { @@ -302,12 +308,14 @@ func fromIngressV1(log logrus.FieldLogger, ingressList []*networkingv1.Ingress) r := kongstate.Route{ Ingress: util.FromK8sObject(&ingress), Route: kong.Route{ - Name: kong.String(ingress.Namespace + "." + ingress.Name), - Paths: kong.StringSlice("/"), - StripPath: kong.Bool(false), - PreserveHost: kong.Bool(true), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String(ingress.Namespace + "." + ingress.Name), + Paths: kong.StringSlice("/"), + StripPath: kong.Bool(false), + PreserveHost: kong.Bool(true), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + RequestBuffering: kong.Bool(true), + ResponseBuffering: kong.Bool(true), }, } service.Routes = append(service.Routes, r) @@ -597,12 +605,14 @@ func fromKnativeIngress(log logrus.FieldLogger, ingressList []*knative.Ingress) // 2. Is it guaranteed that the order is stable? // Meaning, the routes will always appear in the same // order? - Name: kong.String(fmt.Sprintf("%s.%s.%d%d", ingress.Namespace, ingress.Name, i, j)), - Paths: kong.StringSlice(path), - StripPath: kong.Bool(false), - PreserveHost: kong.Bool(true), - Protocols: kong.StringSlice("http", "https"), - RegexPriority: kong.Int(0), + Name: kong.String(fmt.Sprintf("%s.%s.%d%d", ingress.Namespace, ingress.Name, i, j)), + Paths: kong.StringSlice(path), + StripPath: kong.Bool(false), + PreserveHost: kong.Bool(true), + Protocols: kong.StringSlice("http", "https"), + RegexPriority: kong.Int(0), + RequestBuffering: kong.Bool(true), + ResponseBuffering: kong.Bool(true), }, } r.Hosts = kong.StringSlice(hosts...) diff --git a/internal/parser/translate_test.go b/internal/parser/translate_test.go index 24a2b90ffd..3fa55c2d95 100644 --- a/internal/parser/translate_test.go +++ b/internal/parser/translate_test.go @@ -1022,13 +1022,15 @@ func TestFromKnativeIngress(t *testing.T) { Retries: kong.Int(5), }, svc.Service) assert.Equal(kong.Route{ - Name: kong.String("foo-namespace.foo.00"), - RegexPriority: kong.Int(0), - StripPath: kong.Bool(false), - Paths: kong.StringSlice("/"), - PreserveHost: kong.Bool(true), - Protocols: kong.StringSlice("http", "https"), - Hosts: kong.StringSlice("my-func.example.com"), + Name: kong.String("foo-namespace.foo.00"), + RegexPriority: kong.Int(0), + StripPath: kong.Bool(false), + Paths: kong.StringSlice("/"), + PreserveHost: kong.Bool(true), + Protocols: kong.StringSlice("http", "https"), + Hosts: kong.StringSlice("my-func.example.com"), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, svc.Routes[0].Route) assert.Equal(kong.Plugin{ Name: kong.String("request-transformer"), @@ -1065,13 +1067,15 @@ func TestFromKnativeIngress(t *testing.T) { Retries: kong.Int(5), }, svc.Service) assert.Equal(kong.Route{ - Name: kong.String("foo-namespace.foo.00"), - RegexPriority: kong.Int(0), - StripPath: kong.Bool(false), - Paths: kong.StringSlice("/"), - PreserveHost: kong.Bool(true), - Protocols: kong.StringSlice("http", "https"), - Hosts: kong.StringSlice("my-func.example.com"), + Name: kong.String("foo-namespace.foo.00"), + RegexPriority: kong.Int(0), + StripPath: kong.Bool(false), + Paths: kong.StringSlice("/"), + PreserveHost: kong.Bool(true), + Protocols: kong.StringSlice("http", "https"), + Hosts: kong.StringSlice("my-func.example.com"), + ResponseBuffering: kong.Bool(true), + RequestBuffering: kong.Bool(true), }, svc.Routes[0].Route) assert.Equal(kong.Plugin{ Name: kong.String("request-transformer"), diff --git a/internal/store/store.go b/internal/store/store.go index f58470110d..9b00acd535 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -791,8 +791,6 @@ func mkObjFromGVK(gvk schema.GroupVersionKind) (runtime.Object, error) { return &kongv1.KongClusterPlugin{}, nil case kongv1.SchemeGroupVersion.WithKind("KongConsumer"): return &kongv1.KongConsumer{}, nil - case kongv1.SchemeGroupVersion.WithKind("ConfigSource"): - return &kongv1.ConfigSource{}, nil // ---------------------------------------------------------------------------- // Knative APIs // ---------------------------------------------------------------------------- diff --git a/pkg/apis/configuration/v1/configsource.go b/pkg/apis/configuration/v1/configsource.go index aafc5c9f1f..4680b09469 100644 --- a/pkg/apis/configuration/v1/configsource.go +++ b/pkg/apis/configuration/v1/configsource.go @@ -1,29 +1,20 @@ package v1 -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - // ConfigSource is a wrapper around SecretValueFromSource +//+kubebuilder:object:generate=true type ConfigSource struct { - metav1.TypeMeta `json:",inline"` - SecretValue SecretValueFromSource `json:"secretKeyRef,omitempty"` + SecretValue SecretValueFromSource `json:"secretKeyRef,omitempty"` } -//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - // NamespacedConfigSource is a wrapper around NamespacedSecretValueFromSource +//+kubebuilder:object:generate=true type NamespacedConfigSource struct { - metav1.TypeMeta `json:",inline"` - SecretValue NamespacedSecretValueFromSource `json:"secretKeyRef,omitempty"` + SecretValue NamespacedSecretValueFromSource `json:"secretKeyRef,omitempty"` } -//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -//+kubebuilder:validation:Optional - // SecretValueFromSource represents the source of a secret value +//+kubebuilder:object:generate=true type SecretValueFromSource struct { - metav1.TypeMeta `json:",inline"` // the secret containing the key //+kubebuilder:validation:Required Secret string `json:"name,omitempty"` @@ -32,12 +23,9 @@ type SecretValueFromSource struct { Key string `json:"key,omitempty"` } -//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -//+kubebuilder:validation:Optional - // NamespacedSecretValueFromSource represents the source of a secret value specifying the secret namespace +//+kubebuilder:object:generate=true type NamespacedSecretValueFromSource struct { - metav1.TypeMeta `json:",inline"` // The namespace containing the secret //+kubebuilder:validation:Required Namespace string `json:"namespace,omitempty"` diff --git a/pkg/apis/configuration/v1/kongclusterplugin_types.go b/pkg/apis/configuration/v1/kongclusterplugin_types.go index 689738841a..1609ca1d86 100644 --- a/pkg/apis/configuration/v1/kongclusterplugin_types.go +++ b/pkg/apis/configuration/v1/kongclusterplugin_types.go @@ -63,8 +63,7 @@ type KongClusterPlugin struct { // Protocols configures plugin to run on requests received on specific // protocols. - //+kubebuilder:validation:Enum=http;https;grpc;grpcs;tcp;tls;udp - Protocols []string `json:"protocols,omitempty"` + Protocols []KongProtocol `json:"protocols,omitempty"` } //+kubebuilder:object:root=true diff --git a/pkg/apis/configuration/v1/kongingress_types.go b/pkg/apis/configuration/v1/kongingress_types.go index f61030b186..3ab8b78789 100644 --- a/pkg/apis/configuration/v1/kongingress_types.go +++ b/pkg/apis/configuration/v1/kongingress_types.go @@ -34,9 +34,9 @@ type KongIngress struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Upstream *kong.Upstream `json:"upstream,omitempty"` - Proxy *kong.Service `json:"proxy,omitempty"` - Route *kong.Route `json:"route,omitempty"` + Upstream *KongIngressUpstream `json:"upstream,omitempty"` + Proxy *KongIngressService `json:"proxy,omitempty"` + Route *KongIngressRoute `json:"route,omitempty"` } //+kubebuilder:object:root=true @@ -48,6 +48,59 @@ type KongIngressList struct { Items []KongIngress `json:"items"` } +// KongIngressService contains KongIngress service configuration +//+ It contains the subset of go-kong.kong.Service fields supported by kongstate.Service.overrideByKongIngress +type KongIngressService struct { + //+kubebuilder:validation:Enum=http;https;grpc;grpcs;tcp;tls;udp + Protocol *string `json:"protocol,omitempty" yaml:"protocol,omitempty"` + //+kubebuilder:validation:Pattern=^/.*$ + Path *string `json:"path,omitempty" yaml:"path,omitempty"` + //+kubebuilder:validation:Minimum=0 + Retries *int `json:"retries,omitempty" yaml:"retries,omitempty"` + //+kubebuilder:validation:Minimum=0 + ConnectTimeout *int `json:"connect_timeout,omitempty" yaml:"connect_timeout,omitempty"` + //+kubebuilder:validation:Minimum=0 + ReadTimeout *int `json:"read_timeout,omitempty" yaml:"read_timeout,omitempty"` + //+kubebuilder:validation:Minimum=0 + WriteTimeout *int `json:"write_timeout,omitempty" yaml:"write_timeout,omitempty"` +} + +// KongIngressRoute contains KongIngress route configuration +//+ It contains the subset of go-kong.kong.Route fields supported by kongstate.Route.overrideByKongIngress +type KongIngressRoute struct { + Methods []*string `json:"methods,omitempty" yaml:"methods,omitempty"` + Headers map[string][]string `json:"headers,omitempty" yaml:"headers,omitempty"` + Protocols []*KongProtocol `json:"protocols,omitempty" yaml:"protocols,omitempty"` + RegexPriority *int `json:"regex_priority,omitempty" yaml:"regex_priority,omitempty"` + StripPath *bool `json:"strip_path,omitempty" yaml:"strip_path,omitempty"` + PreserveHost *bool `json:"preserve_host,omitempty" yaml:"preserve_host,omitempty"` + HTTPSRedirectStatusCode *int `json:"https_redirect_status_code,omitempty" yaml:"https_redirect_status_code,omitempty"` + //+kubebuilder:validation:Enum=v0;v1 + PathHandling *string `json:"path_handling,omitempty" yaml:"path_handling,omitempty"` + SNIs []*string `json:"snis,omitempty" yaml:"snis,omitempty"` + RequestBuffering *bool `json:"request_buffering,omitempty" yaml:"request_buffering,omitempty"` + ResponseBuffering *bool `json:"response_buffering,omitempty" yaml:"response_buffering,omitempty"` +} + +// KongIngressUpstream contains KongIngress upstream configuration +//+ It contains the subset of go-kong.kong.Upstream fields supported by kongstate.Upstream.overrideByKongIngress +type KongIngressUpstream struct { + HostHeader *string `json:"host_header,omitempty" yaml:"host_header,omitempty"` + //+kubebuilder:validation:Enum=round-robin;consistent-hashing;least-connections + Algorithm *string `json:"algorithm,omitempty" yaml:"algorithm,omitempty"` + //+kubebuilder:validation:Minimum=10 + Slots *int `json:"slots,omitempty" yaml:"slots,omitempty"` + Healthchecks *kong.Healthcheck `json:"healthchecks,omitempty" yaml:"healthchecks,omitempty"` + HashOn *string `json:"hash_on,omitempty" yaml:"hash_on,omitempty"` + HashFallback *string `json:"hash_fallback,omitempty" yaml:"hash_fallback,omitempty"` + HashOnHeader *string `json:"hash_on_header,omitempty" yaml:"hash_on_header,omitempty"` + HashFallbackHeader *string `json:"hash_fallback_header,omitempty" yaml:"hash_fallback_header,omitempty"` + HashOnCookie *string `json:"hash_on_cookie,omitempty" yaml:"hash_on_cookie,omitempty"` + HashOnCookiePath *string `json:"hash_on_cookie_path,omitempty" yaml:"hash_on_cookie_path,omitempty"` + // TODO https://github.com/Kong/kubernetes-ingress-controller/issues/2075 + //ClientCertificate *CertificateSecretRef `json:"client_certificate,omitempty" yaml:"client_certificate,omitempty"` +} + func init() { SchemeBuilder.Register(&KongIngress{}, &KongIngressList{}) } diff --git a/pkg/apis/configuration/v1/kongplugin_types.go b/pkg/apis/configuration/v1/kongplugin_types.go index 096ef2e461..1ab9547f28 100644 --- a/pkg/apis/configuration/v1/kongplugin_types.go +++ b/pkg/apis/configuration/v1/kongplugin_types.go @@ -62,8 +62,7 @@ type KongPlugin struct { // Protocols configures plugin to run on requests received on specific // protocols. - //+kubebuilder:validation:Enum=http;https;grpc;grpcs;tcp;tls;udp - Protocols []string `json:"protocols,omitempty"` + Protocols []KongProtocol `json:"protocols,omitempty"` } //+kubebuilder:object:root=true diff --git a/pkg/apis/configuration/v1/kongprotocol_types.go b/pkg/apis/configuration/v1/kongprotocol_types.go new file mode 100644 index 0000000000..14c0312883 --- /dev/null +++ b/pkg/apis/configuration/v1/kongprotocol_types.go @@ -0,0 +1,33 @@ +package v1 + +//+ KongProtocol is a valid Kong protocol +//+ This alias is necessary to deal with https://github.com/kubernetes-sigs/controller-tools/issues/342 +//+kubebuilder:validation:Enum=http;https;grpc;grpcs;tcp;tls;udp +//+kubebuilder:object:generate=true +type KongProtocol string + +// KongProtocolsToStrings converts a slice of KongProtocol to plain strings +func KongProtocolsToStrings(protocols []KongProtocol) (res []string) { + for _, protocol := range protocols { + res = append(res, string(protocol)) + } + return +} + +// StringsToKongProtocols converts a slice of strings to KongProtocols +func StringsToKongProtocols(strings []string) (res []KongProtocol) { + for _, protocol := range strings { + res = append(res, KongProtocol(protocol)) + } + return +} + +// ProtocolSlice converts a slice of string to a slice of *KongProtocol +func ProtocolSlice(elements ...string) []*KongProtocol { + var res []*KongProtocol + for _, element := range elements { + e := KongProtocol(element) + res = append(res, &e) + } + return res +} diff --git a/pkg/apis/configuration/v1/zz_generated.deepcopy.go b/pkg/apis/configuration/v1/zz_generated.deepcopy.go index 8fd587d08f..2c0554ab35 100644 --- a/pkg/apis/configuration/v1/zz_generated.deepcopy.go +++ b/pkg/apis/configuration/v1/zz_generated.deepcopy.go @@ -29,7 +29,6 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConfigSource) DeepCopyInto(out *ConfigSource) { *out = *in - out.TypeMeta = in.TypeMeta out.SecretValue = in.SecretValue } @@ -43,14 +42,6 @@ func (in *ConfigSource) DeepCopy() *ConfigSource { return out } -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ConfigSource) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KongClusterPlugin) DeepCopyInto(out *KongClusterPlugin) { *out = *in @@ -64,7 +55,7 @@ func (in *KongClusterPlugin) DeepCopyInto(out *KongClusterPlugin) { } if in.Protocols != nil { in, out := &in.Protocols, &out.Protocols - *out = make([]string, len(*in)) + *out = make([]KongProtocol, len(*in)) copy(*out, *in) } } @@ -188,17 +179,17 @@ func (in *KongIngress) DeepCopyInto(out *KongIngress) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) if in.Upstream != nil { in, out := &in.Upstream, &out.Upstream - *out = new(kong.Upstream) + *out = new(KongIngressUpstream) (*in).DeepCopyInto(*out) } if in.Proxy != nil { in, out := &in.Proxy, &out.Proxy - *out = new(kong.Service) + *out = new(KongIngressService) (*in).DeepCopyInto(*out) } if in.Route != nil { in, out := &in.Route, &out.Route - *out = new(kong.Route) + *out = new(KongIngressRoute) (*in).DeepCopyInto(*out) } } @@ -253,6 +244,214 @@ func (in *KongIngressList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KongIngressRoute) DeepCopyInto(out *KongIngressRoute) { + *out = *in + if in.Methods != nil { + in, out := &in.Methods, &out.Methods + *out = make([]*string, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(string) + **out = **in + } + } + } + if in.Headers != nil { + in, out := &in.Headers, &out.Headers + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } + if in.Protocols != nil { + in, out := &in.Protocols, &out.Protocols + *out = make([]*KongProtocol, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(KongProtocol) + **out = **in + } + } + } + if in.RegexPriority != nil { + in, out := &in.RegexPriority, &out.RegexPriority + *out = new(int) + **out = **in + } + if in.StripPath != nil { + in, out := &in.StripPath, &out.StripPath + *out = new(bool) + **out = **in + } + if in.PreserveHost != nil { + in, out := &in.PreserveHost, &out.PreserveHost + *out = new(bool) + **out = **in + } + if in.HTTPSRedirectStatusCode != nil { + in, out := &in.HTTPSRedirectStatusCode, &out.HTTPSRedirectStatusCode + *out = new(int) + **out = **in + } + if in.PathHandling != nil { + in, out := &in.PathHandling, &out.PathHandling + *out = new(string) + **out = **in + } + if in.SNIs != nil { + in, out := &in.SNIs, &out.SNIs + *out = make([]*string, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(string) + **out = **in + } + } + } + if in.RequestBuffering != nil { + in, out := &in.RequestBuffering, &out.RequestBuffering + *out = new(bool) + **out = **in + } + if in.ResponseBuffering != nil { + in, out := &in.ResponseBuffering, &out.ResponseBuffering + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KongIngressRoute. +func (in *KongIngressRoute) DeepCopy() *KongIngressRoute { + if in == nil { + return nil + } + out := new(KongIngressRoute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KongIngressService) DeepCopyInto(out *KongIngressService) { + *out = *in + if in.Protocol != nil { + in, out := &in.Protocol, &out.Protocol + *out = new(string) + **out = **in + } + if in.Path != nil { + in, out := &in.Path, &out.Path + *out = new(string) + **out = **in + } + if in.Retries != nil { + in, out := &in.Retries, &out.Retries + *out = new(int) + **out = **in + } + if in.ConnectTimeout != nil { + in, out := &in.ConnectTimeout, &out.ConnectTimeout + *out = new(int) + **out = **in + } + if in.ReadTimeout != nil { + in, out := &in.ReadTimeout, &out.ReadTimeout + *out = new(int) + **out = **in + } + if in.WriteTimeout != nil { + in, out := &in.WriteTimeout, &out.WriteTimeout + *out = new(int) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KongIngressService. +func (in *KongIngressService) DeepCopy() *KongIngressService { + if in == nil { + return nil + } + out := new(KongIngressService) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KongIngressUpstream) DeepCopyInto(out *KongIngressUpstream) { + *out = *in + if in.HostHeader != nil { + in, out := &in.HostHeader, &out.HostHeader + *out = new(string) + **out = **in + } + if in.Algorithm != nil { + in, out := &in.Algorithm, &out.Algorithm + *out = new(string) + **out = **in + } + if in.Slots != nil { + in, out := &in.Slots, &out.Slots + *out = new(int) + **out = **in + } + if in.Healthchecks != nil { + in, out := &in.Healthchecks, &out.Healthchecks + *out = new(kong.Healthcheck) + (*in).DeepCopyInto(*out) + } + if in.HashOn != nil { + in, out := &in.HashOn, &out.HashOn + *out = new(string) + **out = **in + } + if in.HashFallback != nil { + in, out := &in.HashFallback, &out.HashFallback + *out = new(string) + **out = **in + } + if in.HashOnHeader != nil { + in, out := &in.HashOnHeader, &out.HashOnHeader + *out = new(string) + **out = **in + } + if in.HashFallbackHeader != nil { + in, out := &in.HashFallbackHeader, &out.HashFallbackHeader + *out = new(string) + **out = **in + } + if in.HashOnCookie != nil { + in, out := &in.HashOnCookie, &out.HashOnCookie + *out = new(string) + **out = **in + } + if in.HashOnCookiePath != nil { + in, out := &in.HashOnCookiePath, &out.HashOnCookiePath + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KongIngressUpstream. +func (in *KongIngressUpstream) DeepCopy() *KongIngressUpstream { + if in == nil { + return nil + } + out := new(KongIngressUpstream) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KongPlugin) DeepCopyInto(out *KongPlugin) { *out = *in @@ -266,7 +465,7 @@ func (in *KongPlugin) DeepCopyInto(out *KongPlugin) { } if in.Protocols != nil { in, out := &in.Protocols, &out.Protocols - *out = make([]string, len(*in)) + *out = make([]KongProtocol, len(*in)) copy(*out, *in) } } @@ -324,7 +523,6 @@ func (in *KongPluginList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespacedConfigSource) DeepCopyInto(out *NamespacedConfigSource) { *out = *in - out.TypeMeta = in.TypeMeta out.SecretValue = in.SecretValue } @@ -338,18 +536,9 @@ func (in *NamespacedConfigSource) DeepCopy() *NamespacedConfigSource { return out } -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NamespacedConfigSource) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespacedSecretValueFromSource) DeepCopyInto(out *NamespacedSecretValueFromSource) { *out = *in - out.TypeMeta = in.TypeMeta } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedSecretValueFromSource. @@ -362,18 +551,9 @@ func (in *NamespacedSecretValueFromSource) DeepCopy() *NamespacedSecretValueFrom return out } -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NamespacedSecretValueFromSource) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretValueFromSource) DeepCopyInto(out *SecretValueFromSource) { *out = *in - out.TypeMeta = in.TypeMeta } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretValueFromSource. @@ -385,11 +565,3 @@ func (in *SecretValueFromSource) DeepCopy() *SecretValueFromSource { in.DeepCopyInto(out) return out } - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *SecretValueFromSource) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} diff --git a/test/e2e/all_in_one_test.go b/test/e2e/all_in_one_test.go index 4c00496850..7115ddb257 100644 --- a/test/e2e/all_in_one_test.go +++ b/test/e2e/all_in_one_test.go @@ -15,6 +15,7 @@ import ( "os" "os/exec" "path/filepath" + "sort" "strings" "testing" "time" @@ -24,6 +25,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/kustomize/api/krusty" @@ -37,6 +39,8 @@ import ( "github.com/kong/kubernetes-testing-framework/pkg/utils/kubernetes/generators" "github.com/kong/kubernetes-ingress-controller/v2/internal/annotations" + kongv1 "github.com/kong/kubernetes-ingress-controller/v2/pkg/apis/configuration/v1" + "github.com/kong/kubernetes-ingress-controller/v2/pkg/clientset" ) // ----------------------------------------------------------------------------- @@ -71,7 +75,10 @@ var imageOverride = os.Getenv("TEST_KONG_CONTROLLER_IMAGE_OVERRIDE") // ensure that things are up and running. // ----------------------------------------------------------------------------- -const dblessPath = "../../deploy/single/all-in-one-dbless.yaml" +const ( + dblessPath = "../../deploy/single/all-in-one-dbless.yaml" + dblessURL = "https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/%v.%v.x/deploy/single/all-in-one-dbless.yaml" +) func TestDeployAllInOneDBLESS(t *testing.T) { t.Log("configuring all-in-one-dbless.yaml manifest test") @@ -103,6 +110,57 @@ func TestDeployAllInOneDBLESS(t *testing.T) { deployKong(ctx, t, env, manifest) t.Log("running ingress tests to verify all-in-one deployed ingress controller and proxy are functional") + deployIngress(ctx, t, env) + verifyIngress(ctx, t, env) +} + +func TestDeployAndUpgradeAllInOneDBLESS(t *testing.T) { + curTag, err := getCurrentGitTag("") + require.NoError(t, err) + preTag, err := getPreviousGitTag("", curTag) + require.NoError(t, err) + if curTag.Patch != 0 || len(curTag.Pre) > 0 { + t.Skipf("%v not a new minor version, skipping upgrade test", curTag) + } + oldManifest, err := http.Get(fmt.Sprintf(dblessURL, preTag.Major, preTag.Minor)) + require.NoError(t, err) + defer oldManifest.Body.Close() + + t.Log("configuring all-in-one-dbless.yaml manifest test") + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + t.Log("building test cluster and environment") + addons := []clusters.Addon{} + addons = append(addons, metallb.New()) + if b, err := loadimage.NewBuilder().WithImage(imageOverride); err == nil { + addons = append(addons, b.Build()) + } + builder := environments.NewBuilder().WithAddons(addons...) + if clusterVersionStr != "" { + clusterVersion, err := semver.Parse(clusterVersionStr) + require.NoError(t, err) + builder.WithKubernetesVersion(clusterVersion) + } + env, err := builder.Build(ctx) + require.NoError(t, err) + defer func() { + assert.NoError(t, env.Cleanup(ctx)) + }() + + t.Logf("deploying previous version %s kong manifest", preTag) + deployKong(ctx, t, env, oldManifest.Body) + + t.Log("running ingress tests to verify all-in-one deployed ingress controller and proxy are functional") + deployIngress(ctx, t, env) + verifyIngress(ctx, t, env) + + t.Logf("deploying current version %s kong manifest", curTag) + + manifest, err := getTestManifest(t, dblessPath) + require.NoError(t, err) + deployKong(ctx, t, env, manifest) verifyIngress(ctx, t, env) } @@ -137,6 +195,7 @@ func TestDeployAllInOneDBLESSNoLoadBalancer(t *testing.T) { deployKong(ctx, t, env, manifest) t.Log("running ingress tests to verify all-in-one deployed ingress controller and proxy are functional") + deployIngress(ctx, t, env) verifyIngress(ctx, t, env) } @@ -186,6 +245,7 @@ func TestDeployAllInOneEnterpriseDBLESS(t *testing.T) { exposeAdminAPI(ctx, t, env) t.Log("running ingress tests to verify all-in-one deployed ingress controller and proxy are functional") + deployIngress(ctx, t, env) verifyIngress(ctx, t, env) t.Log("verifying enterprise mode was enabled properly") @@ -227,6 +287,7 @@ func TestDeployAllInOnePostgres(t *testing.T) { verifyPostgres(ctx, t, env) t.Log("running ingress tests to verify all-in-one deployed ingress controller and proxy are functional") + deployIngress(ctx, t, env) verifyIngress(ctx, t, env) } @@ -276,6 +337,7 @@ func TestDeployAllInOneEnterprisePostgres(t *testing.T) { verifyPostgres(ctx, t, env) t.Log("running ingress tests to verify ingress controller and proxy are functional") + deployIngress(ctx, t, env) verifyIngress(ctx, t, env) t.Log("this deployment used enterprise kong, verifying that enterprise functionality was set up properly") @@ -307,27 +369,29 @@ func deployKong(ctx context.Context, t *testing.T, env environments.Environment, written, err := kubeconfigFile.Write(kubeconfig) require.NoError(t, err) require.Equal(t, len(kubeconfig), written) + kubeconfigFilename := kubeconfigFile.Name() t.Log("waiting for testing environment to be ready") require.NoError(t, <-env.WaitForReady(ctx)) t.Log("creating the kong namespace") - kubeconfigFilename := kubeconfigFile.Name() - stdout, stderr := new(bytes.Buffer), new(bytes.Buffer) - cmd := exec.CommandContext(ctx, "kubectl", "--kubeconfig", kubeconfigFilename, "create", "namespace", namespace) - cmd.Stdout = stdout - cmd.Stderr = stderr - require.NoError(t, cmd.Run(), fmt.Sprintf("STDOUT=(%s), STDERR=(%s)", stdout.String(), stderr.String())) + ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "kong"}} + _, err = env.Cluster().Client().CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) + if !kerrors.IsAlreadyExists(err) { + require.NoError(t, err) + } t.Logf("deploying any supplemental secrets (found: %d)", len(additionalSecrets)) for _, secret := range additionalSecrets { _, err := env.Cluster().Client().CoreV1().Secrets("kong").Create(ctx, secret, metav1.CreateOptions{}) - require.NoError(t, err) + if !kerrors.IsAlreadyExists(err) { + require.NoError(t, err) + } } t.Log("deploying the manifest to the cluster") - stdout, stderr = new(bytes.Buffer), new(bytes.Buffer) - cmd = exec.CommandContext(ctx, "kubectl", "--kubeconfig", kubeconfigFilename, "apply", "-f", "-") + stdout, stderr := new(bytes.Buffer), new(bytes.Buffer) + cmd := exec.CommandContext(ctx, "kubectl", "--kubeconfig", kubeconfigFilename, "apply", "-f", "-") cmd.Stdout = stdout cmd.Stderr = stderr cmd.Stdin = manifest @@ -341,11 +405,13 @@ func deployKong(ctx context.Context, t *testing.T, env environments.Environment, }, kongComponentWait, time.Second) } -func verifyIngress(ctx context.Context, t *testing.T, env environments.Environment) { +func deployIngress(ctx context.Context, t *testing.T, env environments.Environment) { + c, err := clientset.NewForConfig(env.Cluster().Config()) + assert.NoError(t, err) t.Log("deploying an HTTP service to test the ingress controller and proxy") container := generators.NewContainer("httpbin", httpBinImage, 80) deployment := generators.NewDeploymentForContainer(container) - deployment, err := env.Cluster().Client().AppsV1().Deployments(corev1.NamespaceDefault).Create(ctx, deployment, metav1.CreateOptions{}) + deployment, err = env.Cluster().Client().AppsV1().Deployments(corev1.NamespaceDefault).Create(ctx, deployment, metav1.CreateOptions{}) require.NoError(t, err) t.Logf("exposing deployment %s via service", deployment.Name) @@ -353,15 +419,33 @@ func verifyIngress(ctx context.Context, t *testing.T, env environments.Environme _, err = env.Cluster().Client().CoreV1().Services(corev1.NamespaceDefault).Create(ctx, service, metav1.CreateOptions{}) require.NoError(t, err) + getString := "GET" + king := &kongv1.KongIngress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testki", + Namespace: corev1.NamespaceDefault, + Annotations: map[string]string{ + annotations.IngressClassKey: ingressClass, + }, + }, + Route: &kongv1.KongIngressRoute{ + Methods: []*string{&getString}, + }, + } + king, err = c.ConfigurationV1().KongIngresses(corev1.NamespaceDefault).Create(ctx, king, + metav1.CreateOptions{}) t.Logf("creating an ingress for service %s with ingress.class %s", service.Name, ingressClass) kubernetesVersion, err := env.Cluster().Version() require.NoError(t, err) ingress := generators.NewIngressForServiceWithClusterVersion(kubernetesVersion, "/httpbin", map[string]string{ annotations.IngressClassKey: ingressClass, "konghq.com/strip-path": "true", + "konghq.com/override": "testki", }, service) require.NoError(t, clusters.DeployIngress(ctx, env.Cluster(), corev1.NamespaceDefault, ingress)) +} +func verifyIngress(ctx context.Context, t *testing.T, env environments.Environment) { t.Log("finding the kong proxy service ip") svc, err := env.Cluster().Client().CoreV1().Services(namespace).Get(ctx, "kong-proxy", metav1.GetOptions{}) require.NoError(t, err) @@ -419,7 +503,19 @@ func verifyIngress(ctx context.Context, t *testing.T, env environments.Environme n, err := b.ReadFrom(resp.Body) require.NoError(t, err) require.True(t, n > 0) - return strings.Contains(b.String(), "httpbin.org") + if !strings.Contains(b.String(), "httpbin.org") { + return false + } + } + // verify the KongIngress method restriction + fakeData := url.Values{} + fakeData.Set("foo", "bar") + resp, err = httpc.PostForm(fmt.Sprintf("http://%s/httpbin", proxyIP), fakeData) + if err != nil { + return false + } + if resp.StatusCode == http.StatusNotFound { + return true } return false }, ingressWait, time.Second) @@ -652,3 +748,34 @@ func kustomizeManifest(path string) ([]byte, error) { } return m.AsYaml() } + +func getCurrentGitTag(path string) (semver.Version, error) { + cmd := exec.Command("git", "describe", "--tags") + cmd.Dir = path + tagBytes, _ := cmd.Output() + tag, err := semver.ParseTolerant(string(tagBytes)) + if err != nil { + return semver.Version{}, err + } + return tag, nil +} + +func getPreviousGitTag(path string, cur semver.Version) (semver.Version, error) { + var tags []semver.Version + cmd := exec.Command("git", "tag") + cmd.Dir = path + tagsBytes, _ := cmd.Output() + foo := strings.Split(string(tagsBytes), "\n") + for _, tag := range foo { + ver, err := semver.ParseTolerant(tag) + if err == nil { + tags = append(tags, ver) + } + } + sort.Slice(tags, func(i, j int) bool { return tags[i].LT(tags[j]) }) + curIndex := sort.Search(len(tags), func(i int) bool { return tags[i].EQ(cur) }) + if curIndex == 0 { + return tags[curIndex], nil + } + return tags[curIndex-1], nil +} diff --git a/test/integration/knative_test.go b/test/integration/knative_test.go index ab121c4057..456db50fd9 100644 --- a/test/integration/knative_test.go +++ b/test/integration/knative_test.go @@ -166,7 +166,6 @@ func accessKnativeSrv(ctx context.Context, proxy, nsn string, t *testing.T) bool return assert.Eventually(t, func() bool { resp, err := client.Do(req) - t.Logf("resp <%v> ", resp.StatusCode) if err != nil { return false } diff --git a/test/integration/kongingress_test.go b/test/integration/kongingress_test.go index a996c1c337..8ceb4c1f21 100644 --- a/test/integration/kongingress_test.go +++ b/test/integration/kongingress_test.go @@ -75,7 +75,7 @@ func TestKongIngressEssentials(t *testing.T) { annotations.IngressClassKey: ingressClass, }, }, - Proxy: &kong.Service{ + Proxy: &kongv1.KongIngressService{ ReadTimeout: kong.Int(1000), }, }