Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add imagePullSecrets inheritance for VGDP pod and maintenance job.
Signed-off-by: Xun Jiang <xun.jiang@broadcom.com>
  • Loading branch information
blackpiglet committed Jul 24, 2025
commit d633cdb87341a06e9a6f7c1308f3a2b2fdcc7f87
1 change: 1 addition & 0 deletions changelogs/unreleased/9102-blackpiglet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add imagePullSecrets inheritance for VGDP pod and maintenance job.
1 change: 1 addition & 0 deletions pkg/exposer/csi_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ func (e *csiSnapshotExposer) createBackupPod(
RestartPolicy: corev1.RestartPolicyNever,
SecurityContext: securityCtx,
Tolerations: toleration,
ImagePullSecrets: podInfo.imagePullSecrets,
},
}

Expand Down
1 change: 1 addition & 0 deletions pkg/exposer/generic_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ func (e *genericRestoreExposer) createRestorePod(ctx context.Context, ownerObjec
RestartPolicy: corev1.RestartPolicyNever,
SecurityContext: securityCtx,
Tolerations: toleration,
ImagePullSecrets: podInfo.imagePullSecrets,
},
}

Expand Down
19 changes: 11 additions & 8 deletions pkg/exposer/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ import (
)

type inheritedPodInfo struct {
image string
serviceAccount string
env []v1.EnvVar
envFrom []v1.EnvFromSource
volumeMounts []v1.VolumeMount
volumes []v1.Volume
logLevelArgs []string
logFormatArgs []string
image string
serviceAccount string
env []v1.EnvVar
envFrom []v1.EnvFromSource
volumeMounts []v1.VolumeMount
volumes []v1.Volume
logLevelArgs []string
logFormatArgs []string
imagePullSecrets []v1.LocalObjectReference
}

func getInheritedPodInfo(ctx context.Context, client kubernetes.Interface, veleroNamespace string, osType string) (inheritedPodInfo, error) {
Expand Down Expand Up @@ -71,5 +72,7 @@ func getInheritedPodInfo(ctx context.Context, client kubernetes.Interface, veler
}
}

podInfo.imagePullSecrets = podSpec.ImagePullSecrets

return podInfo, nil
}
14 changes: 12 additions & 2 deletions pkg/exposer/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"

"github.com/vmware-tanzu/velero/pkg/util/kube"

appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes/fake"

"github.com/vmware-tanzu/velero/pkg/util/kube"
)

func TestGetInheritedPodInfo(t *testing.T) {
Expand Down Expand Up @@ -177,6 +177,11 @@ func TestGetInheritedPodInfo(t *testing.T) {
},
},
ServiceAccountName: "sa-1",
ImagePullSecrets: []v1.LocalObjectReference{
{
Name: "imagePullSecret1",
},
},
},
},
},
Expand Down Expand Up @@ -317,6 +322,11 @@ func TestGetInheritedPodInfo(t *testing.T) {
"--log-level",
"debug",
},
imagePullSecrets: []v1.LocalObjectReference{
{
Name: "imagePullSecret1",
},
},
},
},
}
Expand Down
15 changes: 13 additions & 2 deletions pkg/repository/maintenance/maintenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,16 @@ func StartNewJob(cli client.Client, ctx context.Context, repo *velerov1api.Backu
return maintenanceJob.Name, nil
}

