Added PhysicalBackup webhook

This commit is contained in:
mmontes11
2025-05-02 22:22:21 +02:00
committed by Martin Montes
parent 483959f2fd
commit 080a8c1fe3
6 changed files with 149 additions and 1 deletions

View File

@ -134,4 +134,7 @@ resources:
kind: PhysicalBackup
path: github.com/mariadb-operator/mariadb-operator/api/v1alpha1
version: v1alpha1
webhooks:
validation: true
webhookVersion: v1
version: "3"

View File

@ -79,8 +79,12 @@ var webhookCmd = &cobra.Command{
setupLog.Error(err, "Unable to create webhook", "webhook", "Backup")
os.Exit(1)
}
if err = webhookv1alpha1.SetupPhysicalBackupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "Unable to create webhook", "webhook", "PhysicalBackup")
os.Exit(1)
}
if err = webhookv1alpha1.SetupRestoreWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "Unable to create webhook", "webhook", "restore")
setupLog.Error(err, "Unable to create webhook", "webhook", "Restore")
os.Exit(1)
}
if err = webhookv1alpha1.SetupUserWebhookWithManager(mgr); err != nil {

View File

@ -73,6 +73,26 @@ webhooks:
resources:
- backups
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: {{ $fullName }}-webhook
namespace: {{ .Release.Namespace }}
path: /validate-k8s-mariadb-com-v1alpha1-physicalbackup
failurePolicy: Fail
name: vbackup-v1alpha1.kb.io
rules:
- apiGroups:
- k8s.mariadb.com
apiVersions:
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- physicalbackups
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:

View File

@ -0,0 +1,64 @@
package v1alpha1
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
k8sv1alpha1 "github.com/mariadb-operator/mariadb-operator/api/v1alpha1"
)
// nolint:unused
// log is for logging in this package.
var physicalbackuplog = logf.Log.WithName("physicalbackup-resource")
// SetupPhysicalBackupWebhookWithManager registers the webhook for PhysicalBackup in the manager.
func SetupPhysicalBackupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).For(&k8sv1alpha1.PhysicalBackup{}).
WithValidator(&PhysicalBackupCustomValidator{}).
Complete()
}
// PhysicalBackupCustomValidator struct is responsible for validating the PhysicalBackup resource
// when it is created, updated, or deleted.
type PhysicalBackupCustomValidator struct{}
var _ webhook.CustomValidator = &PhysicalBackupCustomValidator{}
// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type PhysicalBackup.
func (v *PhysicalBackupCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
physicalbackup, ok := obj.(*k8sv1alpha1.PhysicalBackup)
if !ok {
return nil, fmt.Errorf("expected a PhysicalBackup object but got %T", obj)
}
physicalbackuplog.Info("Validation for PhysicalBackup upon creation", "name", physicalbackup.GetName())
return nil, nil
}
// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type PhysicalBackup.
func (v *PhysicalBackupCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
physicalbackup, ok := newObj.(*k8sv1alpha1.PhysicalBackup)
if !ok {
return nil, fmt.Errorf("expected a PhysicalBackup object for the newObj but got %T", newObj)
}
physicalbackuplog.Info("Validation for PhysicalBackup upon update", "name", physicalbackup.GetName())
return nil, nil
}
// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type PhysicalBackup.
func (v *PhysicalBackupCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
physicalbackup, ok := obj.(*k8sv1alpha1.PhysicalBackup)
if !ok {
return nil, fmt.Errorf("expected a PhysicalBackup object but got %T", obj)
}
physicalbackuplog.Info("Validation for PhysicalBackup upon deletion", "name", physicalbackup.GetName())
return nil, nil
}

View File

@ -0,0 +1,54 @@
package v1alpha1
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
k8sv1alpha1 "github.com/mariadb-operator/mariadb-operator/api/v1alpha1"
)
var _ = Describe("PhysicalBackup Webhook", func() {
var (
obj *k8sv1alpha1.PhysicalBackup
oldObj *k8sv1alpha1.PhysicalBackup
validator PhysicalBackupCustomValidator
)
BeforeEach(func() {
obj = &k8sv1alpha1.PhysicalBackup{}
oldObj = &k8sv1alpha1.PhysicalBackup{}
validator = PhysicalBackupCustomValidator{}
Expect(validator).NotTo(BeNil(), "Expected validator to be initialized")
Expect(oldObj).NotTo(BeNil(), "Expected oldObj to be initialized")
Expect(obj).NotTo(BeNil(), "Expected obj to be initialized")
// TODO (user): Add any setup logic common to all tests
})
AfterEach(func() {
// TODO (user): Add any teardown logic common to all tests
})
Context("When creating or updating PhysicalBackup under Validating Webhook", func() {
// TODO (user): Add logic for validating webhooks
// Example:
// It("Should deny creation if a required field is missing", func() {
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = ""
// Expect(validator.ValidateCreate(ctx, obj)).Error().To(HaveOccurred())
// })
//
// It("Should admit creation if all required fields are present", func() {
// By("simulating an invalid creation scenario")
// obj.SomeRequiredField = "valid_value"
// Expect(validator.ValidateCreate(ctx, obj)).To(BeNil())
// })
//
// It("Should validate updates correctly", func() {
// By("simulating a valid update scenario")
// oldObj.SomeRequiredField = "updated_value"
// obj.SomeRequiredField = "updated_value"
// Expect(validator.ValidateUpdate(ctx, oldObj, obj)).To(BeNil())
// })
})
})

View File

@ -112,6 +112,9 @@ var _ = BeforeSuite(func() {
err = SetupBackupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupPhysicalBackupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupRestoreWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())