From 70f036c18c229fdbd5a394763b29e7a73d65fd4b Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Wed, 8 May 2024 15:56:07 +0200 Subject: [PATCH] Add webhook to validate service override endpoint type Can also be called from the openstack-operator webhook on the SwiftSpecCore, 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/swift_webhook.go | 100 ++++++++++++++++++++++++++++++----- go.mod | 2 + go.sum | 4 +- 5 files changed, 94 insertions(+), 18 deletions(-) diff --git a/api/go.mod b/api/go.mod index 34cdf4f2..46c39fef 100644 --- a/api/go.mod +++ b/api/go.mod @@ -78,3 +78,5 @@ require ( // mschuppert: map to latest commit from release-4.13 tag // must consistent within modules and service operators replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20240508083919-01ef8c1d28c5 diff --git a/api/go.sum b/api/go.sum index 0d5b0970..4a6556a6 100644 --- a/api/go.sum +++ b/api/go.sum @@ -70,8 +70,6 @@ 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/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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -92,6 +90,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stuggi/lib-common/modules/common v0.0.0-20240508083919-01ef8c1d28c5 h1:RwBWawOf7fLsojvTdCeCZ+O5k3VqOqoX5f7PRQfa9lY= +github.com/stuggi/lib-common/modules/common v0.0.0-20240508083919-01ef8c1d28c5/go.mod h1:lYhFzul37AR/6gAhTAA1KKWbOlzB3F/7014lejn883c= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/api/v1beta1/swift_webhook.go b/api/v1beta1/swift_webhook.go index 0c7db941..915e03e0 100644 --- a/api/v1beta1/swift_webhook.go +++ b/api/v1beta1/swift_webhook.go @@ -19,6 +19,7 @@ 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" @@ -114,10 +115,45 @@ var _ webhook.Validator = &Swift{} func (r *Swift) ValidateCreate() (admission.Warnings, error) { swiftlog.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: "swift.openstack.org", Kind: "Swift"}, + r.Name, allErrs) + } + return nil, nil } +// ValidateCreate - Exported function wrapping non-exported validate functions, +// this function can be called externally to validate an swift spec. +func (r *SwiftSpec) ValidateCreate(basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("swiftProxy").Child("override").Child("service"), + r.SwiftProxy.Override.Service)...) + + return allErrs +} + +func (r *SwiftSpecCore) ValidateCreate(basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("swiftProxy").Child("override").Child("service"), + r.SwiftProxy.Override.Service)...) + + return allErrs +} + // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type func (r *Swift) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { swiftlog.Info("validate update", "name", r.Name) @@ -127,24 +163,60 @@ func (r *Swift) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { return nil, apierrors.NewInternalError(fmt.Errorf("unable to convert existing object")) } - if *r.Spec.SwiftStorage.Replicas < *oldSwift.Spec.SwiftStorage.Replicas { - return nil, apierrors.NewForbidden( - schema.GroupResource{ - Group: GroupVersion.WithKind("Swift").Group, - Resource: GroupVersion.WithKind("Swift").Kind, - }, - r.GetName(), - field.Invalid( - field.NewPath("spec").Child("swiftStorage").Child("replicas"), - *r.Spec.SwiftStorage.Replicas, - "SwiftStorage does not support scale-in", - ), - ) + var allErrs field.ErrorList + basePath := field.NewPath("spec") + + if err := r.Spec.ValidateUpdate(oldSwift.Spec, basePath); err != nil { + allErrs = append(allErrs, err...) + } + + if len(allErrs) != 0 { + return nil, apierrors.NewInvalid( + schema.GroupKind{Group: "swift.openstack.org", Kind: "Swift"}, + r.Name, allErrs) } return nil, nil } +// ValidateUpdate - Exported function wrapping non-exported validate functions, +// this function can be called externally to validate an swift spec. +func (r *SwiftSpec) ValidateUpdate(old SwiftSpec, basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + if *r.SwiftStorage.Replicas < *old.SwiftStorage.Replicas { + allErrs = append(allErrs, field.Invalid( + basePath.Child("swiftStorage").Child("replicas"), + *r.SwiftStorage.Replicas, + "SwiftStorage does not support scale-in")) + } + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("barbicanAPI").Child("override").Child("service"), + r.SwiftProxy.Override.Service)...) + + return allErrs +} + +func (r *SwiftSpecCore) ValidateUpdate(old SwiftSpecCore, basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + if *r.SwiftStorage.Replicas < *old.SwiftStorage.Replicas { + allErrs = append(allErrs, field.Invalid( + basePath.Child("swiftStorage").Child("replicas"), + *r.SwiftStorage.Replicas, + "SwiftStorage does not support scale-in")) + } + + // validate the service override key is valid + allErrs = append(allErrs, service.ValidateRoutedOverrides( + basePath.Child("barbicanAPI").Child("override").Child("service"), + r.SwiftProxy.Override.Service)...) + + return allErrs +} + // ValidateDelete implements webhook.Validator so a webhook will be registered for the type func (r *Swift) ValidateDelete() (admission.Warnings, error) { swiftlog.Info("validate delete", "name", r.Name) diff --git a/go.mod b/go.mod index 89e4d71c..18a07720 100644 --- a/go.mod +++ b/go.mod @@ -120,3 +120,5 @@ replace github.com/openshift/api => github.com/openshift/api v0.0.0-202304141430 // custom RabbitmqClusterSpecCore for OpenStackControlplane (v2.6.0_patches_tag) replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20240313124519-961a0ee8bf7f //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20240508083919-01ef8c1d28c5 diff --git a/go.sum b/go.sum index 5cd0313e..7eabb95d 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,6 @@ github.com/openstack-k8s-operators/ironic-operator/api v0.3.1-0.20240429052915-7 github.com/openstack-k8s-operators/ironic-operator/api v0.3.1-0.20240429052915-792d53d4efc2/go.mod h1:Rhsm05ZhcCXT9g6jj1SKwQitX2hSbeIKZyc0Y5IbSFE= 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/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/lib-common/modules/storage v0.3.1-0.20240429052447-09a614506ca6 h1:NNSOEpTZCa9RL5sZiF4ZOlB+agBrL7q7FB9pC58d4S8= @@ -164,6 +162,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stuggi/lib-common/modules/common v0.0.0-20240508083919-01ef8c1d28c5 h1:RwBWawOf7fLsojvTdCeCZ+O5k3VqOqoX5f7PRQfa9lY= +github.com/stuggi/lib-common/modules/common v0.0.0-20240508083919-01ef8c1d28c5/go.mod h1:lYhFzul37AR/6gAhTAA1KKWbOlzB3F/7014lejn883c= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=