Skip to content

Commit fc6d4ba

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

File tree

3 files changed

+176
-58
lines changed

3 files changed

+176
-58
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-39
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"errors"
2020
"fmt"
2121
"math/rand"
22+
neturl "net/url"
2223
"regexp"
2324
"sort"
2425
"strings"
@@ -138,6 +139,15 @@ const (
138139

139140
// Keys in the volume context.
140141
contextForceAttach = "force-attach"
142+
143+
resourceApiScheme = "https"
144+
resourceApiService = "compute"
145+
resourceProject = "projects"
146+
)
147+
148+
var (
149+
resourceApiHost = regexp.MustCompile("^www.*apis.com$")
150+
validResourceApiVersions = map[string]bool{"v1": true, "alpha": true, "beta": true}
141151
)
142152

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

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

325335
snapshotID := ""
@@ -434,7 +444,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
434444
}
435445

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

439449
}
440450

@@ -869,13 +879,23 @@ func (gceCS *GCEControllerServer) ListVolumes(ctx context.Context, req *csi.List
869879
entries := []*csi.ListVolumesResponse_Entry{}
870880
for i := 0; i+offset < len(gceCS.disks) && i < maxEntries; i++ {
871881
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+
}
872887
users := []string{}
873888
for _, u := range d.Users {
874-
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+
}
875895
}
876896
entries = append(entries, &csi.ListVolumesResponse_Entry{
877897
Volume: &csi.Volume{
878-
VolumeId: cleanSelfLink(d.SelfLink),
898+
VolumeId: diskRsrc,
879899
},
880900
Status: &csi.ListVolumesResponse_VolumeStatus{
881901
PublishedNodeIds: users,
@@ -988,6 +1008,10 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
9881008
return nil, common.LoggedError("Failed to create snapshot: ", err)
9891009
}
9901010
}
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+
}
9911015

9921016
err = gceCS.validateExistingSnapshot(snapshot, volKey)
9931017
if err != nil {
@@ -1006,7 +1030,7 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
10061030

10071031
return &csi.Snapshot{
10081032
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
1009-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1033+
SnapshotId: snapshotId,
10101034
SourceVolumeId: volumeID,
10111035
CreationTime: timestamp,
10121036
ReadyToUse: ready,
@@ -1035,6 +1059,10 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10351059
return nil, common.LoggedError("Failed to create image: ", err)
10361060
}
10371061
}
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+
}
10381066

10391067
err = gceCS.validateExistingImage(image, volKey)
10401068
if err != nil {
@@ -1053,7 +1081,7 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10531081

10541082
return &csi.Snapshot{
10551083
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1056-
SnapshotId: cleanSelfLink(image.SelfLink),
1084+
SnapshotId: imageId,
10571085
SourceVolumeId: volumeID,
10581086
CreationTime: timestamp,
10591087
ReadyToUse: ready,
@@ -1065,9 +1093,13 @@ func (gceCS *GCEControllerServer) validateExistingImage(image *compute.Image, vo
10651093
return fmt.Errorf("disk does not exist")
10661094
}
10671095

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

10731105
if sourceKey.String() != volKey.String() {
@@ -1116,7 +1148,11 @@ func (gceCS *GCEControllerServer) validateExistingSnapshot(snapshot *compute.Sna
11161148
return fmt.Errorf("disk does not exist")
11171149
}
11181150

1119-
_, 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)
11201156
if err != nil {
11211157
return fmt.Errorf("fail to get source disk key %s, %w", snapshot.SourceDisk, err)
11221158
}
@@ -1159,7 +1195,7 @@ func (gceCS *GCEControllerServer) DeleteSnapshot(ctx context.Context, req *csi.D
11591195
if err != nil {
11601196
// Cannot get snapshot ID from the passing request
11611197
// This is a success according to the spec
1162-
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)
11631199
return &csi.DeleteSnapshotResponse{}, nil
11641200
}
11651201

@@ -1350,7 +1386,7 @@ func (gceCS *GCEControllerServer) getSnapshotByID(ctx context.Context, snapshotI
13501386
return &csi.ListSnapshotsResponse{}, nil
13511387
}
13521388
}
1353-
e, err := generateImageEntry(image)
1389+
e, err := generateDiskImageEntry(image)
13541390
if err != nil {
13551391
return nil, fmt.Errorf("failed to generate image entry: %w", err)
13561392
}
@@ -1372,6 +1408,15 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13721408
return nil, fmt.Errorf("Failed to covert creation timestamp: %w", err)
13731409
}
13741410

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+
13751420
// We ignore the error intentionally here since we are just listing snapshots
13761421
// TODO: If the snapshot is in "FAILED" state we need to think through what this
13771422
// should actually look like.
@@ -1380,8 +1425,8 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13801425
entry := &csi.ListSnapshotsResponse_Entry{
13811426
Snapshot: &csi.Snapshot{
13821427
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
1383-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1384-
SourceVolumeId: cleanSelfLink(snapshot.SourceDisk),
1428+
SnapshotId: snapshotId,
1429+
SourceVolumeId: sourceId,
13851430
CreationTime: tp,
13861431
ReadyToUse: ready,
13871432
},
@@ -1397,35 +1442,23 @@ func generateDiskImageEntry(image *compute.Image) (*csi.ListSnapshotsResponse_En
13971442
return nil, fmt.Errorf("failed to covert creation timestamp: %w", err)
13981443
}
13991444

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-
},
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)
14101448
}
1411-
return entry, nil
1412-
}
1413-
1414-
func generateImageEntry(image *compute.Image) (*csi.ListSnapshotsResponse_Entry, error) {
1415-
timestamp, err := parseTimestamp(image.CreationTimestamp)
1449+
sourceId, err := getResourceId(image.SourceDisk)
14161450
if err != nil {
1417-
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)
14181452
}
14191453

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

