Skip to content

Commit b01e071

Browse files
committed
Remove dependency with VolumeSnapshotClass in DataUpload.
Don't add VSClass in the additionalItems when it's empty. Signed-off-by: Xun Jiang <xun.jiang@broadcom.com>
1 parent 95cd0a1 commit b01e071

7 files changed

Lines changed: 172 additions & 25 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove dependency with VolumeSnapshotClass in DataUpload.

internal/volume/volumes_information.go

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,51 @@ func (v *BackupVolumesInformation) getVolumeSnapshotClasses() (
557557
return vsClassList.Items, nil
558558
}
559559

560+
func (v *BackupVolumesInformation) getDriverFromVolumeSnapshot(
561+
vsName string,
562+
namespace string,
563+
) (string, error) {
564+
if vsName == "" {
565+
v.logger.Debugf("vsName is empty. Return early.")
566+
return "", nil
567+
}
568+
569+
vs := new(snapshotv1api.VolumeSnapshot)
570+
if err := v.crClient.Get(
571+
context.TODO(),
572+
kbclient.ObjectKey{Namespace: namespace, Name: vsName},
573+
vs,
574+
); err != nil {
575+
v.logger.Infof("Fail to get VolumeSnapshot %s: %s", namespace+"/"+vsName, err.Error())
576+
return "", errors.Errorf("fail to get VolumeSnapshot %s: %s",
577+
namespace+"/"+vsName, err.Error())
578+
}
579+
580+
if vs.Status == nil || vs.Status.BoundVolumeSnapshotContentName == nil {
581+
v.logger.Infof("VolumeSnapshot %s doesn't have a bound VolumeSnapshotContent",
582+
namespace+"/"+vsName)
583+
return "", errors.Errorf("volumeSnapshot %s doesn't have a bound VolumeSnapshotContent", namespace+"/"+vsName)
584+
}
585+
586+
vsc := new(snapshotv1api.VolumeSnapshotContent)
587+
if err := v.crClient.Get(
588+
context.TODO(),
589+
kbclient.ObjectKey{Name: *vs.Status.BoundVolumeSnapshotContentName},
590+
vsc,
591+
); err != nil {
592+
v.logger.Infof("Fail to get VolumeSnapshotContent %s: %s",
593+
*vs.Status.BoundVolumeSnapshotContentName, err.Error())
594+
return "",
595+
errors.Errorf("fail to get VolumeSnapshotContent %s: %s",
596+
*vs.Status.BoundVolumeSnapshotContentName,
597+
err.Error(),
598+
)
599+
}
600+
601+
v.logger.Debugf("Found driver %s for VolumeSnapshot %s.", vsc.Spec.Driver, namespace+"/"+vsName)
602+
return vsc.Spec.Driver, nil
603+
}
604+
560605
// generateVolumeInfoFromDataUpload generate BackupVolumeInfo for DataUpload.
561606
func (v *BackupVolumesInformation) generateVolumeInfoFromDataUpload() {
562607
if !features.IsEnabled(velerov1api.CSIFeatureFlag) {
@@ -581,14 +626,7 @@ func (v *BackupVolumesInformation) generateVolumeInfoFromDataUpload() {
581626
}
582627
}
583628

584-
var vsClassList []snapshotv1api.VolumeSnapshotClass
585-
if len(duOperationMap) > 0 {
586-
var err error
587-
vsClassList, err = v.getVolumeSnapshotClasses()
588-
if err != nil {
589-
return
590-
}
591-
} else {
629+
if len(duOperationMap) <= 0 {
592630
// No DataUpload is found. Return early.
593631
return
594632
}
@@ -609,11 +647,16 @@ func (v *BackupVolumesInformation) generateVolumeInfoFromDataUpload() {
609647
continue
610648
}
611649

612-
driverUsedByVSClass := ""
613-
for index := range vsClassList {
614-
if vsClassList[index].Name == dataUpload.Spec.CSISnapshot.SnapshotClass {
615-
driverUsedByVSClass = vsClassList[index].Driver
616-
}
650+
driver, driverErr := v.getDriverFromVolumeSnapshot(
651+
dataUpload.Spec.CSISnapshot.VolumeSnapshot,
652+
dataUpload.Namespace,
653+
)
654+
if driverErr != nil {
655+
v.logger.Warnf("Fail to get driver for VolumeSnapshot %s: %s",
656+
dataUpload.Namespace+"/"+dataUpload.Spec.CSISnapshot.VolumeSnapshot,
657+
driverErr.Error(),
658+
)
659+
continue
617660
}
618661

619662
if pvcPVInfo := v.pvMap.retrieve(
@@ -637,7 +680,7 @@ func (v *BackupVolumesInformation) generateVolumeInfoFromDataUpload() {
637680
SnapshotHandle: FieldValueIsUnknown,
638681
VSCName: FieldValueIsUnknown,
639682
OperationID: FieldValueIsUnknown,
640-
Driver: driverUsedByVSClass,
683+
Driver: driver,
641684
},
642685
SnapshotDataMovementInfo: &SnapshotDataMovementInfo{
643686
DataMover: dataMover,

internal/volume/volumes_information_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"sync"
2222
"testing"
2323

24+
"github.com/pkg/errors"
2425
"github.com/stretchr/testify/assert"
2526

2627
snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumesnapshot/v1"
@@ -29,6 +30,7 @@ import (
2930
corev1api "k8s.io/api/core/v1"
3031
"k8s.io/apimachinery/pkg/api/resource"
3132
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
33+
"k8s.io/apimachinery/pkg/runtime"
3234
"k8s.io/apimachinery/pkg/runtime/schema"
3335

3436
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
@@ -1327,3 +1329,73 @@ func TestGetVolumeSnapshotClasses(t *testing.T) {
13271329
require.NoError(t, err)
13281330
require.Equal(t, []snapshotv1api.VolumeSnapshotClass{*class}, result)
13291331
}
1332+
1333+
func TestGetDriverFromVolumeSnapshot(t *testing.T) {
1334+
tests := []struct {
1335+
name string
1336+
vsName string
1337+
vs *snapshotv1api.VolumeSnapshot
1338+
vsc *snapshotv1api.VolumeSnapshotContent
1339+
expectedErr error
1340+
expectedDriver string
1341+
}{
1342+
{
1343+
name: "vsName is empty",
1344+
vsName: "",
1345+
expectedErr: nil,
1346+
expectedDriver: "",
1347+
},
1348+
{
1349+
name: "vs is not created",
1350+
vsName: "vs-01",
1351+
expectedErr: errors.Errorf("fail to get VolumeSnapshot %s: %s", velerov1api.DefaultNamespace+"/"+"vs-01", "volumesnapshots.snapshot.storage.k8s.io \"vs-01\" not found"),
1352+
expectedDriver: "",
1353+
},
1354+
{
1355+
name: "vs status is nil",
1356+
vsName: "vs-01",
1357+
vs: builder.ForVolumeSnapshot(velerov1api.DefaultNamespace, "vs-01").Result(),
1358+
expectedErr: errors.Errorf("volumeSnapshot %s doesn't have a bound VolumeSnapshotContent", velerov1api.DefaultNamespace+"/"+"vs-01"),
1359+
expectedDriver: "",
1360+
},
1361+
{
1362+
name: "vsc is not created",
1363+
vsName: "vs-01",
1364+
vs: builder.ForVolumeSnapshot(velerov1api.DefaultNamespace, "vs-01").Status().BoundVolumeSnapshotContentName("vsc-01").Result(),
1365+
expectedErr: errors.Errorf("fail to get VolumeSnapshotContent %s: %s", "vsc-01", "volumesnapshotcontents.snapshot.storage.k8s.io \"vsc-01\" not found"),
1366+
expectedDriver: "",
1367+
},
1368+
{
1369+
name: "success case",
1370+
vsName: "vs-01",
1371+
vs: builder.ForVolumeSnapshot(velerov1api.DefaultNamespace, "vs-01").Status().BoundVolumeSnapshotContentName("vsc-01").Result(),
1372+
vsc: builder.ForVolumeSnapshotContent("vsc-01").Driver("csi.storage.vsphere.com").Result(),
1373+
expectedErr: nil,
1374+
expectedDriver: "csi.storage.vsphere.com",
1375+
},
1376+
}
1377+
1378+
for _, tc := range tests {
1379+
t.Run(tc.name, func(t *testing.T) {
1380+
volumesInfo := BackupVolumesInformation{}
1381+
volumesInfo.Init()
1382+
volumesInfo.logger = velerotest.NewLogger()
1383+
1384+
objects := []runtime.Object{}
1385+
if tc.vs != nil {
1386+
objects = append(objects, tc.vs)
1387+
}
1388+
if tc.vsc != nil {
1389+
objects = append(objects, tc.vsc)
1390+
}
1391+
1392+
volumesInfo.crClient = velerotest.NewFakeControllerRuntimeClient(t, objects...)
1393+
1394+
driver, err := volumesInfo.getDriverFromVolumeSnapshot(tc.vsName, velerov1api.DefaultNamespace)
1395+
if err != nil {
1396+
assert.ErrorAs(t, tc.expectedErr, &err)
1397+
}
1398+
assert.Equal(t, tc.expectedDriver, driver)
1399+
})
1400+
}
1401+
}

pkg/apis/velero/v2alpha1/data_upload_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type CSISnapshotSpec struct {
7878

7979
// SnapshotClass is the name of the snapshot class that the volume snapshot is created with
8080
// +optional
81-
SnapshotClass string `json:"snapshotClass"`
81+
SnapshotClass string `json:"snapshotClass,omitempty"`
8282
}
8383

8484
// DataUploadPhase represents the lifecycle phase of a DataUpload.

pkg/backup/actions/csi/pvc_action.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,6 @@ func newDataUpload(
471471
CSISnapshot: &velerov2alpha1.CSISnapshotSpec{
472472
VolumeSnapshot: vs.Name,
473473
StorageClass: *pvc.Spec.StorageClassName,
474-
SnapshotClass: *vs.Spec.VolumeSnapshotClassName,
475474
},
476475
SourcePVC: pvc.Name,
477476
DataMover: backup.Spec.DataMover,

pkg/backup/actions/csi/volumesnapshot_action.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,15 @@ func (p *volumeSnapshotBackupItemAction) Execute(
8484
return nil, nil, "", nil, errors.WithStack(err)
8585
}
8686

87-
volumeSnapshotClassName := ""
87+
additionalItems := make([]velero.ResourceIdentifier, 0)
8888
if vs.Spec.VolumeSnapshotClassName != nil {
89-
volumeSnapshotClassName = *vs.Spec.VolumeSnapshotClassName
90-
}
91-
92-
additionalItems := []velero.ResourceIdentifier{
93-
{
94-
GroupResource: kuberesource.VolumeSnapshotClasses,
95-
Name: volumeSnapshotClassName,
96-
},
89+
additionalItems = append(
90+
additionalItems,
91+
velero.ResourceIdentifier{
92+
GroupResource: kuberesource.VolumeSnapshotClasses,
93+
Name: *vs.Spec.VolumeSnapshotClassName,
94+
},
95+
)
9796
}
9897

9998
p.log.Infof("Getting VolumesnapshotContent for Volumesnapshot %s/%s",

pkg/backup/actions/csi/volumesnapshot_action_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,39 @@ func TestVSExecute(t *testing.T) {
8686
},
8787
},
8888
},
89+
{
90+
name: "VS not have VSClass",
91+
backup: builder.ForBackup("velero", "backup").
92+
Phase(velerov1api.BackupPhaseInProgress).Result(),
93+
vs: builder.ForVolumeSnapshot("velero", "vs").
94+
ObjectMeta(builder.WithLabels(
95+
velerov1api.BackupNameLabel, "backup")).
96+
Status().
97+
BoundVolumeSnapshotContentName("vsc").Result(),
98+
vsc: builder.ForVolumeSnapshotContent("vsc").Status(
99+
&snapshotv1api.VolumeSnapshotContentStatus{
100+
SnapshotHandle: &snapshotHandle,
101+
},
102+
).Result(),
103+
expectedErr: "",
104+
expectedAdditionalItems: []velero.ResourceIdentifier{
105+
{
106+
GroupResource: kuberesource.VolumeSnapshotContents,
107+
Name: "vsc",
108+
},
109+
},
110+
expectedItemToUpdate: []velero.ResourceIdentifier{
111+
{
112+
GroupResource: kuberesource.VolumeSnapshots,
113+
Namespace: "velero",
114+
Name: "vs",
115+
},
116+
{
117+
GroupResource: kuberesource.VolumeSnapshotContents,
118+
Name: "vsc",
119+
},
120+
},
121+
},
89122
}
90123

91124
for _, tc := range tests {

0 commit comments

Comments
 (0)