Skip to content

Commit 32733c8

Browse files
committed
Replace cleanSelfLink with getResourceId
Change-Id: I81e79dd89d7bab65c7ccab3cd490b173593a888f
1 parent d14b457 commit 32733c8

File tree

3 files changed

+198
-61
lines changed

3 files changed

+198
-61
lines changed

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

+2-2
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

+100-40
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"
@@ -138,6 +138,14 @@ const (
138138

139139
// Keys in the volume context.
140140
contextForceAttach = "force-attach"
141+
142+
resourceApiScheme = "https"
143+
resourceApiService = "compute"
144+
resourceProject = "projects"
145+
)
146+
147+
var (
148+
validResourceApiVersions = map[string]bool{"v1": true, "alpha": true, "beta": true}
141149
)
142150

143151
func isDiskReady(disk *gce.CloudDisk) (bool, error) {
@@ -319,7 +327,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
319327

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

325333
snapshotID := ""
@@ -434,7 +442,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
434442
}
435443

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

439447
}
440448

@@ -869,13 +877,23 @@ func (gceCS *GCEControllerServer) ListVolumes(ctx context.Context, req *csi.List
869877
entries := []*csi.ListVolumesResponse_Entry{}
870878
for i := 0; i+offset < len(gceCS.disks) && i < maxEntries; i++ {
871879
d := gceCS.disks[i+offset]
880+
diskRsrc, err := getResourceId(d.SelfLink)
881+
if err != nil {
882+
klog.Warningf("Bad ListVolumes disk resource %s, skipped: %v (%+v)", d.SelfLink, err, d)
883+
continue
884+
}
872885
users := []string{}
873886
for _, u := range d.Users {
874-
users = append(users, cleanSelfLink(u))
887+
rsrc, err := getResourceId(u)
888+
if err != nil {
889+
klog.Warningf("Bad ListVolumes user %s, skipped: %v", u, err)
890+
} else {
891+
users = append(users, rsrc)
892+
}
875893
}
876894
entries = append(entries, &csi.ListVolumesResponse_Entry{
877895
Volume: &csi.Volume{
878-
VolumeId: cleanSelfLink(d.SelfLink),
896+
VolumeId: diskRsrc,
879897
},
880898
Status: &csi.ListVolumesResponse_VolumeStatus{
881899
PublishedNodeIds: users,
@@ -988,6 +1006,10 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
9881006
return nil, common.LoggedError("Failed to create snapshot: ", err)
9891007
}
9901008
}
1009+
snapshotId, err := getResourceId(snapshot.SelfLink)
1010+
if err != nil {
1011+
return nil, common.LoggedError(fmt.Sprintf("Cannot extract resource id from snapshot %s", snapshot.SelfLink), err)
1012+
}
9911013

9921014
err = gceCS.validateExistingSnapshot(snapshot, volKey)
9931015
if err != nil {
@@ -1006,7 +1028,7 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
10061028

10071029
return &csi.Snapshot{
10081030
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
1009-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1031+
SnapshotId: snapshotId,
10101032
SourceVolumeId: volumeID,
10111033
CreationTime: timestamp,
10121034
ReadyToUse: ready,
@@ -1035,6 +1057,10 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10351057
return nil, common.LoggedError("Failed to create image: ", err)
10361058
}
10371059
}
1060+
imageId, err := getResourceId(image.SelfLink)
1061+
if err != nil {
1062+
return nil, common.LoggedError(fmt.Sprintf("Cannot extract resource id from snapshot %s", image.SelfLink), err)
1063+
}
10381064

10391065
err = gceCS.validateExistingImage(image, volKey)
10401066
if err != nil {
@@ -1053,7 +1079,7 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10531079

10541080
return &csi.Snapshot{
10551081
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1056-
SnapshotId: cleanSelfLink(image.SelfLink),
1082+
SnapshotId: imageId,
10571083
SourceVolumeId: volumeID,
10581084
CreationTime: timestamp,
10591085
ReadyToUse: ready,
@@ -1065,9 +1091,13 @@ func (gceCS *GCEControllerServer) validateExistingImage(image *compute.Image, vo
10651091
return fmt.Errorf("disk does not exist")
10661092
}
10671093

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

10731103
if sourceKey.String() != volKey.String() {
@@ -1116,7 +1146,11 @@ func (gceCS *GCEControllerServer) validateExistingSnapshot(snapshot *compute.Sna
11161146
return fmt.Errorf("disk does not exist")
11171147
}
11181148

1119-
_, sourceKey, err := common.VolumeIDToKey(cleanSelfLink(snapshot.SourceDisk))
1149+
sourceId, err := getResourceId(snapshot.SourceDisk)
1150+
if err != nil {
1151+
return fmt.Errorf("failed to get source id from %s: %w", snapshot.SourceDisk, err)
1152+
}
1153+
_, sourceKey, err := common.VolumeIDToKey(sourceId)
11201154
if err != nil {
11211155
return fmt.Errorf("fail to get source disk key %s, %w", snapshot.SourceDisk, err)
11221156
}
@@ -1159,7 +1193,7 @@ func (gceCS *GCEControllerServer) DeleteSnapshot(ctx context.Context, req *csi.D
11591193
if err != nil {
11601194
// Cannot get snapshot ID from the passing request
11611195
// This is a success according to the spec
1162-
klog.Warningf("Snapshot id does not have the correct format %s", snapshotID)
1196+
klog.Warningf("Snapshot id does not have the correct format %s: %v", snapshotID, err)
11631197
return &csi.DeleteSnapshotResponse{}, nil
11641198
}
11651199

@@ -1350,7 +1384,7 @@ func (gceCS *GCEControllerServer) getSnapshotByID(ctx context.Context, snapshotI
13501384
return &csi.ListSnapshotsResponse{}, nil
13511385
}
13521386
}
1353-
e, err := generateImageEntry(image)
1387+
e, err := generateDiskImageEntry(image)
13541388
if err != nil {
13551389
return nil, fmt.Errorf("failed to generate image entry: %w", err)
13561390
}
@@ -1372,6 +1406,15 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13721406
return nil, fmt.Errorf("Failed to covert creation timestamp: %w", err)
13731407
}
13741408

1409+
snapshotId, err := getResourceId(snapshot.SelfLink)
1410+
if err != nil {
1411+
return nil, fmt.Errorf("failed to get snapshot id from %s: %w", snapshot.SelfLink, err)
1412+
}
1413+
sourceId, err := getResourceId(snapshot.SourceDisk)
1414+
if err != nil {
1415+
return nil, fmt.Errorf("failed to get source id from %s: %w", snapshot.SourceDisk, err)
1416+
}
1417+
13751418
// We ignore the error intentionally here since we are just listing snapshots
13761419
// TODO: If the snapshot is in "FAILED" state we need to think through what this
13771420
// should actually look like.
@@ -1380,8 +1423,8 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13801423
entry := &csi.ListSnapshotsResponse_Entry{
13811424
Snapshot: &csi.Snapshot{
13821425
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
1383-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1384-
SourceVolumeId: cleanSelfLink(snapshot.SourceDisk),
1426+
SnapshotId: snapshotId,
1427+
SourceVolumeId: sourceId,
13851428
CreationTime: tp,
13861429
ReadyToUse: ready,
13871430
},
@@ -1397,35 +1440,23 @@ func generateDiskImageEntry(image *compute.Image) (*csi.ListSnapshotsResponse_En
13971440
return nil, fmt.Errorf("failed to covert creation timestamp: %w", err)
13981441
}
13991442

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

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

14231454
entry := &csi.ListSnapshotsResponse_Entry{
14241455
Snapshot: &csi.Snapshot{
14251456
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1426-
SnapshotId: cleanSelfLink(image.SelfLink),
1427-
SourceVolumeId: cleanSelfLink(image.SourceDisk),
1428-
CreationTime: timestamp,
1457+
SnapshotId: imageId,
1458+
SourceVolumeId: sourceId,
1459+
CreationTime: tp,
14291460
ReadyToUse: ready,
14301461
},
14311462
}
@@ -1691,7 +1722,12 @@ func extractVolumeContext(context map[string]string) (*PDCSIContext, error) {
16911722
return info, nil
16921723
}
16931724

1694-
func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params common.DiskParameters) *csi.CreateVolumeResponse {
1725+
func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params common.DiskParameters) (*csi.CreateVolumeResponse, error) {
1726+
volumeId, err := getResourceId(disk.GetSelfLink())
1727+
if err != nil {
1728+
return nil, fmt.Errorf("cannot get volume id from %s: %w", disk.GetSelfLink(), err)
1729+
}
1730+
16951731
tops := []*csi.Topology{}
16961732
for _, zone := range zones {
16971733
tops = append(tops, &csi.Topology{
@@ -1702,7 +1738,7 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params co
17021738
createResp := &csi.CreateVolumeResponse{
17031739
Volume: &csi.Volume{
17041740
CapacityBytes: realDiskSizeBytes,
1705-
VolumeId: cleanSelfLink(disk.GetSelfLink()),
1741+
VolumeId: volumeId,
17061742
VolumeContext: paramsToVolumeContext(params),
17071743
AccessibleTopology: tops,
17081744
},
@@ -1741,12 +1777,36 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params co
17411777
}
17421778
createResp.Volume.ContentSource = contentSource
17431779
}
1744-
return createResp
1780+
return createResp, nil
17451781
}
17461782

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

17521812
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)