14231456
entry := &csi.ListSnapshotsResponse_Entry{
14241457
Snapshot: &csi.Snapshot{
14251458
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1426-
SnapshotId: cleanSelfLink(image.SelfLink),
1427-
SourceVolumeId: cleanSelfLink(image.SourceDisk),
1428-
CreationTime: timestamp,
1459+
SnapshotId: imageId,
1460+
SourceVolumeId: sourceId,
1461+
CreationTime: tp,
14291462
ReadyToUse: ready,
14301463
},
14311464
}
@@ -1691,7 +1724,12 @@ func extractVolumeContext(context map[string]string) (*PDCSIContext, error) {
16911724
return info, nil
16921725
}
16931726

1694-
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+
16951733
tops := []*csi.Topology{}
16961734
for _, zone := range zones {
16971735
tops = append(tops, &csi.Topology{
@@ -1702,7 +1740,7 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params co
17021740
createResp := &csi.CreateVolumeResponse{
17031741
Volume: &csi.Volume{
17041742
CapacityBytes: realDiskSizeBytes,
1705-
VolumeId: cleanSelfLink(disk.GetSelfLink()),
1743+
VolumeId: volumeId,
17061744
VolumeContext: paramsToVolumeContext(params),
17071745
AccessibleTopology: tops,
17081746
},
@@ -1741,12 +1779,35 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string, params co
17411779
}
17421780
createResp.Volume.ContentSource = contentSource
17431781
}
1744-
return createResp
1782+
return createResp, nil
17451783
}
17461784

1747-
func cleanSelfLink(selfLink string) string {
1748-
r, _ := regexp.Compile("https:\\/\\/www.*apis.com\\/.*(v1|beta|alpha)\\/")
1749-
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+
if !resourceApiHost.MatchString(url.Host) {
1794+
return "", fmt.Errorf("Unexpected API host for resource %s", resourceLink)
1795+
}
1796+
// The path should be /compute/VERSION/project/....
1797+
elts := strings.Split(url.Path, "/")
1798+
if len(elts) < 4 {
1799+
return "", fmt.Errorf("Short resource path %s", resourceLink)
1800+
}
1801+
if elts[1] != resourceApiService {
1802+
return "", fmt.Errorf("Bad resource service %s in %s", elts[1], resourceLink)
1803+
}
1804+
if _, ok := validResourceApiVersions[elts[2]]; !ok {
1805+
return "", fmt.Errorf("Bad version %s in %s", elts[2], resourceLink)
1806+
}
1807+
if elts[3] != resourceProject {
1808+
return "", fmt.Errorf("Expected %v to start with %s in resource %s", elts[3:], resourceProject, resourceLink)
1809+
}
1810+
return strings.Join(elts[3:], "/"), nil
17501811
}
17511812

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