Skip to content

Commit

Permalink
Include --annotations flag in backup and restore create commands
Browse files Browse the repository at this point in the history
This commit implements a new --annotations flag in the backup and restore create commands.

This allows users to specify key-value pairs for annotations directly at the time of backup and restore creation, in the same way as the --labels flag.

Signed-off-by: Alvaro Romero <[email protected]>
  • Loading branch information
alromeros committed Oct 28, 2024
1 parent 8320df4 commit 5b4706f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 5 deletions.
5 changes: 4 additions & 1 deletion pkg/cmd/cli/backup/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ type CreateOptions struct {
IncludeNamespaceScopedResources flag.StringArray
ExcludeNamespaceScopedResources flag.StringArray
Labels flag.Map
Annotations flag.Map
Selector flag.LabelSelector
OrSelector flag.OrLabelSelector
IncludeClusterResources flag.OptionalBool
Expand All @@ -113,6 +114,7 @@ func NewCreateOptions() *CreateOptions {
return &CreateOptions{
IncludeNamespaces: flag.NewStringArray("*"),
Labels: flag.NewMap(),
Annotations: flag.NewMap(),
SnapshotVolumes: flag.NewOptionalBool(nil),
IncludeClusterResources: flag.NewOptionalBool(nil),
}
Expand All @@ -129,6 +131,7 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) {
flags.Var(&o.IncludeNamespaceScopedResources, "include-namespace-scoped-resources", "Namespaced resources to include in the backup, formatted as resource.group, such as deployments.apps(use '*' for all resources). Cannot work with include-resources, exclude-resources and include-cluster-resources.")
flags.Var(&o.ExcludeNamespaceScopedResources, "exclude-namespace-scoped-resources", "Namespaced resources to exclude from the backup, formatted as resource.group, such as deployments.apps(use '*' for all resources). Cannot work with include-resources, exclude-resources and include-cluster-resources.")
flags.Var(&o.Labels, "labels", "Labels to apply to the backup.")
flags.Var(&o.Annotations, "annotations", "Annotations to apply to the backup.")
flags.StringVar(&o.StorageLocation, "storage-location", "", "Location in which to store the backup.")
flags.StringSliceVar(&o.SnapshotLocations, "volume-snapshot-locations", o.SnapshotLocations, "List of locations (at most one per provider) where volume snapshots should be stored.")
flags.VarP(&o.Selector, "selector", "l", "Only back up resources matching this label selector.")
Expand Down Expand Up @@ -403,7 +406,7 @@ func (o *CreateOptions) BuildBackup(namespace string) (*velerov1api.Backup, erro
}
}

backup := backupBuilder.ObjectMeta(builder.WithLabelsMap(o.Labels.Data())).Result()
backup := backupBuilder.ObjectMeta(builder.WithLabelsMap(o.Labels.Data()), builder.WithAnnotationsMap(o.Annotations.Data())).Result()
return backup, nil
}

