From 27a852c171cac869f32cb6f569e5a831af0bc48f Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Wed, 8 May 2024 16:15:03 +0200 Subject: [PATCH] Add webhook to validate service override endpoint type Can also be called from the openstack-operator webhook on the OctaviaSpecCore, like for other operators in [1]. Depends-On: https://github.com/openstack-k8s-operators/lib-common/pull/505 [1] https://github.com/openstack-k8s-operators/openstack-operator/blob/d2703d3a321c979dacaca95b5d4a634bf116e0db/apis/core/v1beta1/openstackcontrolplane_webhook.go#L181 --- api/go.mod | 2 +- api/go.sum | 4 +- api/v1beta1/octavia_webhook.go | 86 +++++++++++++++++++++++++++++++++- go.mod | 2 +- go.sum | 4 +- 5 files changed, 90 insertions(+), 8 deletions(-) diff --git a/api/go.mod b/api/go.mod index 87fd8e7d..3b224423 100644 --- a/api/go.mod +++ b/api/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/onsi/ginkgo/v2 v2.17.2 github.com/onsi/gomega v1.33.0 - github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240429052447-09a614506ca6 + github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240522141801-d6e03083e82a k8s.io/api v0.28.9 k8s.io/apimachinery v0.28.9 k8s.io/client-go v0.28.9 diff --git a/api/go.sum b/api/go.sum index aaed442a..377ed60f 100644 --- a/api/go.sum +++ b/api/go.sum @@ -68,8 +68,8 @@ github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= -github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240429052447-09a614506ca6 h1:WLsG3Ko+phW5xZJjncypLWGASoLqKrt05qN9Zxsad6g= -github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240429052447-09a614506ca6/go.mod h1:lYhFzul37AR/6gAhTAA1KKWbOlzB3F/7014lejn883c= +github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240522141801-d6e03083e82a h1:kcASVA9sZg9DtggyJlN6JZE6pIenJgXivFK6ry7WUVM= +github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240522141801-d6e03083e82a/go.mod h1:lYhFzul37AR/6gAhTAA1KKWbOlzB3F/7014lejn883c= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/api/v1beta1/octavia_webhook.go b/api/v1beta1/octavia_webhook.go index c0e2ca3d..fbcf2174 100644 --- a/api/v1beta1/octavia_webhook.go +++ b/api/v1beta1/octavia_webhook.go @@ -17,7 +17,13 @@ limitations under the License. package v1beta1 import ( + "fmt" + + "github.com/openstack-k8s-operators/lib-common/modules/common/service" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" @@ -95,18 +101,94 @@ var _ webhook.Validator = &Octavia{} func (r *Octavia) ValidateCreate() (admission.Warnings, error) { octavialog.Info("validate create", "name", r.Name) - // TODO(user): fill in your validation logic upon object creation. + var allErrs field.ErrorList + basePath := field.NewPath("spec") + if err := r.Spec.ValidateCreate(basePath); err != nil { + allErrs = append(allErrs, err...) + } + + if len(allErrs) != 0 { + return nil, apierrors.NewInvalid( + schema.GroupKind{Group: "octavia.openstack.org", Kind: "Octavia"}, + r.Name, allErrs) + } + return nil, nil } +// ValidateCreate - Exported function wrapping non-exported validate functions, +// this function can be called externally to validate an octavia spec. +func (r *OctaviaSpec) ValidateCreate(basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("octaviaAPI").Child("override").Child("service"), + r.OctaviaAPI.Override.Service)...) + + return allErrs +} + +func (r *OctaviaSpecCore) ValidateCreate(basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("octaviaAPI").Child("override").Child("service"), + r.OctaviaAPI.Override.Service)...) + + return allErrs +} + // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type func (r *Octavia) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { octavialog.Info("validate update", "name", r.Name) - // TODO(user): fill in your validation logic upon object update. + oldOctavia, ok := old.(*Octavia) + if !ok || oldOctavia == nil { + return nil, apierrors.NewInternalError(fmt.Errorf("unable to convert existing object")) + } + + var allErrs field.ErrorList + basePath := field.NewPath("spec") + + if err := r.Spec.ValidateUpdate(oldOctavia.Spec, basePath); err != nil { + allErrs = append(allErrs, err...) + } + + if len(allErrs) != 0 { + return nil, apierrors.NewInvalid( + schema.GroupKind{Group: "octavia.openstack.org", Kind: "Octavia"}, + r.Name, allErrs) + } + return nil, nil } +// ValidateUpdate - Exported function wrapping non-exported validate functions, +// this function can be called externally to validate an barbican spec. +func (r *OctaviaSpec) ValidateUpdate(old OctaviaSpec, basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("octaviaAPI").Child("override").Child("service"), + r.OctaviaAPI.Override.Service)...) + + return allErrs +} + +func (r *OctaviaSpecCore) ValidateUpdate(old OctaviaSpecCore, basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("octaviaAPI").Child("override").Child("service"), + r.OctaviaAPI.Override.Service)...) + + return allErrs +} + // ValidateDelete implements webhook.Validator so a webhook will be registered for the type func (r *Octavia) ValidateDelete() (admission.Warnings, error) { octavialog.Info("validate delete", "name", r.Name) diff --git a/go.mod b/go.mod index 7ee8fadc..f10477c6 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/onsi/gomega v1.33.0 github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240429104248-25176c735750 github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240429164853-7e1e3b111ee9 - github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240429052447-09a614506ca6 + github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240522141801-d6e03083e82a github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240429052447-09a614506ca6 github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240429121622-952f44520872 github.com/openstack-k8s-operators/octavia-operator/api v0.0.0-00010101000000-000000000000 diff --git a/go.sum b/go.sum index a99407ff..cf8bbc50 100644 --- a/go.sum +++ b/go.sum @@ -78,8 +78,8 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240429104248-2 github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240429104248-25176c735750/go.mod h1:QN2DJpfEc+mbvvfhoCuJ/UhQzvw12Mf+8nS0QX1HGIg= github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240429164853-7e1e3b111ee9 h1:aS7xUxC/uOXfw0T4ARTu0G1qb6eJ0WnB2JRv9donPOE= github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240429164853-7e1e3b111ee9/go.mod h1:Y/ge/l24phVaJb9S8mYRjtnDkohFkX/KEOUXLArcyvQ= -github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240429052447-09a614506ca6 h1:WLsG3Ko+phW5xZJjncypLWGASoLqKrt05qN9Zxsad6g= -github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240429052447-09a614506ca6/go.mod h1:lYhFzul37AR/6gAhTAA1KKWbOlzB3F/7014lejn883c= +github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240522141801-d6e03083e82a h1:kcASVA9sZg9DtggyJlN6JZE6pIenJgXivFK6ry7WUVM= +github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240522141801-d6e03083e82a/go.mod h1:lYhFzul37AR/6gAhTAA1KKWbOlzB3F/7014lejn883c= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240429052447-09a614506ca6 h1:/mhzQQ9FF70z00zZD7dpgOoNXvEu9q68oob3oAiJW08= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240429052447-09a614506ca6/go.mod h1:mrRNYeg8jb1zgGsufpN1/IB3sdbaST8btTBLwQ+taaA= github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240429121622-952f44520872 h1:ViWyS1AQ2mTn/sS0CA9GVw0+BuGpazpUSjSBUzdX3NE=