Skip to content

Commit

Permalink
Handle the volumes created by the CSI driver
Browse files Browse the repository at this point in the history
Current VolumeSnapshotter works with volumes allocated by the "in-tree" storage driver. Kubernetes is moving to the CSI driver for Azure and will deprecate the in-tree driver, however we may not be able to get CSI snapshots in Velero to GA before that happens. As an interim solution, we handle volumes created by the CSI driver with the existing VolumeSnapshotter.

Fixes vmware-tanzu/velero#4109

Signed-off-by: Wenkai Yin(尹文开) <yinw@vmware.com>
  • Loading branch information
ywk253100 committed Nov 4, 2021
1 parent 9621c88 commit 2fcc88b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 7 deletions.
28 changes: 21 additions & 7 deletions velero-plugin-for-microsoft-azure/volume_snapshotter.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,11 @@ func getComputeResourceName(subscription, resourceGroup, resource, name string)
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/%s/%s", subscription, resourceGroup, resource, name)
}

var snapshotURIRegexp = regexp.MustCompile(
`^\/subscriptions\/(?P<subscription>.*)\/resourceGroups\/(?P<resourceGroup>.*)\/providers\/Microsoft.Compute\/snapshots\/(?P<snapshotName>.*)$`)
var (
snapshotURIRegexp = regexp.MustCompile(
`^\/subscriptions\/(?P<subscription>.*)\/resourceGroups\/(?P<resourceGroup>.*)\/providers\/Microsoft.Compute\/snapshots\/(?P<snapshotName>.*)$`)
diskURIRegexp = regexp.MustCompile(`\/Microsoft.Compute\/disks\/.*$`)
)

// parseFullSnapshotName takes a fully-qualified snapshot name and returns
// a snapshot identifier or an error if the snapshot name does not match the
Expand Down Expand Up @@ -396,6 +399,10 @@ func (b *VolumeSnapshotter) GetVolumeID(unstructuredPV runtime.Unstructured) (st
return "", errors.WithStack(err)
}

if pv.Spec.CSI != nil && pv.Spec.CSI.Driver == "disk.csi.azure.com" {
return strings.TrimPrefix(diskURIRegexp.FindString(pv.Spec.CSI.VolumeHandle), "/Microsoft.Compute/disks/"), nil
}

if pv.Spec.AzureDisk == nil {
return "", nil
}
Expand All @@ -413,12 +420,19 @@ func (b *VolumeSnapshotter) SetVolumeID(unstructuredPV runtime.Unstructured, vol
return nil, errors.WithStack(err)
}

if pv.Spec.AzureDisk == nil {
return nil, errors.New("spec.azureDisk not found")
}
if pv.Spec.CSI != nil && pv.Spec.CSI.Driver == "disk.csi.azure.com" {
pv.Spec.CSI.VolumeHandle = getComputeResourceName(b.disksSubscription, b.disksResourceGroup, disksResource, volumeID)
if _, exist := pv.Spec.CSI.VolumeAttributes["csi.storage.k8s.io/pv/name"]; exist {
pv.Spec.CSI.VolumeAttributes["csi.storage.k8s.io/pv/name"] = volumeID
}
} else {
if pv.Spec.AzureDisk == nil {
return nil, errors.New("spec.azureDisk not found")
}

pv.Spec.AzureDisk.DiskName = volumeID
pv.Spec.AzureDisk.DataDiskURI = getComputeResourceName(b.disksSubscription, b.disksResourceGroup, disksResource, volumeID)
pv.Spec.AzureDisk.DiskName = volumeID
pv.Spec.AzureDisk.DataDiskURI = getComputeResourceName(b.disksSubscription, b.disksResourceGroup, disksResource, volumeID)
}

res, err := runtime.DefaultUnstructuredConverter.ToUnstructured(pv)
if err != nil {
Expand Down
28 changes: 28 additions & 0 deletions velero-plugin-for-microsoft-azure/volume_snapshotter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ func TestGetVolumeID(t *testing.T) {
volumeID, err = b.GetVolumeID(pv)
assert.NoError(t, err)
assert.Equal(t, "foo", volumeID)

// CSI driver
csi := map[string]interface{}{
"driver": "disk.csi.azure.com",
"volumeHandle": " /subscriptions/subscription-id/resourceGroups/resource-group-name/providers/Microsoft.Compute/disks/bar",
}
pv.Object["spec"].(map[string]interface{})["csi"] = csi
volumeID, err = b.GetVolumeID(pv)
assert.NoError(t, err)
assert.Equal(t, "bar", volumeID)
}

func TestSetVolumeID(t *testing.T) {
Expand Down Expand Up @@ -92,6 +102,24 @@ func TestSetVolumeID(t *testing.T) {
require.NotNil(t, res.Spec.AzureDisk)
assert.Equal(t, "revised", res.Spec.AzureDisk.DiskName)
assert.Equal(t, "/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Compute/disks/revised", res.Spec.AzureDisk.DataDiskURI)

// CSI driver
csi := map[string]interface{}{
"driver": "disk.csi.azure.com",
"volumeHandle": " /subscriptions/subscription-id/resourceGroups/resource-group-name/providers/Microsoft.Compute/disks/foo",
"volumeAttributes": map[string]string{
"csi.storage.k8s.io/pv/name": "foo",
},
}
pv.Object["spec"].(map[string]interface{})["csi"] = csi
updatedPV, err = b.SetVolumeID(pv, "updated")
require.NoError(t, err)

res = new(v1.PersistentVolume)
require.NoError(t, runtime.DefaultUnstructuredConverter.FromUnstructured(updatedPV.UnstructuredContent(), res))
require.NotNil(t, res.Spec.CSI)
assert.Equal(t, "/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Compute/disks/updated", res.Spec.CSI.VolumeHandle)
assert.Equal(t, "updated", res.Spec.CSI.VolumeAttributes["csi.storage.k8s.io/pv/name"])
}

func TestParseFullSnapshotName(t *testing.T) {
Expand Down

0 comments on commit 2fcc88b

Please sign in to comment.