Issue 8433: add third party labels to data mover pods when the same labels exist in node-agent pods (#8487)
Some checks failed
Run the E2E test on kind / build (push) Failing after 6m42s
Run the E2E test on kind / setup-test-matrix (push) Successful in 8s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / Build (push) Failing after 1m26s
Close stale issues and PRs / stale (push) Successful in 14s
Trivy Nightly Scan / Trivy nightly scan (velero, main) (push) Failing after 1m7s
Trivy Nightly Scan / Trivy nightly scan (velero-restore-helper, main) (push) Failing after 1m19s

* issue 8433: add ask label to data mover pods

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>

* check existence of the same label from node-agent

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>

---------

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
lyndon-li
2024-12-10 01:44:39 +08:00
committed by GitHub
parent 11f100fc59
commit a1cf952b8d
6 changed files with 195 additions and 2 deletions

View File

@@ -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,15 @@ 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 {
if err != nodeagent.ErrNodeAgentLabelNotFound {
log.WithError(err).Warnf("Failed to check node-agent label, skip adding host pod label %s", k)
}
} else {
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.

View File

@@ -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"
)
@@ -810,11 +811,22 @@ 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 {
if err != nodeagent.ErrNodeAgentLabelNotFound {
r.logger.WithError(err).Warnf("Failed to check node-agent label, skip adding host pod label %s", k)
}
} else {
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,

View File

@@ -38,7 +38,8 @@ const (
)
var (
ErrDaemonSetNotFound = errors.New("daemonset not found")
ErrDaemonSetNotFound = errors.New("daemonset not found")
ErrNodeAgentLabelNotFound = errors.New("node-agent label not found")
)
type LoadConcurrency struct {
@@ -161,3 +162,21 @@ 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 "", ErrNodeAgentLabelNotFound
}
val, found := ds.Spec.Template.Labels[key]
if !found {
return "", ErrNodeAgentLabelNotFound
}
return val, nil
}

View File

@@ -331,3 +331,132 @@ 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",
},
},
},
},
}
daemonSetWithEmptyLabel := &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": "",
},
},
},
},
}
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,
},
expectErr: ErrNodeAgentLabelNotFound.Error(),
},
{
name: "no expecting label",
namespace: "fake-ns",
kubeClientObj: []runtime.Object{
daemonSetWithOtherLabel,
},
expectErr: ErrNodeAgentLabelNotFound.Error(),
},
{
name: "expecting label",
namespace: "fake-ns",
kubeClientObj: []runtime.Object{
daemonSetWithLabel,
},
expectedValue: "fake-value-2",
},
{
name: "expecting empty label",
namespace: "fake-ns",
kubeClientObj: []runtime.Object{
daemonSetWithEmptyLabel,
},
expectedValue: "",
},
}
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)
}
})
}
}

21
pkg/util/third_party.go Normal file
View File

@@ -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",
}