Skip to content

Commit

Permalink
add backup annotations for air gap specific embedded cluster infra (#…
Browse files Browse the repository at this point in the history
…4601)

* use orLabelSelectors for backups

* handle OrLabelSelectors

* backup registry namespace

* fix unit test

* use release=docker-registry as that label is shared by the PVC

* refactor to use function instead of duplicating code

* preserve nonzero check

* return to app label
  • Loading branch information
laverya authored May 8, 2024
1 parent 0996039 commit de315f2
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 42 deletions.
84 changes: 59 additions & 25 deletions pkg/kotsadmsnapshot/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre
IncludedNamespaces: prepareIncludedNamespaces(includedNamespaces, util.IsEmbeddedCluster()),
ExcludedNamespaces: excludedNamespaces,
IncludeClusterResources: &includeClusterResources,
LabelSelector: instanceBackupLabelSelector(util.IsEmbeddedCluster()),
OrLabelSelectors: instanceBackupLabelSelectors(util.IsEmbeddedCluster()),
OrderedResources: backupOrderedResources,
Hooks: backupHooks,
},
Expand Down Expand Up @@ -985,6 +985,7 @@ func prepareIncludedNamespaces(namespaces []string, isEC bool) []string {
uniqueNamespaces["embedded-cluster"] = true
uniqueNamespaces["kube-system"] = true
uniqueNamespaces["openebs"] = true
uniqueNamespaces["registry"] = true
}

includedNamespaces := make([]string, len(uniqueNamespaces))
Expand All @@ -1003,17 +1004,18 @@ func excludeShutdownPodsFromBackup(ctx context.Context, clientset kubernetes.Int
}

labelSets := []string{}
if veleroBackup.Spec.LabelSelector.MatchLabels != nil && len(veleroBackup.Spec.LabelSelector.MatchLabels) != 0 {
labelSets = []string{labels.SelectorFromSet(veleroBackup.Spec.LabelSelector.MatchLabels).String()}
} else {
for _, expr := range veleroBackup.Spec.LabelSelector.MatchExpressions {
if expr.Operator != metav1.LabelSelectorOpIn {
return fmt.Errorf("unsupported operator %s in label selector %q", expr.Operator, veleroBackup.Spec.LabelSelector.String())
}
for _, value := range expr.Values {
labelSets = append(labelSets, fmt.Sprintf("%s=%s", expr.Key, value))
}
staticSet, err := getLabelSetsForLabelSelector(veleroBackup.Spec.LabelSelector)
if err != nil {
return errors.Wrap(err, "failed to get label sets for label selector")
}
labelSets = append(labelSets, staticSet...)

for _, sel := range veleroBackup.Spec.OrLabelSelectors {
orLabelSet, err := getLabelSetsForLabelSelector(sel)
if err != nil {
return errors.Wrap(err, "failed to get label sets for or label selector")
}
labelSets = append(labelSets, orLabelSet...)
}

for _, labelSet := range labelSets {
Expand Down Expand Up @@ -1065,27 +1067,59 @@ func excludeShutdownPodsFromBackupInNamespace(ctx context.Context, clientset kub
return nil
}

func instanceBackupLabelSelector(isEmbeddedCluster bool) *metav1.LabelSelector {
func instanceBackupLabelSelectors(isEmbeddedCluster bool) []*metav1.LabelSelector {
if isEmbeddedCluster { // only DR on embedded-cluster
return &metav1.LabelSelector{
MatchLabels: map[string]string{},
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "replicated.com/disaster-recovery",
Operator: metav1.LabelSelectorOpIn,
Values: []string{
"infra",
"app",
"ec-install",
return []*metav1.LabelSelector{
{
MatchLabels: map[string]string{},
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "replicated.com/disaster-recovery",
Operator: metav1.LabelSelectorOpIn,
Values: []string{
"infra",
"app",
"ec-install",
},
},
},
},
{
// we cannot add new labels to the docker-registry chart as of May 7th 2024
// so we need to add a label selector for the docker-registry app
// https://github.com/twuni/docker-registry.helm/blob/main/templates/deployment.yaml
MatchLabels: map[string]string{
"app": "docker-registry",
},
},
}
}

return &metav1.LabelSelector{
MatchLabels: map[string]string{
kotsadmtypes.BackupLabel: kotsadmtypes.BackupLabelValue,
return []*metav1.LabelSelector{
{
MatchLabels: map[string]string{
kotsadmtypes.BackupLabel: kotsadmtypes.BackupLabelValue,
},
},
}
}

func getLabelSetsForLabelSelector(labelSelector *metav1.LabelSelector) ([]string, error) {
if labelSelector == nil {
return nil, nil
}

labelSets := []string{}
if labelSelector.MatchLabels != nil && len(labelSelector.MatchLabels) > 0 {
labelSets = append(labelSets, labels.SelectorFromSet(labelSelector.MatchLabels).String())
}
for _, expr := range labelSelector.MatchExpressions {
if expr.Operator != metav1.LabelSelectorOpIn {
return nil, fmt.Errorf("unsupported operator %s in label selector %q", expr.Operator, labelSelector.String())
}
for _, value := range expr.Values {
labelSets = append(labelSets, fmt.Sprintf("%s=%s", expr.Key, value))
}
}
return labelSets, nil
}
45 changes: 28 additions & 17 deletions pkg/kotsadmsnapshot/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func TestPrepareIncludedNamespaces(t *testing.T) {
{
name: "embedded-cluster install",
namespaces: []string{"test", "abcapp"},
want: []string{"test", "abcapp", "embedded-cluster", "kube-system", "openebs"},
want: []string{"test", "abcapp", "embedded-cluster", "kube-system", "openebs", "registry"},
isEC: true,
},
}
Expand Down Expand Up @@ -634,43 +634,54 @@ func Test_excludeShutdownPodsFromBackup_check(t *testing.T) {
}
}

func Test_instanceBackupLabelSelector(t *testing.T) {
func Test_instanceBackupLabelSelectors(t *testing.T) {
tests := []struct {
name string
isEmbeddedCluster bool
want *metav1.LabelSelector
want []*metav1.LabelSelector
}{
{
name: "not embedded cluster",
isEmbeddedCluster: false,
want: &metav1.LabelSelector{
MatchLabels: map[string]string{
"kots.io/backup": "velero",
want: []*metav1.LabelSelector{
{
MatchLabels: map[string]string{
"kots.io/backup": "velero",
},
},
},
},
{
name: "embedded cluster",
isEmbeddedCluster: true,
want: &metav1.LabelSelector{
MatchLabels: map[string]string{},
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "replicated.com/disaster-recovery",
Operator: metav1.LabelSelectorOpIn,
Values: []string{
"infra",
"app",
"ec-install",
want: []*metav1.LabelSelector{
{
MatchLabels: map[string]string{},
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "replicated.com/disaster-recovery",
Operator: metav1.LabelSelectorOpIn,
Values: []string{
"infra",
"app",
"ec-install",
},
},
},
},
{
MatchLabels: map[string]string{
"app": "docker-registry",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, instanceBackupLabelSelector(tt.isEmbeddedCluster), "instanceBackupLabelSelector(%v)", tt.isEmbeddedCluster)
req := require.New(t)
got := instanceBackupLabelSelectors(tt.isEmbeddedCluster)
req.ElementsMatch(tt.want, got)
})
}
}

0 comments on commit de315f2

Please sign in to comment.