diff --git a/api/configuration/v1/kongconsumer_types.go b/api/configuration/v1/kongconsumer_types.go index 3e1f8fe..73794bf 100644 --- a/api/configuration/v1/kongconsumer_types.go +++ b/api/configuration/v1/kongconsumer_types.go @@ -34,6 +34,8 @@ import ( // +kubebuilder:printcolumn:name="Programmed",type=string,JSONPath=`.status.conditions[?(@.type=="Programmed")].status` // +kubebuilder:validation:XValidation:rule="has(self.username) || has(self.custom_id)", message="Need to provide either username or custom_id" // +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)", message="controlPlaneRef is required once set" +// REVIEW: allow same namespace? +// +kubebuilder:validation:XValidation:rule="!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)", message="spec.controlPlaneRef cannot specify namespace for namespaced resource" // +kubebuilder:validation:XValidation:rule="(!has(self.status) || !self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef", message="spec.controlPlaneRef is immutable when an entity is already Programmed" // KongConsumer is the Schema for the kongconsumers API. diff --git a/api/configuration/v1alpha1/kong_ca_certificate.go b/api/configuration/v1alpha1/kong_ca_certificate.go index 938faab..33e967d 100644 --- a/api/configuration/v1alpha1/kong_ca_certificate.go +++ b/api/configuration/v1alpha1/kong_ca_certificate.go @@ -15,6 +15,7 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:printcolumn:name="Programmed",description="The Resource is Programmed on Konnect",type=string,JSONPath=`.status.conditions[?(@.type=='Programmed')].status` // +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)", message="controlPlaneRef is required once set" +// +kubebuilder:validation:XValidation:rule="!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)", message="spec.controlPlaneRef cannot specify namespace for namespaced resource" // +kubebuilder:validation:XValidation:rule="(!self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef", message="spec.controlPlaneRef is immutable when an entity is already Programmed" type KongCACertificate struct { metav1.TypeMeta `json:",inline"` diff --git a/api/configuration/v1alpha1/kongservice_types.go b/api/configuration/v1alpha1/kongservice_types.go index 8611e79..59471f2 100644 --- a/api/configuration/v1alpha1/kongservice_types.go +++ b/api/configuration/v1alpha1/kongservice_types.go @@ -35,6 +35,7 @@ import ( // +kubebuilder:printcolumn:name="Protocol",type=string,JSONPath=`.spec.procol`,description="Protocol of the service" // +kubebuilder:printcolumn:name="Programmed",description="The Resource is Programmed on Konnect",type=string,JSONPath=`.status.conditions[?(@.type=='Programmed')].status` // +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)", message="controlPlaneRef is required once set" +// +kubebuilder:validation:XValidation:rule="!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)", message="spec.controlPlaneRef cannot specify namespace for namespaced resource" // +kubebuilder:validation:XValidation:rule="(!self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef", message="spec.controlPlaneRef is immutable when an entity is already Programmed" type KongService struct { metav1.TypeMeta `json:",inline"` diff --git a/api/configuration/v1alpha1/kongupstream_types.go b/api/configuration/v1alpha1/kongupstream_types.go index 061f21e..db09101 100644 --- a/api/configuration/v1alpha1/kongupstream_types.go +++ b/api/configuration/v1alpha1/kongupstream_types.go @@ -33,6 +33,7 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:printcolumn:name="Programmed",description="The Resource is Programmed on Konnect",type=string,JSONPath=`.status.conditions[?(@.type=='Programmed')].status` // +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)", message="controlPlaneRef is required once set" +// +kubebuilder:validation:XValidation:rule="!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)", message="spec.controlPlaneRef cannot specify namespace for namespaced resource" // +kubebuilder:validation:XValidation:rule="(!self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef", message="spec.controlPlaneRef is immutable when an entity is already Programmed" type KongUpstream struct { metav1.TypeMeta `json:",inline"` diff --git a/api/configuration/v1alpha1/konnect_controlplaneref_types.go b/api/configuration/v1alpha1/konnect_controlplaneref_types.go index 92203c2..8fac7f3 100644 --- a/api/configuration/v1alpha1/konnect_controlplaneref_types.go +++ b/api/configuration/v1alpha1/konnect_controlplaneref_types.go @@ -39,6 +39,9 @@ type KonnectNamespacedRef struct { // +kubebuilder:validation:Required Name string `json:"name"` + // TODO: Implement cross namespace references: + // https://github.com/Kong/kubernetes-configuration/issues/36 + // Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. // Namespace is the namespace where the Konnect Control Plane is in. // +optional Namespace string `json:"namespace,omitempty"` diff --git a/api/configuration/v1beta1/kongconsumergroup_types.go b/api/configuration/v1beta1/kongconsumergroup_types.go index 83fa98b..968e79d 100644 --- a/api/configuration/v1beta1/kongconsumergroup_types.go +++ b/api/configuration/v1beta1/kongconsumergroup_types.go @@ -32,6 +32,7 @@ import ( // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`,description="Age" // +kubebuilder:printcolumn:name="Programmed",type=string,JSONPath=`.status.conditions[?(@.type=="Programmed")].status` // +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)", message="controlPlaneRef is required once set" +// +kubebuilder:validation:XValidation:rule="!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)", message="spec.controlPlaneRef cannot specify namespace for namespaced resource" // +kubebuilder:validation:XValidation:rule="(!has(self.status) || !self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef", message="spec.controlPlaneRef is immutable when an entity is already Programmed" // KongConsumerGroup is the Schema for the kongconsumergroups API. diff --git a/config/crd/bases/configuration.konghq.com_kongcacertificates.yaml b/config/crd/bases/configuration.konghq.com_kongcacertificates.yaml index 1dba78d..64f08c2 100644 --- a/config/crd/bases/configuration.konghq.com_kongcacertificates.yaml +++ b/config/crd/bases/configuration.konghq.com_kongcacertificates.yaml @@ -68,8 +68,10 @@ spec: description: Name is the name of the Konnect Control Plane. type: string namespace: - description: Namespace is the namespace where the Konnect - Control Plane is in. + description: |- + https://github.com/Kong/kubernetes-configuration/issues/36 + Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. + Namespace is the namespace where the Konnect Control Plane is in. type: string required: - name @@ -198,6 +200,8 @@ spec: x-kubernetes-validations: - message: controlPlaneRef is required once set rule: '!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)' + - message: spec.controlPlaneRef cannot specify namespace for namespaced resource + rule: '!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)' - message: spec.controlPlaneRef is immutable when an entity is already Programmed rule: '(!self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef' diff --git a/config/crd/bases/configuration.konghq.com_kongconsumergroups.yaml b/config/crd/bases/configuration.konghq.com_kongconsumergroups.yaml index 325894a..df48f53 100644 --- a/config/crd/bases/configuration.konghq.com_kongconsumergroups.yaml +++ b/config/crd/bases/configuration.konghq.com_kongconsumergroups.yaml @@ -69,8 +69,10 @@ spec: description: Name is the name of the Konnect Control Plane. type: string namespace: - description: Namespace is the namespace where the Konnect - Control Plane is in. + description: |- + https://github.com/Kong/kubernetes-configuration/issues/36 + Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. + Namespace is the namespace where the Konnect Control Plane is in. type: string required: - name @@ -199,6 +201,8 @@ spec: x-kubernetes-validations: - message: controlPlaneRef is required once set rule: '!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)' + - message: spec.controlPlaneRef cannot specify namespace for namespaced resource + rule: '!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)' - message: spec.controlPlaneRef is immutable when an entity is already Programmed rule: '(!has(self.status) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : oldSelf.spec.controlPlaneRef diff --git a/config/crd/bases/configuration.konghq.com_kongconsumers.yaml b/config/crd/bases/configuration.konghq.com_kongconsumers.yaml index d82b846..65fd33e 100644 --- a/config/crd/bases/configuration.konghq.com_kongconsumers.yaml +++ b/config/crd/bases/configuration.konghq.com_kongconsumers.yaml @@ -94,8 +94,10 @@ spec: description: Name is the name of the Konnect Control Plane. type: string namespace: - description: Namespace is the namespace where the Konnect - Control Plane is in. + description: |- + https://github.com/Kong/kubernetes-configuration/issues/36 + Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. + Namespace is the namespace where the Konnect Control Plane is in. type: string required: - name @@ -226,6 +228,8 @@ spec: rule: has(self.username) || has(self.custom_id) - message: controlPlaneRef is required once set rule: '!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)' + - message: spec.controlPlaneRef cannot specify namespace for namespaced resource + rule: '!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)' - message: spec.controlPlaneRef is immutable when an entity is already Programmed rule: '(!has(self.status) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : oldSelf.spec.controlPlaneRef diff --git a/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml b/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml index 180c096..703cef9 100644 --- a/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml +++ b/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml @@ -72,8 +72,10 @@ spec: description: Name is the name of the Konnect Control Plane. type: string namespace: - description: Namespace is the namespace where the Konnect - Control Plane is in. + description: |- + https://github.com/Kong/kubernetes-configuration/issues/36 + Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. + Namespace is the namespace where the Konnect Control Plane is in. type: string required: - name diff --git a/config/crd/bases/configuration.konghq.com_kongservices.yaml b/config/crd/bases/configuration.konghq.com_kongservices.yaml index fe9647d..5abde12 100644 --- a/config/crd/bases/configuration.konghq.com_kongservices.yaml +++ b/config/crd/bases/configuration.konghq.com_kongservices.yaml @@ -77,8 +77,10 @@ spec: description: Name is the name of the Konnect Control Plane. type: string namespace: - description: Namespace is the namespace where the Konnect - Control Plane is in. + description: |- + https://github.com/Kong/kubernetes-configuration/issues/36 + Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. + Namespace is the namespace where the Konnect Control Plane is in. type: string required: - name @@ -259,6 +261,8 @@ spec: x-kubernetes-validations: - message: controlPlaneRef is required once set rule: '!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)' + - message: spec.controlPlaneRef cannot specify namespace for namespaced resource + rule: '!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)' - message: spec.controlPlaneRef is immutable when an entity is already Programmed rule: '(!self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef' diff --git a/config/crd/bases/configuration.konghq.com_kongupstreams.yaml b/config/crd/bases/configuration.konghq.com_kongupstreams.yaml index 164ecd7..1dda154 100644 --- a/config/crd/bases/configuration.konghq.com_kongupstreams.yaml +++ b/config/crd/bases/configuration.konghq.com_kongupstreams.yaml @@ -74,8 +74,10 @@ spec: description: Name is the name of the Konnect Control Plane. type: string namespace: - description: Namespace is the namespace where the Konnect - Control Plane is in. + description: |- + https://github.com/Kong/kubernetes-configuration/issues/36 + Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. + Namespace is the namespace where the Konnect Control Plane is in. type: string required: - name @@ -415,6 +417,8 @@ spec: x-kubernetes-validations: - message: controlPlaneRef is required once set rule: '!has(oldSelf.spec.controlPlaneRef) || has(self.spec.controlPlaneRef)' + - message: spec.controlPlaneRef cannot specify namespace for namespaced resource + rule: '!has(self.spec.controlPlaneRef.konnectNamespacedRef) ? true : !has(self.spec.controlPlaneRef.konnectNamespacedRef.__namespace__)' - message: spec.controlPlaneRef is immutable when an entity is already Programmed rule: '(!self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : oldSelf.spec.controlPlaneRef == self.spec.controlPlaneRef' diff --git a/config/crd/bases/configuration.konghq.com_kongvaults.yaml b/config/crd/bases/configuration.konghq.com_kongvaults.yaml index 0bde5ac..5047049 100644 --- a/config/crd/bases/configuration.konghq.com_kongvaults.yaml +++ b/config/crd/bases/configuration.konghq.com_kongvaults.yaml @@ -97,8 +97,10 @@ spec: description: Name is the name of the Konnect Control Plane. type: string namespace: - description: Namespace is the namespace where the Konnect - Control Plane is in. + description: |- + https://github.com/Kong/kubernetes-configuration/issues/36 + Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. + Namespace is the namespace where the Konnect Control Plane is in. type: string required: - name diff --git a/docs/api-reference.md b/docs/api-reference.md index 8e819cd..8ad6769 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -965,7 +965,7 @@ KonnectNamespacedRef is the schema for the KonnectNamespacedRef type. | Field | Description | | --- | --- | | `name` _string_ | Name is the name of the Konnect Control Plane. | -| `namespace` _string_ | Namespace is the namespace where the Konnect Control Plane is in. | +| `namespace` _string_ | TODO: Implement cross namespace references: https://github.com/Kong/kubernetes-configuration/issues/36 Currently only cluster scoped resources (KongVault) are allowed to set `konnectNamespacedRef.namespace`. Namespace is the namespace where the Konnect Control Plane is in. | _Appears in:_ diff --git a/test/crdsvalidation/kongconsumer/testcases/common.go b/test/crdsvalidation/kongconsumer/testcases/common.go index bee516d..b4f5bcb 100644 --- a/test/crdsvalidation/kongconsumer/testcases/common.go +++ b/test/crdsvalidation/kongconsumer/testcases/common.go @@ -28,6 +28,7 @@ var TestCases = []testCasesGroup{} func init() { TestCases = append(TestCases, + controlPlaneRef, requiredFields, updatesNotAllowedForStatus, ) diff --git a/test/crdsvalidation/kongconsumer/testcases/controlplaneref.go b/test/crdsvalidation/kongconsumer/testcases/controlplaneref.go new file mode 100644 index 0000000..ce1a475 --- /dev/null +++ b/test/crdsvalidation/kongconsumer/testcases/controlplaneref.go @@ -0,0 +1,31 @@ +package testcases + +import ( + "github.com/samber/lo" + + configurationv1 "github.com/kong/kubernetes-configuration/api/configuration/v1" + configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1" +) + +var controlPlaneRef = testCasesGroup{ + Name: "fields of controlPlaneRef", + TestCases: []testCase{ + { + Name: "cpRef cannot have namespace", + KongConsumer: configurationv1.KongConsumer{ + ObjectMeta: commonObjectMeta, + Spec: configurationv1.KongConsumerSpec{ + ControlPlaneRef: &configurationv1alpha1.ControlPlaneRef{ + Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef, + KonnectNamespacedRef: &configurationv1alpha1.KonnectNamespacedRef{ + Name: "test-konnect-control-plane", + Namespace: "another-namespace", + }, + }, + }, + Username: "username-1", + }, + ExpectedErrorMessage: lo.ToPtr("spec.controlPlaneRef cannot specify namespace for namespaced resource"), + }, + }, +} diff --git a/test/crdsvalidation/kongconsumergroup/testcases/common.go b/test/crdsvalidation/kongconsumergroup/testcases/common.go index 28bf091..b1747ee 100644 --- a/test/crdsvalidation/kongconsumergroup/testcases/common.go +++ b/test/crdsvalidation/kongconsumergroup/testcases/common.go @@ -29,6 +29,7 @@ var TestCases = []testCasesGroup{} func init() { TestCases = append(TestCases, fields, + controlPlaneRef, updatesNotAllowedForStatus, ) } diff --git a/test/crdsvalidation/kongconsumergroup/testcases/controlplaneref.go b/test/crdsvalidation/kongconsumergroup/testcases/controlplaneref.go new file mode 100644 index 0000000..be5f3a4 --- /dev/null +++ b/test/crdsvalidation/kongconsumergroup/testcases/controlplaneref.go @@ -0,0 +1,30 @@ +package testcases + +import ( + "github.com/samber/lo" + + configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1" + configurationv1beta1 "github.com/kong/kubernetes-configuration/api/configuration/v1beta1" +) + +var controlPlaneRef = testCasesGroup{ + Name: "fields of controlPlaneRef", + TestCases: []testCase{ + { + Name: "cpRef cannot have namespace", + KongConsumerGroup: configurationv1beta1.KongConsumerGroup{ + ObjectMeta: commonObjectMeta, + Spec: configurationv1beta1.KongConsumerGroupSpec{ + ControlPlaneRef: &configurationv1alpha1.ControlPlaneRef{ + Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef, + KonnectNamespacedRef: &configurationv1alpha1.KonnectNamespacedRef{ + Name: "test-konnect-control-plane", + Namespace: "another-namespace", + }, + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("spec.controlPlaneRef cannot specify namespace for namespaced resource"), + }, + }, +} diff --git a/test/crdsvalidation/kongservice/testcases/controlplaneref.go b/test/crdsvalidation/kongservice/testcases/controlplaneref.go index e42fc40..06cb09c 100644 --- a/test/crdsvalidation/kongservice/testcases/controlplaneref.go +++ b/test/crdsvalidation/kongservice/testcases/controlplaneref.go @@ -57,6 +57,25 @@ var cpRef = testCasesGroup{ }, ExpectedErrorMessage: lo.ToPtr("when type is konnectID, konnectID must be set"), }, + { + Name: "providing namespace in konnectNamespacedRef yields an error", + KongService: configurationv1alpha1.KongService{ + ObjectMeta: commonObjectMeta, + Spec: configurationv1alpha1.KongServiceSpec{ + ControlPlaneRef: &configurationv1alpha1.ControlPlaneRef{ + Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef, + KonnectNamespacedRef: &configurationv1alpha1.KonnectNamespacedRef{ + Name: "test-konnect-control-plane", + Namespace: "another-namespace", + }, + }, + KongServiceAPISpec: configurationv1alpha1.KongServiceAPISpec{ + Host: "example.com", + }, + }, + }, + ExpectedErrorMessage: lo.ToPtr("spec.controlPlaneRef cannot specify namespace for namespaced resource"), + }, { Name: "konnectNamespacedRef reference name cannot be changed when an entity is Programmed", KongService: configurationv1alpha1.KongService{ diff --git a/test/crdsvalidation/kongupstream/testcases/controlplaneref.go b/test/crdsvalidation/kongupstream/testcases/controlplaneref.go index ee214cb..a2ffe8f 100644 --- a/test/crdsvalidation/kongupstream/testcases/controlplaneref.go +++ b/test/crdsvalidation/kongupstream/testcases/controlplaneref.go @@ -51,6 +51,23 @@ var cpRef = testCasesGroup{ }, ExpectedErrorMessage: lo.ToPtr("when type is konnectID, konnectID must be set"), }, + { + Name: "providing namespace in konnectNamespacedRef yields an error", + KongUpstream: configurationv1alpha1.KongUpstream{ + ObjectMeta: commonObjectMeta, + Spec: configurationv1alpha1.KongUpstreamSpec{ + ControlPlaneRef: &configurationv1alpha1.ControlPlaneRef{ + Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef, + KonnectNamespacedRef: &configurationv1alpha1.KonnectNamespacedRef{ + Name: "test-konnect-control-plane", + Namespace: "another-namespace", + }, + }, + KongUpstreamAPISpec: configurationv1alpha1.KongUpstreamAPISpec{}, + }, + }, + ExpectedErrorMessage: lo.ToPtr("spec.controlPlaneRef cannot specify namespace for namespaced resource"), + }, { Name: "konnectNamespacedRef reference name cannot be changed when an entity is Programmed", KongUpstream: configurationv1alpha1.KongUpstream{