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..93caf1ec
--- /dev/null
+++ b/api/gateway-operator/v2alpha1/controlplane_types.go
@@ -0,0 +1,303 @@
+/*
+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
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/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"`
+
+ // 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.
+ //
+ // +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 {
+ // 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.
+ //
+ // +required
+ DataPlane ControlPlaneDataPlaneTarget `json:"dataplane"`
+
+ // Extensions provide additional or replacement features for the ControlPlane
+ // resources to influence or enhance functionality.
+ //
+ // +optional
+ // +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="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.
+ //
+ // +required
+ // +kubebuilder:validation:Enum=external;ref;managedByOwner
+ Type ControlPlaneDataPlaneTargetType `json:"type"`
+
+ // External is the External of the DataPlane target. This is used for configuring
+ // externally managed DataPlanes like those installed independently with Helm.
+ //
+ // +optional
+ External *ControlPlaneDataPlaneTargetExternal `json:"external,omitempty"`
+
+ // Ref is the name of the DataPlane to configure.
+ //
+ // +optional
+ Ref *ControlPlaneDataPlaneTargetRef `json:"ref,omitempty"`
+}
+
+// ControlPlaneDataPlaneTargetType defines the type of the DataPlane target
+// that the ControlPlane is responsible for configuring.
+type ControlPlaneDataPlaneTargetType string
+
+const (
+ // 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"
+
+ // ControlPlaneDataPlaneTargetRefType indicates that the DataPlane target is a ref
+ // of a DataPlane resource managed by the operator.
+ // 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.
+ // If left empty then no Kong workspace will be used.
+ //
+ // +optional
+ 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.
+//
+// +apireference:kgo:include
+type ControlPlaneController struct {
+ // Name is the name of the controller.
+ //
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ Name string `json:"name"`
+
+ // State indicates whether the feature gate is enabled or disabled.
+ //
+ // +required
+ // +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.
+//
+// +apireference:kgo:include
+type ControlPlaneFeatureGate struct {
+ // Name is the name of the feature gate.
+ //
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ Name string `json:"name"`
+
+ // State indicates whether the feature gate is enabled or disabled.
+ //
+ // +required
+ // +kubebuilder:validation:Enum=enabled;disabled
+ State FeatureGateState `json:"state"`
+}
+
+// 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"`
+
+ // 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
+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..ab848b66
--- /dev/null
+++ b/api/gateway-operator/v2alpha1/groupversion_info.go
@@ -0,0 +1,36 @@
+/*
+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
+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/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",
+ }
+}
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..49b79277
--- /dev/null
+++ b/api/gateway-operator/v2alpha1/zz_generated.deepcopy.go
@@ -0,0 +1,283 @@
+//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"
+ "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+)
+
+// 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
+}
+
+// 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
+ if in.External != nil {
+ in, out := &in.External, &out.External
+ *out = new(ControlPlaneDataPlaneTargetExternal)
+ **out = **in
+ }
+ if in.Ref != nil {
+ in, out := &in.Ref, &out.Ref
+ *out = new(ControlPlaneDataPlaneTargetRef)
+ **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 *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
+}
+
+// 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
+ in.DataPlane.DeepCopyInto(&out.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))
+ copy(*out, *in)
+ }
+ if in.Controllers != nil {
+ in, out := &in.Controllers, &out.Controllers
+ *out = make([]ControlPlaneController, len(*in))
+ copy(*out, *in)
+ }
+ 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.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([]v1.Condition, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.FeatureGates != nil {
+ in, out := &in.FeatureGates, &out.FeatureGates
+ *out = make([]ControlPlaneFeatureGate, len(*in))
+ copy(*out, *in)
+ }
+ if in.Controllers != nil {
+ in, out := &in.Controllers, &out.Controllers
+ *out = make([]ControlPlaneController, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// 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..ffdc526f 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,366 @@ 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:
+ 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:
+ - name
+ - state
+ type: object
+ maxItems: 32
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ dataplane:
+ description: |-
+ 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.
+ properties:
+ 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:
+ - external
+ - ref
+ - managedByOwner
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - 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: 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
+ 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
+ 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:
+ 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:
+ - name
+ - state
+ type: object
+ maxItems: 32
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ ingressClass:
+ description: |-
+ 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.
+ 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
+ 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:
+ 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:
+ - name
+ - state
+ 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:
+ 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:
+ - name
+ - state
+ type: object
+ maxItems: 32
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ type: object
+ type: object
+ served: true
+ storage: false
+ subresources:
+ status: {}
diff --git a/config/samples/controlplane_v2_dataplane_external_url.yaml b/config/samples/controlplane_v2_dataplane_external_url.yaml
new file mode 100644
index 00000000..ad2cc269
--- /dev/null
+++ b/config/samples/controlplane_v2_dataplane_external_url.yaml
@@ -0,0 +1,14 @@
+apiVersion: gateway-operator.konghq.com/v2alpha1
+kind: ControlPlane
+metadata:
+ name: controlplane-v2-example
+spec:
+ dataplane:
+ type: external
+ external:
+ url: https://dataplane.example.com:8100/api
+ featureGates:
+ - name: GatewayAlpha
+ 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
new file mode 100644
index 00000000..c395d954
--- /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
+ state: enabled
+ controllers:
+ - name: Konnect
+ state: enabled
diff --git a/config/samples/controlplane_v2_dataplane_ref_name.yaml b/config/samples/controlplane_v2_dataplane_ref_name.yaml
new file mode 100644
index 00000000..0aa494e0
--- /dev/null
+++ b/config/samples/controlplane_v2_dataplane_ref_name.yaml
@@ -0,0 +1,19 @@
+apiVersion: gateway-operator.konghq.com/v2alpha1
+kind: ControlPlane
+metadata:
+ name: controlplane-v2-example
+spec:
+ dataplane:
+ type: ref
+ ref:
+ name: dataplane-name
+ featureGates:
+ - name: GatewayAlpha
+ state: enabled
+ controllers:
+ - name: TCPIngress
+ state: disabled
+ - name: Konnect
+ state: enabled
+ adminAPI:
+ workspace: my_custom_workspace
diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md
index a5946e6d..87f89a96 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)
@@ -3349,6 +3350,8 @@ WatchNamespaces defines the namespaces to watch for resources
_Appears in:_
- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneSpec](#controlplanespec)
- [ControlPlaneSpec](#controlplanespec)
#### WatchNamespacesType
@@ -3364,6 +3367,219 @@ _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 DataPlane Kong Admin API.
+
+
+
+| 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. |
+| `state` _[ControllerState](#controllerstate)_ | State indicates whether the feature gate is enabled or disabled. |
+
+
+_Appears in:_
+- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneSpec](#controlplanespec)
+- [ControlPlaneStatus](#controlplanestatus)
+
+#### ControlPlaneDataPlaneTarget
+
+
+ControlPlaneDataPlaneTarget defines the target for the DataPlane that the ControlPlane
+is responsible for configuring.
+
+
+
+| Field | Description |
+| --- | --- |
+| `type` _[ControlPlaneDataPlaneTargetType](#controlplanedataplanetargettype)_ | Type indicates the type of the DataPlane target. |
+| `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`
+
+ControlPlaneDataPlaneTargetType defines the type of the DataPlane target
+that the ControlPlane is responsible for configuring.
+
+
+
+
+
+_Appears in:_
+- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)
+
+#### 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. |
+| `state` _[FeatureGateState](#featuregatestate)_ | State indicates whether the feature gate is enabled or disabled. |
+
+
+_Appears in:_
+- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneSpec](#controlplanespec)
+- [ControlPlaneStatus](#controlplanestatus)
+
+#### ControlPlaneOptions
+
+
+ControlPlaneOptions indicates the specific information needed to
+deploy and connect a ControlPlane to a DataPlane object.
+
+
+
+| Field | Description |
+| --- | --- |
+| `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. |
+| `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)_ | 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. |
+| `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. |
+| `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:_
+- [ControlPlane](#controlplane)
+
+
+
+#### 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
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 3df76844..cd56e391 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
@@ -1295,6 +1296,8 @@ WatchNamespaces defines the namespaces to watch for resources
_Appears in:_
- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneSpec](#controlplanespec)
- [ControlPlaneSpec](#controlplanespec)
#### WatchNamespacesType
@@ -1309,3 +1312,216 @@ 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 DataPlane Kong Admin API.
+
+
+
+| 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. |
+| `state` _[ControllerState](#controllerstate)_ | State indicates whether the feature gate is enabled or disabled. |
+
+
+_Appears in:_
+- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneSpec](#controlplanespec)
+- [ControlPlaneStatus](#controlplanestatus)
+
+#### ControlPlaneDataPlaneTarget
+
+
+ControlPlaneDataPlaneTarget defines the target for the DataPlane that the ControlPlane
+is responsible for configuring.
+
+
+
+| Field | Description |
+| --- | --- |
+| `type` _[ControlPlaneDataPlaneTargetType](#controlplanedataplanetargettype)_ | Type indicates the type of the DataPlane target. |
+| `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`
+
+ControlPlaneDataPlaneTargetType defines the type of the DataPlane target
+that the ControlPlane is responsible for configuring.
+
+
+
+
+
+_Appears in:_
+- [ControlPlaneDataPlaneTarget](#controlplanedataplanetarget)
+
+#### 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. |
+| `state` _[FeatureGateState](#featuregatestate)_ | State indicates whether the feature gate is enabled or disabled. |
+
+
+_Appears in:_
+- [ControlPlaneOptions](#controlplaneoptions)
+- [ControlPlaneSpec](#controlplanespec)
+- [ControlPlaneStatus](#controlplanestatus)
+
+#### ControlPlaneOptions
+
+
+ControlPlaneOptions indicates the specific information needed to
+deploy and connect a ControlPlane to a DataPlane object.
+
+
+
+| Field | Description |
+| --- | --- |
+| `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. |
+| `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)_ | 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. |
+| `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. |
+| `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:_
+- [ControlPlane](#controlplane)
+
+
+
+#### 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/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",
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..cb2bc4ae
--- /dev/null
+++ b/test/crdsvalidation/gateway-operator.konghq.com/controlplane_v2_test.go
@@ -0,0 +1,424 @@
+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.ControlPlaneDataPlaneTargetRefType,
+ Ref: &operatorv2alpha1.ControlPlaneDataPlaneTargetRef{
+ Name: "dataplane-1",
+ },
+ }
+
+ 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("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: Unsupported 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.ControlPlaneDataPlaneTargetRefType,
+ },
+ },
+ },
+ },
+ ExpectedErrorMessage: lo.ToPtr("Ref has to be provided when type is set to ref"),
+ },
+ {
+ 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{
+ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{
+ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{
+ Type: operatorv2alpha1.ControlPlaneDataPlaneTargetExternalType,
+ },
+ },
+ },
+ },
+ 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{
+ ObjectMeta: common.CommonObjectMeta,
+ Spec: operatorv2alpha1.ControlPlaneSpec{
+ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{
+ DataPlane: operatorv2alpha1.ControlPlaneDataPlaneTarget{
+ Type: operatorv2alpha1.ControlPlaneDataPlaneTargetRefType,
+ Ref: &operatorv2alpha1.ControlPlaneDataPlaneTargetRef{
+ Name: "dataplane-1",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ 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.ControlPlaneDataPlaneTargetExternalType,
+ External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{
+ URL: "https://dataplane.example.com:8444/admin",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ 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.ControlPlaneDataPlaneTargetExternalType,
+ External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{
+ 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.ControlPlaneDataPlaneTargetExternalType,
+ External: &operatorv2alpha1.ControlPlaneDataPlaneTargetExternal{
+ URL: "not-a-valid-url",
+ },
+ },
+ },
+ },
+ },
+ ExpectedErrorMessage: lo.ToPtr("URL has to be a valid URL"),
+ },
+ }.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",
+ State: operatorv2alpha1.FeatureGateStateEnabled,
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ Name: "feature gate disabled",
+ TestObject: &operatorv2alpha1.ControlPlane{
+ ObjectMeta: common.CommonObjectMeta,
+ Spec: operatorv2alpha1.ControlPlaneSpec{
+ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{
+ DataPlane: validDataPlaneTarget,
+ FeatureGates: []operatorv2alpha1.ControlPlaneFeatureGate{
+ {
+ Name: "KongCustomEntity",
+ State: operatorv2alpha1.FeatureGateStateDisabled,
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ 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",
+ State: operatorv2alpha1.FeatureGateStateEnabled,
+ },
+ },
+ },
+ },
+ },
+ Update: func(cp *operatorv2alpha1.ControlPlane) {
+ 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].state: Unsupported value: \"\": supported values: \"enabled\", \"disabled\""),
+ },
+ }.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",
+ State: operatorv2alpha1.ControllerStateEnabled,
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ Name: "controller overrides specified - disabled",
+ TestObject: &operatorv2alpha1.ControlPlane{
+ ObjectMeta: common.CommonObjectMeta,
+ Spec: operatorv2alpha1.ControlPlaneSpec{
+ ControlPlaneOptions: operatorv2alpha1.ControlPlaneOptions{
+ DataPlane: validDataPlaneTarget,
+ Controllers: []operatorv2alpha1.ControlPlaneController{
+ {
+ Name: "GatewayAPI",
+ State: operatorv2alpha1.ControllerStateDisabled,
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ 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",
+ State: operatorv2alpha1.ControllerStateEnabled,
+ },
+ },
+ },
+ },
+ },
+ Update: func(cp *operatorv2alpha1.ControlPlane) {
+ 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].state: Unsupported value: \"\": supported values: \"enabled\", \"disabled\""),
+ },
+ }.Run(t)
+ })
+}