From 72293bb8964190766830dee75460ee00ff5f9e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Thu, 22 May 2025 18:34:16 +0200 Subject: [PATCH 01/19] chore: add v2alpha1 group and add ControlPlane type --- Makefile | 1 + .../v1beta1/controlplane_types.go | 1 + .../v2alpha1/controlplane_types.go | 236 ++++++++++++++ api/gateway-operator/v2alpha1/doc.go | 21 ++ .../v2alpha1/groupversion_info.go | 36 +++ .../v2alpha1/zz_generated.deepcopy.go | 253 +++++++++++++++ ...way-operator.konghq.com_controlplanes.yaml | 297 ++++++++++++++++++ .../controlplane_v2_dataplane_name.yaml | 19 ++ .../controlplane_v2_dataplane_url.yaml | 14 + docs/all-api-reference.md | 147 +++++++++ docs/gateway-operator-api-reference.md | 147 +++++++++ pkg/clientset/clientset.go | 13 + pkg/clientset/fake/clientset_generated.go | 7 + pkg/clientset/fake/register.go | 2 + pkg/clientset/scheme/register.go | 2 + .../gateway-operator/v2alpha1/controlplane.go | 70 +++++ .../typed/gateway-operator/v2alpha1/doc.go | 20 ++ .../gateway-operator/v2alpha1/fake/doc.go | 20 ++ .../v2alpha1/fake/fake_controlplane.go | 52 +++ .../fake/fake_gateway-operator_client.go | 40 +++ .../v2alpha1/gateway-operator_client.go | 101 ++++++ .../v2alpha1/generated_expansion.go | 21 ++ scripts/crds-generator/main.go | 1 + 23 files changed, 1521 insertions(+) create mode 100644 api/gateway-operator/v2alpha1/controlplane_types.go create mode 100644 api/gateway-operator/v2alpha1/doc.go create mode 100644 api/gateway-operator/v2alpha1/groupversion_info.go create mode 100644 api/gateway-operator/v2alpha1/zz_generated.deepcopy.go create mode 100644 config/samples/controlplane_v2_dataplane_name.yaml create mode 100644 config/samples/controlplane_v2_dataplane_url.yaml create mode 100644 pkg/clientset/typed/gateway-operator/v2alpha1/controlplane.go create mode 100644 pkg/clientset/typed/gateway-operator/v2alpha1/doc.go create mode 100644 pkg/clientset/typed/gateway-operator/v2alpha1/fake/doc.go create mode 100644 pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_controlplane.go create mode 100644 pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_gateway-operator_client.go create mode 100644 pkg/clientset/typed/gateway-operator/v2alpha1/gateway-operator_client.go create mode 100644 pkg/clientset/typed/gateway-operator/v2alpha1/generated_expansion.go diff --git a/Makefile b/Makefile index 7f8be044..db31bb5a 100644 --- a/Makefile +++ b/Makefile @@ -176,6 +176,7 @@ generate.clientsets: client-gen --input incubator/v1alpha1 \ --input gateway-operator/v1alpha1 \ --input gateway-operator/v1beta1 \ + --input gateway-operator/v2alpha1 \ --output-dir pkg/ \ --output-pkg $(REPO_URL)/pkg/ diff --git a/api/gateway-operator/v1beta1/controlplane_types.go b/api/gateway-operator/v1beta1/controlplane_types.go index 49f40777..bed69b4b 100644 --- a/api/gateway-operator/v1beta1/controlplane_types.go +++ b/api/gateway-operator/v1beta1/controlplane_types.go @@ -31,6 +31,7 @@ func init() { // ControlPlane is the Schema for the controlplanes API // // +genclient +// +kubebuilder:storageversion // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:object:root=true // +kubebuilder:subresource:status diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go new file mode 100644 index 00000000..a4ab4a77 --- /dev/null +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -0,0 +1,236 @@ +/* +Copyright 2022 Kong Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" + + commonv1alpha1 "github.com/kong/kubernetes-configuration/api/common/v1alpha1" + operatorv1beta1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1" +) + +func init() { + SchemeBuilder.Register(&ControlPlane{}, &ControlPlaneList{}) +} + +// ControlPlane is the Schema for the controlplanes API +// +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:shortName=kocp,categories=kong;all +// +kubebuilder:printcolumn:name="Ready",description="The Resource is ready",type=string,JSONPath=`.status.conditions[?(@.type=='Ready')].status` +// +apireference:kgo:include +// +kong:channels=gateway-operator +type ControlPlane struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ControlPlaneSpec `json:"spec,omitempty"` + Status ControlPlaneStatus `json:"status,omitempty"` +} + +// ControlPlaneList contains a list of ControlPlane +// +// +kubebuilder:object:root=true +// +apireference:kgo:include +type ControlPlaneList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ControlPlane `json:"items"` +} + +// ControlPlaneSpec defines the desired state of ControlPlane +// +// +apireference:kgo:include +type ControlPlaneSpec struct { + ControlPlaneOptions `json:",inline"` + + // GatewayClass indicates the Gateway resources which this ControlPlane + // should be responsible for configuring routes for (e.g. HTTPRoute, + // TCPRoute, UDPRoute, TLSRoute, e.t.c.). + // + // Required for the ControlPlane to have any effect: at least one Gateway + // must be present for configuration to be pushed to the data-plane and + // only Gateway resources can be used to identify data-plane entities. + // + // +optional + GatewayClass *gatewayv1.ObjectName `json:"gatewayClass,omitempty"` + + // IngressClass enables support for the older Ingress resource and indicates + // which Ingress resources this ControlPlane should be responsible for. + // + // Routing configured this way will be applied to the Gateway resources + // indicated by GatewayClass. + // + // If omitted, Ingress resources will not be supported by the ControlPlane. + // + // +optional + IngressClass *string `json:"ingressClass,omitempty"` +} + +// ControlPlaneOptions indicates the specific information needed to +// deploy and connect a ControlPlane to a DataPlane object. +// +// +apireference:kgo:include +// +kubebuilder:validation:XValidation:message="Extension not allowed for ControlPlane",rule="has(self.extensions) ? self.extensions.all(e, (e.group == 'konnect.konghq.com' && e.kind == 'KonnectExtension') || (e.group == 'gateway-operator.konghq.com' && e.kind == 'DataPlaneMetricsExtension')) : true" +type ControlPlaneOptions struct { + // DataPlanes designates the target data plane to configure. + // + // It can be either a URL to an externally managed DataPlane (e.g. installed + // independently with Helm) or a name of a DataPlane resource that is + // managed by the operator. + // + // +required + DataPlane ControlPlaneDataPlaneTarget `json:"dataplane,omitempty"` + + // Extensions provide additional or replacement features for the ControlPlane + // resources to influence or enhance functionality. + // + // +optional + // +kubebuilder:validation:MinItems=0 + // +kubebuilder:validation:MaxItems=2 + Extensions []commonv1alpha1.ExtensionRef `json:"extensions,omitempty"` + + // WatchNamespaces indicates the namespaces to watch for resources. + // + // +optional + // +kubebuilder:default={type: all} + WatchNamespaces *operatorv1beta1.WatchNamespaces `json:"watchNamespaces,omitempty"` + + // FeatureGates is a list of feature gates that are enabled for this ControlPlane. + // + // +optional + // +listType=map + // +listMapKey=name + // +kubebuilder:validation:MaxItems=32 + FeatureGates []ControlPlaneFeatureGate `json:"featureGates,omitempty"` + + // Controllers defines the controllers that are enabled for this ControlPlane. + // + // +optional + // +listType=map + // +listMapKey=name + // +kubebuilder:validation:MaxItems=32 + Controllers []ControlPlaneController `json:"controllers,omitempty"` + + // AdminAPI defines the configuration for the Kong Admin API. + // + // +optional + AdminAPI *ControlPlaneAdminAPI `json:"adminAPI,omitempty"` +} + +// ControlPlaneDataPlaneTarget defines the target for the DataPlane that the ControlPlane +// is responsible for configuring. +// +// +kubebuilder:validation:XValidation:message="URL has to be provided when type is set to url",rule="self.type != 'url' || has(self.url)" +// +kubebuilder:validation:XValidation:message="Name cannot be provided when type is set to url",rule="self.type != 'url' || !has(self.name)" +// +kubebuilder:validation:XValidation:message="Name has to be provided when type is set to name",rule="self.type != 'name' || has(self.name)" +// +kubebuilder:validation:XValidation:message="URL cannot be provided when type is set to name",rule="self.type != 'name' || !has(self.url)" +type ControlPlaneDataPlaneTarget struct { + // Type indicates the type of the DataPlane target. + // + // +kubebuilder:validation:Enum=url;name + // +kubebuilder:validation:Required + Type string `json:"type,omitempty"` + + // URL is the URL of the DataPlane target. This is used for configuring + // externally managed DataPlanes like those installed independently with Helm. + // + // +optional + URL string `json:"url,omitempty"` + + // Name is the name of the DataPlane to configure. + // + // +optional + Name string `json:"name,omitempty"` +} + +// ControlPlaneAdminAPI defines the configuration for the Kong Admin API that +// a ControlPlane when configuring the DataPlane. +type ControlPlaneAdminAPI struct { + // Workspace indicates the Kong Workspace to use for the ControlPlane. + // If left empty then no Kong workspace will be used. + // + // +optional + Workspace string `json:"workspace,omitempty"` +} + +// ControlPlaneController defines a controller state for the ControlPlane. +// It overrides the default behavior as defined in the deployed operator version. +// +// +apireference:kgo:include +type ControlPlaneController struct { + // Name is the name of the controller. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Name string `json:"name,omitempty"` + + // Enabled indicates whether the controller is enabled or not. + // + // +kubebuilder:validation:Required + Enabled *bool `json:"enabled,omitempty"` +} + +// ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. +// It overrides the default behavior as defined in the deployed operator version. +// +// +apireference:kgo:include +type ControlPlaneFeatureGate struct { + // Name is the name of the feature gate. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Name string `json:"name,omitempty"` + + // Enabled indicates whether the feature gate is enabled or not. + // + // +kubebuilder:validation:Required + Enabled *bool `json:"enabled,omitempty"` +} + +// ControlPlaneStatus defines the observed state of ControlPlane +// +// +apireference:kgo:include +type ControlPlaneStatus struct { + // Conditions describe the current conditions of the Gateway. + // + // +optional + // +listType=map + // +listMapKey=type + // +kubebuilder:validation:MaxItems=8 + // +kubebuilder:default={{type: "Scheduled", status: "Unknown", reason:"NotReconciled", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}} + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// GetConditions returns the ControlPlane Status Conditions +func (c *ControlPlane) GetConditions() []metav1.Condition { + return c.Status.Conditions +} + +// SetConditions sets the ControlPlane Status Conditions +func (c *ControlPlane) SetConditions(conditions []metav1.Condition) { + c.Status.Conditions = conditions +} + +// GetExtensions retrieves the ControlPlane Extensions +func (c *ControlPlane) GetExtensions() []commonv1alpha1.ExtensionRef { + return c.Spec.Extensions +} diff --git a/api/gateway-operator/v2alpha1/doc.go b/api/gateway-operator/v2alpha1/doc.go new file mode 100644 index 00000000..13fe3e73 --- /dev/null +++ b/api/gateway-operator/v2alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2025 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v2alpha1 contains API Schema definitions for the gateway-operator.konghq.com v2alpha1 API group. +// +kubebuilder:object:generate=true +// +groupName=gateway-operator.konghq.com +// +groupGoName=GatewayOperator +package v2alpha1 diff --git a/api/gateway-operator/v2alpha1/groupversion_info.go b/api/gateway-operator/v2alpha1/groupversion_info.go new file mode 100644 index 00000000..99b781bd --- /dev/null +++ b/api/gateway-operator/v2alpha1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 Kong Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v2alpha1 contains API Schema definitions for the gateway-operator.konghq.com v2alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=gateway-operator.konghq.com +package v2alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "gateway-operator.konghq.com", Version: "v2alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..04113cb8 --- /dev/null +++ b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go @@ -0,0 +1,253 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v2alpha1 + +import ( + "github.com/kong/kubernetes-configuration/api/common/v1alpha1" + "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/gateway-api/apis/v1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlane) DeepCopyInto(out *ControlPlane) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlane. +func (in *ControlPlane) DeepCopy() *ControlPlane { + if in == nil { + return nil + } + out := new(ControlPlane) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ControlPlane) 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 *ControlPlaneAdminAPI) DeepCopyInto(out *ControlPlaneAdminAPI) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneAdminAPI. +func (in *ControlPlaneAdminAPI) DeepCopy() *ControlPlaneAdminAPI { + if in == nil { + return nil + } + out := new(ControlPlaneAdminAPI) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneController) DeepCopyInto(out *ControlPlaneController) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneController. +func (in *ControlPlaneController) DeepCopy() *ControlPlaneController { + if in == nil { + return nil + } + out := new(ControlPlaneController) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneDataPlaneTarget) DeepCopyInto(out *ControlPlaneDataPlaneTarget) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneDataPlaneTarget. +func (in *ControlPlaneDataPlaneTarget) DeepCopy() *ControlPlaneDataPlaneTarget { + if in == nil { + return nil + } + out := new(ControlPlaneDataPlaneTarget) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneFeatureGate) DeepCopyInto(out *ControlPlaneFeatureGate) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneFeatureGate. +func (in *ControlPlaneFeatureGate) DeepCopy() *ControlPlaneFeatureGate { + if in == nil { + return nil + } + out := new(ControlPlaneFeatureGate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneList) DeepCopyInto(out *ControlPlaneList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ControlPlane, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneList. +func (in *ControlPlaneList) DeepCopy() *ControlPlaneList { + if in == nil { + return nil + } + out := new(ControlPlaneList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ControlPlaneList) 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 *ControlPlaneOptions) DeepCopyInto(out *ControlPlaneOptions) { + *out = *in + out.DataPlane = in.DataPlane + if in.Extensions != nil { + in, out := &in.Extensions, &out.Extensions + *out = make([]v1alpha1.ExtensionRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.WatchNamespaces != nil { + in, out := &in.WatchNamespaces, &out.WatchNamespaces + *out = new(v1beta1.WatchNamespaces) + (*in).DeepCopyInto(*out) + } + if in.FeatureGates != nil { + in, out := &in.FeatureGates, &out.FeatureGates + *out = make([]ControlPlaneFeatureGate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Controllers != nil { + in, out := &in.Controllers, &out.Controllers + *out = make([]ControlPlaneController, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AdminAPI != nil { + in, out := &in.AdminAPI, &out.AdminAPI + *out = new(ControlPlaneAdminAPI) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneOptions. +func (in *ControlPlaneOptions) DeepCopy() *ControlPlaneOptions { + if in == nil { + return nil + } + out := new(ControlPlaneOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneSpec) DeepCopyInto(out *ControlPlaneSpec) { + *out = *in + in.ControlPlaneOptions.DeepCopyInto(&out.ControlPlaneOptions) + if in.GatewayClass != nil { + in, out := &in.GatewayClass, &out.GatewayClass + *out = new(v1.ObjectName) + **out = **in + } + if in.IngressClass != nil { + in, out := &in.IngressClass, &out.IngressClass + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneSpec. +func (in *ControlPlaneSpec) DeepCopy() *ControlPlaneSpec { + if in == nil { + return nil + } + out := new(ControlPlaneSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneStatus) DeepCopyInto(out *ControlPlaneStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneStatus. +func (in *ControlPlaneStatus) DeepCopy() *ControlPlaneStatus { + if in == nil { + return nil + } + out := new(ControlPlaneStatus) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index 1662314d..88d36066 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8383,3 +8383,300 @@ spec: storage: true subresources: status: {} + - additionalPrinterColumns: + - description: The Resource is ready + jsonPath: .status.conditions[?(@.type=='Ready')].status + name: Ready + type: string + name: v2alpha1 + schema: + openAPIV3Schema: + description: ControlPlane is the Schema for the controlplanes 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 + spec: + description: ControlPlaneSpec defines the desired state of ControlPlane + properties: + adminAPI: + description: AdminAPI defines the configuration for the Kong Admin + API. + properties: + workspace: + description: |- + Workspace indicates the Kong Workspace to use for the ControlPlane. + If left empty then no Kong workspace will be used. + type: string + type: object + controllers: + description: Controllers defines the controllers that are enabled + for this ControlPlane. + items: + description: |- + ControlPlaneController defines a controller state for the ControlPlane. + It overrides the default behavior as defined in the deployed operator version. + properties: + enabled: + description: Enabled indicates whether the controller is enabled + or not. + type: boolean + name: + description: Name is the name of the controller. + minLength: 1 + type: string + required: + - enabled + - name + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dataplane: + description: |- + DataPlanes designates the target data plane to configure. + + It can be either a URL to an externally managed DataPlane (e.g. installed + independently with Helm) or a name of a DataPlane resource that is + managed by the operator. + properties: + name: + description: Name is the name of the DataPlane to configure. + type: string + type: + description: Type indicates the type of the DataPlane target. + enum: + - url + - name + type: string + url: + description: |- + URL is the URL of the DataPlane target. This is used for configuring + externally managed DataPlanes like those installed independently with Helm. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: URL has to be provided when type is set to url + rule: self.type != 'url' || has(self.url) + - message: Name cannot be provided when type is set to url + rule: self.type != 'url' || !has(self.name) + - message: Name has to be provided when type is set to name + rule: self.type != 'name' || has(self.name) + - message: URL cannot be provided when type is set to name + rule: self.type != 'name' || !has(self.url) + extensions: + description: |- + Extensions provide additional or replacement features for the ControlPlane + resources to influence or enhance functionality. + items: + description: |- + ExtensionRef corresponds to another resource in the Kubernetes cluster which + defines extended behavior for a resource (e.g. ControlPlane). + properties: + group: + default: gateway-operator.konghq.com + description: Group is the group of the extension resource. + type: string + kind: + description: Kind is kind of the extension resource. + type: string + name: + description: Name is the name of the referred resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referred resource. + + For namespace-scoped resources if no Namespace is provided then the + namespace of the parent object MUST be used. + + This field MUST not be set when referring to cluster-scoped resources. + type: string + required: + - kind + - name + type: object + maxItems: 2 + minItems: 0 + type: array + featureGates: + description: FeatureGates is a list of feature gates that are enabled + for this ControlPlane. + items: + description: |- + ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. + It overrides the default behavior as defined in the deployed operator version. + properties: + enabled: + description: Enabled indicates whether the feature gate is enabled + or not. + type: boolean + name: + description: Name is the name of the feature gate. + minLength: 1 + type: string + required: + - enabled + - name + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + gatewayClass: + description: |- + GatewayClass indicates the Gateway resources which this ControlPlane + should be responsible for configuring routes for (e.g. HTTPRoute, + TCPRoute, UDPRoute, TLSRoute, e.t.c.). + + Required for the ControlPlane to have any effect: at least one Gateway + must be present for configuration to be pushed to the data-plane and + only Gateway resources can be used to identify data-plane entities. + maxLength: 253 + minLength: 1 + type: string + ingressClass: + description: |- + IngressClass enables support for the older Ingress resource and indicates + which Ingress resources this ControlPlane should be responsible for. + + Routing configured this way will be applied to the Gateway resources + indicated by GatewayClass. + + If omitted, Ingress resources will not be supported by the ControlPlane. + type: string + watchNamespaces: + default: + type: all + description: WatchNamespaces indicates the namespaces to watch for + resources. + properties: + list: + description: |- + List is a list of namespaces to watch for resources. + Only used when Type is set to List. + items: + type: string + type: array + type: + description: |- + Type indicates the type of namespace watching to be done. + By default, all namespaces are watched. + enum: + - all + - list + - own + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: list is required when type is 'list' + rule: 'self.type == ''list'' ? has(self.list) : true' + - message: list must not be specified when type is not 'list' + rule: 'self.type != ''list'' ? !has(self.list) : true' + required: + - dataplane + type: object + x-kubernetes-validations: + - message: Extension not allowed for ControlPlane + rule: 'has(self.extensions) ? self.extensions.all(e, (e.group == ''konnect.konghq.com'' + && e.kind == ''KonnectExtension'') || (e.group == ''gateway-operator.konghq.com'' + && e.kind == ''DataPlaneMetricsExtension'')) : true' + status: + description: ControlPlaneStatus defines the observed state of ControlPlane + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: NotReconciled + status: Unknown + type: Scheduled + description: Conditions describe the current conditions of the Gateway. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: false + subresources: + status: {} diff --git a/config/samples/controlplane_v2_dataplane_name.yaml b/config/samples/controlplane_v2_dataplane_name.yaml new file mode 100644 index 00000000..c216502e --- /dev/null +++ b/config/samples/controlplane_v2_dataplane_name.yaml @@ -0,0 +1,19 @@ +apiVersion: gateway-operator.konghq.com/v2alpha1 +kind: ControlPlane +metadata: + name: controlplane-v2-example +spec: + dataplane: + type: name + name: dataplane-name + gatewayClass: kong + featureGates: + - name: GatewayAlpha + enabled: true + controllers: + - name: TCPIngress + enabled: false + - name: Konnect + enabled: true + adminAPI: + workspace: my_custom_workspace diff --git a/config/samples/controlplane_v2_dataplane_url.yaml b/config/samples/controlplane_v2_dataplane_url.yaml new file mode 100644 index 00000000..636f75c6 --- /dev/null +++ b/config/samples/controlplane_v2_dataplane_url.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway-operator.konghq.com/v2alpha1 +kind: ControlPlane +metadata: + name: controlplane-v2-example +spec: + dataplane: + type: url + url: https://dataplane.example.com:8100/api + gatewayClass: kong + featureGates: + - name: GatewayAlpha + enabled: true + adminAPI: + workspace: my_custom_workspace diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index de46961f..b9e1843b 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -6,6 +6,7 @@ - [configuration.konghq.com/v1beta1](#configurationkonghqcomv1beta1) - [gateway-operator.konghq.com/v1alpha1](#gateway-operatorkonghqcomv1alpha1) - [gateway-operator.konghq.com/v1beta1](#gateway-operatorkonghqcomv1beta1) +- [gateway-operator.konghq.com/v2alpha1](#gateway-operatorkonghqcomv2alpha1) - [incubator.ingress-controller.konghq.com/v1alpha1](#incubatoringress-controllerkonghqcomv1alpha1) - [konnect.konghq.com/v1alpha1](#konnectkonghqcomv1alpha1) @@ -3353,6 +3354,8 @@ WatchNamespaces defines the namespaces to watch for resources _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) - [ControlPlaneSpec](#controlplanespec) #### WatchNamespacesType @@ -3368,6 +3371,150 @@ _Appears in:_ - [WatchNamespaces](#watchnamespaces) +## gateway-operator.konghq.com/v2alpha1 + +Package v2alpha1 contains API Schema definitions for the gateway-operator.konghq.com v2alpha1 API group. + +Package v2alpha1 contains API Schema definitions for the gateway-operator.konghq.com v2alpha1 API group + +- [ControlPlane](#controlplane) +### ControlPlane + + +ControlPlane is the Schema for the controlplanes API + + + +| Field | Description | +| --- | --- | +| `apiVersion` _string_ | `gateway-operator.konghq.com/v2alpha1` +| `kind` _string_ | `ControlPlane` +| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | +| `spec` _[ControlPlaneSpec](#controlplanespec)_ | | + + + +### Types + +In this section you will find types that the CRDs rely on. +#### ControlPlaneAdminAPI + + +ControlPlaneAdminAPI defines the configuration for the Kong Admin API that +a ControlPlane when configuring the DataPlane. + + + +| Field | Description | +| --- | --- | +| `workspace` _string_ | Workspace indicates the Kong Workspace to use for the ControlPlane. If left empty then no Kong workspace will be used. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneController + + +ControlPlaneController defines a controller state for the ControlPlane. +It overrides the default behavior as defined in the deployed operator version. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the name of the controller. | +| `enabled` _boolean_ | Enabled indicates whether the controller is enabled or not. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneDataPlaneTarget + + +ControlPlaneDataPlaneTarget defines the target for the DataPlane that the ControlPlane +is responsible for configuring. + + + +| Field | Description | +| --- | --- | +| `type` _string_ | Type indicates the type of the DataPlane target. | +| `url` _string_ | URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | +| `name` _string_ | Name is the name of the DataPlane to configure. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneFeatureGate + + +ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. +It overrides the default behavior as defined in the deployed operator version. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the name of the feature gate. | +| `enabled` _boolean_ | Enabled indicates whether the feature gate is enabled or not. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneOptions + + +ControlPlaneOptions indicates the specific information needed to +deploy and connect a ControlPlane to a DataPlane object. + + + +| Field | Description | +| --- | --- | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | +| `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | +| `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | +| `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | +| `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | + + +_Appears in:_ +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneSpec + + +ControlPlaneSpec defines the desired state of ControlPlane + + + +| Field | Description | +| --- | --- | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | +| `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | +| `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | +| `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | +| `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | +| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, e.t.c.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | +| `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

Routing configured this way will be applied to the Gateway resources indicated by GatewayClass.

If omitted, Ingress resources will not be supported by the ControlPlane. | + + +_Appears in:_ +- [ControlPlane](#controlplane) + + + + ## incubator.ingress-controller.konghq.com/v1alpha1 Package v1alpha1 contains API Schema definitions for the incubator.ingress-controller.konghq.com v1alpha1 API group. diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index b4f7835b..1f78d502 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -3,6 +3,7 @@ ## Packages - [gateway-operator.konghq.com/v1alpha1](#gateway-operatorkonghqcomv1alpha1) - [gateway-operator.konghq.com/v1beta1](#gateway-operatorkonghqcomv1beta1) +- [gateway-operator.konghq.com/v2alpha1](#gateway-operatorkonghqcomv2alpha1) ## gateway-operator.konghq.com/v1alpha1 @@ -1299,6 +1300,8 @@ WatchNamespaces defines the namespaces to watch for resources _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) - [ControlPlaneSpec](#controlplanespec) #### WatchNamespacesType @@ -1313,3 +1316,147 @@ WatchNamespacesType indicates the type of namespace watching to be done. _Appears in:_ - [WatchNamespaces](#watchnamespaces) + +## gateway-operator.konghq.com/v2alpha1 + +Package v2alpha1 contains API Schema definitions for the gateway-operator.konghq.com v2alpha1 API group. + +Package v2alpha1 contains API Schema definitions for the gateway-operator.konghq.com v2alpha1 API group + +- [ControlPlane](#controlplane) +### ControlPlane + + +ControlPlane is the Schema for the controlplanes API + + + +| Field | Description | +| --- | --- | +| `apiVersion` _string_ | `gateway-operator.konghq.com/v2alpha1` +| `kind` _string_ | `ControlPlane` +| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | +| `spec` _[ControlPlaneSpec](#controlplanespec)_ | | + + + +### Types + +In this section you will find types that the CRDs rely on. +#### ControlPlaneAdminAPI + + +ControlPlaneAdminAPI defines the configuration for the Kong Admin API that +a ControlPlane when configuring the DataPlane. + + + +| Field | Description | +| --- | --- | +| `workspace` _string_ | Workspace indicates the Kong Workspace to use for the ControlPlane. If left empty then no Kong workspace will be used. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneController + + +ControlPlaneController defines a controller state for the ControlPlane. +It overrides the default behavior as defined in the deployed operator version. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the name of the controller. | +| `enabled` _boolean_ | Enabled indicates whether the controller is enabled or not. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneDataPlaneTarget + + +ControlPlaneDataPlaneTarget defines the target for the DataPlane that the ControlPlane +is responsible for configuring. + + + +| Field | Description | +| --- | --- | +| `type` _string_ | Type indicates the type of the DataPlane target. | +| `url` _string_ | URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | +| `name` _string_ | Name is the name of the DataPlane to configure. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneFeatureGate + + +ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. +It overrides the default behavior as defined in the deployed operator version. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the name of the feature gate. | +| `enabled` _boolean_ | Enabled indicates whether the feature gate is enabled or not. | + + +_Appears in:_ +- [ControlPlaneOptions](#controlplaneoptions) +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneOptions + + +ControlPlaneOptions indicates the specific information needed to +deploy and connect a ControlPlane to a DataPlane object. + + + +| Field | Description | +| --- | --- | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | +| `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | +| `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | +| `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | +| `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | + + +_Appears in:_ +- [ControlPlaneSpec](#controlplanespec) + +#### ControlPlaneSpec + + +ControlPlaneSpec defines the desired state of ControlPlane + + + +| Field | Description | +| --- | --- | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | +| `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | +| `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | +| `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | +| `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | +| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, e.t.c.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | +| `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

Routing configured this way will be applied to the Gateway resources indicated by GatewayClass.

If omitted, Ingress resources will not be supported by the ControlPlane. | + + +_Appears in:_ +- [ControlPlane](#controlplane) + + + diff --git a/pkg/clientset/clientset.go b/pkg/clientset/clientset.go index 78cba632..77ecfeff 100644 --- a/pkg/clientset/clientset.go +++ b/pkg/clientset/clientset.go @@ -27,6 +27,7 @@ import ( configurationv1beta1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/configuration/v1beta1" gatewayoperatorv1alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v1alpha1" gatewayoperatorv1beta1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v1beta1" + gatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v2alpha1" incubatorv1alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/incubator/v1alpha1" konnectv1alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/konnect/v1alpha1" discovery "k8s.io/client-go/discovery" @@ -41,6 +42,7 @@ type Interface interface { ConfigurationV1beta1() configurationv1beta1.ConfigurationV1beta1Interface GatewayOperatorV1alpha1() gatewayoperatorv1alpha1.GatewayOperatorV1alpha1Interface GatewayOperatorV1beta1() gatewayoperatorv1beta1.GatewayOperatorV1beta1Interface + GatewayOperatorV2alpha1() gatewayoperatorv2alpha1.GatewayOperatorV2alpha1Interface IncubatorV1alpha1() incubatorv1alpha1.IncubatorV1alpha1Interface KonnectV1alpha1() konnectv1alpha1.KonnectV1alpha1Interface } @@ -53,6 +55,7 @@ type Clientset struct { configurationV1beta1 *configurationv1beta1.ConfigurationV1beta1Client gatewayOperatorV1alpha1 *gatewayoperatorv1alpha1.GatewayOperatorV1alpha1Client gatewayOperatorV1beta1 *gatewayoperatorv1beta1.GatewayOperatorV1beta1Client + gatewayOperatorV2alpha1 *gatewayoperatorv2alpha1.GatewayOperatorV2alpha1Client incubatorV1alpha1 *incubatorv1alpha1.IncubatorV1alpha1Client konnectV1alpha1 *konnectv1alpha1.KonnectV1alpha1Client } @@ -82,6 +85,11 @@ func (c *Clientset) GatewayOperatorV1beta1() gatewayoperatorv1beta1.GatewayOpera return c.gatewayOperatorV1beta1 } +// GatewayOperatorV2alpha1 retrieves the GatewayOperatorV2alpha1Client +func (c *Clientset) GatewayOperatorV2alpha1() gatewayoperatorv2alpha1.GatewayOperatorV2alpha1Interface { + return c.gatewayOperatorV2alpha1 +} + // IncubatorV1alpha1 retrieves the IncubatorV1alpha1Client func (c *Clientset) IncubatorV1alpha1() incubatorv1alpha1.IncubatorV1alpha1Interface { return c.incubatorV1alpha1 @@ -156,6 +164,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.gatewayOperatorV2alpha1, err = gatewayoperatorv2alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.incubatorV1alpha1, err = incubatorv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -190,6 +202,7 @@ func New(c rest.Interface) *Clientset { cs.configurationV1beta1 = configurationv1beta1.New(c) cs.gatewayOperatorV1alpha1 = gatewayoperatorv1alpha1.New(c) cs.gatewayOperatorV1beta1 = gatewayoperatorv1beta1.New(c) + cs.gatewayOperatorV2alpha1 = gatewayoperatorv2alpha1.New(c) cs.incubatorV1alpha1 = incubatorv1alpha1.New(c) cs.konnectV1alpha1 = konnectv1alpha1.New(c) diff --git a/pkg/clientset/fake/clientset_generated.go b/pkg/clientset/fake/clientset_generated.go index 4d3e9856..d5065e89 100644 --- a/pkg/clientset/fake/clientset_generated.go +++ b/pkg/clientset/fake/clientset_generated.go @@ -30,6 +30,8 @@ import ( fakegatewayoperatorv1alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v1alpha1/fake" gatewayoperatorv1beta1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v1beta1" fakegatewayoperatorv1beta1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v1beta1/fake" + gatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v2alpha1" + fakegatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v2alpha1/fake" incubatorv1alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/incubator/v1alpha1" fakeincubatorv1alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/incubator/v1alpha1/fake" konnectv1alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/konnect/v1alpha1" @@ -125,6 +127,11 @@ func (c *Clientset) GatewayOperatorV1beta1() gatewayoperatorv1beta1.GatewayOpera return &fakegatewayoperatorv1beta1.FakeGatewayOperatorV1beta1{Fake: &c.Fake} } +// GatewayOperatorV2alpha1 retrieves the GatewayOperatorV2alpha1Client +func (c *Clientset) GatewayOperatorV2alpha1() gatewayoperatorv2alpha1.GatewayOperatorV2alpha1Interface { + return &fakegatewayoperatorv2alpha1.FakeGatewayOperatorV2alpha1{Fake: &c.Fake} +} + // IncubatorV1alpha1 retrieves the IncubatorV1alpha1Client func (c *Clientset) IncubatorV1alpha1() incubatorv1alpha1.IncubatorV1alpha1Interface { return &fakeincubatorv1alpha1.FakeIncubatorV1alpha1{Fake: &c.Fake} diff --git a/pkg/clientset/fake/register.go b/pkg/clientset/fake/register.go index f188cd73..9487daa7 100644 --- a/pkg/clientset/fake/register.go +++ b/pkg/clientset/fake/register.go @@ -24,6 +24,7 @@ import ( configurationv1beta1 "github.com/kong/kubernetes-configuration/api/configuration/v1beta1" gatewayoperatorv1alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v1alpha1" gatewayoperatorv1beta1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1" + gatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v2alpha1" incubatorv1alpha1 "github.com/kong/kubernetes-configuration/api/incubator/v1alpha1" konnectv1alpha1 "github.com/kong/kubernetes-configuration/api/konnect/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,6 +43,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ configurationv1beta1.AddToScheme, gatewayoperatorv1alpha1.AddToScheme, gatewayoperatorv1beta1.AddToScheme, + gatewayoperatorv2alpha1.AddToScheme, incubatorv1alpha1.AddToScheme, konnectv1alpha1.AddToScheme, } diff --git a/pkg/clientset/scheme/register.go b/pkg/clientset/scheme/register.go index 4bd44a1b..bbb2317a 100644 --- a/pkg/clientset/scheme/register.go +++ b/pkg/clientset/scheme/register.go @@ -24,6 +24,7 @@ import ( configurationv1beta1 "github.com/kong/kubernetes-configuration/api/configuration/v1beta1" gatewayoperatorv1alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v1alpha1" gatewayoperatorv1beta1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1" + gatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v2alpha1" incubatorv1alpha1 "github.com/kong/kubernetes-configuration/api/incubator/v1alpha1" konnectv1alpha1 "github.com/kong/kubernetes-configuration/api/konnect/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,6 +43,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ configurationv1beta1.AddToScheme, gatewayoperatorv1alpha1.AddToScheme, gatewayoperatorv1beta1.AddToScheme, + gatewayoperatorv2alpha1.AddToScheme, incubatorv1alpha1.AddToScheme, konnectv1alpha1.AddToScheme, } diff --git a/pkg/clientset/typed/gateway-operator/v2alpha1/controlplane.go b/pkg/clientset/typed/gateway-operator/v2alpha1/controlplane.go new file mode 100644 index 00000000..3ca2ede6 --- /dev/null +++ b/pkg/clientset/typed/gateway-operator/v2alpha1/controlplane.go @@ -0,0 +1,70 @@ +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v2alpha1 + +import ( + context "context" + + gatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v2alpha1" + scheme "github.com/kong/kubernetes-configuration/pkg/clientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// ControlPlanesGetter has a method to return a ControlPlaneInterface. +// A group's client should implement this interface. +type ControlPlanesGetter interface { + ControlPlanes(namespace string) ControlPlaneInterface +} + +// ControlPlaneInterface has methods to work with ControlPlane resources. +type ControlPlaneInterface interface { + Create(ctx context.Context, controlPlane *gatewayoperatorv2alpha1.ControlPlane, opts v1.CreateOptions) (*gatewayoperatorv2alpha1.ControlPlane, error) + Update(ctx context.Context, controlPlane *gatewayoperatorv2alpha1.ControlPlane, opts v1.UpdateOptions) (*gatewayoperatorv2alpha1.ControlPlane, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, controlPlane *gatewayoperatorv2alpha1.ControlPlane, opts v1.UpdateOptions) (*gatewayoperatorv2alpha1.ControlPlane, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*gatewayoperatorv2alpha1.ControlPlane, error) + List(ctx context.Context, opts v1.ListOptions) (*gatewayoperatorv2alpha1.ControlPlaneList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *gatewayoperatorv2alpha1.ControlPlane, err error) + ControlPlaneExpansion +} + +// controlPlanes implements ControlPlaneInterface +type controlPlanes struct { + *gentype.ClientWithList[*gatewayoperatorv2alpha1.ControlPlane, *gatewayoperatorv2alpha1.ControlPlaneList] +} + +// newControlPlanes returns a ControlPlanes +func newControlPlanes(c *GatewayOperatorV2alpha1Client, namespace string) *controlPlanes { + return &controlPlanes{ + gentype.NewClientWithList[*gatewayoperatorv2alpha1.ControlPlane, *gatewayoperatorv2alpha1.ControlPlaneList]( + "controlplanes", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *gatewayoperatorv2alpha1.ControlPlane { return &gatewayoperatorv2alpha1.ControlPlane{} }, + func() *gatewayoperatorv2alpha1.ControlPlaneList { return &gatewayoperatorv2alpha1.ControlPlaneList{} }, + ), + } +} diff --git a/pkg/clientset/typed/gateway-operator/v2alpha1/doc.go b/pkg/clientset/typed/gateway-operator/v2alpha1/doc.go new file mode 100644 index 00000000..78fcf21d --- /dev/null +++ b/pkg/clientset/typed/gateway-operator/v2alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v2alpha1 diff --git a/pkg/clientset/typed/gateway-operator/v2alpha1/fake/doc.go b/pkg/clientset/typed/gateway-operator/v2alpha1/fake/doc.go new file mode 100644 index 00000000..4bdd0222 --- /dev/null +++ b/pkg/clientset/typed/gateway-operator/v2alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_controlplane.go b/pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_controlplane.go new file mode 100644 index 00000000..5b52ac49 --- /dev/null +++ b/pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_controlplane.go @@ -0,0 +1,52 @@ +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v2alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v2alpha1" + gatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v2alpha1" + gentype "k8s.io/client-go/gentype" +) + +// fakeControlPlanes implements ControlPlaneInterface +type fakeControlPlanes struct { + *gentype.FakeClientWithList[*v2alpha1.ControlPlane, *v2alpha1.ControlPlaneList] + Fake *FakeGatewayOperatorV2alpha1 +} + +func newFakeControlPlanes(fake *FakeGatewayOperatorV2alpha1, namespace string) gatewayoperatorv2alpha1.ControlPlaneInterface { + return &fakeControlPlanes{ + gentype.NewFakeClientWithList[*v2alpha1.ControlPlane, *v2alpha1.ControlPlaneList]( + fake.Fake, + namespace, + v2alpha1.SchemeGroupVersion.WithResource("controlplanes"), + v2alpha1.SchemeGroupVersion.WithKind("ControlPlane"), + func() *v2alpha1.ControlPlane { return &v2alpha1.ControlPlane{} }, + func() *v2alpha1.ControlPlaneList { return &v2alpha1.ControlPlaneList{} }, + func(dst, src *v2alpha1.ControlPlaneList) { dst.ListMeta = src.ListMeta }, + func(list *v2alpha1.ControlPlaneList) []*v2alpha1.ControlPlane { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v2alpha1.ControlPlaneList, items []*v2alpha1.ControlPlane) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_gateway-operator_client.go b/pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_gateway-operator_client.go new file mode 100644 index 00000000..7d42555f --- /dev/null +++ b/pkg/clientset/typed/gateway-operator/v2alpha1/fake/fake_gateway-operator_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v2alpha1 "github.com/kong/kubernetes-configuration/pkg/clientset/typed/gateway-operator/v2alpha1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeGatewayOperatorV2alpha1 struct { + *testing.Fake +} + +func (c *FakeGatewayOperatorV2alpha1) ControlPlanes(namespace string) v2alpha1.ControlPlaneInterface { + return newFakeControlPlanes(c, namespace) +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeGatewayOperatorV2alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/clientset/typed/gateway-operator/v2alpha1/gateway-operator_client.go b/pkg/clientset/typed/gateway-operator/v2alpha1/gateway-operator_client.go new file mode 100644 index 00000000..3df0c697 --- /dev/null +++ b/pkg/clientset/typed/gateway-operator/v2alpha1/gateway-operator_client.go @@ -0,0 +1,101 @@ +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v2alpha1 + +import ( + http "net/http" + + gatewayoperatorv2alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v2alpha1" + scheme "github.com/kong/kubernetes-configuration/pkg/clientset/scheme" + rest "k8s.io/client-go/rest" +) + +type GatewayOperatorV2alpha1Interface interface { + RESTClient() rest.Interface + ControlPlanesGetter +} + +// GatewayOperatorV2alpha1Client is used to interact with features provided by the gateway-operator.konghq.com group. +type GatewayOperatorV2alpha1Client struct { + restClient rest.Interface +} + +func (c *GatewayOperatorV2alpha1Client) ControlPlanes(namespace string) ControlPlaneInterface { + return newControlPlanes(c, namespace) +} + +// NewForConfig creates a new GatewayOperatorV2alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*GatewayOperatorV2alpha1Client, error) { + config := *c + setConfigDefaults(&config) + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new GatewayOperatorV2alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*GatewayOperatorV2alpha1Client, error) { + config := *c + setConfigDefaults(&config) + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &GatewayOperatorV2alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new GatewayOperatorV2alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *GatewayOperatorV2alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new GatewayOperatorV2alpha1Client for the given RESTClient. +func New(c rest.Interface) *GatewayOperatorV2alpha1Client { + return &GatewayOperatorV2alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) { + gv := gatewayoperatorv2alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *GatewayOperatorV2alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/clientset/typed/gateway-operator/v2alpha1/generated_expansion.go b/pkg/clientset/typed/gateway-operator/v2alpha1/generated_expansion.go new file mode 100644 index 00000000..1bea7cda --- /dev/null +++ b/pkg/clientset/typed/gateway-operator/v2alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2021 Kong, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v2alpha1 + +type ControlPlaneExpansion interface{} diff --git a/scripts/crds-generator/main.go b/scripts/crds-generator/main.go index ca827be1..ef1aec67 100644 --- a/scripts/crds-generator/main.go +++ b/scripts/crds-generator/main.go @@ -64,6 +64,7 @@ func main() { // gateway-operator.konghq.com "github.com/kong/kubernetes-configuration/api/gateway-operator/v1alpha1", "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1", + "github.com/kong/kubernetes-configuration/api/gateway-operator/v2alpha1", // common types "github.com/kong/kubernetes-configuration/api/common/v1alpha1", From 452b946fff1387ef442a2700cadfa048a2a98ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Mon, 2 Jun 2025 14:08:48 +0200 Subject: [PATCH 02/19] Apply suggestions from code review Co-authored-by: Jakub Warczarek --- api/gateway-operator/v2alpha1/controlplane_types.go | 4 ++-- api/gateway-operator/v2alpha1/groupversion_info.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index a4ab4a77..1d6e18f8 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -1,5 +1,5 @@ /* -Copyright 2022 Kong Inc. +Copyright 2025 Kong Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ type ControlPlaneSpec struct { // GatewayClass indicates the Gateway resources which this ControlPlane // should be responsible for configuring routes for (e.g. HTTPRoute, - // TCPRoute, UDPRoute, TLSRoute, e.t.c.). + // TCPRoute, UDPRoute, TLSRoute, etc.). // // Required for the ControlPlane to have any effect: at least one Gateway // must be present for configuration to be pushed to the data-plane and diff --git a/api/gateway-operator/v2alpha1/groupversion_info.go b/api/gateway-operator/v2alpha1/groupversion_info.go index 99b781bd..ab848b66 100644 --- a/api/gateway-operator/v2alpha1/groupversion_info.go +++ b/api/gateway-operator/v2alpha1/groupversion_info.go @@ -1,5 +1,5 @@ /* -Copyright 2022 Kong Inc. +Copyright 2025 Kong Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From c9289b5f6df24b487169f07af497e2e90805ba2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Mon, 2 Jun 2025 14:09:24 +0200 Subject: [PATCH 03/19] chore: make generate --- .../gateway-operator.konghq.com_controlplanes.yaml | 2 +- docs/all-api-reference.md | 2 +- docs/gateway-operator-api-reference.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index 88d36066..8a8ec53b 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8548,7 +8548,7 @@ spec: description: |- GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, - TCPRoute, UDPRoute, TLSRoute, e.t.c.). + TCPRoute, UDPRoute, TLSRoute, etc.). Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index b9e1843b..51880879 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -3505,7 +3505,7 @@ ControlPlaneSpec defines the desired state of ControlPlane | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | | `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | | `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | -| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, e.t.c.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | +| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, etc.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | | `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

Routing configured this way will be applied to the Gateway resources indicated by GatewayClass.

If omitted, Ingress resources will not be supported by the ControlPlane. | diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index 1f78d502..c39c3fe0 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -1451,7 +1451,7 @@ ControlPlaneSpec defines the desired state of ControlPlane | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | | `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | | `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | -| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, e.t.c.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | +| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, etc.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | | `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

Routing configured this way will be applied to the Gateway resources indicated by GatewayClass.

If omitted, Ingress resources will not be supported by the ControlPlane. | From 65991e8613fc3b9aac1bfa256765f2c338bfe325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 3 Jun 2025 09:59:27 +0200 Subject: [PATCH 04/19] Update api/gateway-operator/v2alpha1/controlplane_types.go Co-authored-by: Jintao Zhang --- api/gateway-operator/v2alpha1/controlplane_types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 1d6e18f8..9a3bcc4b 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -91,7 +91,7 @@ type ControlPlaneSpec struct { // +apireference:kgo:include // +kubebuilder:validation:XValidation:message="Extension not allowed for ControlPlane",rule="has(self.extensions) ? self.extensions.all(e, (e.group == 'konnect.konghq.com' && e.kind == 'KonnectExtension') || (e.group == 'gateway-operator.konghq.com' && e.kind == 'DataPlaneMetricsExtension')) : true" type ControlPlaneOptions struct { - // DataPlanes designates the target data plane to configure. + // DataPlane designates the target data plane to configure. // // It can be either a URL to an externally managed DataPlane (e.g. installed // independently with Helm) or a name of a DataPlane resource that is From b49858ce6fda1d3267517ec7f9d150cdf4a3f6f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 3 Jun 2025 10:00:23 +0200 Subject: [PATCH 05/19] chore: make generate --- .../gateway-operator.konghq.com_controlplanes.yaml | 2 +- docs/all-api-reference.md | 4 ++-- docs/gateway-operator-api-reference.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index 8a8ec53b..b66ca4ae 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8450,7 +8450,7 @@ spec: x-kubernetes-list-type: map dataplane: description: |- - DataPlanes designates the target data plane to configure. + DataPlane designates the target data plane to configure. It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index 51880879..6fcf4e2a 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -3479,7 +3479,7 @@ deploy and connect a ControlPlane to a DataPlane object. | Field | Description | | --- | --- | -| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlane designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | | `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | | `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | @@ -3499,7 +3499,7 @@ ControlPlaneSpec defines the desired state of ControlPlane | Field | Description | | --- | --- | -| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlane designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | | `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | | `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index c39c3fe0..d77b2d5b 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -1425,7 +1425,7 @@ deploy and connect a ControlPlane to a DataPlane object. | Field | Description | | --- | --- | -| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlane designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | | `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | | `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | @@ -1445,7 +1445,7 @@ ControlPlaneSpec defines the desired state of ControlPlane | Field | Description | | --- | --- | -| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlanes designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | +| `dataplane` _[ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)_ | DataPlane designates the target data plane to configure.

It can be either a URL to an externally managed DataPlane (e.g. installed independently with Helm) or a name of a DataPlane resource that is managed by the operator. | | `extensions` _ExtensionRef array_ | Extensions provide additional or replacement features for the ControlPlane resources to influence or enhance functionality. | | `watchNamespaces` _[WatchNamespaces](#watchnamespaces)_ | WatchNamespaces indicates the namespaces to watch for resources. | | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | From ded6cf1513fd19b48ef123a98ccdd10ece56d94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 3 Jun 2025 15:38:50 +0200 Subject: [PATCH 06/19] chore: add tests and type for ControlPlane's DataPlane target type --- .../v2alpha1/controlplane_types.go | 15 +- docs/all-api-reference.md | 15 +- docs/gateway-operator-api-reference.md | 15 +- .../controlplane_v2_test.go | 240 ++++++++++++++++++ 4 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 9a3bcc4b..77f2b5f8 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -148,7 +148,7 @@ type ControlPlaneDataPlaneTarget struct { // // +kubebuilder:validation:Enum=url;name // +kubebuilder:validation:Required - Type string `json:"type,omitempty"` + Type ControlPlaneDataPlaneTargetType `json:"type,omitempty"` // URL is the URL of the DataPlane target. This is used for configuring // externally managed DataPlanes like those installed independently with Helm. @@ -162,6 +162,19 @@ type ControlPlaneDataPlaneTarget struct { Name string `json:"name,omitempty"` } +// ControlPlaneDataPlaneTargetType defines the type of the DataPlane target +// that the ControlPlane is responsible for configuring. +type ControlPlaneDataPlaneTargetType string + +const ( + // ControlPlaneDataPlaneTargetURL indicates that the DataPlane target is a URL. + ControlPlaneDataPlaneTargetURL ControlPlaneDataPlaneTargetType = "url" + + // ControlPlaneDataPlaneTargetName indicates that the DataPlane target is a name + // of a DataPlane resource managed by the operator. + ControlPlaneDataPlaneTargetName ControlPlaneDataPlaneTargetType = "name" +) + // ControlPlaneAdminAPI defines the configuration for the Kong Admin API that // a ControlPlane when configuring the DataPlane. type ControlPlaneAdminAPI struct { diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index 6fcf4e2a..8367e10c 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -3442,7 +3442,7 @@ is responsible for configuring. | Field | Description | | --- | --- | -| `type` _string_ | Type indicates the type of the DataPlane target. | +| `type` _[ControlPlaneDataPlaneTargetType](#controlplanedataplanetargettype)_ | Type indicates the type of the DataPlane target. | | `url` _string_ | URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | | `name` _string_ | Name is the name of the DataPlane to configure. | @@ -3451,6 +3451,19 @@ _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +#### ControlPlaneDataPlaneTargetType +_Underlying type:_ `string` + +ControlPlaneDataPlaneTargetType defines the type of the DataPlane target +that the ControlPlane is responsible for configuring. + + + + + +_Appears in:_ +- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget) + #### ControlPlaneFeatureGate diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index d77b2d5b..5178f6cc 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -1388,7 +1388,7 @@ is responsible for configuring. | Field | Description | | --- | --- | -| `type` _string_ | Type indicates the type of the DataPlane target. | +| `type` _[ControlPlaneDataPlaneTargetType](#controlplanedataplanetargettype)_ | Type indicates the type of the DataPlane target. | | `url` _string_ | URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | | `name` _string_ | Name is the name of the DataPlane to configure. | @@ -1397,6 +1397,19 @@ _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +#### ControlPlaneDataPlaneTargetType +_Underlying type:_ `string` + +ControlPlaneDataPlaneTargetType defines the type of the DataPlane target +that the ControlPlane is responsible for configuring. + + + + + +_Appears in:_ +- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget) + #### ControlPlaneFeatureGate diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go new file mode 100644 index 00000000..312d81d3 --- /dev/null +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -0,0 +1,240 @@ +package crdsvalidation_test + +import ( + "testing" + + "github.com/samber/lo" + + commonv1alpha1 "github.com/kong/kubernetes-configuration/api/common/v1alpha1" + operatorv2alpha1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v2alpha1" + "github.com/kong/kubernetes-configuration/test/crdsvalidation/common" +) + +func TestControlPlaneV2(t *testing.T) { + validDataPlaneTarget := operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, + Name: "dataplane", + } + + validControlPlaneOptions := operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + } + + t.Run("extensions", func(t *testing.T) { + common.TestCasesGroup[*operatorv2alpha1.ControlPlane]{ + { + Name: "no extensions", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: validControlPlaneOptions, + }, + }, + }, + { + Name: "konnectExtension set", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + Extensions: []commonv1alpha1.ExtensionRef{ + { + Group: "konnect.konghq.com", + Kind: "KonnectExtension", + NamespacedRef: commonv1alpha1.NamespacedRef{ + Name: "my-konnect-extension", + }, + }, + }, + }, + }, + }, + }, + { + Name: "konnectExtension and DataPlaneMetricsExtension set", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + Extensions: []commonv1alpha1.ExtensionRef{ + { + Group: "konnect.konghq.com", + Kind: "KonnectExtension", + NamespacedRef: commonv1alpha1.NamespacedRef{ + Name: "my-konnect-extension", + }, + }, + { + Group: "gateway-operator.konghq.com", + Kind: "DataPlaneMetricsExtension", + NamespacedRef: commonv1alpha1.NamespacedRef{ + Name: "my-metrics-extension", + }, + }, + }, + }, + }, + }, + }, + { + Name: "invalid extension", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + Extensions: []commonv1alpha1.ExtensionRef{ + { + Group: "invalid.konghq.com", + Kind: "KonnectExtension", + NamespacedRef: commonv1alpha1.NamespacedRef{ + Name: "my-konnect-extension", + }, + }, + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("Extension not allowed for ControlPlane"), + }, + }.Run(t) + }) + + t.Run("feature gates", func(t *testing.T) { + common.TestCasesGroup[*operatorv2alpha1.ControlPlane]{ + { + Name: "no feature gates", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: validControlPlaneOptions, + }, + }, + }, + { + Name: "feature gate set", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{ + { + Name: "KongCustomEntity", + Enabled: lo.ToPtr(true), + }, + }, + }, + }, + }, + }, + { + Name: "feature gate disabled", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{ + { + Name: "KongCustomEntity", + Enabled: lo.ToPtr(false), + }, + }, + }, + }, + }, + }, + { + Name: "feature gate set and then removed", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{ + { + Name: "KongCustomEntity", + Enabled: lo.ToPtr(true), + }, + }, + }, + }, + }, + Update: func(cp *operatorv2alpha1.ControlPlane) { + cp.Spec.ControlPlaneOptions = validControlPlaneOptions + }, + }, + }.Run(t) + }) + + t.Run("controllers", func(t *testing.T) { + common.TestCasesGroup[*operatorv2alpha1.ControlPlane]{ + { + Name: "no controller overrides specified", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: validControlPlaneOptions, + }, + }, + }, + { + Name: "controller overrides specified", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + Controllers: []operatorv2alpha1.ControlPlaneController{ + { + Name: "GatewayAPI", + Enabled: lo.ToPtr(true), + }, + }, + }, + }, + }, + }, + { + Name: "controller overrides specified - disabled", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + Controllers: []operatorv2alpha1.ControlPlaneController{ + { + Name: "GatewayAPI", + Enabled: lo.ToPtr(false), + }, + }, + }, + }, + }, + }, + { + Name: "controller overrides specified and then removed", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + Controllers: []operatorv2alpha1.ControlPlaneController{ + { + Name: "GatewayAPI", + Enabled: lo.ToPtr(true), + }, + }, + }, + }, + }, + Update: func(cp *operatorv2alpha1.ControlPlane) { + cp.Spec.ControlPlaneOptions = validControlPlaneOptions + }, + }, + }.Run(t) + }) +} From dc002844a8a76bd398fadabd44929380f26b022c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 3 Jun 2025 15:57:50 +0200 Subject: [PATCH 07/19] chore: add tests and type for ControlPlane's DataPlane target type, require URL to be a valid URL --- .../v2alpha1/controlplane_types.go | 1 + ...way-operator.konghq.com_controlplanes.yaml | 1 + .../controlplane_v2_test.go | 100 ++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 77f2b5f8..26d43693 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -154,6 +154,7 @@ type ControlPlaneDataPlaneTarget struct { // externally managed DataPlanes like those installed independently with Helm. // // +optional + // +kubebuilder:validation:Pattern=`^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$` URL string `json:"url,omitempty"` // Name is the name of the DataPlane to configure. diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index b66ca4ae..1457a65d 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8469,6 +8469,7 @@ spec: description: |- URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. + pattern: ^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$ type: string required: - type diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go index 312d81d3..45abe6b5 100644 --- a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -102,6 +102,106 @@ func TestControlPlaneV2(t *testing.T) { }.Run(t) }) + t.Run("dataplane", func(t *testing.T) { + common.TestCasesGroup[*operatorv2alpha1.ControlPlane]{ + { + Name: "missing dataplane causes an error", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{}, + }, + }, + ExpectedErrorMessage: lo.ToPtr("spec.dataplane.type: Required value"), + }, + { + Name: "when dataplane.type is set to name, name must be specified", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("Name has to be provided when type is set to name"), + }, + { + Name: "when dataplane.type is set to url, url must be specified", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("URL has to be provided when type is set to url"), + }, + { + Name: "specifying dataplane name when type is name passes", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, + Name: "dataplane", + }, + }, + }, + }, + }, + { + Name: "specifying dataplane url when type is url passes: https", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, + URL: "https://dataplane.example.com:8444/admin", + }, + }, + }, + }, + }, + { + Name: "specifying dataplane url when type is url passes: http, no port", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, + URL: "http://dataplane.example.com/admin", + }, + }, + }, + }, + }, + { + Name: "dataplane url must be a valid URL, otherwise it fails", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, + URL: "not-a-valid-url", + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("invalid: spec.dataplane.url: Invalid value: \"not-a-valid-url\": spec.dataplane.url in body should match '^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$'"), + }, + }.Run(t) + }) + t.Run("feature gates", func(t *testing.T) { common.TestCasesGroup[*operatorv2alpha1.ControlPlane]{ { From 2946df242484dc1b061844f0f1b8df6a98386d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 3 Jun 2025 16:30:13 +0200 Subject: [PATCH 08/19] chore: ControlPlane's DataPlane name and url fields are pointers now given that they are optional --- api/gateway-operator/v2alpha1/controlplane_types.go | 4 ++-- .../v2alpha1/zz_generated.deepcopy.go | 12 +++++++++++- .../controlplane_v2_test.go | 10 +++++----- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 26d43693..c9f93c2d 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -155,12 +155,12 @@ type ControlPlaneDataPlaneTarget struct { // // +optional // +kubebuilder:validation:Pattern=`^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$` - URL string `json:"url,omitempty"` + URL *string `json:"url,omitempty"` // Name is the name of the DataPlane to configure. // // +optional - Name string `json:"name,omitempty"` + Name *string `json:"name,omitempty"` } // ControlPlaneDataPlaneTargetType defines the type of the DataPlane target diff --git a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go index 04113cb8..dc633baa 100644 --- a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go +++ b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go @@ -93,6 +93,16 @@ func (in *ControlPlaneController) DeepCopy() *ControlPlaneController { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneDataPlaneTarget) DeepCopyInto(out *ControlPlaneDataPlaneTarget) { *out = *in + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(string) + **out = **in + } + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneDataPlaneTarget. @@ -160,7 +170,7 @@ func (in *ControlPlaneList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneOptions) DeepCopyInto(out *ControlPlaneOptions) { *out = *in - out.DataPlane = in.DataPlane + in.DataPlane.DeepCopyInto(&out.DataPlane) if in.Extensions != nil { in, out := &in.Extensions, &out.Extensions *out = make([]v1alpha1.ExtensionRef, len(*in)) diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go index 45abe6b5..a6992de2 100644 --- a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -13,7 +13,7 @@ import ( func TestControlPlaneV2(t *testing.T) { validDataPlaneTarget := operatorv2alpha1.ControlPlaneDataPlaneTarget{ Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, - Name: "dataplane", + Name: lo.ToPtr("dataplane"), } validControlPlaneOptions := operatorv2alpha1.ControlPlaneOptions{ @@ -150,7 +150,7 @@ func TestControlPlaneV2(t *testing.T) { ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, - Name: "dataplane", + Name: lo.ToPtr("dataplane"), }, }, }, @@ -164,7 +164,7 @@ func TestControlPlaneV2(t *testing.T) { ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, - URL: "https://dataplane.example.com:8444/admin", + URL: lo.ToPtr("https://dataplane.example.com:8444/admin"), }, }, }, @@ -178,7 +178,7 @@ func TestControlPlaneV2(t *testing.T) { ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, - URL: "http://dataplane.example.com/admin", + URL: lo.ToPtr("http://dataplane.example.com/admin"), }, }, }, @@ -192,7 +192,7 @@ func TestControlPlaneV2(t *testing.T) { ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, - URL: "not-a-valid-url", + URL: lo.ToPtr("not-a-valid-url"), }, }, }, From f287f8b87209a0db2fecfcbb64ab9a5530ee3036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 3 Jun 2025 16:32:50 +0200 Subject: [PATCH 09/19] chore: rewording ControlPlaneAdminAPI comment --- api/gateway-operator/v2alpha1/controlplane_types.go | 3 +-- docs/all-api-reference.md | 3 +-- docs/gateway-operator-api-reference.md | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index c9f93c2d..24dbd440 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -176,8 +176,7 @@ const ( ControlPlaneDataPlaneTargetName ControlPlaneDataPlaneTargetType = "name" ) -// ControlPlaneAdminAPI defines the configuration for the Kong Admin API that -// a ControlPlane when configuring the DataPlane. +// ControlPlaneAdminAPI defines the configuration for the DataPlane Kong Admin API. type ControlPlaneAdminAPI struct { // Workspace indicates the Kong Workspace to use for the ControlPlane. // If left empty then no Kong workspace will be used. diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index 8367e10c..befb3eb7 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -3400,8 +3400,7 @@ In this section you will find types that the CRDs rely on. #### ControlPlaneAdminAPI -ControlPlaneAdminAPI defines the configuration for the Kong Admin API that -a ControlPlane when configuring the DataPlane. +ControlPlaneAdminAPI defines the configuration for the DataPlane Kong Admin API. diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index 5178f6cc..ce91e138 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -1346,8 +1346,7 @@ In this section you will find types that the CRDs rely on. #### ControlPlaneAdminAPI -ControlPlaneAdminAPI defines the configuration for the Kong Admin API that -a ControlPlane when configuring the DataPlane. +ControlPlaneAdminAPI defines the configuration for the DataPlane Kong Admin API. From 286fec3d7dc690f00d4902b4af4bd7b4cd56b64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 3 Jun 2025 16:42:53 +0200 Subject: [PATCH 10/19] feat(controlplane): add controllers and feature gates status --- .../v2alpha1/controlplane_types.go | 16 ++++++ .../v2alpha1/zz_generated.deepcopy.go | 14 ++++++ ...way-operator.konghq.com_controlplanes.yaml | 50 +++++++++++++++++++ docs/all-api-reference.md | 2 + docs/gateway-operator-api-reference.md | 2 + 5 files changed, 84 insertions(+) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 24dbd440..4f002df8 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -231,6 +231,22 @@ type ControlPlaneStatus struct { // +kubebuilder:validation:MaxItems=8 // +kubebuilder:default={{type: "Scheduled", status: "Unknown", reason:"NotReconciled", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}} Conditions []metav1.Condition `json:"conditions,omitempty"` + + // FeatureGates is a list of effective feature gates for this ControlPlane. + // + // +optional + // +listType=map + // +listMapKey=name + // +kubebuilder:validation:MaxItems=32 + FeatureGates []ControlPlaneFeatureGate `json:"featureGates,omitempty"` + + // Controllers is a list of enabled and disabled controllers for this ControlPlane. + // + // +optional + // +listType=map + // +listMapKey=name + // +kubebuilder:validation:MaxItems=32 + Controllers []ControlPlaneController `json:"controllers,omitempty"` } // GetConditions returns the ControlPlane Status Conditions diff --git a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go index dc633baa..8c315e60 100644 --- a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go +++ b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go @@ -250,6 +250,20 @@ func (in *ControlPlaneStatus) DeepCopyInto(out *ControlPlaneStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.FeatureGates != nil { + in, out := &in.FeatureGates, &out.FeatureGates + *out = make([]ControlPlaneFeatureGate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Controllers != nil { + in, out := &in.Controllers, &out.Controllers + *out = make([]ControlPlaneController, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneStatus. diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index 1457a65d..71a6bb53 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8675,6 +8675,56 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map + controllers: + description: Controllers is a list of enabled and disabled controllers + for this ControlPlane. + items: + description: |- + ControlPlaneController defines a controller state for the ControlPlane. + It overrides the default behavior as defined in the deployed operator version. + properties: + enabled: + description: Enabled indicates whether the controller is enabled + or not. + type: boolean + name: + description: Name is the name of the controller. + minLength: 1 + type: string + required: + - enabled + - name + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + featureGates: + description: FeatureGates is a list of effective feature gates for + this ControlPlane. + items: + description: |- + ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. + It overrides the default behavior as defined in the deployed operator version. + properties: + enabled: + description: Enabled indicates whether the feature gate is enabled + or not. + type: boolean + name: + description: Name is the name of the feature gate. + minLength: 1 + type: string + required: + - enabled + - name + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map type: object type: object served: true diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index befb3eb7..bf87b56e 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -3430,6 +3430,7 @@ It overrides the default behavior as defined in the deployed operator version. _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +- [ControlPlaneStatus](#controlplanestatus) #### ControlPlaneDataPlaneTarget @@ -3480,6 +3481,7 @@ It overrides the default behavior as defined in the deployed operator version. _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +- [ControlPlaneStatus](#controlplanestatus) #### ControlPlaneOptions diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index ce91e138..7a97bc0e 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -1376,6 +1376,7 @@ It overrides the default behavior as defined in the deployed operator version. _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +- [ControlPlaneStatus](#controlplanestatus) #### ControlPlaneDataPlaneTarget @@ -1426,6 +1427,7 @@ It overrides the default behavior as defined in the deployed operator version. _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +- [ControlPlaneStatus](#controlplanestatus) #### ControlPlaneOptions From 93b36efe3641d84e5a8329c46a032dd98392eb7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Wed, 4 Jun 2025 11:44:33 +0200 Subject: [PATCH 11/19] chore: use isURL() for validating URL and remove MinItems=0 --- api/gateway-operator/v2alpha1/controlplane_types.go | 3 +-- .../gateway-operator.konghq.com_controlplanes.yaml | 4 +++- .../gateway-operator.konghq.com/controlplane_v2_test.go | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 4f002df8..49a3172a 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -104,7 +104,6 @@ type ControlPlaneOptions struct { // resources to influence or enhance functionality. // // +optional - // +kubebuilder:validation:MinItems=0 // +kubebuilder:validation:MaxItems=2 Extensions []commonv1alpha1.ExtensionRef `json:"extensions,omitempty"` @@ -154,7 +153,7 @@ type ControlPlaneDataPlaneTarget struct { // externally managed DataPlanes like those installed independently with Helm. // // +optional - // +kubebuilder:validation:Pattern=`^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$` + // +kubebuilder:validation:XValidation:message="URL has to be a valid URL",rule="isURL(self)" URL *string `json:"url,omitempty"` // Name is the name of the DataPlane to configure. diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index 71a6bb53..5138ed11 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8469,8 +8469,10 @@ spec: description: |- URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. - pattern: ^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$ type: string + x-kubernetes-validations: + - message: URL has to be a valid URL + rule: isURL(self) required: - type type: object diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go index a6992de2..e45c251d 100644 --- a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -197,7 +197,7 @@ func TestControlPlaneV2(t *testing.T) { }, }, }, - ExpectedErrorMessage: lo.ToPtr("invalid: spec.dataplane.url: Invalid value: \"not-a-valid-url\": spec.dataplane.url in body should match '^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$'"), + ExpectedErrorMessage: lo.ToPtr("URL has to be a valid URL"), }, }.Run(t) }) From f9d51958d7634dacd2613320fc20f26dd9193dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Wed, 4 Jun 2025 11:53:02 +0200 Subject: [PATCH 12/19] chore: make generate --- .../gateway-operator.konghq.com_controlplanes.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index 5138ed11..e222088e 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8520,7 +8520,6 @@ spec: - name type: object maxItems: 2 - minItems: 0 type: array featureGates: description: FeatureGates is a list of feature gates that are enabled From f357eb47acadfd79061e8d55de4600e266d7d62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Wed, 4 Jun 2025 12:28:40 +0200 Subject: [PATCH 13/19] chore: remove omitempty on enabled --- api/gateway-operator/v2alpha1/controlplane_types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 49a3172a..28497ab9 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -198,7 +198,7 @@ type ControlPlaneController struct { // Enabled indicates whether the controller is enabled or not. // // +kubebuilder:validation:Required - Enabled *bool `json:"enabled,omitempty"` + Enabled *bool `json:"enabled"` } // ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. @@ -215,7 +215,7 @@ type ControlPlaneFeatureGate struct { // Enabled indicates whether the feature gate is enabled or not. // // +kubebuilder:validation:Required - Enabled *bool `json:"enabled,omitempty"` + Enabled *bool `json:"enabled"` } // ControlPlaneStatus defines the observed state of ControlPlane From 4819c3db1803fc9e585d22e24af7e0465a159f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Wed, 4 Jun 2025 12:53:05 +0200 Subject: [PATCH 14/19] tests: add CRD validation tests for ControlPlane v2alpha1 ensuring that enabled is set for controllers and featureGates --- .../controlplane_v2_test.go | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go index e45c251d..49cbe48a 100644 --- a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -267,6 +267,23 @@ func TestControlPlaneV2(t *testing.T) { cp.Spec.ControlPlaneOptions = validControlPlaneOptions }, }, + { + Name: "cannot provide a feature gate with enabled unset", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{ + { + Name: "KongCustomEntity", + }, + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("spec.featureGates[0].enabled: Required value"), + }, }.Run(t) }) @@ -335,6 +352,23 @@ func TestControlPlaneV2(t *testing.T) { cp.Spec.ControlPlaneOptions = validControlPlaneOptions }, }, + { + Name: "cannot provide a controller with enabled unset", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: validDataPlaneTarget, + Controllers: []operatorv2alpha1.ControlPlaneController{ + { + Name: "GatewayAPI", + }, + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("spec.controllers[0].enabled: Required value"), + }, }.Run(t) }) } From 39fa87d845a60e98bcab30d2270634a37baa58d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Thu, 5 Jun 2025 16:57:20 +0200 Subject: [PATCH 15/19] chore: add gvrs.go --- api/gateway-operator/v2alpha1/gvrs.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 api/gateway-operator/v2alpha1/gvrs.go diff --git a/api/gateway-operator/v2alpha1/gvrs.go b/api/gateway-operator/v2alpha1/gvrs.go new file mode 100644 index 00000000..b5df32da --- /dev/null +++ b/api/gateway-operator/v2alpha1/gvrs.go @@ -0,0 +1,12 @@ +package v2alpha1 + +import "k8s.io/apimachinery/pkg/runtime/schema" + +// ControlPlaneGVR returns current package ControlPlane GVR. +func ControlPlaneGVR() schema.GroupVersionResource { + return schema.GroupVersionResource{ + Group: SchemeGroupVersion.Group, + Version: SchemeGroupVersion.Version, + Resource: "controlplanes", + } +} From 45f2bc326b748d82d971da3f9387f0f4fda4a3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Fri, 6 Jun 2025 13:14:38 +0200 Subject: [PATCH 16/19] chore: refactor dataplane reference API based on review --- .../v2alpha1/controlplane_types.go | 91 +++++++++++-------- .../v2alpha1/zz_generated.deepcopy.go | 52 ++++++++--- ...way-operator.konghq.com_controlplanes.yaml | 70 +++++++------- ...ntrolplane_v2_dataplane_external_url.yaml} | 6 +- ...olplane_v2_dataplane_managed_by_owner.yaml | 13 +++ ...> controlplane_v2_dataplane_ref_name.yaml} | 6 +- docs/all-api-reference.md | 39 +++++++- docs/gateway-operator-api-reference.md | 39 +++++++- .../controlplane_v2_test.go | 46 ++++++---- 9 files changed, 242 insertions(+), 120 deletions(-) rename config/samples/{controlplane_v2_dataplane_url.yaml => controlplane_v2_dataplane_external_url.yaml} (73%) create mode 100644 config/samples/controlplane_v2_dataplane_managed_by_owner.yaml rename config/samples/{controlplane_v2_dataplane_name.yaml => controlplane_v2_dataplane_ref_name.yaml} (84%) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 28497ab9..5b3a5dfa 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -18,7 +18,6 @@ package v2alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" commonv1alpha1 "github.com/kong/kubernetes-configuration/api/common/v1alpha1" operatorv1beta1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1" @@ -62,23 +61,9 @@ type ControlPlaneList struct { type ControlPlaneSpec struct { ControlPlaneOptions `json:",inline"` - // GatewayClass indicates the Gateway resources which this ControlPlane - // should be responsible for configuring routes for (e.g. HTTPRoute, - // TCPRoute, UDPRoute, TLSRoute, etc.). - // - // Required for the ControlPlane to have any effect: at least one Gateway - // must be present for configuration to be pushed to the data-plane and - // only Gateway resources can be used to identify data-plane entities. - // - // +optional - GatewayClass *gatewayv1.ObjectName `json:"gatewayClass,omitempty"` - // IngressClass enables support for the older Ingress resource and indicates // which Ingress resources this ControlPlane should be responsible for. // - // Routing configured this way will be applied to the Gateway resources - // indicated by GatewayClass. - // // If omitted, Ingress resources will not be supported by the ControlPlane. // // +optional @@ -98,7 +83,7 @@ type ControlPlaneOptions struct { // managed by the operator. // // +required - DataPlane ControlPlaneDataPlaneTarget `json:"dataplane,omitempty"` + DataPlane ControlPlaneDataPlaneTarget `json:"dataplane"` // Extensions provide additional or replacement features for the ControlPlane // resources to influence or enhance functionality. @@ -138,28 +123,27 @@ type ControlPlaneOptions struct { // ControlPlaneDataPlaneTarget defines the target for the DataPlane that the ControlPlane // is responsible for configuring. // -// +kubebuilder:validation:XValidation:message="URL has to be provided when type is set to url",rule="self.type != 'url' || has(self.url)" -// +kubebuilder:validation:XValidation:message="Name cannot be provided when type is set to url",rule="self.type != 'url' || !has(self.name)" -// +kubebuilder:validation:XValidation:message="Name has to be provided when type is set to name",rule="self.type != 'name' || has(self.name)" -// +kubebuilder:validation:XValidation:message="URL cannot be provided when type is set to name",rule="self.type != 'name' || !has(self.url)" +// +kubebuilder:validation:XValidation:message="External has to be provided when type is set to external",rule="self.type != 'external' || has(self.external)" +// +kubebuilder:validation:XValidation:message="External cannot be provided when type is set to managedByOwner",rule="self.type != 'managedByOwner' || !has(self.external)" +// +kubebuilder:validation:XValidation:message="Ref has to be provided when type is set to ref",rule="self.type != 'ref' || has(self.ref)" +// +kubebuilder:validation:XValidation:message="Ref cannot be provided when type is set to managedByOwner",rule="self.type != 'managedByOwner' || !has(self.ref)" type ControlPlaneDataPlaneTarget struct { // Type indicates the type of the DataPlane target. // - // +kubebuilder:validation:Enum=url;name - // +kubebuilder:validation:Required - Type ControlPlaneDataPlaneTargetType `json:"type,omitempty"` + // +required + // +kubebuilder:validation:Enum=external;ref;managedByOwner + Type ControlPlaneDataPlaneTargetType `json:"type"` - // URL is the URL of the DataPlane target. This is used for configuring + // External is the External of the DataPlane target. This is used for configuring // externally managed DataPlanes like those installed independently with Helm. // // +optional - // +kubebuilder:validation:XValidation:message="URL has to be a valid URL",rule="isURL(self)" - URL *string `json:"url,omitempty"` + External *ControlPlaneDataPlaneTargetExternal `json:"external,omitempty"` - // Name is the name of the DataPlane to configure. + // Ref is the name of the DataPlane to configure. // // +optional - Name *string `json:"name,omitempty"` + Ref *ControlPlaneDataPlaneTargetRef `json:"ref,omitempty"` } // ControlPlaneDataPlaneTargetType defines the type of the DataPlane target @@ -167,14 +151,45 @@ type ControlPlaneDataPlaneTarget struct { type ControlPlaneDataPlaneTargetType string const ( - // ControlPlaneDataPlaneTargetURL indicates that the DataPlane target is a URL. - ControlPlaneDataPlaneTargetURL ControlPlaneDataPlaneTargetType = "url" + // ControlPlaneDataPlaneTargetExternalType indicates that the DataPlane target is external. + // This is used for configuring externally managed DataPlanes like those + // installed independently with Helm. + ControlPlaneDataPlaneTargetExternalType ControlPlaneDataPlaneTargetType = "external" - // ControlPlaneDataPlaneTargetName indicates that the DataPlane target is a name + // ControlPlaneDataPlaneTargetRefType indicates that the DataPlane target is a ref // of a DataPlane resource managed by the operator. - ControlPlaneDataPlaneTargetName ControlPlaneDataPlaneTargetType = "name" + // This is used for configuring DataPlanes that are managed by the operator. + ControlPlaneDataPlaneTargetRefType ControlPlaneDataPlaneTargetType = "ref" + + // ControlPlaneDataPlaneTargetManagedByType indicates that the DataPlane target + // is managed by the owner of the ControlPlane. + // This is the case when using a Gateway resource to manage the DataPlane + // and the ControlPlane is responsible for configuring it. + ControlPlaneDataPlaneTargetManagedByType ControlPlaneDataPlaneTargetType = "managedByOwner" ) +// ControlPlaneDataPlaneTargetExternal defines the configuration for an external DataPlane +// that the ControlPlane is responsible for configuring. +type ControlPlaneDataPlaneTargetExternal struct { + // URL is the URL of the external DataPlane to configure. + // + // +required + // +kubebuilder:validation:XValidation:message="URL has to be a valid URL",rule="isURL(self)" + URL string `json:"url"` + + // TODO: add additional fields for authenticating with the external DataPlane. + // ref: https://github.com/Kong/gateway-operator/issues/1366 +} + +// ControlPlaneDataPlaneTargetRef defines the reference to a DataPlane resource +// that the ControlPlane is responsible for configuring. +type ControlPlaneDataPlaneTargetRef struct { + // Ref is the name of the DataPlane to configure. + // + // +required + Name string `json:"name"` +} + // ControlPlaneAdminAPI defines the configuration for the DataPlane Kong Admin API. type ControlPlaneAdminAPI struct { // Workspace indicates the Kong Workspace to use for the ControlPlane. @@ -191,13 +206,13 @@ type ControlPlaneAdminAPI struct { type ControlPlaneController struct { // Name is the name of the controller. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:MinLength=1 - Name string `json:"name,omitempty"` + Name string `json:"name"` // Enabled indicates whether the controller is enabled or not. // - // +kubebuilder:validation:Required + // +required Enabled *bool `json:"enabled"` } @@ -208,13 +223,13 @@ type ControlPlaneController struct { type ControlPlaneFeatureGate struct { // Name is the name of the feature gate. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:MinLength=1 - Name string `json:"name,omitempty"` + Name string `json:"name"` // Enabled indicates whether the feature gate is enabled or not. // - // +kubebuilder:validation:Required + // +required Enabled *bool `json:"enabled"` } diff --git a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go index 8c315e60..710dcb6d 100644 --- a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go +++ b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go @@ -23,9 +23,8 @@ package v2alpha1 import ( "github.com/kong/kubernetes-configuration/api/common/v1alpha1" "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/gateway-api/apis/v1" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -93,14 +92,14 @@ func (in *ControlPlaneController) DeepCopy() *ControlPlaneController { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneDataPlaneTarget) DeepCopyInto(out *ControlPlaneDataPlaneTarget) { *out = *in - if in.URL != nil { - in, out := &in.URL, &out.URL - *out = new(string) + if in.External != nil { + in, out := &in.External, &out.External + *out = new(ControlPlaneDataPlaneTargetExternal) **out = **in } - if in.Name != nil { - in, out := &in.Name, &out.Name - *out = new(string) + if in.Ref != nil { + in, out := &in.Ref, &out.Ref + *out = new(ControlPlaneDataPlaneTargetRef) **out = **in } } @@ -115,6 +114,36 @@ func (in *ControlPlaneDataPlaneTarget) DeepCopy() *ControlPlaneDataPlaneTarget { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneDataPlaneTargetExternal) DeepCopyInto(out *ControlPlaneDataPlaneTargetExternal) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneDataPlaneTargetExternal. +func (in *ControlPlaneDataPlaneTargetExternal) DeepCopy() *ControlPlaneDataPlaneTargetExternal { + if in == nil { + return nil + } + out := new(ControlPlaneDataPlaneTargetExternal) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneDataPlaneTargetRef) DeepCopyInto(out *ControlPlaneDataPlaneTargetRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneDataPlaneTargetRef. +func (in *ControlPlaneDataPlaneTargetRef) DeepCopy() *ControlPlaneDataPlaneTargetRef { + if in == nil { + return nil + } + out := new(ControlPlaneDataPlaneTargetRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneFeatureGate) DeepCopyInto(out *ControlPlaneFeatureGate) { *out = *in @@ -218,11 +247,6 @@ func (in *ControlPlaneOptions) DeepCopy() *ControlPlaneOptions { func (in *ControlPlaneSpec) DeepCopyInto(out *ControlPlaneSpec) { *out = *in in.ControlPlaneOptions.DeepCopyInto(&out.ControlPlaneOptions) - if in.GatewayClass != nil { - in, out := &in.GatewayClass, &out.GatewayClass - *out = new(v1.ObjectName) - **out = **in - } if in.IngressClass != nil { in, out := &in.IngressClass, &out.IngressClass *out = new(string) @@ -245,7 +269,7 @@ func (in *ControlPlaneStatus) DeepCopyInto(out *ControlPlaneStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) + *out = make([]v1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index e222088e..5bf848df 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8456,35 +8456,48 @@ spec: independently with Helm) or a name of a DataPlane resource that is managed by the operator. properties: - name: - description: Name is the name of the DataPlane to configure. - type: string + external: + description: |- + External is the External of the DataPlane target. This is used for configuring + externally managed DataPlanes like those installed independently with Helm. + properties: + url: + description: URL is the URL of the external DataPlane to configure. + type: string + x-kubernetes-validations: + - message: URL has to be a valid URL + rule: isURL(self) + required: + - url + type: object + ref: + description: Ref is the name of the DataPlane to configure. + properties: + name: + description: Ref is the name of the DataPlane to configure. + type: string + required: + - name + type: object type: description: Type indicates the type of the DataPlane target. enum: - - url - - name - type: string - url: - description: |- - URL is the URL of the DataPlane target. This is used for configuring - externally managed DataPlanes like those installed independently with Helm. + - external + - ref + - managedByOwner type: string - x-kubernetes-validations: - - message: URL has to be a valid URL - rule: isURL(self) required: - type type: object x-kubernetes-validations: - - message: URL has to be provided when type is set to url - rule: self.type != 'url' || has(self.url) - - message: Name cannot be provided when type is set to url - rule: self.type != 'url' || !has(self.name) - - message: Name has to be provided when type is set to name - rule: self.type != 'name' || has(self.name) - - message: URL cannot be provided when type is set to name - rule: self.type != 'name' || !has(self.url) + - message: External has to be provided when type is set to external + rule: self.type != 'external' || has(self.external) + - message: External cannot be provided when type is set to managedByOwner + rule: self.type != 'managedByOwner' || !has(self.external) + - message: Ref has to be provided when type is set to ref + rule: self.type != 'ref' || has(self.ref) + - message: Ref cannot be provided when type is set to managedByOwner + rule: self.type != 'managedByOwner' || !has(self.ref) extensions: description: |- Extensions provide additional or replacement features for the ControlPlane @@ -8546,26 +8559,11 @@ spec: x-kubernetes-list-map-keys: - name x-kubernetes-list-type: map - gatewayClass: - description: |- - GatewayClass indicates the Gateway resources which this ControlPlane - should be responsible for configuring routes for (e.g. HTTPRoute, - TCPRoute, UDPRoute, TLSRoute, etc.). - - Required for the ControlPlane to have any effect: at least one Gateway - must be present for configuration to be pushed to the data-plane and - only Gateway resources can be used to identify data-plane entities. - maxLength: 253 - minLength: 1 - type: string ingressClass: description: |- IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for. - Routing configured this way will be applied to the Gateway resources - indicated by GatewayClass. - If omitted, Ingress resources will not be supported by the ControlPlane. type: string watchNamespaces: diff --git a/config/samples/controlplane_v2_dataplane_url.yaml b/config/samples/controlplane_v2_dataplane_external_url.yaml similarity index 73% rename from config/samples/controlplane_v2_dataplane_url.yaml rename to config/samples/controlplane_v2_dataplane_external_url.yaml index 636f75c6..de83e3e5 100644 --- a/config/samples/controlplane_v2_dataplane_url.yaml +++ b/config/samples/controlplane_v2_dataplane_external_url.yaml @@ -4,9 +4,9 @@ metadata: name: controlplane-v2-example spec: dataplane: - type: url - url: https://dataplane.example.com:8100/api - gatewayClass: kong + type: external + external: + url: https://dataplane.example.com:8100/api featureGates: - name: GatewayAlpha enabled: true diff --git a/config/samples/controlplane_v2_dataplane_managed_by_owner.yaml b/config/samples/controlplane_v2_dataplane_managed_by_owner.yaml new file mode 100644 index 00000000..27b9bc0f --- /dev/null +++ b/config/samples/controlplane_v2_dataplane_managed_by_owner.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway-operator.konghq.com/v2alpha1 +kind: ControlPlane +metadata: + name: controlplane-v2-example +spec: + dataplane: + type: managedByOwner + featureGates: + - name: GatewayAlpha + enabled: true + controllers: + - name: Konnect + enabled: true diff --git a/config/samples/controlplane_v2_dataplane_name.yaml b/config/samples/controlplane_v2_dataplane_ref_name.yaml similarity index 84% rename from config/samples/controlplane_v2_dataplane_name.yaml rename to config/samples/controlplane_v2_dataplane_ref_name.yaml index c216502e..3e777b92 100644 --- a/config/samples/controlplane_v2_dataplane_name.yaml +++ b/config/samples/controlplane_v2_dataplane_ref_name.yaml @@ -4,9 +4,9 @@ metadata: name: controlplane-v2-example spec: dataplane: - type: name - name: dataplane-name - gatewayClass: kong + type: ref + ref: + name: dataplane-name featureGates: - name: GatewayAlpha enabled: true diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index b40bcbe3..5113173c 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -3439,14 +3439,46 @@ is responsible for configuring. | Field | Description | | --- | --- | | `type` _[ControlPlaneDataPlaneTargetType](#controlplanedataplanetargettype)_ | Type indicates the type of the DataPlane target. | -| `url` _string_ | URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | -| `name` _string_ | Name is the name of the DataPlane to configure. | +| `external` _[ControlPlaneDataPlaneTargetExternal](#controlplanedataplanetargetexternal)_ | External is the External of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | +| `ref` _[ControlPlaneDataPlaneTargetRef](#controlplanedataplanetargetref)_ | Ref is the name of the DataPlane to configure. | _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +#### ControlPlaneDataPlaneTargetExternal + + +ControlPlaneDataPlaneTargetExternal defines the configuration for an external DataPlane +that the ControlPlane is responsible for configuring. + + + +| Field | Description | +| --- | --- | +| `url` _string_ | URL is the URL of the external DataPlane to configure. | + + +_Appears in:_ +- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget) + +#### ControlPlaneDataPlaneTargetRef + + +ControlPlaneDataPlaneTargetRef defines the reference to a DataPlane resource +that the ControlPlane is responsible for configuring. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Ref is the name of the DataPlane to configure. | + + +_Appears in:_ +- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget) + #### ControlPlaneDataPlaneTargetType _Underlying type:_ `string` @@ -3515,8 +3547,7 @@ ControlPlaneSpec defines the desired state of ControlPlane | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | | `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | | `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | -| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, etc.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | -| `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

Routing configured this way will be applied to the Gateway resources indicated by GatewayClass.

If omitted, Ingress resources will not be supported by the ControlPlane. | +| `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

If omitted, Ingress resources will not be supported by the ControlPlane. | _Appears in:_ diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index a29da34c..22477692 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -1385,14 +1385,46 @@ is responsible for configuring. | Field | Description | | --- | --- | | `type` _[ControlPlaneDataPlaneTargetType](#controlplanedataplanetargettype)_ | Type indicates the type of the DataPlane target. | -| `url` _string_ | URL is the URL of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | -| `name` _string_ | Name is the name of the DataPlane to configure. | +| `external` _[ControlPlaneDataPlaneTargetExternal](#controlplanedataplanetargetexternal)_ | External is the External of the DataPlane target. This is used for configuring externally managed DataPlanes like those installed independently with Helm. | +| `ref` _[ControlPlaneDataPlaneTargetRef](#controlplanedataplanetargetref)_ | Ref is the name of the DataPlane to configure. | _Appears in:_ - [ControlPlaneOptions](#controlplaneoptions) - [ControlPlaneSpec](#controlplanespec) +#### ControlPlaneDataPlaneTargetExternal + + +ControlPlaneDataPlaneTargetExternal defines the configuration for an external DataPlane +that the ControlPlane is responsible for configuring. + + + +| Field | Description | +| --- | --- | +| `url` _string_ | URL is the URL of the external DataPlane to configure. | + + +_Appears in:_ +- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget) + +#### ControlPlaneDataPlaneTargetRef + + +ControlPlaneDataPlaneTargetRef defines the reference to a DataPlane resource +that the ControlPlane is responsible for configuring. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Ref is the name of the DataPlane to configure. | + + +_Appears in:_ +- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget) + #### ControlPlaneDataPlaneTargetType _Underlying type:_ `string` @@ -1461,8 +1493,7 @@ ControlPlaneSpec defines the desired state of ControlPlane | `featureGates` _[ControlPlaneFeatureGate](#controlplanefeaturegate) array_ | FeatureGates is a list of feature gates that are enabled for this ControlPlane. | | `controllers` _[ControlPlaneController](#controlplanecontroller) array_ | Controllers defines the controllers that are enabled for this ControlPlane. | | `adminAPI` _[ControlPlaneAdminAPI](#controlplaneadminapi)_ | AdminAPI defines the configuration for the Kong Admin API. | -| `gatewayClass` _[ObjectName](#objectname)_ | GatewayClass indicates the Gateway resources which this ControlPlane should be responsible for configuring routes for (e.g. HTTPRoute, TCPRoute, UDPRoute, TLSRoute, etc.).

Required for the ControlPlane to have any effect: at least one Gateway must be present for configuration to be pushed to the data-plane and only Gateway resources can be used to identify data-plane entities. | -| `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

Routing configured this way will be applied to the Gateway resources indicated by GatewayClass.

If omitted, Ingress resources will not be supported by the ControlPlane. | +| `ingressClass` _string_ | IngressClass enables support for the older Ingress resource and indicates which Ingress resources this ControlPlane should be responsible for.

If omitted, Ingress resources will not be supported by the ControlPlane. | _Appears in:_ diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go index 49cbe48a..87cd4bd2 100644 --- a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -12,8 +12,10 @@ import ( func TestControlPlaneV2(t *testing.T) { validDataPlaneTarget := operatorv2alpha1.ControlPlaneDataPlaneTarget{ - Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, - Name: lo.ToPtr("dataplane"), + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetRefType, + Ref: &operatorv2alpha1.ControlPlaneDataPlaneTargetRef{ + Name: "dataplane-1", + }, } validControlPlaneOptions := operatorv2alpha1.ControlPlaneOptions{ @@ -121,64 +123,70 @@ func TestControlPlaneV2(t *testing.T) { Spec: operatorv2alpha1.ControlPlaneSpec{ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ - Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetRefType, }, }, }, }, - ExpectedErrorMessage: lo.ToPtr("Name has to be provided when type is set to name"), + ExpectedErrorMessage: lo.ToPtr("Ref has to be provided when type is set to ref"), }, { - Name: "when dataplane.type is set to url, url must be specified", + Name: "when dataplane.type is set to external, url must be specified", TestObject: &operatorv2alpha1.ControlPlane{ ObjectMeta: common.CommonObjectMeta, Spec: operatorv2alpha1.ControlPlaneSpec{ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ - Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetExternalType, }, }, }, }, - ExpectedErrorMessage: lo.ToPtr("URL has to be provided when type is set to url"), + ExpectedErrorMessage: lo.ToPtr("External has to be provided when type is set to external"), }, { - Name: "specifying dataplane name when type is name passes", + Name: "specifying dataplane ref name when type is ref passes", TestObject: &operatorv2alpha1.ControlPlane{ ObjectMeta: common.CommonObjectMeta, Spec: operatorv2alpha1.ControlPlaneSpec{ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ - Type: operatorv2alpha1.ControlPlaneDataPlaneTargetName, - Name: lo.ToPtr("dataplane"), + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetRefType, + Ref: &operatorv2alpha1.ControlPlaneDataPlaneTargetRef{ + Name: "dataplane-1", + }, }, }, }, }, }, { - Name: "specifying dataplane url when type is url passes: https", + Name: "specifying dataplane url when type is external passes: https", TestObject: &operatorv2alpha1.ControlPlane{ ObjectMeta: common.CommonObjectMeta, Spec: operatorv2alpha1.ControlPlaneSpec{ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ - Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, - URL: lo.ToPtr("https://dataplane.example.com:8444/admin"), + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetExternalType, + External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{ + URL: "https://dataplane.example.com:8444/admin", + }, }, }, }, }, }, { - Name: "specifying dataplane url when type is url passes: http, no port", + Name: "specifying dataplane url when type is external passes: http, no port", TestObject: &operatorv2alpha1.ControlPlane{ ObjectMeta: common.CommonObjectMeta, Spec: operatorv2alpha1.ControlPlaneSpec{ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ - Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, - URL: lo.ToPtr("http://dataplane.example.com/admin"), + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetExternalType, + External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{ + URL: "http://dataplane.example.com/admin", + }, }, }, }, @@ -191,8 +199,10 @@ func TestControlPlaneV2(t *testing.T) { Spec: operatorv2alpha1.ControlPlaneSpec{ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ - Type: operatorv2alpha1.ControlPlaneDataPlaneTargetURL, - URL: lo.ToPtr("not-a-valid-url"), + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetExternalType, + External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{ + URL: "not-a-valid-url", + }, }, }, }, From bc8a3b1ebbac6d4fab1f07adb943105b047c3783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Fri, 6 Jun 2025 13:29:57 +0200 Subject: [PATCH 17/19] chore: don't use bools as suggested by kube-api-linter --- .../v2alpha1/controlplane_types.go | 30 +++++++++-- .../v2alpha1/zz_generated.deepcopy.go | 26 ++-------- ...way-operator.konghq.com_controlplanes.yaml | 52 ++++++++++++------- docs/all-api-reference.md | 28 +++++++++- docs/gateway-operator-api-reference.md | 28 +++++++++- .../controlplane_v2_test.go | 30 +++++------ 6 files changed, 129 insertions(+), 65 deletions(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 5b3a5dfa..8758eea6 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -199,6 +199,16 @@ type ControlPlaneAdminAPI struct { Workspace string `json:"workspace,omitempty"` } +// ControllerState defines the state of a feature gate. +type ControllerState string + +const ( + // ControllerStateEnabled indicates that the feature gate is enabled. + ControllerStateEnabled ControllerState = "enabled" + // ControllerStateDisabled indicates that the feature gate is disabled. + ControllerStateDisabled ControllerState = "disabled" +) + // ControlPlaneController defines a controller state for the ControlPlane. // It overrides the default behavior as defined in the deployed operator version. // @@ -210,12 +220,23 @@ type ControlPlaneController struct { // +kubebuilder:validation:MinLength=1 Name string `json:"name"` - // Enabled indicates whether the controller is enabled or not. + // State indicates whether the feature gate is enabled or disabled. // // +required - Enabled *bool `json:"enabled"` + // +kubebuilder:validation:Enum=enabled;disabled + State ControllerState `json:"state"` } +// FeatureGateState defines the state of a feature gate. +type FeatureGateState string + +const ( + // FeatureGateStateEnabled indicates that the feature gate is enabled. + FeatureGateStateEnabled FeatureGateState = "enabled" + // FeatureGateStateDisabled indicates that the feature gate is disabled. + FeatureGateStateDisabled FeatureGateState = "disabled" +) + // ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. // It overrides the default behavior as defined in the deployed operator version. // @@ -227,10 +248,11 @@ type ControlPlaneFeatureGate struct { // +kubebuilder:validation:MinLength=1 Name string `json:"name"` - // Enabled indicates whether the feature gate is enabled or not. + // State indicates whether the feature gate is enabled or disabled. // // +required - Enabled *bool `json:"enabled"` + // +kubebuilder:validation:Enum=enabled;disabled + State FeatureGateState `json:"state"` } // ControlPlaneStatus defines the observed state of ControlPlane diff --git a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go index 710dcb6d..49b79277 100644 --- a/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go +++ b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go @@ -72,11 +72,6 @@ func (in *ControlPlaneAdminAPI) DeepCopy() *ControlPlaneAdminAPI { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneController) DeepCopyInto(out *ControlPlaneController) { *out = *in - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = new(bool) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneController. @@ -147,11 +142,6 @@ func (in *ControlPlaneDataPlaneTargetRef) DeepCopy() *ControlPlaneDataPlaneTarge // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneFeatureGate) DeepCopyInto(out *ControlPlaneFeatureGate) { *out = *in - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = new(bool) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneFeatureGate. @@ -215,16 +205,12 @@ func (in *ControlPlaneOptions) DeepCopyInto(out *ControlPlaneOptions) { if in.FeatureGates != nil { in, out := &in.FeatureGates, &out.FeatureGates *out = make([]ControlPlaneFeatureGate, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + copy(*out, *in) } if in.Controllers != nil { in, out := &in.Controllers, &out.Controllers *out = make([]ControlPlaneController, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + copy(*out, *in) } if in.AdminAPI != nil { in, out := &in.AdminAPI, &out.AdminAPI @@ -277,16 +263,12 @@ func (in *ControlPlaneStatus) DeepCopyInto(out *ControlPlaneStatus) { if in.FeatureGates != nil { in, out := &in.FeatureGates, &out.FeatureGates *out = make([]ControlPlaneFeatureGate, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + copy(*out, *in) } if in.Controllers != nil { in, out := &in.Controllers, &out.Controllers *out = make([]ControlPlaneController, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + copy(*out, *in) } } diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index 5bf848df..e5117838 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8431,17 +8431,20 @@ spec: ControlPlaneController defines a controller state for the ControlPlane. It overrides the default behavior as defined in the deployed operator version. properties: - enabled: - description: Enabled indicates whether the controller is enabled - or not. - type: boolean name: description: Name is the name of the controller. minLength: 1 type: string + state: + description: State indicates whether the feature gate is enabled + or disabled. + enum: + - enabled + - disabled + type: string required: - - enabled - name + - state type: object maxItems: 32 type: array @@ -8542,17 +8545,20 @@ spec: ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. It overrides the default behavior as defined in the deployed operator version. properties: - enabled: - description: Enabled indicates whether the feature gate is enabled - or not. - type: boolean name: description: Name is the name of the feature gate. minLength: 1 type: string + state: + description: State indicates whether the feature gate is enabled + or disabled. + enum: + - enabled + - disabled + type: string required: - - enabled - name + - state type: object maxItems: 32 type: array @@ -8682,17 +8688,20 @@ spec: ControlPlaneController defines a controller state for the ControlPlane. It overrides the default behavior as defined in the deployed operator version. properties: - enabled: - description: Enabled indicates whether the controller is enabled - or not. - type: boolean name: description: Name is the name of the controller. minLength: 1 type: string + state: + description: State indicates whether the feature gate is enabled + or disabled. + enum: + - enabled + - disabled + type: string required: - - enabled - name + - state type: object maxItems: 32 type: array @@ -8707,17 +8716,20 @@ spec: ControlPlaneFeatureGate defines a feature gate state for the ControlPlane. It overrides the default behavior as defined in the deployed operator version. properties: - enabled: - description: Enabled indicates whether the feature gate is enabled - or not. - type: boolean name: description: Name is the name of the feature gate. minLength: 1 type: string + state: + description: State indicates whether the feature gate is enabled + or disabled. + enum: + - enabled + - disabled + type: string required: - - enabled - name + - state type: object maxItems: 32 type: array diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index 5113173c..87f89a96 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -3420,7 +3420,7 @@ It overrides the default behavior as defined in the deployed operator version. | Field | Description | | --- | --- | | `name` _string_ | Name is the name of the controller. | -| `enabled` _boolean_ | Enabled indicates whether the controller is enabled or not. | +| `state` _[ControllerState](#controllerstate)_ | State indicates whether the feature gate is enabled or disabled. | _Appears in:_ @@ -3503,7 +3503,7 @@ It overrides the default behavior as defined in the deployed operator version. | Field | Description | | --- | --- | | `name` _string_ | Name is the name of the feature gate. | -| `enabled` _boolean_ | Enabled indicates whether the feature gate is enabled or not. | +| `state` _[FeatureGateState](#featuregatestate)_ | State indicates whether the feature gate is enabled or disabled. | _Appears in:_ @@ -3555,6 +3555,30 @@ _Appears in:_ +#### ControllerState +_Underlying type:_ `string` + +ControllerState defines the state of a feature gate. + + + + + +_Appears in:_ +- [ControlPlaneController](#controlplanecontroller) + +#### FeatureGateState +_Underlying type:_ `string` + +FeatureGateState defines the state of a feature gate. + + + + + +_Appears in:_ +- [ControlPlaneFeatureGate](#controlplanefeaturegate) + ## incubator.ingress-controller.konghq.com/v1alpha1 diff --git a/docs/gateway-operator-api-reference.md b/docs/gateway-operator-api-reference.md index 22477692..cd56e391 100644 --- a/docs/gateway-operator-api-reference.md +++ b/docs/gateway-operator-api-reference.md @@ -1366,7 +1366,7 @@ It overrides the default behavior as defined in the deployed operator version. | Field | Description | | --- | --- | | `name` _string_ | Name is the name of the controller. | -| `enabled` _boolean_ | Enabled indicates whether the controller is enabled or not. | +| `state` _[ControllerState](#controllerstate)_ | State indicates whether the feature gate is enabled or disabled. | _Appears in:_ @@ -1449,7 +1449,7 @@ It overrides the default behavior as defined in the deployed operator version. | Field | Description | | --- | --- | | `name` _string_ | Name is the name of the feature gate. | -| `enabled` _boolean_ | Enabled indicates whether the feature gate is enabled or not. | +| `state` _[FeatureGateState](#featuregatestate)_ | State indicates whether the feature gate is enabled or disabled. | _Appears in:_ @@ -1501,3 +1501,27 @@ _Appears in:_ +#### ControllerState +_Underlying type:_ `string` + +ControllerState defines the state of a feature gate. + + + + + +_Appears in:_ +- [ControlPlaneController](#controlplanecontroller) + +#### FeatureGateState +_Underlying type:_ `string` + +FeatureGateState defines the state of a feature gate. + + + + + +_Appears in:_ +- [ControlPlaneFeatureGate](#controlplanefeaturegate) + diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go index 87cd4bd2..1d8a7952 100644 --- a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -114,7 +114,7 @@ func TestControlPlaneV2(t *testing.T) { ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{}, }, }, - ExpectedErrorMessage: lo.ToPtr("spec.dataplane.type: Required value"), + ExpectedErrorMessage: lo.ToPtr("spec.dataplane.type: Unsupported value: \"\""), }, { Name: "when dataplane.type is set to name, name must be specified", @@ -232,8 +232,8 @@ func TestControlPlaneV2(t *testing.T) { DataPlane: validDataPlaneTarget, FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{ { - Name: "KongCustomEntity", - Enabled: lo.ToPtr(true), + Name: "KongCustomEntity", + State: operatorv2alpha1.FeatureGateStateEnabled, }, }, }, @@ -249,8 +249,8 @@ func TestControlPlaneV2(t *testing.T) { DataPlane: validDataPlaneTarget, FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{ { - Name: "KongCustomEntity", - Enabled: lo.ToPtr(false), + Name: "KongCustomEntity", + State: operatorv2alpha1.FeatureGateStateDisabled, }, }, }, @@ -266,8 +266,8 @@ func TestControlPlaneV2(t *testing.T) { DataPlane: validDataPlaneTarget, FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{ { - Name: "KongCustomEntity", - Enabled: lo.ToPtr(true), + Name: "KongCustomEntity", + State: operatorv2alpha1.FeatureGateStateEnabled, }, }, }, @@ -292,7 +292,7 @@ func TestControlPlaneV2(t *testing.T) { }, }, }, - ExpectedErrorMessage: lo.ToPtr("spec.featureGates[0].enabled: Required value"), + ExpectedErrorMessage: lo.ToPtr("spec.featureGates[0].state: Unsupported value: \"\": supported values: \"enabled\", \"disabled\""), }, }.Run(t) }) @@ -317,8 +317,8 @@ func TestControlPlaneV2(t *testing.T) { DataPlane: validDataPlaneTarget, Controllers: []operatorv2alpha1.ControlPlaneController{ { - Name: "GatewayAPI", - Enabled: lo.ToPtr(true), + Name: "GatewayAPI", + State: operatorv2alpha1.ControllerStateEnabled, }, }, }, @@ -334,8 +334,8 @@ func TestControlPlaneV2(t *testing.T) { DataPlane: validDataPlaneTarget, Controllers: []operatorv2alpha1.ControlPlaneController{ { - Name: "GatewayAPI", - Enabled: lo.ToPtr(false), + Name: "GatewayAPI", + State: operatorv2alpha1.ControllerStateDisabled, }, }, }, @@ -351,8 +351,8 @@ func TestControlPlaneV2(t *testing.T) { DataPlane: validDataPlaneTarget, Controllers: []operatorv2alpha1.ControlPlaneController{ { - Name: "GatewayAPI", - Enabled: lo.ToPtr(true), + Name: "GatewayAPI", + State: operatorv2alpha1.ControllerStateEnabled, }, }, }, @@ -377,7 +377,7 @@ func TestControlPlaneV2(t *testing.T) { }, }, }, - ExpectedErrorMessage: lo.ToPtr("spec.controllers[0].enabled: Required value"), + ExpectedErrorMessage: lo.ToPtr("spec.controllers[0].state: Unsupported value: \"\": supported values: \"enabled\", \"disabled\""), }, }.Run(t) }) From 604bd578cd5e3447ff4bc225059a6e46ab1878c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Fri, 6 Jun 2025 13:35:38 +0200 Subject: [PATCH 18/19] chore: adjust samples --- config/samples/controlplane_v2_dataplane_external_url.yaml | 2 +- .../samples/controlplane_v2_dataplane_managed_by_owner.yaml | 4 ++-- config/samples/controlplane_v2_dataplane_ref_name.yaml | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/samples/controlplane_v2_dataplane_external_url.yaml b/config/samples/controlplane_v2_dataplane_external_url.yaml index de83e3e5..ad2cc269 100644 --- a/config/samples/controlplane_v2_dataplane_external_url.yaml +++ b/config/samples/controlplane_v2_dataplane_external_url.yaml @@ -9,6 +9,6 @@ spec: url: https://dataplane.example.com:8100/api featureGates: - name: GatewayAlpha - enabled: true + state: enabled adminAPI: workspace: my_custom_workspace diff --git a/config/samples/controlplane_v2_dataplane_managed_by_owner.yaml b/config/samples/controlplane_v2_dataplane_managed_by_owner.yaml index 27b9bc0f..c395d954 100644 --- a/config/samples/controlplane_v2_dataplane_managed_by_owner.yaml +++ b/config/samples/controlplane_v2_dataplane_managed_by_owner.yaml @@ -7,7 +7,7 @@ spec: type: managedByOwner featureGates: - name: GatewayAlpha - enabled: true + state: enabled controllers: - name: Konnect - enabled: true + state: enabled diff --git a/config/samples/controlplane_v2_dataplane_ref_name.yaml b/config/samples/controlplane_v2_dataplane_ref_name.yaml index 3e777b92..0aa494e0 100644 --- a/config/samples/controlplane_v2_dataplane_ref_name.yaml +++ b/config/samples/controlplane_v2_dataplane_ref_name.yaml @@ -9,11 +9,11 @@ spec: name: dataplane-name featureGates: - name: GatewayAlpha - enabled: true + state: enabled controllers: - name: TCPIngress - enabled: false + state: disabled - name: Konnect - enabled: true + state: enabled adminAPI: workspace: my_custom_workspace From 804f3bf9c28973307676769f796091e260ae91e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Fri, 6 Jun 2025 15:18:10 +0200 Subject: [PATCH 19/19] chore(controlplane): add dataplane target validation --- .../v2alpha1/controlplane_types.go | 2 + ...way-operator.konghq.com_controlplanes.yaml | 4 ++ .../controlplane_v2_test.go | 42 ++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/api/gateway-operator/v2alpha1/controlplane_types.go b/api/gateway-operator/v2alpha1/controlplane_types.go index 8758eea6..93caf1ec 100644 --- a/api/gateway-operator/v2alpha1/controlplane_types.go +++ b/api/gateway-operator/v2alpha1/controlplane_types.go @@ -125,8 +125,10 @@ type ControlPlaneOptions struct { // // +kubebuilder:validation:XValidation:message="External has to be provided when type is set to external",rule="self.type != 'external' || has(self.external)" // +kubebuilder:validation:XValidation:message="External cannot be provided when type is set to managedByOwner",rule="self.type != 'managedByOwner' || !has(self.external)" +// +kubebuilder:validation:XValidation:message="External cannot be provided when type is set to ref",rule="self.type != 'ref' || !has(self.external)" // +kubebuilder:validation:XValidation:message="Ref has to be provided when type is set to ref",rule="self.type != 'ref' || has(self.ref)" // +kubebuilder:validation:XValidation:message="Ref cannot be provided when type is set to managedByOwner",rule="self.type != 'managedByOwner' || !has(self.ref)" +// +kubebuilder:validation:XValidation:message="Ref cannot be provided when type is set to external",rule="self.type != 'external' || !has(self.ref)" type ControlPlaneDataPlaneTarget struct { // Type indicates the type of the DataPlane target. // diff --git a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml index e5117838..ffdc526f 100644 --- a/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml +++ b/config/crd/gateway-operator/gateway-operator.konghq.com_controlplanes.yaml @@ -8497,10 +8497,14 @@ spec: rule: self.type != 'external' || has(self.external) - message: External cannot be provided when type is set to managedByOwner rule: self.type != 'managedByOwner' || !has(self.external) + - message: External cannot be provided when type is set to ref + rule: self.type != 'ref' || !has(self.external) - message: Ref has to be provided when type is set to ref rule: self.type != 'ref' || has(self.ref) - message: Ref cannot be provided when type is set to managedByOwner rule: self.type != 'managedByOwner' || !has(self.ref) + - message: Ref cannot be provided when type is set to external + rule: self.type != 'external' || !has(self.ref) extensions: description: |- Extensions provide additional or replacement features for the ControlPlane diff --git a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go index 1d8a7952..cb2bc4ae 100644 --- a/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go +++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go @@ -131,7 +131,27 @@ func TestControlPlaneV2(t *testing.T) { ExpectedErrorMessage: lo.ToPtr("Ref has to be provided when type is set to ref"), }, { - Name: "when dataplane.type is set to external, url must be specified", + Name: "when dataplane.type is set to ref, external must not be specified", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetRefType, + Ref: &operatorv2alpha1.ControlPlaneDataPlaneTargetRef{ + Name: "dataplane-1", + }, + External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{ + URL: "https://dataplane.example.com:8444/admin", + }, + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("spec.dataplane: Invalid value: \"object\": External cannot be provided when type is set to ref"), + }, + { + Name: "when dataplane.type is set to external, external.url must be specified", TestObject: &operatorv2alpha1.ControlPlane{ ObjectMeta: common.CommonObjectMeta, Spec: operatorv2alpha1.ControlPlaneSpec{ @@ -144,6 +164,26 @@ func TestControlPlaneV2(t *testing.T) { }, ExpectedErrorMessage: lo.ToPtr("External has to be provided when type is set to external"), }, + { + Name: "when dataplane.type is set to external, ref cannot be specified", + TestObject: &operatorv2alpha1.ControlPlane{ + ObjectMeta: common.CommonObjectMeta, + Spec: operatorv2alpha1.ControlPlaneSpec{ + ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{ + DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{ + Type: operatorv2alpha1.ControlPlaneDataPlaneTargetExternalType, + Ref: &operatorv2alpha1.ControlPlaneDataPlaneTargetRef{ + Name: "dataplane-1", + }, + External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{ + URL: "https://dataplane.example.com:8444/admin", + }, + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("Invalid value: \"object\": Ref cannot be provided when type is set to external"), + }, { Name: "specifying dataplane ref name when type is ref passes", TestObject: &operatorv2alpha1.ControlPlane{