func buildJob(cli client.Client, ctx context.Context, repo *velerov1api.BackupRepository, bslName string, config *JobConfigs,
podResources kube.PodResources, logLevel logrus.Level, logFormat *logging.FormatFlag) (*batchv1.Job, error) {
func buildJob(
cli client.Client,
ctx context.Context,
repo *velerov1api.BackupRepository,
bslName string,
config *JobConfigs,
podResources kube.PodResources,
logLevel logrus.Level,
logFormat *logging.FormatFlag,
) (*batchv1.Job, error) {
// Get the Velero server deployment
deployment := &appsv1.Deployment{}
err := cli.Get(ctx, types.NamespacedName{Name: "velero", Namespace: repo.Namespace}, deployment)
Expand All @@ -431,6 +439,8 @@ func buildJob(cli client.Client, ctx context.Context, repo *velerov1api.BackupRe
// Get the service account from the Velero server deployment
serviceAccount := veleroutil.GetServiceAccountFromVeleroServer(deployment)

imagePullSecrets := veleroutil.GetImagePullSecretsFromVeleroServer(deployment)

// Get image
image := veleroutil.GetVeleroServerImage(deployment)

Expand Down Expand Up @@ -520,6 +530,7 @@ func buildJob(cli client.Client, ctx context.Context, repo *velerov1api.BackupRe
Value: "windows",
},
},
ImagePullSecrets: imagePullSecrets,
},
},
},
Expand Down
51 changes: 39 additions & 12 deletions pkg/repository/maintenance/maintenance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,11 @@ func TestBuildJob(t *testing.T) {
},
},
},
ImagePullSecrets: []v1.LocalObjectReference{
{
Name: "imagePullSecret1",
},
},
},
},
},
Expand All @@ -912,17 +917,18 @@ func TestBuildJob(t *testing.T) {
deploy2.Spec.Template.Labels = map[string]string{"azure.workload.identity/use": "fake-label-value"}

testCases := []struct {
name string
m *JobConfigs
deploy *appsv1.Deployment
logLevel logrus.Level
logFormat *logging.FormatFlag
thirdPartyLabel map[string]string
expectedJobName string
expectedError bool
expectedEnv []v1.EnvVar
expectedEnvFrom []v1.EnvFromSource
expectedPodLabel map[string]string
name string
m *JobConfigs
deploy *appsv1.Deployment
logLevel logrus.Level
logFormat *logging.FormatFlag
thirdPartyLabel map[string]string
expectedJobName string
expectedError bool
expectedEnv []v1.EnvVar
expectedEnvFrom []v1.EnvFromSource
expectedPodLabel map[string]string
expectedImagePullSecrets []v1.LocalObjectReference
}{
{
name: "Valid maintenance job without third party labels",
Expand Down Expand Up @@ -964,6 +970,11 @@ func TestBuildJob(t *testing.T) {
expectedPodLabel: map[string]string{
RepositoryNameLabel: "test-123",
},
expectedImagePullSecrets: []v1.LocalObjectReference{
{
Name: "imagePullSecret1",
},
},
},
{
name: "Valid maintenance job with third party labels",
Expand Down Expand Up @@ -1006,6 +1017,11 @@ func TestBuildJob(t *testing.T) {
RepositoryNameLabel: "test-123",
"azure.workload.identity/use": "fake-label-value",
},
expectedImagePullSecrets: []v1.LocalObjectReference{
{
Name: "imagePullSecret1",
},
},
},
{
name: "Error getting Velero server deployment",
Expand Down Expand Up @@ -1057,7 +1073,16 @@ func TestBuildJob(t *testing.T) {
cli := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(objs...).Build()

// Call the function to test
job, err := buildJob(cli, context.TODO(), param.BackupRepo, param.BackupLocation.Name, tc.m, *tc.m.PodResources, tc.logLevel, tc.logFormat)
job, err := buildJob(
cli,
context.TODO(),
param.BackupRepo,
param.BackupLocation.Name,
tc.m,
*tc.m.PodResources,
tc.logLevel,
tc.logFormat,
)

// Check the error
if tc.expectedError {
Expand Down Expand Up @@ -1108,6 +1133,8 @@ func TestBuildJob(t *testing.T) {
assert.Equal(t, expectedArgs, container.Args)

assert.Equal(t, tc.expectedPodLabel, job.Spec.Template.Labels)

assert.Equal(t, tc.expectedImagePullSecrets, job.Spec.Template.Spec.ImagePullSecrets)
}
})
}
Expand Down
24 changes: 12 additions & 12 deletions pkg/uploader/provider/kopia_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,6 @@ type FakeRestoreProgressUpdater struct {
func (f *FakeRestoreProgressUpdater) UpdateProgress(p *uploader.Progress) {}

func TestRunBackup(t *testing.T) {
mockBRepo := udmrepomocks.NewBackupRepo(t)
mockBRepo.On("GetAdvancedFeatures").Return(udmrepo.AdvancedFeatureInfo{})

var kp kopiaProvider
kp.log = logrus.New()
kp.bkRepo = mockBRepo
updater := FakeBackupProgressUpdater{PodVolumeBackup: &velerov1api.PodVolumeBackup{}, Log: kp.log, Ctx: context.Background(), Cli: fake.NewClientBuilder().WithScheme(util.VeleroScheme).Build()}

testCases := []struct {
name string
hookBackupFunc func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error)
Expand Down Expand Up @@ -102,6 +94,14 @@ func TestRunBackup(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
mockBRepo := udmrepomocks.NewBackupRepo(t)
mockBRepo.On("GetAdvancedFeatures").Return(udmrepo.AdvancedFeatureInfo{})

var kp kopiaProvider
kp.log = logrus.New()
kp.bkRepo = mockBRepo
updater := FakeBackupProgressUpdater{PodVolumeBackup: &velerov1api.PodVolumeBackup{}, Log: kp.log, Ctx: context.Background(), Cli: fake.NewClientBuilder().WithScheme(util.VeleroScheme).Build()}

if tc.volMode == "" {
tc.volMode = uploader.PersistentVolumeFilesystem
}
Expand All @@ -117,10 +117,6 @@ func TestRunBackup(t *testing.T) {
}

func TestRunRestore(t *testing.T) {
var kp kopiaProvider
kp.log = logrus.New()
updater := FakeRestoreProgressUpdater{PodVolumeRestore: &velerov1api.PodVolumeRestore{}, Log: kp.log, Ctx: context.Background(), Cli: fake.NewClientBuilder().WithScheme(util.VeleroScheme).Build()}

testCases := []struct {
name string
hookRestoreFunc func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error)
Expand Down Expand Up @@ -153,6 +149,10 @@ func TestRunRestore(t *testing.T) {

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var kp kopiaProvider
kp.log = logrus.New()
updater := FakeRestoreProgressUpdater{PodVolumeRestore: &velerov1api.PodVolumeRestore{}, Log: kp.log, Ctx: context.Background(), Cli: fake.NewClientBuilder().WithScheme(util.VeleroScheme).Build()}

if tc.volMode == "" {
tc.volMode = uploader.PersistentVolumeFilesystem
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/util/velero/velero.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ func GetServiceAccountFromVeleroServer(deployment *appsv1.Deployment) string {
return deployment.Spec.Template.Spec.ServiceAccountName
}

// GetImagePullSecretsFromVeleroServer get the image pull secrets from the Velero server deployment
func GetImagePullSecretsFromVeleroServer(deployment *appsv1.Deployment) []v1.LocalObjectReference {
return deployment.Spec.Template.Spec.ImagePullSecrets
}

// getVeleroServerImage get the image of the Velero server deployment
func GetVeleroServerImage(deployment *appsv1.Deployment) string {
return deployment.Spec.Template.Spec.Containers[0].Image
Expand Down
58 changes: 58 additions & 0 deletions pkg/util/velero/velero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -582,6 +583,63 @@ func TestGetServiceAccountFromVeleroServer(t *testing.T) {
}
}

func TestGetImagePullSecretsFromVeleroServer(t *testing.T) {
tests := []struct {
name string
deploy *appsv1.Deployment
want []v1.LocalObjectReference
}{
{
name: "no image pull secrets",
deploy: &appsv1.Deployment{
Spec: appsv1.DeploymentSpec{
Template: v1.PodTemplateSpec{
Spec: v1.PodSpec{
ServiceAccountName: "",
},
},
},
},
want: nil,
},
{
name: "image pull secrets",
deploy: &appsv1.Deployment{
Spec: appsv1.DeploymentSpec{
Template: v1.PodTemplateSpec{
Spec: v1.PodSpec{
ImagePullSecrets: []v1.LocalObjectReference{
{
Name: "imagePullSecret1",
},
{
Name: "imagePullSecret2",
},
},
},
},
},
},
want: []v1.LocalObjectReference{
{
Name: "imagePullSecret1",
},
{
Name: "imagePullSecret2",
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := GetImagePullSecretsFromVeleroServer(test.deploy)

require.Equal(t, test.want, got)
})
}
}

func TestGetVeleroServerImage(t *testing.T) {
tests := []struct {
name string
Expand Down
Loading