Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/v1alpha1/velero_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ type VeleroSpec struct {
// add annotations to pods deployed by operator
// +optional
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
// RestoreResourceVersionPriority represents a configmap that will be created if defined for use in conjunction with `EnableAPIGroupVersions` feature flag
// Defining this field automatically add EnableAPIGroupVersions to the velero server feature flag
// +optional
RestoreResourcesVersionPriority string `json:"restoreResourcesVersionPriority,omitempty"`
}

// VeleroStatus defines the observed state of Velero
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/oadp.openshift.io_veleroes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ spec:
type: string
type: object
type: array
restoreResourcesVersionPriority:
description: RestoreResourceVersionPriority represents a configmap
that will be created if defined for use in conjunction with `EnableAPIGroupVersions`
feature flag Defining this field automatically add EnableAPIGroupVersions
to the velero server feature flag
type: string
unsupportedOverrides:
additionalProperties:
type: string
Expand Down
52 changes: 52 additions & 0 deletions controllers/restore_resource_version_priority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package controllers

import (
"fmt"

oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

const (
enableApiGroupVersionsFeatureFlag = "EnableAPIGroupVersions"
enableApiGroupVersionsConfigMapName = "enableapigroupversions"
restoreResourcesVersionPriorityDataKey = "restoreResourcesVersionPriority"
)
// If RestoreResourcesVersionPriority is defined, configmap is created or updated and feature flag for EnableAPIGroupVersions is added to velero
func (r *VeleroReconciler) ReconcileRestoreResourcesVersionPriority(velero *oadpv1alpha1.Velero) (bool, error) {
if len(velero.Spec.RestoreResourcesVersionPriority) == 0 {
return true, nil
}
// if the RestoreResourcesVersionPriority is specified then ensure feature flag is enabled for enableApiGroupVersions
// duplicate feature flag checks are done in ReconcileVeleroDeployment
velero.Spec.VeleroFeatureFlags = append(velero.Spec.VeleroFeatureFlags, enableApiGroupVersionsFeatureFlag)
configMap := corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: enableApiGroupVersionsConfigMapName,
Namespace: velero.Namespace,
},
}
// Create ConfigMap
op, err := controllerutil.CreateOrUpdate(r.Context, r.Client, &configMap, func() error {
if err := controllerutil.SetControllerReference(velero, &configMap, r.Scheme); err != nil {
return err
}
configMap.Data = make(map[string]string, 1)
Comment thread
kaovilai marked this conversation as resolved.
configMap.Data[restoreResourcesVersionPriorityDataKey] = velero.Spec.RestoreResourcesVersionPriority
return nil
})
if err != nil {
return false, err
}
if op == controllerutil.OperationResultCreated || op == controllerutil.OperationResultUpdated {
// Trigger event to indicate ConfigMap was created or updated
r.EventRecorder.Event(&configMap,
corev1.EventTypeNormal,
"RestoreResourcesVersionPriorityReconciled",
fmt.Sprintf("performed %s on RestoreResourcesVersionPriority %s/%s", op, configMap.Namespace, configMap.Name),
)
}
return true, nil
}
30 changes: 20 additions & 10 deletions controllers/velero.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,19 +355,13 @@ func (r *VeleroReconciler) buildVeleroDeployment(veleroDeployment *appsv1.Deploy
for _, plugin := range velero.Spec.DefaultVeleroPlugins {
if plugin == oadpv1alpha1.DefaultPluginCSI {
// CSI plugin is added so ensure that CSI feature flags is set
foundCSIFeatureFlag := false
for _, featureFlag := range velero.Spec.VeleroFeatureFlags {
if featureFlag == enableCSIFeatureFlag {
foundCSIFeatureFlag = true
break
}
}
if !foundCSIFeatureFlag { // Not Found so append to feature flag
velero.Spec.VeleroFeatureFlags = append(velero.Spec.VeleroFeatureFlags, enableCSIFeatureFlag)
}
velero.Spec.VeleroFeatureFlags = append(velero.Spec.VeleroFeatureFlags, enableCSIFeatureFlag)
Comment thread
dymurray marked this conversation as resolved.
break
}
}
r.ReconcileRestoreResourcesVersionPriority(velero)

velero.Spec.VeleroFeatureFlags = removeDuplicateValues(velero.Spec.VeleroFeatureFlags)
deploymentName := veleroDeployment.Name //saves desired deployment name before install.Deployment overwrites them.
ownerRefs := veleroDeployment.OwnerReferences // saves desired owner refs
*veleroDeployment = *install.Deployment(veleroDeployment.Namespace,
Expand All @@ -386,6 +380,22 @@ func (r *VeleroReconciler) buildVeleroDeployment(veleroDeployment *appsv1.Deploy
return r.customizeVeleroDeployment(velero, veleroDeployment)
}

// remove duplicate entry in string slice
func removeDuplicateValues(slice []string) []string {
if slice == nil {
return nil
}
keys := make(map[string]bool)
list := []string{}
for _, entry := range slice {
if _, found := keys[entry]; !found { //add entry to list if not found in keys already
keys[entry] = true
list = append(list, entry)
}
}
return list // return the result through the passed in argument
}

func (r *VeleroReconciler) customizeVeleroDeployment(velero *oadpv1alpha1.Velero, veleroDeployment *appsv1.Deployment) error {
veleroDeployment.Labels = r.getAppLabels(velero)
veleroDeployment.Spec.Selector = veleroLabelSelector
Expand Down
43 changes: 43 additions & 0 deletions controllers/velero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -826,3 +826,46 @@ func TestVeleroReconciler_getVeleroImage(t *testing.T) {
})
}
}
func Test_removeDuplicateValues(t *testing.T) {
type args struct {
slice []string
}
tests := []struct {
name string
args args
want []string
}{
{
name: "nill slice",
args: args{slice: nil},
want: nil,
},
{
name: "empty slice",
args: args{slice: []string{}},
want: []string{},
},
{
name: "one item in slice",
args: args{slice: []string{"yo"}},
want: []string{"yo"},
},
{
name: "duplicate item in slice",
args: args{slice: []string{"ice", "ice", "baby"}},
want: []string{"ice", "baby"},
},
{
name: "maintain order of first appearance in slice",
args: args{slice: []string{"ice", "ice", "baby", "ice"}},
want: []string{"ice", "baby"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := removeDuplicateValues(tt.args.slice); !reflect.DeepEqual(got, tt.want) {
t.Errorf("removeDuplicateValues() = %v, want %v", got, tt.want)
}
})
}
}
Loading