Skip to content

Commit 74d094f

Browse files
authored
Merge pull request #1308 from mattcary/getresource-1.9
Cherry-pick #1304 to release-1.9
2 parents 96741d1 + f2cfc81 commit 74d094f

File tree

3 files changed

+201
-61
lines changed

3 files changed

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

+103-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"
@@ -130,6 +130,17 @@ const (
130130
// but 500 is a good proxy (gives ~8KB of data per ListVolumesResponse#Entry)
131131
// See https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/grpc_types.h#L503)
132132
maxListVolumesResponseEntries = 500
133+
134+
// Keys in the volume context.
135+
contextForceAttach = "force-attach"
136+
137+
resourceApiScheme = "https"
138+
resourceApiService = "compute"
139+
resourceProject = "projects"
140+
)
141+
142+
var (
143+
validResourceApiVersions = map[string]bool{"v1": true, "alpha": true, "beta": true}
133144
)
134145

135146
func isDiskReady(disk *gce.CloudDisk) (bool, error) {
@@ -306,7 +317,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
306317

307318
// If there is no validation error, immediately return success
308319
klog.V(4).Infof("CreateVolume succeeded for disk %v, it already exists and was compatible", volKey)
309-
return generateCreateVolumeResponse(existingDisk, zones), nil
320+
return generateCreateVolumeResponse(existingDisk, zones)
310321
}
311322

312323
snapshotID := ""
@@ -421,7 +432,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
421432
}
422433

423434
klog.V(4).Infof("CreateVolume succeeded for disk %v", volKey)
424-
return generateCreateVolumeResponse(disk, zones), nil
435+
return generateCreateVolumeResponse(disk, zones)
425436

426437
}
427438

