From 02e7c3719ff6711582633a25cde031b16eed89da Mon Sep 17 00:00:00 2001 From: Pujan Shah Date: Thu, 6 Jul 2023 23:06:52 +0200 Subject: [PATCH] Add support for CSI driver gcp.csi.confidential.cloud Signed-off-by: Pujan Shah --- changelogs/unreleased/146-ps-occrp | 1 + velero-plugin-for-gcp/volume_snapshotter.go | 27 +++++++----- .../volume_snapshotter_test.go | 43 +++++++++++++++++++ 3 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/146-ps-occrp diff --git a/changelogs/unreleased/146-ps-occrp b/changelogs/unreleased/146-ps-occrp new file mode 100644 index 00000000..86cfb70d --- /dev/null +++ b/changelogs/unreleased/146-ps-occrp @@ -0,0 +1 @@ +Add support for CSI driver gcp.csi.confidential.cloud diff --git a/velero-plugin-for-gcp/volume_snapshotter.go b/velero-plugin-for-gcp/volume_snapshotter.go index e186d6f8..6198d893 100644 --- a/velero-plugin-for-gcp/volume_snapshotter.go +++ b/velero-plugin-for-gcp/volume_snapshotter.go @@ -43,9 +43,13 @@ const ( zoneSeparator = "__" projectKey = "project" snapshotLocationKey = "snapshotLocation" - pdCSIDriver = "pd.csi.storage.gke.io" ) +var pdCSIDriver = map[string]bool{ + "pd.csi.storage.gke.io": true, + "gcp.csi.confidential.cloud": true, +} + var pdVolRegexp = regexp.MustCompile(`^projects\/[^\/]+\/(zones|regions)\/[^\/]+\/disks\/[^\/]+$`) type VolumeSnapshotter struct { @@ -131,15 +135,18 @@ func isMultiZone(volumeAZ string) bool { // parseRegion parses a failure-domain tag with multiple zones // and returns a single region. Zones are sperated by double underscores (__). // For example -// input: us-central1-a__us-central1-b -// return: us-central1 +// +// input: us-central1-a__us-central1-b +// return: us-central1 +// // When a custom storage class spans multiple geographical zones, // such as us-central1 and us-west1 only the zone matching the cluster is used // in the failure-domain tag. // For example -// Cluster nodes in us-central1-c, us-central1-f -// Storage class zones us-central1-a, us-central1-f, us-east1-a, us-east1-d -// The failure-domain tag would be: us-central1-a__us-central1-f +// +// Cluster nodes in us-central1-c, us-central1-f +// Storage class zones us-central1-a, us-central1-f, us-east1-a, us-east1-d +// The failure-domain tag would be: us-central1-a__us-central1-f func parseRegion(volumeAZ string) (string, error) { zones := strings.Split(volumeAZ, zoneSeparator) zone := zones[0] @@ -374,11 +381,11 @@ func (b *VolumeSnapshotter) GetVolumeID(unstructuredPV runtime.Unstructured) (st if pv.Spec.CSI != nil { driver := pv.Spec.CSI.Driver - if driver == pdCSIDriver { + if pdCSIDriver[driver] { handle := pv.Spec.CSI.VolumeHandle if !pdVolRegexp.MatchString(handle) { return "", fmt.Errorf("invalid volumeHandle for CSI driver:%s, expected projects/{project}/zones/{zone}/disks/{name}, got %s", - pdCSIDriver, handle) + driver, handle) } l := strings.Split(handle, "/") return l[len(l)-1], nil @@ -404,12 +411,12 @@ func (b *VolumeSnapshotter) SetVolumeID(unstructuredPV runtime.Unstructured, vol if pv.Spec.CSI != nil { // PV is provisioned by CSI driver driver := pv.Spec.CSI.Driver - if driver == pdCSIDriver { + if pdCSIDriver[driver] { handle := pv.Spec.CSI.VolumeHandle // To restore in the same AZ, here we only replace the 'disk' chunk. if !pdVolRegexp.MatchString(handle) { return nil, fmt.Errorf("invalid volumeHandle for restore with CSI driver:%s, expected projects/{project}/zones/{zone}/disks/{name}, got %s", - pdCSIDriver, handle) + driver, handle) } pv.Spec.CSI.VolumeHandle = handle[:strings.LastIndex(handle, "/")+1] + volumeID } else { diff --git a/velero-plugin-for-gcp/volume_snapshotter_test.go b/velero-plugin-for-gcp/volume_snapshotter_test.go index c85c5d80..4094652f 100644 --- a/velero-plugin-for-gcp/volume_snapshotter_test.go +++ b/velero-plugin-for-gcp/volume_snapshotter_test.go @@ -94,6 +94,29 @@ func TestGetVolumeIDForCSI(t *testing.T) { want: "", wantErr: true, }, + { + name: "Constellation csi driver", + csiJSON: `{ + "driver": "gcp.csi.confidential.cloud", + "fsType": "ext4", + "volumeAttributes": { + "storage.kubernetes.io/csiProvisionerIdentity": "1637243273131-8081-gcp.csi.confidential.cloud" + }, + "volumeHandle": "projects/velero-gcp/zones/us-central1-f/disks/pvc-a970184f-6cc1-4769-85ad-61dcaf8bf51d" + }`, + want: "pvc-a970184f-6cc1-4769-85ad-61dcaf8bf51d", + wantErr: false, + }, + { + name: "Constellation csi driver with invalid handle name", + csiJSON: `{ + "driver": "gcp.csi.confidential.cloud", + "fsType": "ext4", + "volumeHandle": "pvc-a970184f-6cc1-4769-85ad-61dcaf8bf51d" + }`, + want: "", + wantErr: true, + }, { name: "unknown driver", csiJSON: `{ @@ -185,6 +208,26 @@ func TestSetVolumeIDForCSI(t *testing.T) { volumeID: "restore-fd9729b5-868b-4544-9568-1c5d9121dabc", wantErr: true, }, + { + name: "set ID to CSI with Constellation pd CSI driver", + csiJSON: `{ + "driver": "gcp.csi.confidential.cloud", + "fsType": "ext4", + "volumeHandle": "projects/velero-gcp/zones/us-central1-f/disks/pvc-a970184f-6cc1-4769-85ad-61dcaf8bf51d" + }`, + volumeID: "restore-fd9729b5-868b-4544-9568-1c5d9121dabc", + wantErr: false, + }, + { + name: "set ID to CSI with Constellation pd CSI driver, but the volumeHandle is invalid", + csiJSON: `{ + "driver": "gcp.csi.confidential.cloud", + "fsType": "ext4", + "volumeHandle": "pvc-a970184f-6cc1-4769-85ad-61dcaf8bf51d" + }`, + volumeID: "restore-fd9729b5-868b-4544-9568-1c5d9121dabc", + wantErr: true, + }, { name: "set ID to CSI with unknown driver", csiJSON: `"{