Skip to content

Commit 20bbe2b

Browse files
authored
Merge pull request #1304 from mattcary/volid
Replace cleanSelfLink with getResourceId
2 parents fcbc9ac + 4d07b05 commit 20bbe2b

File tree

3 files changed

+198
-61
lines changed

3 files changed

+198
-61
lines changed

pkg/gce-cloud-provider/compute/fake-gce.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,10 @@ func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, project string,
229229
switch volKey.Type() {
230230
case meta.Zonal:
231231
computeDisk.Zone = volKey.Zone
232-
computeDisk.SelfLink = fmt.Sprintf("projects/%s/zones/%s/disks/%s", project, volKey.Zone, volKey.Name)
232+
computeDisk.SelfLink = fmt.Sprintf("%sprojects/%s/zones/%s/disks/%s", BasePath, project, volKey.Zone, volKey.Name)
233233
case meta.Regional:
234234
computeDisk.Region = volKey.Region
235-
computeDisk.SelfLink = fmt.Sprintf("projects/%s/regions/%s/disks/%s", project, volKey.Region, volKey.Name)
235+
computeDisk.SelfLink = fmt.Sprintf("%sprojects/%s/regions/%s/disks/%s", BasePath, project, volKey.Region, volKey.Name)
236236
default:
237237
return fmt.Errorf("could not create disk, key was neither zonal nor regional, instead got: %v", volKey.String())
238238
}

pkg/gce-pd-csi-driver/controller.go

Lines changed: 100 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"errors"
2020
"fmt"
2121
"math/rand"
22-
"regexp"
22+
neturl "net/url"
2323
"sort"
2424
"strings"
2525
"time"
@@ -140,6 +140,14 @@ const (
140140

141141
// Keys in the volume context.
142142
contextForceAttach = "force-attach"
143+
144+
resourceApiScheme = "https"
145+
resourceApiService = "compute"
146+
resourceProject = "projects"
147+
)
148+
149+
var (
150+
validResourceApiVersions = map[string]bool{"v1": true, "alpha": true, "beta": true}
143151
)
144152

145153
func isDiskReady(disk *gce.CloudDisk) (bool, error) {
@@ -321,7 +329,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
321329

322330
// If there is no validation error, immediately return success
323331
klog.V(4).Infof("CreateVolume succeeded for disk %v, it already exists and was compatible", volKey)
324-
return generateCreateVolumeResponse(existingDisk, zones, params), nil
332+
return generateCreateVolumeResponse(existingDisk, zones, params)
325333
}
326334

327335
snapshotID := ""
@@ -436,7 +444,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
436444
}
437445

438446
klog.V(4).Infof("CreateVolume succeeded for disk %v", volKey)
439-
return generateCreateVolumeResponse(disk, zones, params), nil
447+
return generateCreateVolumeResponse(disk, zones, params)
440448

441449
}
442450

