diff --git a/api/configuration/v1alpha1/credential_basic_auth_types.go b/api/configuration/v1alpha1/credential_basic_auth_types.go index 25f6c5c..cdaad7a 100644 --- a/api/configuration/v1alpha1/credential_basic_auth_types.go +++ b/api/configuration/v1alpha1/credential_basic_auth_types.go @@ -32,8 +32,8 @@ import ( // +kubebuilder:storageversion // +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.consumerRef) || has(self.spec.consumerRef)", message="consumerRef is required once set" -// +kubebuilder:validation:XValidation:rule="(!self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : oldSelf.spec.consumerRef == self.spec.consumerRef", message="spec.consumerRef is immutable when an entity is already Programmed" +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.consumerRef) || has(self.spec.consumerRef)",message="consumerRef is required once set" +// +kubebuilder:validation:XValidation:rule="(!self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : oldSelf.spec.consumerRef == self.spec.consumerRef",message="spec.consumerRef is immutable when an entity is already Programmed" type CredentialBasicAuth struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -113,22 +113,23 @@ type CredentialBasicAuthSpec struct { // +kubebuilder:validation:Required ConsumerRef corev1.LocalObjectReference `json:"consumerRef"` - // SecretRef is a reference to a Secret this CredentialBasicAuth is associated with. - // - // +kubebuilder:validation:Required - SecretRef corev1.LocalObjectReference `json:"secretRef"` - CredentialBasicAuthAPISpec `json:",inline"` } // CredentialBasicAuthAPISpec defines specification of a BasicAuth credential. type CredentialBasicAuthAPISpec struct { // Password is the password for the BasicAuth credential. - Password *string `json:"password,omitempty"` + // + // +kubebuilder:validation:Required + Password string `json:"password"` + // Tags is a list of tags for the BasicAuth credential. Tags []string `json:"tags,omitempty"` + // Username is the username for the BasicAuth credential. - Username *string `json:"username,omitempty"` + // + // +kubebuilder:validation:Required + Username string `json:"username"` } // CredentialBasicAuthStatus represents the current status of the BasicAuth credential resource. diff --git a/api/configuration/v1alpha1/zz_generated.deepcopy.go b/api/configuration/v1alpha1/zz_generated.deepcopy.go index 019a7d8..22ffbb6 100644 --- a/api/configuration/v1alpha1/zz_generated.deepcopy.go +++ b/api/configuration/v1alpha1/zz_generated.deepcopy.go @@ -112,21 +112,11 @@ func (in *CredentialBasicAuth) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CredentialBasicAuthAPISpec) DeepCopyInto(out *CredentialBasicAuthAPISpec) { *out = *in - if in.Password != nil { - in, out := &in.Password, &out.Password - *out = new(string) - **out = **in - } if in.Tags != nil { in, out := &in.Tags, &out.Tags *out = make([]string, len(*in)) copy(*out, *in) } - if in.Username != nil { - in, out := &in.Username, &out.Username - *out = new(string) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialBasicAuthAPISpec. @@ -175,7 +165,6 @@ func (in *CredentialBasicAuthList) DeepCopyObject() runtime.Object { func (in *CredentialBasicAuthSpec) DeepCopyInto(out *CredentialBasicAuthSpec) { *out = *in out.ConsumerRef = in.ConsumerRef - out.SecretRef = in.SecretRef in.CredentialBasicAuthAPISpec.DeepCopyInto(&out.CredentialBasicAuthAPISpec) } diff --git a/config/crd/bases/configuration.konghq.com_credentialbasicauths.yaml b/config/crd/bases/configuration.konghq.com_credentialbasicauths.yaml index 7da3c4e..dd4fced 100644 --- a/config/crd/bases/configuration.konghq.com_credentialbasicauths.yaml +++ b/config/crd/bases/configuration.konghq.com_credentialbasicauths.yaml @@ -63,21 +63,6 @@ spec: password: description: Password is the password for the BasicAuth credential. type: string - secretRef: - description: SecretRef is a reference to a Secret this CredentialBasicAuth - is associated with. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic tags: description: Tags is a list of tags for the BasicAuth credential. items: @@ -88,7 +73,8 @@ spec: type: string required: - consumerRef - - secretRef + - password + - username type: object status: default: diff --git a/config/samples/konnect_kongconsumer.yaml b/config/samples/konnect_kongconsumer.yaml index 108b057..fdd5d99 100644 --- a/config/samples/konnect_kongconsumer.yaml +++ b/config/samples/konnect_kongconsumer.yaml @@ -22,28 +22,25 @@ spec: authRef: name: konnect-api-auth-dev-1 --- -apiVersion: v1 -kind: Secret -metadata: - name: consumer1-basic-auth - namespace: default - labels: - konghq.com/credential: basic-auth -type: Opaque -stringData: - username: alex - password: secret123 ---- apiVersion: configuration.konghq.com/v1 kind: KongConsumer metadata: name: consumer1 namespace: default username: consumer1 -credentials: -- consumer1-basic-auth spec: controlPlaneRef: type: konnectNamespacedRef konnectNamespacedRef: name: test1 +--- +apiVersion: configuration.konghq.com/v1alpha1 +kind: CredentialBasicAuth +metadata: + name: basic-auth-1 + namespace: default +spec: + consumerRef: + name: consumer1 + password: pass + username: username diff --git a/docs/api-reference.md b/docs/api-reference.md index 45b3188..78049b9 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -590,7 +590,6 @@ CredentialBasicAuthSpec defines specification of a Kong Route. | Field | Description | | --- | --- | | `consumerRef` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#localobjectreference-v1-core)_ | ConsumerRef is a reference to a Consumer this CredentialBasicAuth is associated with. | -| `secretRef` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#localobjectreference-v1-core)_ | SecretRef is a reference to a Secret this CredentialBasicAuth is associated with. | | `password` _string_ | Password is the password for the BasicAuth credential. | | `tags` _string array_ | Tags is a list of tags for the BasicAuth credential. | | `username` _string_ | Username is the username for the BasicAuth credential. | diff --git a/test/crdsvalidation/credentialbasicauth/credentialbasicauth_test.go b/test/crdsvalidation/credentialbasicauth/credentialbasicauth_test.go index a4d544b..925bf86 100644 --- a/test/crdsvalidation/credentialbasicauth/credentialbasicauth_test.go +++ b/test/crdsvalidation/credentialbasicauth/credentialbasicauth_test.go @@ -14,7 +14,7 @@ import ( "github.com/kong/kubernetes-configuration/test/crdsvalidation/credentialbasicauth/testcases" ) -func CredentialBasicAuth(t *testing.T) { +func TestCredentialBasicAuth(t *testing.T) { ctx := context.Background() cfg, err := config.GetConfig() require.NoError(t, err, "error loading Kubernetes config") diff --git a/test/crdsvalidation/credentialbasicauth/testcases/common.go b/test/crdsvalidation/credentialbasicauth/testcases/common.go index 5a53eee..35e06ec 100644 --- a/test/crdsvalidation/credentialbasicauth/testcases/common.go +++ b/test/crdsvalidation/credentialbasicauth/testcases/common.go @@ -28,6 +28,7 @@ var TestCases = []testCasesGroup{} func init() { TestCases = append(TestCases, + requiredFields, updatesNotAllowedForStatus, ) } diff --git a/test/crdsvalidation/credentialbasicauth/testcases/consumerref-update-not-allowed-for-status.go b/test/crdsvalidation/credentialbasicauth/testcases/consumerref-update-not-allowed-for-status.go index 5a40cf7..3d7bb68 100644 --- a/test/crdsvalidation/credentialbasicauth/testcases/consumerref-update-not-allowed-for-status.go +++ b/test/crdsvalidation/credentialbasicauth/testcases/consumerref-update-not-allowed-for-status.go @@ -22,12 +22,9 @@ var updatesNotAllowedForStatus = testCasesGroup{ ConsumerRef: corev1.LocalObjectReference{ Name: "test-kong-consumer", }, - SecretRef: corev1.LocalObjectReference{ - Name: "test-secret", - }, CredentialBasicAuthAPISpec: configurationv1alpha1.CredentialBasicAuthAPISpec{ - Password: lo.ToPtr("password"), - Username: lo.ToPtr("username"), + Password: "password", + Username: "username", }, }, }, @@ -45,7 +42,7 @@ var updatesNotAllowedForStatus = testCasesGroup{ Update: func(c *configurationv1alpha1.CredentialBasicAuth) { c.Spec.ConsumerRef.Name = "new-consumer" }, - ExpectedUpdateErrorMessage: lo.ToPtr("spec.consumerREf is immutable when an entity is already Programmed"), + ExpectedUpdateErrorMessage: lo.ToPtr("spec.consumerRef is immutable when an entity is already Programmed"), }, { Name: "consumerRef change is allowed when consumer is not Programmed=True nor APIAuthValid=True", @@ -55,12 +52,9 @@ var updatesNotAllowedForStatus = testCasesGroup{ ConsumerRef: corev1.LocalObjectReference{ Name: "test-kong-consumer", }, - SecretRef: corev1.LocalObjectReference{ - Name: "test-secret", - }, CredentialBasicAuthAPISpec: configurationv1alpha1.CredentialBasicAuthAPISpec{ - Password: lo.ToPtr("password"), - Username: lo.ToPtr("username"), + Password: "password", + Username: "username", }, }, }, @@ -79,37 +73,5 @@ var updatesNotAllowedForStatus = testCasesGroup{ c.Spec.ConsumerRef.Name = "new-consumer" }, }, - { - Name: "secretRef change is allowed when consumer is Programmed=True", - CredentialBasicAuth: configurationv1alpha1.CredentialBasicAuth{ - ObjectMeta: commonObjectMeta, - Spec: configurationv1alpha1.CredentialBasicAuthSpec{ - ConsumerRef: corev1.LocalObjectReference{ - Name: "test-kong-consumer", - }, - SecretRef: corev1.LocalObjectReference{ - Name: "test-secret", - }, - CredentialBasicAuthAPISpec: configurationv1alpha1.CredentialBasicAuthAPISpec{ - Password: lo.ToPtr("password"), - Username: lo.ToPtr("username"), - }, - }, - }, - CredentialBasicAuthStatus: &configurationv1alpha1.CredentialBasicAuthStatus{ - Konnect: &konnectv1alpha1.KonnectEntityStatusWithControlPlaneRef{}, - Conditions: []metav1.Condition{ - { - Type: "Programmed", - Status: metav1.ConditionTrue, - Reason: "Valid", - LastTransitionTime: metav1.Now(), - }, - }, - }, - Update: func(c *configurationv1alpha1.CredentialBasicAuth) { - c.Spec.SecretRef.Name = "new-secret" - }, - }, }, } diff --git a/test/crdsvalidation/credentialbasicauth/testcases/required_fields.go b/test/crdsvalidation/credentialbasicauth/testcases/required_fields.go new file mode 100644 index 0000000..af99857 --- /dev/null +++ b/test/crdsvalidation/credentialbasicauth/testcases/required_fields.go @@ -0,0 +1,59 @@ +package testcases + +import ( + "github.com/samber/lo" + corev1 "k8s.io/api/core/v1" + + configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1" +) + +var requiredFields = testCasesGroup{ + Name: "required fields validation", + TestCases: []testCase{ + { + Name: "password is required", + CredentialBasicAuth: configurationv1alpha1.CredentialBasicAuth{ + ObjectMeta: commonObjectMeta, + Spec: configurationv1alpha1.CredentialBasicAuthSpec{ + ConsumerRef: corev1.LocalObjectReference{ + Name: "test-kong-consumer", + }, + CredentialBasicAuthAPISpec: configurationv1alpha1.CredentialBasicAuthAPISpec{ + Username: "username", + }, + }, + }, + ExpectedUpdateErrorMessage: lo.ToPtr("spec.consumerREf is immutable when an entity is already Programmed"), + }, + { + Name: "username is required", + CredentialBasicAuth: configurationv1alpha1.CredentialBasicAuth{ + ObjectMeta: commonObjectMeta, + Spec: configurationv1alpha1.CredentialBasicAuthSpec{ + ConsumerRef: corev1.LocalObjectReference{ + Name: "test-kong-consumer", + }, + CredentialBasicAuthAPISpec: configurationv1alpha1.CredentialBasicAuthAPISpec{ + Password: "password", + }, + }, + }, + ExpectedUpdateErrorMessage: lo.ToPtr("spec.consumerREf is immutable when an entity is already Programmed"), + }, + { + Name: "password and username are required", + CredentialBasicAuth: configurationv1alpha1.CredentialBasicAuth{ + ObjectMeta: commonObjectMeta, + Spec: configurationv1alpha1.CredentialBasicAuthSpec{ + ConsumerRef: corev1.LocalObjectReference{ + Name: "test-kong-consumer", + }, + CredentialBasicAuthAPISpec: configurationv1alpha1.CredentialBasicAuthAPISpec{ + Username: "username", + Password: "password", + }, + }, + }, + }, + }, +}