Expand Down
14 changes: 13 additions & 1 deletion pkg/cmd/cli/backup/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
func TestCreateOptions_BuildBackup(t *testing.T) {
o := NewCreateOptions()
o.Labels.Set("velero.io/test=true")
o.Annotations.Set("velero.io/annTest=true")
o.OrderedResources = "pods=p1,p2;persistentvolumeclaims=pvc1,pvc2"
orders, err := ParseOrderedResources(o.OrderedResources)
o.CSISnapshotTimeout = 20 * time.Minute
Expand Down Expand Up @@ -75,6 +76,9 @@ func TestCreateOptions_BuildBackup(t *testing.T) {
assert.Equal(t, map[string]string{
"velero.io/test": "true",
}, backup.GetLabels())
assert.Equal(t, map[string]string{
"velero.io/annTest": "true",
}, backup.GetAnnotations())
assert.Equal(t, map[string]string{
"pods": "p1,p2",
"persistentvolumeclaims": "pvc1,pvc2",
Expand Down Expand Up @@ -113,8 +117,9 @@ func TestCreateOptions_BuildBackupFromSchedule(t *testing.T) {
}, backup.GetAnnotations())
})

t.Run("command line labels take precedence over schedule labels", func(t *testing.T) {
t.Run("command line labels and annotations take precedence over scheduled ones", func(t *testing.T) {
o.Labels.Set("velero.io/test=yes,custom-label=true")
o.Annotations.Set("velero.io/test=yes,custom-annotation=true")
backup, err := o.BuildBackup(cmdtest.VeleroNameSpace)
assert.NoError(t, err)

Expand All @@ -124,6 +129,10 @@ func TestCreateOptions_BuildBackupFromSchedule(t *testing.T) {
velerov1api.ScheduleNameLabel: "test",
"custom-label": "true",
}, backup.GetLabels())
assert.Equal(t, map[string]string{
"velero.io/test": "yes",
"custom-annotation": "true",
}, backup.GetAnnotations())
})
}

Expand Down Expand Up @@ -171,6 +180,7 @@ func TestCreateCommand(t *testing.T) {
includeNamespaceScopedResources := "Endpoints,Event,PodTemplate"
excludeNamespaceScopedResources := "Secret,MultiClusterIngress"
labels := "c=foo"
annotations := "ann=foo"
storageLocation := "bsl-name-1"
snapshotLocations := "region=minio"
selector := "a=pod"
Expand Down Expand Up @@ -199,6 +209,7 @@ func TestCreateCommand(t *testing.T) {
flags.Parse([]string{"--include-namespace-scoped-resources", includeNamespaceScopedResources})
flags.Parse([]string{"--exclude-namespace-scoped-resources", excludeNamespaceScopedResources})
flags.Parse([]string{"--labels", labels})
flags.Parse([]string{"--annotations", annotations})
flags.Parse([]string{"--storage-location", storageLocation})
flags.Parse([]string{"--volume-snapshot-locations", snapshotLocations})
flags.Parse([]string{"--selector", selector})
Expand Down Expand Up @@ -248,6 +259,7 @@ func TestCreateCommand(t *testing.T) {
require.Equal(t, includeNamespaceScopedResources, o.IncludeNamespaceScopedResources.String())
require.Equal(t, excludeNamespaceScopedResources, o.ExcludeNamespaceScopedResources.String())
require.True(t, test.CompareSlice(strings.Split(labels, ","), strings.Split(o.Labels.String(), ",")))
require.True(t, test.CompareSlice(strings.Split(annotations, ","), strings.Split(o.Annotations.String(), ",")))
require.Equal(t, storageLocation, o.StorageLocation)
require.Equal(t, snapshotLocations, strings.Split(o.SnapshotLocations[0], ",")[0])
require.Equal(t, selector, o.Selector.String())
Expand Down
10 changes: 7 additions & 3 deletions pkg/cmd/cli/restore/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type CreateOptions struct {
RestoreVolumes flag.OptionalBool
PreserveNodePorts flag.OptionalBool
Labels flag.Map
Annotations flag.Map
IncludeNamespaces flag.StringArray
ExcludeNamespaces flag.StringArray
ExistingResourcePolicy string
Expand All @@ -107,6 +108,7 @@ type CreateOptions struct {
func NewCreateOptions() *CreateOptions {
return &CreateOptions{
Labels: flag.NewMap(),
Annotations: flag.NewMap(),
IncludeNamespaces: flag.NewStringArray("*"),
NamespaceMappings: flag.NewMap().WithEntryDelimiter(',').WithKeyValueDelimiter(':'),
RestoreVolumes: flag.NewOptionalBool(nil),
Expand All @@ -123,6 +125,7 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) {
flags.Var(&o.ExcludeNamespaces, "exclude-namespaces", "Namespaces to exclude from the restore.")
flags.Var(&o.NamespaceMappings, "namespace-mappings", "Namespace mappings from name in the backup to desired restored name in the form src1:dst1,src2:dst2,...")
flags.Var(&o.Labels, "labels", "Labels to apply to the restore.")
flags.Var(&o.Annotations, "annotations", "Annotations to apply to the restore.")
flags.Var(&o.IncludeResources, "include-resources", "Resources to include in the restore, formatted as resource.group, such as storageclasses.storage.k8s.io (use '*' for all resources).")
flags.Var(&o.ExcludeResources, "exclude-resources", "Resources to exclude from the restore, formatted as resource.group, such as storageclasses.storage.k8s.io.")
flags.StringVar(&o.ExistingResourcePolicy, "existing-resource-policy", "", "Restore Policy to be used during the restore workflow, can be - none or update")
Expand Down Expand Up @@ -309,9 +312,10 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {

restore := &api.Restore{
ObjectMeta: metav1.ObjectMeta{
Namespace: f.Namespace(),
Name: o.RestoreName,
Labels: o.Labels.Data(),
Namespace: f.Namespace(),
Name: o.RestoreName,
Labels: o.Labels.Data(),
Annotations: o.Annotations.Data(),
},
Spec: api.RestoreSpec{
BackupName: o.BackupName,
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/cli/restore/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func TestCreateCommand(t *testing.T) {
restoreVolumes := "true"
preserveNodePorts := "true"
labels := "c=foo"
annotations := "ann=foo"
includeNamespaces := "app1,app2"
excludeNamespaces := "pod1,pod2,pod3"
existingResourcePolicy := "none"
Expand All @@ -88,6 +89,7 @@ func TestCreateCommand(t *testing.T) {
flags.Parse([]string{"--restore-volumes", restoreVolumes})
flags.Parse([]string{"--preserve-nodeports", preserveNodePorts})
flags.Parse([]string{"--labels", labels})
flags.Parse([]string{"--annotations", annotations})
flags.Parse([]string{"--existing-resource-policy", existingResourcePolicy})
flags.Parse([]string{"--include-namespaces", includeNamespaces})
flags.Parse([]string{"--exclude-namespaces", excludeNamespaces})
Expand Down Expand Up @@ -124,6 +126,7 @@ func TestCreateCommand(t *testing.T) {
require.Equal(t, restoreVolumes, o.RestoreVolumes.String())
require.Equal(t, preserveNodePorts, o.PreserveNodePorts.String())
require.Equal(t, labels, o.Labels.String())
require.Equal(t, annotations, o.Annotations.String())
require.Equal(t, includeNamespaces, o.IncludeNamespaces.String())
require.Equal(t, excludeNamespaces, o.ExcludeNamespaces.String())
require.Equal(t, existingResourcePolicy, o.ExistingResourcePolicy)
Expand Down

0 comments on commit 5b4706f

Please sign in to comment.