diff --git a/changelogs/unreleased/8487-Lyndon-Li b/changelogs/unreleased/8487-Lyndon-Li index 8ea6009cf1..cd67ee404d 100644 --- a/changelogs/unreleased/8487-Lyndon-Li +++ b/changelogs/unreleased/8487-Lyndon-Li @@ -1 +1 @@ -Fix issue #8433, add aks label to data mover pods \ No newline at end of file +Fix issue #8433, add third party labels to data mover pods when the same labels exist in node-agent pods \ No newline at end of file diff --git a/pkg/controller/data_download_controller.go b/pkg/controller/data_download_controller.go index a691063b01..190a4725e5 100644 --- a/pkg/controller/data_download_controller.go +++ b/pkg/controller/data_download_controller.go @@ -47,7 +47,9 @@ import ( "github.com/vmware-tanzu/velero/pkg/datapath" "github.com/vmware-tanzu/velero/pkg/exposer" "github.com/vmware-tanzu/velero/pkg/metrics" + "github.com/vmware-tanzu/velero/pkg/nodeagent" "github.com/vmware-tanzu/velero/pkg/uploader" + "github.com/vmware-tanzu/velero/pkg/util" "github.com/vmware-tanzu/velero/pkg/util/kube" ) @@ -178,6 +180,13 @@ func (r *DataDownloadReconciler) Reconcile(ctx context.Context, req ctrl.Request } hostingPodLabels := map[string]string{velerov1api.DataDownloadLabel: dd.Name} + for _, k := range util.ThirdPartyLabels { + if v, err := nodeagent.GetLabelValue(ctx, r.kubeClient, dd.Namespace, k); err != nil { + log.WithError(err).Warnf("Failed to check existence of label from node-agent, skip adding label %s", k) + } else if v != "" { + hostingPodLabels[k] = v + } + } // Expose() will trigger to create one pod whose volume is restored by a given volume snapshot, // but the pod maybe is not in the same node of the current controller, so we need to return it here. diff --git a/pkg/controller/data_upload_controller.go b/pkg/controller/data_upload_controller.go index b0d44be5ba..fdb2fb018e 100644 --- a/pkg/controller/data_upload_controller.go +++ b/pkg/controller/data_upload_controller.go @@ -50,6 +50,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/metrics" "github.com/vmware-tanzu/velero/pkg/nodeagent" "github.com/vmware-tanzu/velero/pkg/uploader" + "github.com/vmware-tanzu/velero/pkg/util" "github.com/vmware-tanzu/velero/pkg/util/kube" ) @@ -806,11 +807,20 @@ func (r *DataUploadReconciler) setupExposeParam(du *velerov2alpha1api.DataUpload accessMode = exposer.AccessModeBlock } + hostingPodLabels := map[string]string{velerov1api.DataUploadLabel: du.Name} + for _, k := range util.ThirdPartyLabels { + if v, err := nodeagent.GetLabelValue(context.Background(), r.kubeClient, du.Namespace, k); err != nil { + r.logger.WithError(err).Warnf("Failed to check existence of label from node-agent, skip adding label %s", k) + } else if v != "" { + hostingPodLabels[k] = v + } + } + return &exposer.CSISnapshotExposeParam{ SnapshotName: du.Spec.CSISnapshot.VolumeSnapshot, SourceNamespace: du.Spec.SourceNamespace, StorageClass: du.Spec.CSISnapshot.StorageClass, - HostingPodLabels: map[string]string{velerov1api.DataUploadLabel: du.Name}, + HostingPodLabels: hostingPodLabels, AccessMode: accessMode, OperationTimeout: du.Spec.OperationTimeout.Duration, ExposeTimeout: r.preparingTimeout, diff --git a/pkg/exposer/csi_snapshot.go b/pkg/exposer/csi_snapshot.go index 0e2d0b4db8..bb421a794a 100644 --- a/pkg/exposer/csi_snapshot.go +++ b/pkg/exposer/csi_snapshot.go @@ -488,10 +488,6 @@ func (e *csiSnapshotExposer) createBackupPod( } label[podGroupLabel] = podGroupSnapshot - for k, v := range thirdPartyLabels { - label[k] = v - } - volumeMode := corev1.PersistentVolumeFilesystem if backupPVC.Spec.VolumeMode != nil { volumeMode = *backupPVC.Spec.VolumeMode diff --git a/pkg/exposer/generic_restore.go b/pkg/exposer/generic_restore.go index e81d820380..975981d49a 100644 --- a/pkg/exposer/generic_restore.go +++ b/pkg/exposer/generic_restore.go @@ -323,14 +323,6 @@ func (e *genericRestoreExposer) createRestorePod(ctx context.Context, ownerObjec }} volumes = append(volumes, podInfo.volumes...) - if label == nil { - label = make(map[string]string) - } - - for k, v := range thirdPartyLabels { - label[k] = v - } - volumeMode := corev1.PersistentVolumeFilesystem if targetPVC.Spec.VolumeMode != nil { volumeMode = *targetPVC.Spec.VolumeMode diff --git a/pkg/exposer/types.go b/pkg/exposer/types.go index a75f5d3791..d4d8c87300 100644 --- a/pkg/exposer/types.go +++ b/pkg/exposer/types.go @@ -39,7 +39,3 @@ type ExposeByPod struct { HostingContainer string VolumeName string } - -var thirdPartyLabels map[string]string = map[string]string{ - "azure.workload.identity/use": "true", -} diff --git a/pkg/nodeagent/node_agent.go b/pkg/nodeagent/node_agent.go index b83efc6f47..d682c14fc8 100644 --- a/pkg/nodeagent/node_agent.go +++ b/pkg/nodeagent/node_agent.go @@ -161,3 +161,16 @@ func GetConfigs(ctx context.Context, namespace string, kubeClient kubernetes.Int return configs, nil } + +func GetLabelValue(ctx context.Context, kubeClient kubernetes.Interface, namespace string, key string) (string, error) { + ds, err := kubeClient.AppsV1().DaemonSets(namespace).Get(ctx, daemonSet, metav1.GetOptions{}) + if err != nil { + return "", errors.Wrap(err, "error getting node-agent daemonset") + } + + if ds.Spec.Template.Labels == nil { + return "", nil + } + + return ds.Spec.Template.Labels[key], nil +} diff --git a/pkg/nodeagent/node_agent_test.go b/pkg/nodeagent/node_agent_test.go index 9bbf0f46d1..3a76d46633 100644 --- a/pkg/nodeagent/node_agent_test.go +++ b/pkg/nodeagent/node_agent_test.go @@ -331,3 +331,103 @@ func TestGetConfigs(t *testing.T) { }) } } + +func TestGetLabelValue(t *testing.T) { + daemonSet := &appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "fake-ns", + Name: "node-agent", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "DaemonSet", + }, + } + + daemonSetWithOtherLabel := &appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "fake-ns", + Name: "node-agent", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "DaemonSet", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "fake-other-label": "fake-value-1", + }, + }, + }, + }, + } + + daemonSetWithLabel := &appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "fake-ns", + Name: "node-agent", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "DaemonSet", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "fake-label": "fake-value-2", + }, + }, + }, + }, + } + + tests := []struct { + name string + kubeClientObj []runtime.Object + namespace string + expectedValue string + expectErr string + }{ + { + name: "ds get error", + namespace: "fake-ns", + expectErr: "error getting node-agent daemonset: daemonsets.apps \"node-agent\" not found", + }, + { + name: "no label", + namespace: "fake-ns", + kubeClientObj: []runtime.Object{ + daemonSet, + }, + }, + { + name: "no expecting label", + namespace: "fake-ns", + kubeClientObj: []runtime.Object{ + daemonSetWithOtherLabel, + }, + }, + { + name: "expecting label", + namespace: "fake-ns", + kubeClientObj: []runtime.Object{ + daemonSetWithLabel, + }, + expectedValue: "fake-value-2", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + fakeKubeClient := fake.NewSimpleClientset(test.kubeClientObj...) + + value, err := GetLabelValue(context.TODO(), fakeKubeClient, test.namespace, "fake-label") + if test.expectErr == "" { + assert.NoError(t, err) + assert.Equal(t, test.expectedValue, value) + } else { + assert.EqualError(t, err, test.expectErr) + } + }) + } +} diff --git a/pkg/util/third_party.go b/pkg/util/third_party.go new file mode 100644 index 0000000000..2be1586811 --- /dev/null +++ b/pkg/util/third_party.go @@ -0,0 +1,21 @@ +/* +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 util + +var ThirdPartyLabels []string = []string{ + "azure.workload.identity/use", +}