@@ -856,13 +867,23 @@ func (gceCS *GCEControllerServer) ListVolumes(ctx context.Context, req *csi.List
856867
entries := []*csi.ListVolumesResponse_Entry{}
857868
for i := 0; i+offset < len(gceCS.disks) && i < maxEntries; i++ {
858869
d := gceCS.disks[i+offset]
870+
diskRsrc, err := getResourceId(d.SelfLink)
871+
if err != nil {
872+
klog.Warningf("Bad ListVolumes disk resource %s, skipped: %v (%+v)", d.SelfLink, err, d)
873+
continue
874+
}
859875
users := []string{}
860876
for _, u := range d.Users {
861-
users = append(users, cleanSelfLink(u))
877+
rsrc, err := getResourceId(u)
878+
if err != nil {
879+
klog.Warningf("Bad ListVolumes user %s, skipped: %v", u, err)
880+
} else {
881+
users = append(users, rsrc)
882+
}
862883
}
863884
entries = append(entries, &csi.ListVolumesResponse_Entry{
864885
Volume: &csi.Volume{
865-
VolumeId: cleanSelfLink(d.SelfLink),
886+
VolumeId: diskRsrc,
866887
},
867888
Status: &csi.ListVolumesResponse_VolumeStatus{
868889
PublishedNodeIds: users,
@@ -975,6 +996,10 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
975996
return nil, common.LoggedError("Failed to create snapshot: ", err)
976997
}
977998
}
999+
snapshotId, err := getResourceId(snapshot.SelfLink)
1000+
if err != nil {
1001+
return nil, common.LoggedError(fmt.Sprintf("Cannot extract resource id from snapshot %s", snapshot.SelfLink), err)
1002+
}
9781003

9791004
err = gceCS.validateExistingSnapshot(snapshot, volKey)
9801005
if err != nil {
@@ -993,7 +1018,7 @@ func (gceCS *GCEControllerServer) createPDSnapshot(ctx context.Context, project
9931018

9941019
return &csi.Snapshot{
9951020
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
996-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1021+
SnapshotId: snapshotId,
9971022
SourceVolumeId: volumeID,
9981023
CreationTime: timestamp,
9991024
ReadyToUse: ready,
@@ -1022,6 +1047,10 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10221047
return nil, common.LoggedError("Failed to create image: ", err)
10231048
}
10241049
}
1050+
imageId, err := getResourceId(image.SelfLink)
1051+
if err != nil {
1052+
return nil, common.LoggedError(fmt.Sprintf("Cannot extract resource id from snapshot %s", image.SelfLink), err)
1053+
}
10251054

10261055
err = gceCS.validateExistingImage(image, volKey)
10271056
if err != nil {
@@ -1040,7 +1069,7 @@ func (gceCS *GCEControllerServer) createImage(ctx context.Context, project strin
10401069

10411070
return &csi.Snapshot{
10421071
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1043-
SnapshotId: cleanSelfLink(image.SelfLink),
1072+
SnapshotId: imageId,
10441073
SourceVolumeId: volumeID,
10451074
CreationTime: timestamp,
10461075
ReadyToUse: ready,
@@ -1052,9 +1081,13 @@ func (gceCS *GCEControllerServer) validateExistingImage(image *compute.Image, vo
10521081
return fmt.Errorf("disk does not exist")
10531082
}
10541083

1055-
_, sourceKey, err := common.VolumeIDToKey(cleanSelfLink(image.SourceDisk))
1084+
sourceId, err := getResourceId(image.SourceDisk)
10561085
if err != nil {
1057-
return fmt.Errorf("fail to get source disk key %s, %w", image.SourceDisk, err)
1086+
return fmt.Errorf("failed to get source id from %s: %w", image.SourceDisk, err)
1087+
}
1088+
_, sourceKey, err := common.VolumeIDToKey(sourceId)
1089+
if err != nil {
1090+
return fmt.Errorf("failed to get source disk key %s: %w", image.SourceDisk, err)
10581091
}
10591092

10601093
if sourceKey.String() != volKey.String() {
@@ -1103,7 +1136,11 @@ func (gceCS *GCEControllerServer) validateExistingSnapshot(snapshot *compute.Sna
11031136
return fmt.Errorf("disk does not exist")
11041137
}
11051138

1106-
_, sourceKey, err := common.VolumeIDToKey(cleanSelfLink(snapshot.SourceDisk))
1139+
sourceId, err := getResourceId(snapshot.SourceDisk)
1140+
if err != nil {
1141+
return fmt.Errorf("failed to get source id from %s: %w", snapshot.SourceDisk, err)
1142+
}
1143+
_, sourceKey, err := common.VolumeIDToKey(sourceId)
11071144
if err != nil {
11081145
return fmt.Errorf("fail to get source disk key %s, %w", snapshot.SourceDisk, err)
11091146
}
@@ -1146,7 +1183,7 @@ func (gceCS *GCEControllerServer) DeleteSnapshot(ctx context.Context, req *csi.D
11461183
if err != nil {
11471184
// Cannot get snapshot ID from the passing request
11481185
// This is a success according to the spec
1149-
klog.Warningf("Snapshot id does not have the correct format %s", snapshotID)
1186+
klog.Warningf("Snapshot id does not have the correct format %s: %v", snapshotID, err)
11501187
return &csi.DeleteSnapshotResponse{}, nil
11511188
}
11521189

@@ -1337,7 +1374,7 @@ func (gceCS *GCEControllerServer) getSnapshotByID(ctx context.Context, snapshotI
13371374
return &csi.ListSnapshotsResponse{}, nil
13381375
}
13391376
}
1340-
e, err := generateImageEntry(image)
1377+
e, err := generateDiskImageEntry(image)
13411378
if err != nil {
13421379
return nil, fmt.Errorf("failed to generate image entry: %w", err)
13431380
}
@@ -1359,6 +1396,15 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13591396
return nil, fmt.Errorf("Failed to covert creation timestamp: %w", err)
13601397
}
13611398

1399+
snapshotId, err := getResourceId(snapshot.SelfLink)
1400+
if err != nil {
1401+
return nil, fmt.Errorf("failed to get snapshot id from %s: %w", snapshot.SelfLink, err)
1402+
}
1403+
sourceId, err := getResourceId(snapshot.SourceDisk)
1404+
if err != nil {
1405+
return nil, fmt.Errorf("failed to get source id from %s: %w", snapshot.SourceDisk, err)
1406+
}
1407+
13621408
// We ignore the error intentionally here since we are just listing snapshots
13631409
// TODO: If the snapshot is in "FAILED" state we need to think through what this
13641410
// should actually look like.
@@ -1367,8 +1413,8 @@ func generateDiskSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsRe
13671413
entry := &csi.ListSnapshotsResponse_Entry{
13681414
Snapshot: &csi.Snapshot{
13691415
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
1370-
SnapshotId: cleanSelfLink(snapshot.SelfLink),
1371-
SourceVolumeId: cleanSelfLink(snapshot.SourceDisk),
1416+
SnapshotId: snapshotId,
1417+
SourceVolumeId: sourceId,
13721418
CreationTime: tp,
13731419
ReadyToUse: ready,
13741420
},
@@ -1384,35 +1430,23 @@ func generateDiskImageEntry(image *compute.Image) (*csi.ListSnapshotsResponse_En
13841430
return nil, fmt.Errorf("failed to covert creation timestamp: %w", err)
13851431
}
13861432

1387-
ready, _ := isImageReady(image.Status)
1388-
1389-
entry := &csi.ListSnapshotsResponse_Entry{
1390-
Snapshot: &csi.Snapshot{
1391-
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1392-
SnapshotId: cleanSelfLink(image.SelfLink),
1393-
SourceVolumeId: cleanSelfLink(image.SourceDisk),
1394-
CreationTime: tp,
1395-
ReadyToUse: ready,
1396-
},
1433+
imageId, err := getResourceId(image.SelfLink)
1434+
if err != nil {
1435+
return nil, fmt.Errorf("cannot get image id from %s: %w", image.SelfLink, err)
13971436
}
1398-
return entry, nil
1399-
}
1400-
1401-
func generateImageEntry(image *compute.Image) (*csi.ListSnapshotsResponse_Entry, error) {
1402-
timestamp, err := parseTimestamp(image.CreationTimestamp)
1437+
sourceId, err := getResourceId(image.SourceDisk)
14031438
if err != nil {
1404-
return nil, fmt.Errorf("Failed to covert creation timestamp: %w", err)
1439+
return nil, fmt.Errorf("cannot get source id from %s: %w", image.SourceDisk, err)
14051440
}
14061441

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

14101444
entry := &csi.ListSnapshotsResponse_Entry{
14111445
Snapshot: &csi.Snapshot{
14121446
SizeBytes: common.GbToBytes(image.DiskSizeGb),
1413-
SnapshotId: cleanSelfLink(image.SelfLink),
1414-
SourceVolumeId: cleanSelfLink(image.SourceDisk),
1415-
CreationTime: timestamp,
1447+
SnapshotId: imageId,
1448+
SourceVolumeId: sourceId,
1449+
CreationTime: tp,
14161450
ReadyToUse: ready,
14171451
},
14181452
}
@@ -1650,7 +1684,12 @@ func getDefaultZonesInRegion(ctx context.Context, gceCS *GCEControllerServer, ex
16501684
return ret, nil
16511685
}
16521686

1653-
func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string) *csi.CreateVolumeResponse {
1687+
func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string) (*csi.CreateVolumeResponse, error) {
1688+
volumeId, err := getResourceId(disk.GetSelfLink())
1689+
if err != nil {
1690+
return nil, fmt.Errorf("cannot get volume id from %s: %w", disk.GetSelfLink(), err)
1691+
}
1692+
16541693
tops := []*csi.Topology{}
16551694
for _, zone := range zones {
16561695
tops = append(tops, &csi.Topology{
@@ -1661,7 +1700,7 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string) *csi.Crea
16611700
createResp := &csi.CreateVolumeResponse{
16621701
Volume: &csi.Volume{
16631702
CapacityBytes: realDiskSizeBytes,
1664-
VolumeId: cleanSelfLink(disk.GetSelfLink()),
1703+
VolumeId: volumeId,
16651704
VolumeContext: nil,
16661705
AccessibleTopology: tops,
16671706
},
@@ -1700,12 +1739,36 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, zones []string) *csi.Crea
17001739
}
17011740
createResp.Volume.ContentSource = contentSource
17021741
}
1703-
return createResp
1742+
return createResp, nil
17041743
}
17051744

1706-
func cleanSelfLink(selfLink string) string {
1707-
r, _ := regexp.Compile("https:\\/\\/www.*apis.com\\/.*(v1|beta|alpha)\\/")
1708-
return r.ReplaceAllString(selfLink, "")
1745+
func getResourceId(resourceLink string) (string, error) {
1746+
url, err := neturl.Parse(resourceLink)
1747+
if err != nil {
1748+
return "", fmt.Errorf("Could not parse resource %s: %w", resourceLink, err)
1749+
}
1750+
if url.Scheme != resourceApiScheme {
1751+
return "", fmt.Errorf("Unexpected API scheme for resource %s", resourceLink)
1752+
}
1753+
1754+
// Note that the resource host can basically be anything, if we are running in
1755+
// a distributed cloud or trusted partner environment.
1756+
1757+
// The path should be /compute/VERSION/project/....
1758+
elts := strings.Split(url.Path, "/")
1759+
if len(elts) < 4 {
1760+
return "", fmt.Errorf("Short resource path %s", resourceLink)
1761+
}
1762+
if elts[1] != resourceApiService {
1763+
return "", fmt.Errorf("Bad resource service %s in %s", elts[1], resourceLink)
1764+
}
1765+
if _, ok := validResourceApiVersions[elts[2]]; !ok {
1766+
return "", fmt.Errorf("Bad version %s in %s", elts[2], resourceLink)
1767+
}
1768+
if elts[3] != resourceProject {
1769+
return "", fmt.Errorf("Expected %v to start with %s in resource %s", elts[3:], resourceProject, resourceLink)
1770+
}
1771+
return strings.Join(elts[3:], "/"), nil
17091772
}
17101773

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