mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-13 03:24:39 +00:00
Support overriding Schedule annotations via template.metadata.annotations (#10045)
Run the E2E test on kind / setup-test-matrix (push) Successful in 4s
e2e-test-kind.yaml / extract (push) Failing after 13s
Run the E2E test on kind / get-go-version (push) Failing after 14s
Run the E2E test on kind / build (push) Skipped
Run the E2E test on kind / run-e2e-test (push) Skipped
push.yml / extract (push) Successful in 14s
Main CI / get-go-version (push) Successful in 16s
Main CI / Build (push) Failing after 2m46s
Run the E2E test on kind / setup-test-matrix (push) Successful in 4s
e2e-test-kind.yaml / extract (push) Failing after 13s
Run the E2E test on kind / get-go-version (push) Failing after 14s
Run the E2E test on kind / build (push) Skipped
Run the E2E test on kind / run-e2e-test (push) Skipped
push.yml / extract (push) Successful in 14s
Main CI / get-go-version (push) Successful in 16s
Main CI / Build (push) Failing after 2m46s
* Support overriding Schedule annotations via template.metadata.annotations Adds an Annotations field to BackupSpec.Metadata, mirroring the existing Labels override. When Schedule.Spec.Template.Metadata.Annotations is set, it is used for the resulting Backup's annotations instead of copying Schedule.Annotations directly, allowing users to opt out of unwanted annotations (e.g. ArgoCD tracking annotations) being propagated from Schedule to Backup. Fixes #5836 Signed-off-by: Lubron Zhan <lubronzhan@gmail.com> * Rename changelog fragment to match PR number 10045 Signed-off-by: Lubron Zhan <lubronzhan@gmail.com> --------- Signed-off-by: Lubron Zhan <lubronzhan@gmail.com> Co-authored-by: Daniel Jiang <daniel.jiang@broadcom.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Fix issue #5836, respect schedule.spec.template.metadata.annotations to override annotations copied from the Schedule to Backup objects, matching the existing behavior for labels
|
||||
@@ -393,6 +393,11 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
metadata:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
nullable: true
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
|
||||
@@ -434,6 +434,11 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
metadata:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
nullable: true
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -23,6 +23,9 @@ import (
|
||||
|
||||
type Metadata struct {
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
// +optional
|
||||
// +nullable
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// BackupSpec defines the specification for a Velero backup.
|
||||
|
||||
@@ -895,6 +895,13 @@ func (in *Metadata) DeepCopyInto(out *Metadata) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Metadata.
|
||||
|
||||
@@ -109,8 +109,23 @@ func (b *BackupBuilder) FromSchedule(schedule *velerov1api.Schedule) *BackupBuil
|
||||
b.object.Spec = schedule.Spec.Template
|
||||
b.ObjectMeta(WithLabelsMap(labels))
|
||||
|
||||
if schedule.Annotations != nil {
|
||||
b.ObjectMeta(WithAnnotationsMap(schedule.Annotations))
|
||||
var annotations map[string]string
|
||||
|
||||
// Check if there's explicit Annotations defined in the Schedule object template
|
||||
// and if present then copy it to the backup object.
|
||||
if schedule.Spec.Template.Metadata.Annotations != nil {
|
||||
logger := logging.DefaultLogger(logging.LogLevelFlag(logrus.InfoLevel).Parse(), logging.NewFormatFlag().Parse())
|
||||
annotations = schedule.Spec.Template.Metadata.Annotations
|
||||
logger.WithFields(logrus.Fields{
|
||||
"backup": fmt.Sprintf("%s/%s", b.object.GetNamespace(), b.object.GetName()),
|
||||
"annotations": schedule.Spec.Template.Metadata.Annotations,
|
||||
}).Info("Schedule.template.metadata.annotations set - using those annotations instead of schedule.annotations for backup object")
|
||||
} else {
|
||||
annotations = schedule.Annotations
|
||||
}
|
||||
|
||||
if annotations != nil {
|
||||
b.ObjectMeta(WithAnnotationsMap(annotations))
|
||||
}
|
||||
|
||||
if boolptr.IsSetToTrue(schedule.Spec.UseOwnerReferencesInBackup) {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
func TestBackupFromSchedule(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
schedule *velerov1api.Schedule
|
||||
expectedLabels map[string]string
|
||||
expectedAnnotations map[string]string
|
||||
}{
|
||||
{
|
||||
name: "no schedule labels/annotations and no template overrides",
|
||||
schedule: ForSchedule("velero", "test").
|
||||
Result(),
|
||||
expectedLabels: map[string]string{velerov1api.ScheduleNameLabel: "test"},
|
||||
expectedAnnotations: nil,
|
||||
},
|
||||
{
|
||||
name: "schedule labels/annotations are copied when no template override is set",
|
||||
schedule: ForSchedule("velero", "test").
|
||||
ObjectMeta(
|
||||
WithLabels("schedule-label", "schedule-value"),
|
||||
WithAnnotations("schedule-annotation", "schedule-value"),
|
||||
).
|
||||
Result(),
|
||||
expectedLabels: map[string]string{
|
||||
"schedule-label": "schedule-value",
|
||||
velerov1api.ScheduleNameLabel: "test",
|
||||
},
|
||||
expectedAnnotations: map[string]string{"schedule-annotation": "schedule-value"},
|
||||
},
|
||||
{
|
||||
name: "template.metadata.labels/annotations override schedule labels/annotations",
|
||||
schedule: ForSchedule("velero", "test").
|
||||
ObjectMeta(
|
||||
WithLabels("schedule-label", "schedule-value"),
|
||||
WithAnnotations("schedule-annotation", "schedule-value"),
|
||||
).
|
||||
Template(velerov1api.BackupSpec{
|
||||
Metadata: velerov1api.Metadata{
|
||||
Labels: map[string]string{"template-label": "template-value"},
|
||||
Annotations: map[string]string{"template-annotation": "template-value"},
|
||||
},
|
||||
}).
|
||||
Result(),
|
||||
expectedLabels: map[string]string{
|
||||
"template-label": "template-value",
|
||||
velerov1api.ScheduleNameLabel: "test",
|
||||
},
|
||||
expectedAnnotations: map[string]string{"template-annotation": "template-value"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
backup := ForBackup("velero", "test-backup").FromSchedule(test.schedule).Result()
|
||||
assert.Equal(t, test.expectedLabels, backup.GetLabels())
|
||||
assert.Equal(t, test.expectedAnnotations, backup.GetAnnotations())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -155,11 +155,13 @@ spec:
|
||||
uploaderConfig:
|
||||
# ParallelFilesUpload is the number of files parallel uploads to perform when using the uploader.
|
||||
parallelFilesUpload: 10
|
||||
# The labels you want on backup objects, created from this schedule (instead of copying the labels you have on schedule object itself).
|
||||
# When this field is set, the labels from the Schedule resource are not copied to the Backup resource.
|
||||
# The labels/annotations you want on backup objects, created from this schedule (instead of copying the labels/annotations you have on schedule object itself).
|
||||
# When this field is set, the labels/annotations from the Schedule resource are not copied to the Backup resource.
|
||||
metadata:
|
||||
labels:
|
||||
labelname: somelabelvalue
|
||||
annotations:
|
||||
annotationname: someannotationvalue
|
||||
# Actions to perform at different times during a backup. The only hook supported is
|
||||
# executing a command in a container in a pod using the pod exec API. Optional.
|
||||
hooks:
|
||||
|
||||
Reference in New Issue
Block a user