mirror of
https://github.com/mariadb-operator/mariadb-operator.git
synced 2025-08-15 21:02:38 +00:00
Added tests for backup types
This commit is contained in:
@ -2,6 +2,7 @@ package v1alpha1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
@ -12,23 +13,23 @@ import (
|
||||
|
||||
// BackupStorage defines the storage for a Backup.
|
||||
type BackupStorage struct {
|
||||
// Volume is a Kubernetes volume specification.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
Volume *corev1.VolumeSource `json:"volume,omitempty"`
|
||||
// PersistentVolumeClaim is a Kubernetes PVC specification.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
PersistentVolumeClaim *corev1.PersistentVolumeClaimSpec `json:"persistentVolumeClaim,omitempty"`
|
||||
// S3 defines the configuration to store backups in a S3 compatible storage.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
S3 *S3 `json:"s3,omitempty"`
|
||||
// PersistentVolumeClaim is a Kubernetes PVC specification.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
PersistentVolumeClaim *corev1.PersistentVolumeClaimSpec `json:"persistentVolumeClaim,omitempty"`
|
||||
// Volume is a Kubernetes volume specification.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
Volume *corev1.VolumeSource `json:"volume,omitempty"`
|
||||
}
|
||||
|
||||
func (s *BackupStorage) Validate() error {
|
||||
func (b *BackupStorage) Validate() error {
|
||||
storageTypes := 0
|
||||
fields := reflect.ValueOf(s).Elem()
|
||||
fields := reflect.ValueOf(b).Elem()
|
||||
for i := 0; i < fields.NumField(); i++ {
|
||||
field := fields.Field(i)
|
||||
if !field.IsNil() {
|
||||
@ -134,6 +135,27 @@ func (b *Backup) IsComplete() bool {
|
||||
return meta.IsStatusConditionTrue(b.Status.Conditions, ConditionTypeComplete)
|
||||
}
|
||||
|
||||
func (b *Backup) SetDefaults() {
|
||||
if b.Spec.MaxRetention == (metav1.Duration{}) {
|
||||
b.Spec.MaxRetention = metav1.Duration{Duration: 30 * 24 * time.Hour}
|
||||
}
|
||||
if b.Spec.BackoffLimit == 0 {
|
||||
b.Spec.BackoffLimit = 5
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Backup) Validate() error {
|
||||
if b.Spec.Schedule != nil {
|
||||
if err := b.Spec.Schedule.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid Schedule: %v", err)
|
||||
}
|
||||
}
|
||||
if err := b.Spec.Storage.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid Storage: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Backup) Volume() (*corev1.VolumeSource, error) {
|
||||
if b.Spec.Storage.S3 != nil {
|
||||
return &corev1.VolumeSource{
|
||||
@ -153,15 +175,6 @@ func (b *Backup) Volume() (*corev1.VolumeSource, error) {
|
||||
return nil, errors.New("unable to get volume from Backup")
|
||||
}
|
||||
|
||||
func (b *Backup) SetDefaults() {
|
||||
if b.Spec.MaxRetention == (metav1.Duration{}) {
|
||||
b.Spec.MaxRetention = metav1.Duration{Duration: 30 * 24 * time.Hour}
|
||||
}
|
||||
if b.Spec.BackoffLimit == 0 {
|
||||
b.Spec.BackoffLimit = 5
|
||||
}
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// BackupList contains a list of Backup
|
||||
|
@ -5,13 +5,14 @@ import (
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var _ = Describe("Backup types", func() {
|
||||
objMeta := metav1.ObjectMeta{
|
||||
Name: "backup-obj",
|
||||
Namespace: "backup-obj",
|
||||
Namespace: testNamespace,
|
||||
}
|
||||
Context("When creating a Backup object", func() {
|
||||
DescribeTable(
|
||||
@ -21,7 +22,7 @@ var _ = Describe("Backup types", func() {
|
||||
Expect(backup).To(BeEquivalentTo(expected))
|
||||
},
|
||||
Entry(
|
||||
"Emtpty",
|
||||
"Empty",
|
||||
&Backup{
|
||||
ObjectMeta: objMeta,
|
||||
},
|
||||
@ -51,5 +52,83 @@ var _ = Describe("Backup types", func() {
|
||||
},
|
||||
),
|
||||
)
|
||||
DescribeTable(
|
||||
"Should return a volume",
|
||||
func(backup *Backup, expectedVolume *corev1.VolumeSource, wantErr bool) {
|
||||
volume, err := backup.Volume()
|
||||
if wantErr {
|
||||
Expect(err).To(HaveOccurred())
|
||||
} else {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
Expect(volume).To(BeEquivalentTo(expectedVolume))
|
||||
},
|
||||
Entry(
|
||||
"No storage",
|
||||
&Backup{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: BackupSpec{
|
||||
Storage: BackupStorage{},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
true,
|
||||
),
|
||||
Entry(
|
||||
"S3",
|
||||
&Backup{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: BackupSpec{
|
||||
Storage: BackupStorage{
|
||||
S3: &S3{},
|
||||
},
|
||||
},
|
||||
},
|
||||
&corev1.VolumeSource{
|
||||
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||
},
|
||||
false,
|
||||
),
|
||||
Entry(
|
||||
"PVC",
|
||||
&Backup{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: BackupSpec{
|
||||
Storage: BackupStorage{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimSpec{},
|
||||
},
|
||||
},
|
||||
},
|
||||
&corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: objMeta.Name,
|
||||
},
|
||||
},
|
||||
false,
|
||||
),
|
||||
Entry(
|
||||
"Volume",
|
||||
&Backup{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: BackupSpec{
|
||||
Storage: BackupStorage{
|
||||
Volume: &corev1.VolumeSource{
|
||||
NFS: &corev1.NFSVolumeSource{
|
||||
Server: "test",
|
||||
Path: "test",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&corev1.VolumeSource{
|
||||
NFS: &corev1.NFSVolumeSource{
|
||||
Server: "test",
|
||||
Path: "test",
|
||||
},
|
||||
},
|
||||
false,
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -40,33 +40,12 @@ func (r *Backup) ValidateDelete() (admission.Warnings, error) {
|
||||
}
|
||||
|
||||
func (r *Backup) validate() (admission.Warnings, error) {
|
||||
if err := r.validateSchedule(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, r.validateStorage()
|
||||
}
|
||||
|
||||
func (r *Backup) validateSchedule() error {
|
||||
if r.Spec.Schedule == nil {
|
||||
return nil
|
||||
}
|
||||
if err := r.Spec.Schedule.Validate(); err != nil {
|
||||
return field.Invalid(
|
||||
field.NewPath("spec").Child("schedule"),
|
||||
r.Spec.Schedule,
|
||||
fmt.Sprintf("invalid schedule: %v", err),
|
||||
if err := r.Validate(); err != nil {
|
||||
return nil, field.Invalid(
|
||||
field.NewPath("spec"),
|
||||
r.Spec,
|
||||
fmt.Sprintf("invalid Backup: %v", err),
|
||||
)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Backup) validateStorage() error {
|
||||
if err := r.Spec.Storage.Validate(); err != nil {
|
||||
return field.Invalid(
|
||||
field.NewPath("spec").Child("storage"),
|
||||
r.Spec.Storage,
|
||||
fmt.Sprintf("invalid storage: %v", err),
|
||||
)
|
||||
}
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ var _ = Describe("Backup webhook", func() {
|
||||
}
|
||||
},
|
||||
Entry(
|
||||
"Invalid storage",
|
||||
"No storage",
|
||||
&Backup{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "backup-invalid-storage",
|
||||
@ -50,6 +50,73 @@ var _ = Describe("Backup webhook", func() {
|
||||
},
|
||||
true,
|
||||
),
|
||||
Entry(
|
||||
"Multiple storages",
|
||||
&Backup{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "backup-invalid-storage",
|
||||
Namespace: testNamespace,
|
||||
},
|
||||
Spec: BackupSpec{
|
||||
Storage: BackupStorage{
|
||||
S3: &S3{
|
||||
Bucket: "test",
|
||||
Endpoint: "test",
|
||||
},
|
||||
Volume: &corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: "TEST",
|
||||
},
|
||||
},
|
||||
},
|
||||
MariaDBRef: MariaDBRef{
|
||||
ObjectReference: corev1.ObjectReference{
|
||||
Name: "mariadb-webhook",
|
||||
},
|
||||
WaitForIt: true,
|
||||
},
|
||||
BackoffLimit: 10,
|
||||
Resources: &corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"cpu": resource.MustParse("100m"),
|
||||
},
|
||||
},
|
||||
RestartPolicy: corev1.RestartPolicyOnFailure,
|
||||
},
|
||||
},
|
||||
true,
|
||||
),
|
||||
Entry(
|
||||
"Single storage",
|
||||
&Backup{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "backup-invalid-storage",
|
||||
Namespace: testNamespace,
|
||||
},
|
||||
Spec: BackupSpec{
|
||||
Storage: BackupStorage{
|
||||
S3: &S3{
|
||||
Bucket: "test",
|
||||
Endpoint: "test",
|
||||
},
|
||||
},
|
||||
MariaDBRef: MariaDBRef{
|
||||
ObjectReference: corev1.ObjectReference{
|
||||
Name: "mariadb-webhook",
|
||||
},
|
||||
WaitForIt: true,
|
||||
},
|
||||
BackoffLimit: 10,
|
||||
Resources: &corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"cpu": resource.MustParse("100m"),
|
||||
},
|
||||
},
|
||||
RestartPolicy: corev1.RestartPolicyOnFailure,
|
||||
},
|
||||
},
|
||||
false,
|
||||
),
|
||||
Entry(
|
||||
"Invalid schedule",
|
||||
&Backup{
|
||||
@ -62,15 +129,9 @@ var _ = Describe("Backup webhook", func() {
|
||||
Cron: "foo",
|
||||
},
|
||||
Storage: BackupStorage{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimSpec{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"storage": resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
AccessModes: []corev1.PersistentVolumeAccessMode{
|
||||
corev1.ReadWriteOnce,
|
||||
},
|
||||
S3: &S3{
|
||||
Bucket: "test",
|
||||
Endpoint: "test",
|
||||
},
|
||||
},
|
||||
MariaDBRef: MariaDBRef{
|
||||
@ -102,15 +163,9 @@ var _ = Describe("Backup webhook", func() {
|
||||
Cron: "*/1 * * * *",
|
||||
},
|
||||
Storage: BackupStorage{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimSpec{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"storage": resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
AccessModes: []corev1.PersistentVolumeAccessMode{
|
||||
corev1.ReadWriteOnce,
|
||||
},
|
||||
S3: &S3{
|
||||
Bucket: "test",
|
||||
Endpoint: "test",
|
||||
},
|
||||
},
|
||||
MariaDBRef: MariaDBRef{
|
||||
@ -146,15 +201,9 @@ var _ = Describe("Backup webhook", func() {
|
||||
},
|
||||
Spec: BackupSpec{
|
||||
Storage: BackupStorage{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimSpec{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"storage": resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
AccessModes: []corev1.PersistentVolumeAccessMode{
|
||||
corev1.ReadWriteOnce,
|
||||
},
|
||||
S3: &S3{
|
||||
Bucket: "test",
|
||||
Endpoint: "test",
|
||||
},
|
||||
},
|
||||
MariaDBRef: MariaDBRef{
|
||||
@ -217,8 +266,7 @@ var _ = Describe("Backup webhook", func() {
|
||||
Entry(
|
||||
"Updating Storage",
|
||||
func(bmdb *Backup) {
|
||||
newStorageClass := "fast-storage"
|
||||
bmdb.Spec.Storage.PersistentVolumeClaim.StorageClassName = &newStorageClass
|
||||
bmdb.Spec.Storage.S3.Bucket = "another-bucket"
|
||||
},
|
||||
true,
|
||||
),
|
||||
|
@ -174,9 +174,9 @@ func (in *BackupStatus) DeepCopy() *BackupStatus {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *BackupStorage) DeepCopyInto(out *BackupStorage) {
|
||||
*out = *in
|
||||
if in.Volume != nil {
|
||||
in, out := &in.Volume, &out.Volume
|
||||
*out = new(v1.VolumeSource)
|
||||
if in.S3 != nil {
|
||||
in, out := &in.S3, &out.S3
|
||||
*out = new(S3)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.PersistentVolumeClaim != nil {
|
||||
@ -184,9 +184,9 @@ func (in *BackupStorage) DeepCopyInto(out *BackupStorage) {
|
||||
*out = new(v1.PersistentVolumeClaimSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.S3 != nil {
|
||||
in, out := &in.S3, &out.S3
|
||||
*out = new(S3)
|
||||
if in.Volume != nil {
|
||||
in, out := &in.Volume, &out.Volume
|
||||
*out = new(v1.VolumeSource)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ metadata:
|
||||
categories: Database
|
||||
certified: "true"
|
||||
containerImage: mariadb/mariadb-operator-enterprise@sha256:a7bc99c11043b38795b1da6dcb0ecb04a92e6d5db66dd7c058f9c8e772b2ef06
|
||||
createdAt: "2023-12-25T18:42:20Z"
|
||||
createdAt: "2023-12-25T21:10:03Z"
|
||||
operators.openshift.io/valid-subscription: '["MariaDB Enterprise Server License"]'
|
||||
operators.operatorframework.io/builder: operator-sdk-v1.32.0
|
||||
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
|
||||
|
@ -44,7 +44,7 @@ func (r *BackupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
if err := r.setSpecDefaults(ctx, &backup); err != nil {
|
||||
if err := r.setDefaults(ctx, &backup); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error defaulting Backup: %v", err)
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ func (r *BackupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *BackupReconciler) setSpecDefaults(ctx context.Context, backup *mariadbv1alpha1.Backup) error {
|
||||
func (r *BackupReconciler) setDefaults(ctx context.Context, backup *mariadbv1alpha1.Backup) error {
|
||||
return r.patch(ctx, backup, func(b *mariadbv1alpha1.Backup) {
|
||||
backup.SetDefaults()
|
||||
})
|
||||
|
Reference in New Issue
Block a user