add webhook for validation backupClass is immutable in BackupJob
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
This commit is contained in:
parent
f6641c1547
commit
2cca1bc8d8
3 changed files with 79 additions and 0 deletions
|
|
@ -52,6 +52,8 @@ type BackupJobSpec struct {
|
|||
// BackupClassName references a BackupClass that contains strategy and storage configuration.
|
||||
// The BackupClass will be resolved to determine the appropriate strategy and storage
|
||||
// based on the ApplicationRef.
|
||||
// This field is immutable once the BackupJob is created.
|
||||
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="backupClassName is immutable"
|
||||
BackupClassName string `json:"backupClassName"`
|
||||
}
|
||||
|
||||
|
|
|
|||
71
api/backups/v1alpha1/backupjob_webhook.go
Normal file
71
api/backups/v1alpha1/backupjob_webhook.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
)
|
||||
|
||||
// SetupWebhookWithManager registers the BackupJob webhook with the manager.
|
||||
func SetupBackupJobWebhookWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewWebhookManagedBy(mgr).
|
||||
For(&BackupJob{}).
|
||||
Complete()
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:path=/mutate-backups-cozystack-io-v1alpha1-backupjob,mutating=true,failurePolicy=fail,sideEffects=None,groups=backups.cozystack.io,resources=backupjobs,verbs=create;update,versions=v1alpha1,name=mbackupjob.kb.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Defaulter = &BackupJob{}
|
||||
|
||||
// Default implements webhook.Defaulter so a webhook will be registered for the type
|
||||
func (j *BackupJob) Default() {
|
||||
// No defaults needed for BackupJob currently
|
||||
}
|
||||
|
||||
// +kubebuilder:webhook:path=/validate-backups-cozystack-io-v1alpha1-backupjob,mutating=false,failurePolicy=fail,sideEffects=None,groups=backups.cozystack.io,resources=backupjobs,verbs=create;update,versions=v1alpha1,name=vbackupjob.kb.io,admissionReviewVersions=v1
|
||||
|
||||
var _ webhook.Validator = &BackupJob{}
|
||||
|
||||
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (j *BackupJob) ValidateCreate() (admission.Warnings, error) {
|
||||
logger := log.FromContext(context.Background())
|
||||
logger.Info("validating BackupJob creation", "name", j.Name, "namespace", j.Namespace)
|
||||
|
||||
// Validate that backupClassName is set
|
||||
if j.Spec.BackupClassName == "" {
|
||||
return nil, fmt.Errorf("backupClassName is required and cannot be empty")
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||
func (j *BackupJob) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
|
||||
logger := log.FromContext(context.Background())
|
||||
logger.Info("validating BackupJob update", "name", j.Name, "namespace", j.Namespace)
|
||||
|
||||
oldJob, ok := old.(*BackupJob)
|
||||
if !ok {
|
||||
return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a BackupJob but got a %T", old))
|
||||
}
|
||||
|
||||
// Enforce immutability of backupClassName
|
||||
if oldJob.Spec.BackupClassName != "" && oldJob.Spec.BackupClassName != j.Spec.BackupClassName {
|
||||
return nil, fmt.Errorf("backupClassName is immutable and cannot be changed from %q to %q", oldJob.Spec.BackupClassName, j.Spec.BackupClassName)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
|
||||
func (j *BackupJob) ValidateDelete() (admission.Warnings, error) {
|
||||
// No validation needed for deletion
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -168,6 +168,12 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Register BackupJob webhook for validation (immutability of backupClassName)
|
||||
if err = backupsv1alpha1.SetupBackupJobWebhookWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create webhook", "webhook", "BackupJob")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// +kubebuilder:scaffold:builder
|
||||
|
||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue