Skip to content

Commit

Permalink
Move verification strategy field to spec
Browse files Browse the repository at this point in the history
Signed-off-by: Md. Ishtiaq Islam <[email protected]>
  • Loading branch information
ishtiaqhimel committed Jul 3, 2024
1 parent 8e79be6 commit c189406
Show file tree
Hide file tree
Showing 11 changed files with 8,306 additions and 28,562 deletions.
1 change: 1 addition & 0 deletions apis/addons/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apis/config/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 12 additions & 7 deletions apis/core/v1alpha1/backupconfiguration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ type BackupConfigurationSpec struct {
// Sessions defines a list of session configuration that specifies when and how to take backup.
Sessions []Session `json:"sessions,omitempty"`

// VerificationStrategies specifies a list of backup verification configurations
// +optional
VerificationStrategies []VerificationStrategy `json:"verificationStrategies,omitempty"`

// Paused indicates that the BackupConfiguration has been paused from taking backup. Default value is 'false'.
// If you set `paused` field to `true`, KubeStash will suspend the respective backup triggering CronJob and
// skip processing any further events for this BackupConfiguration.
Expand Down Expand Up @@ -113,10 +117,6 @@ type SessionConfig struct {
// Scheduler specifies the configuration for backup triggering CronJob
Scheduler *SchedulerSpec `json:"scheduler,omitempty"`

// VerificationStrategies specifies a list of backup verification configurations
// +optional
VerificationStrategies []VerificationStrategy `json:"verificationStrategies,omitempty"`

// Hooks specifies the backup hooks that should be executed before and/or after the backup.
// +optional
Hooks *BackupHooks `json:"hooks,omitempty"`
Expand Down Expand Up @@ -276,6 +276,10 @@ type RepositoryInfo struct {
// +optional
Backend string `json:"backend,omitempty"`

// VerificationStrategy specifies the name of the verification strategy which will be used to verify the backed up data in this repository.
// +optional
VerificationStrategy string `json:"verificationStrategy,omitempty"`

// Directory specifies the path inside the backend where the backed up data will be stored.
Directory string `json:"directory,omitempty"`

Expand All @@ -297,9 +301,6 @@ type VerificationStrategy struct {
// Namespace specifies where the verification resources should be created.
Namespace string `json:"namespace,omitempty"`

// Repository specifies the name of the repository which data will be verified.
Repository string `json:"repository,omitempty"`

// Verifier refers to the BackupVerification CR that defines how to verify this particular data.
Verifier *kmapi.ObjectReference `json:"verifier,omitempty"`

Expand Down Expand Up @@ -452,6 +453,10 @@ type RepoStatus struct {
// Reason specifies the error messages found while ensuring the respective Repository
// +optional
Reason string `json:"reason,omitempty"`

// VerificationConfigured indicates whether the verification for this repository is configured or not
// +optional
VerificationConfigured bool `json:"verificationConfigured,omitempty"`
}

// SessionStatus specifies the status of a session specific fields.
Expand Down
80 changes: 46 additions & 34 deletions apis/core/v1alpha1/backupconfiguration_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
"sync"
)

// log is for logging in this package.
Expand Down Expand Up @@ -197,18 +196,17 @@ func (b *BackupConfiguration) ValidateCreate() (admission.Warnings, error) {
return nil, err
}

if err := b.validateVerificationStrategies(); err != nil {
return nil, err
}

if err := b.validateBackendsAgainstUsagePolicy(context.Background(), c); err != nil {
return nil, err
}

return nil, b.validateHookTemplatesAgainstUsagePolicy(context.Background(), c)
}

var (
rc client.Client
once sync.Once
)

func (b *BackupConfiguration) validateBackends() error {
if len(b.Spec.Backends) == 0 {
return fmt.Errorf("backend can not be empty")
Expand Down Expand Up @@ -260,10 +258,6 @@ func (b *BackupConfiguration) validateSessions(ctx context.Context, c client.Cli
return err
}

if err := b.validateVerificationStrategyNameUnique(session); err != nil {
return err
}

if err := b.validateSessionConfig(session); err != nil {
return err
}
Expand All @@ -275,10 +269,6 @@ func (b *BackupConfiguration) validateSessions(ctx context.Context, c client.Cli
if err := b.validateRepositories(ctx, c, session); err != nil {
return err
}

if err := b.validateVerificationStrategies(session); err != nil {
return err
}
}

if err := b.validateUniqueRepoDir(ctx, c); err != nil {
Expand Down Expand Up @@ -349,6 +339,11 @@ func (b *BackupConfiguration) validateRepositories(ctx context.Context, c client
return fmt.Errorf("directory is not provided for repository: %q. Please provide a directory", repo.Name)
}

if repo.VerificationStrategy != "" &&
!b.verificationStrategyMatched(repo.VerificationStrategy) {
return fmt.Errorf("verification strategy %q for repository %q doesn't match with any of the given strategy", repo.VerificationStrategy, repo.Name)
}

existingRepo, err := b.getRepository(ctx, c, repo.Name)
if err != nil {
if kerr.IsNotFound(err) {
Expand All @@ -369,6 +364,15 @@ func (b *BackupConfiguration) validateRepositories(ctx context.Context, c client
return nil
}

func (b *BackupConfiguration) verificationStrategyMatched(strategy string) bool {
for _, vs := range b.Spec.VerificationStrategies {
if vs.Name == strategy {
return true
}
}
return false
}

func (b *BackupConfiguration) validateUniqueRepoDir(ctx context.Context, c client.Client) error {
if err := b.validateRepoDirectories(); err != nil {
return err
Expand Down Expand Up @@ -434,16 +438,20 @@ func targetMatched(t1, t2 *kmapi.TypedObjectReference) bool {
t1.Name == t2.Name
}

func (b *BackupConfiguration) validateVerificationStrategies(session Session) error {
for _, vs := range session.VerificationStrategies {
func (b *BackupConfiguration) validateVerificationStrategies() error {
if len(b.Spec.VerificationStrategies) == 0 {
return nil
}

if err := b.validateVerificationStrategyNameUnique(); err != nil {
return err
}

for _, vs := range b.Spec.VerificationStrategies {
if vs.Namespace == "" {
return fmt.Errorf("namespace for verification strategy %q cannot be empty", vs.Name)
}

if vs.Repository == "" {
return fmt.Errorf("repository for verification strategy %q cannot be empty", vs.Name)
}

if vs.Verifier == nil {
return fmt.Errorf("verifier for verification strategy %q cannot be empty", vs.Name)
}
Expand All @@ -455,22 +463,11 @@ func (b *BackupConfiguration) validateVerificationStrategies(session Session) er
return nil
}

func (b *BackupConfiguration) validateRepositoryNameUnique(session Session) error {
repoMap := make(map[string]struct{})
for _, repo := range session.Repositories {
if _, ok := repoMap[repo.Name]; ok {
return fmt.Errorf("duplicate repository name found: %q. Please choose a different repository name", repo.Name)
}
repoMap[repo.Name] = struct{}{}
}
return nil
}

func (b *BackupConfiguration) validateVerificationStrategyNameUnique(session Session) error {
func (b *BackupConfiguration) validateVerificationStrategyNameUnique() error {
vsMap := make(map[string]struct{})
for _, vs := range session.VerificationStrategies {
for _, vs := range b.Spec.VerificationStrategies {
if vs.Name == "" {
return fmt.Errorf("verification strategy name for session %q cannot be empty", session.Name)
return fmt.Errorf("verification strategy name cannot be empty")
}

if _, ok := vsMap[vs.Name]; ok {
Expand All @@ -481,6 +478,17 @@ func (b *BackupConfiguration) validateVerificationStrategyNameUnique(session Ses
return nil
}

func (b *BackupConfiguration) validateRepositoryNameUnique(session Session) error {
repoMap := make(map[string]struct{})
for _, repo := range session.Repositories {
if _, ok := repoMap[repo.Name]; ok {
return fmt.Errorf("duplicate repository name found: %q. Please choose a different repository name", repo.Name)
}
repoMap[repo.Name] = struct{}{}
}
return nil
}

func (b *BackupConfiguration) backendMatched(repo RepositoryInfo) bool {
for _, b := range b.Spec.Backends {
if b.Name == repo.Backend {
Expand Down Expand Up @@ -658,6 +666,10 @@ func (b *BackupConfiguration) ValidateUpdate(old runtime.Object) (admission.Warn
return nil, err
}

if err := b.validateVerificationStrategies(); err != nil {
return nil, err
}

if err := b.validateBackendsAgainstUsagePolicy(context.Background(), c); err != nil {
return nil, err
}
Expand Down
24 changes: 0 additions & 24 deletions apis/core/v1alpha1/backupsession_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,6 @@ type BackupSessionStatus struct {
// +optional
Hooks HookStatus `json:"hooks,omitempty"`

// Verifications specifies the backup verification status
// +optional
Verifications []VerificationStatus `json:"verifications,omitempty"`

// RetentionPolices specifies whether the retention policies were properly applied on the repositories or not
// +optional
RetentionPolicies []RetentionPolicyApplyStatus `json:"retentionPolicy,omitempty"`
Expand Down Expand Up @@ -143,26 +139,6 @@ type SnapshotStatus struct {
Repository string `json:"repository,omitempty"`
}

// VerificationStatus specifies the status of a backup verification
type VerificationStatus struct {
// Name indicates the name of the respective verification strategy
Name string `json:"name,omitempty"`

// Phase represents the state of the verification process
// +optional
Phase BackupVerificationPhase `json:"phase,omitempty"`
}

// BackupVerificationPhase represents the state of the backup verification process
// +kubebuilder:validation:Enum=Verified;NotVerified;VerificationFailed
type BackupVerificationPhase string

const (
Verified BackupVerificationPhase = "Verified"
NotVerified BackupVerificationPhase = "NotVerified"
VerificationFailed BackupVerificationPhase = "VerificationFailed"
)

// RetentionPolicyApplyStatus represents the state of the applying retention policy
type RetentionPolicyApplyStatus struct {
// Ref points to the RetentionPolicy CR that is being used to cleanup the old Snapshots for this session.
Expand Down
35 changes: 8 additions & 27 deletions apis/core/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apis/storage/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apis/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c189406

Please sign in to comment.