@@ -871,13 +879,23 @@ func (gceCS *GCEControllerServer) ListVolumes(ctx context.Context, req *csi.List
871879
entries := []*csi.ListVolumesResponse_Entry{}
872880
for i := 0; i+offset < len(gceCS.disks) && i < maxEntries; i++ {
873881
d := gceCS.disks[i+offset]
882+
diskRsrc, err := getResourceId(d.SelfLink)
883+
if err != nil {
884+
klog.Warningf("Bad ListVolumes disk resource %s, skipped: %v (%+v)", d.SelfLink, err, d)
885+
continue
886+
}
874887
users := []string{}
875888
for _, u := range d.Users {
876-
users = append(users, cleanSelfLink(u))
889+
rsrc, err := getResourceId(u)
890+
if err != nil {
891+
klog.Warningf("Bad ListVolumes user %s, skipped: %v", u, err)
892+
} else {
893+
users = append(users, rsrc)
894+
}
877895
}
878896
entries = append(entries, &csi.ListVolumesResponse_Entry{
879897
Volume: &csi.Volume{
880-
VolumeId: cleanSelfLink(d.SelfLink),
898+
VolumeId: diskRsrc,
881899
},
882900
Status: &csi.ListVolumesResponse_VolumeStatus{
883901
PublishedNodeIds: users,
@@ -990,6 +1008,10 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
9901008
return nil, common.LoggedError("Failed to create snapshot: ", err)
9911009
}
9921010
}
1011+
snapshotId, err := getResourceId(snapshot.SelfLink)
1012+
if err != nil {
1013+
return nil, common.LoggedError(fmt.Sprintf("Cannot extract resource id from snapshot %s", snapshot.SelfLink), err)
1014+
}
9931015

9941016
err = gceCS.validateExistingSnapshot(snapshot, volKey)
9951017
if err != nil {
@@ -1008,7 +1030,7 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
10081030

10091031
return &csi.Snapshot{
10101032
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
1011-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1033+
SnapshotId: snapshotId,
10121034
SourceVolumeId: volumeID,
10131035
CreationTime: timestamp,
10141036
ReadyToUse: ready,
@@ -1037,6 +1059,10 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10371059
return nil, common.LoggedError("Failed to create image: ", err)
10381060
}
10391061
}
1062+
imageId, err := getResourceId(image.SelfLink)
1063+
if err != nil {
1064+
return nil, common.LoggedError(fmt.Sprintf("Cannot extract resource id from snapshot %s", image.SelfLink), err)
1065+
}
10401066

10411067
err = gceCS.validateExistingImage(image, volKey)
10421068
if err != nil {
@@ -1055,7 +1081,7 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10551081

10561082
return &csi.Snapshot{
10571083
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1058-
SnapshotId: cleanSelfLink(image.SelfLink),
1084+
SnapshotId: imageId,
10591085
SourceVolumeId: volumeID,
10601086
CreationTime: timestamp,
10611087
ReadyToUse: ready,
@@ -1067,9 +1093,13 @@ func (gceCS *GCEControllerServer) validateExistingImage(image *compute.Image, vo
10671093
return fmt.Errorf("disk does not exist")
10681094
}
10691095

1070-
_, sourceKey, err := common.VolumeIDToKey(cleanSelfLink(image.SourceDisk))
1096+
sourceId, err := getResourceId(image.SourceDisk)
1097+
if err != nil {
1098+
return fmt.Errorf("failed to get source id from %s: %w", image.SourceDisk, err)
1099+
}
1100+
_, sourceKey, err := common.VolumeIDToKey(sourceId)
10711101
if err != nil {
1072-
return fmt.Errorf("fail to get source disk key %s, %w", image.SourceDisk, err)
1102+
return fmt.Errorf("failed to get source disk key %s: %w", image.SourceDisk, err)
10731103
}
10741104

10751105
if sourceKey.String() != volKey.String() {
@@ -1118,7 +1148,11 @@ func (gceCS *GCEControllerServer) validateExistingSnapshot(snapshot *compute.Sna
11181148
return fmt.Errorf("disk does not exist")
11191149
}
11201150

1121-
_, sourceKey, err := common.VolumeIDToKey(cleanSelfLink(snapshot.SourceDisk))
1151+
sourceId, err := getResourceId(snapshot.SourceDisk)
1152+
if err != nil {
1153+
return fmt.Errorf("failed to get source id from %s: %w", snapshot.SourceDisk, err)
1154+
}
1155+
_, sourceKey, err := common.VolumeIDToKey(sourceId)
11221156
if err != nil {
11231157
return fmt.Errorf("fail to get source disk key %s, %w", snapshot.SourceDisk, err)
11241158
}
@@ -1161,7 +1195,7 @@ func (gceCS *GCEControllerServer) DeleteSnapshot(ctx context.Context, req *csi.D
11611195
if err != nil {
11621196
// Cannot get snapshot ID from the passing request
11631197
// This is a success according to the spec
1164-
klog.Warningf("Snapshot id does not have the correct format %s", snapshotID)
1198+
klog.Warningf("Snapshot id does not have the correct format %s: %v", snapshotID, err)
11651199
return &csi.DeleteSnapshotResponse{}, nil
11661200
}
11671201

@@ -1352,7 +1386,7 @@ func (gceCS *GCEControllerServer) getSnapshotByID(ctx context.Context, snapshotI
13521386
return &csi.ListSnapshotsResponse{}, nil
13531387
}
13541388
}
1355-
e, err := generateImageEntry(image)
1389+
e, err := generateDiskImageEntry(image)
13561390
if err != nil {
13571391
return nil, fmt.Errorf("failed to generate image entry: %w", err)
13581392
}
@@ -1374,6 +1408,15 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13741408
return nil, fmt.Errorf("Failed to covert creation timestamp: %w", err)
13751409
}
13761410

1411+
snapshotId, err := getResourceId(snapshot.SelfLink)
1412+
if err != nil {
1413+
return nil, fmt.Errorf("failed to get snapshot id from %s: %w", snapshot.SelfLink, err)
1414+
}
1415+
sourceId, err := getResourceId(snapshot.SourceDisk)
1416+
if err != nil {
1417+
return nil, fmt.Errorf("failed to get source id from %s: %w", snapshot.SourceDisk, err)
1418+
}
1419+
13771420
// We ignore the error intentionally here since we are just listing snapshots
13781421
// TODO: If the snapshot is in "FAILED" state we need to think through what this
13791422
// should actually look like.
@@ -1382,8 +1425,8 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13821425
entry := &csi.ListSnapshotsResponse_Entry{
13831426
Snapshot: &csi.Snapshot{
13841427
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
1385-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1386-
SourceVolumeId: cleanSelfLink(snapshot.SourceDisk),
1428+
SnapshotId: snapshotId,
1429+
SourceVolumeId: sourceId,
13871430
CreationTime: tp,
13881431
ReadyToUse: ready,
13891432
},
@@ -1399,35 +1442,23 @@ func generateDiskImageEntry(image *compute.Image) (*csi.ListSnapshotsResponse_En
13991442
return nil, fmt.Errorf("failed to covert creation timestamp: %w", err)
14001443
}
14011444

1402-
ready, _ := isImageReady(image.Status)
1403-
1404-
entry := &csi.ListSnapshotsResponse_Entry{
1405-
Snapshot: &csi.Snapshot{
1406-
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1407-
SnapshotId: cleanSelfLink(image.SelfLink),
1408-
SourceVolumeId: cleanSelfLink(image.SourceDisk),
1409-
CreationTime: tp,
1410-
ReadyToUse: ready,
1411-
},
1445+
imageId, err := getResourceId(image.SelfLink)
1446+
if err != nil {
1447+
return nil, fmt.Errorf("cannot get image id from %s: %w", image.SelfLink, err)
14121448
}
1413-
return entry, nil
1414-
}
1415-
1416-
func generateImageEntry(image *compute.Image) (*csi.ListSnapshotsResponse_Entry, error) {
1417-
timestamp, err := parseTimestamp(image.CreationTimestamp)
1449+
sourceId, err := getResourceId(image.SourceDisk)
14181450
if err != nil {
1419-
return nil, fmt.Errorf("Failed to covert creation timestamp: %w", err)
1451+
return nil, fmt.Errorf("cannot get source id from %s: %w", image.SourceDisk, err)
14201452
}
14211453

1422-
// ignore the error intentionally here since we are just listing images
14231454
ready, _ := isImageReady(image.Status)
14241455

14251456
entry := &csi.ListSnapshotsResponse_Entry{
14261457
Snapshot: &csi.Snapshot{
14271458
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1428-
SnapshotId: cleanSelfLink(image.SelfLink),
1429-
SourceVolumeId: cleanSelfLink(image.SourceDisk),
1430-
CreationTime: timestamp,
1459+
SnapshotId: imageId,
1460+
SourceVolumeId: sourceId,
1461+
CreationTime: tp,
14311462
ReadyToUse: ready,
14321463
},
14331464
}
@@ -1693,7 +1724,12 @@ func extractVolumeContext(context map[string]string) (*PDCSIContext, error) {
16931724
return info, nil
16941725
}
16951726

1696-
func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params common.DiskParameters) *csi.CreateVolumeResponse {
1727+
func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params common.DiskParameters) (*csi.CreateVolumeResponse, error) {
1728+
volumeId, err := getResourceId(disk.GetSelfLink())
1729+
if err != nil {
1730+
return nil, fmt.Errorf("cannot get volume id from %s: %w", disk.GetSelfLink(), err)
1731+
}
1732+
16971733
tops := []*csi.Topology{}
16981734
for _, zone := range zones {
16991735
tops = append(tops, &csi.Topology{
@@ -1704,7 +1740,7 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params co
17041740
createResp := &csi.CreateVolumeResponse{
17051741
Volume: &csi.Volume{
17061742
CapacityBytes: realDiskSizeBytes,
1707-
VolumeId: cleanSelfLink(disk.GetSelfLink()),
1743+
VolumeId: volumeId,
17081744
VolumeContext: paramsToVolumeContext(params),
17091745
AccessibleTopology: tops,
17101746
},
@@ -1743,12 +1779,36 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params co
17431779
}
17441780
createResp.Volume.ContentSource = contentSource
17451781
}
1746-
return createResp
1782+
return createResp, nil
17471783
}
17481784

1749-
func cleanSelfLink(selfLink string) string {
1750-
r, _ := regexp.Compile("https:\\/\\/www.*apis.com\\/.*(v1|beta|alpha)\\/")
1751-
return r.ReplaceAllString(selfLink, "")
1785+
func getResourceId(resourceLink string) (string, error) {
1786+
url, err := neturl.Parse(resourceLink)
1787+
if err != nil {
1788+
return "", fmt.Errorf("Could not parse resource %s: %w", resourceLink, err)
1789+
}
1790+
if url.Scheme != resourceApiScheme {
1791+
return "", fmt.Errorf("Unexpected API scheme for resource %s", resourceLink)
1792+
}
1793+
1794+
// Note that the resource host can basically be anything, if we are running in
1795+
// a distributed cloud or trusted partner environment.
1796+
1797+
// The path should be /compute/VERSION/project/....
1798+
elts := strings.Split(url.Path, "/")
1799+
if len(elts) < 4 {
1800+
return "", fmt.Errorf("Short resource path %s", resourceLink)
1801+
}
1802+
if elts[1] != resourceApiService {
1803+
return "", fmt.Errorf("Bad resource service %s in %s", elts[1], resourceLink)
1804+
}
1805+
if _, ok := validResourceApiVersions[elts[2]]; !ok {
1806+
return "", fmt.Errorf("Bad version %s in %s", elts[2], resourceLink)
1807+
}
1808+
if elts[3] != resourceProject {
1809+
return "", fmt.Errorf("Expected %v to start with %s in resource %s", elts[3:], resourceProject, resourceLink)
1810+
}
1811+
return strings.Join(elts[3:], "/"), nil
17521812
}
17531813

17541814
func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, params common.DiskParameters, capacityRange *csi.CapacityRange, capBytes int64, snapshotID string, volumeContentSourceVolumeID string, multiWriter bool) (*gce.CloudDisk, error) {

0 commit comments

Comments
 (0)