@@ -34,16 +34,18 @@ import (
3434const (
3535 operationStatusDone = "DONE"
3636 waitForSnapshotCreationTimeOut = 2 * time .Minute
37+ diskKind = "compute#disk"
3738)
3839
3940type GCECompute interface {
4041 // Disk Methods
4142 GetDisk (ctx context.Context , volumeKey * meta.Key ) (* CloudDisk , error )
43+ RepairUnderspecifiedVolumeKey (ctx context.Context , volumeKey * meta.Key ) (* meta.Key , error )
4244 ValidateExistingDisk (ctx context.Context , disk * CloudDisk , diskType string , reqBytes , limBytes int64 ) error
4345 InsertDisk (ctx context.Context , volKey * meta.Key , diskType string , capBytes int64 , capacityRange * csi.CapacityRange , replicaZones []string ) error
4446 DeleteDisk (ctx context.Context , volumeKey * meta.Key ) error
45- AttachDisk (ctx context.Context , disk * CloudDisk , volKey * meta.Key , readWrite , diskType , instanceZone , instanceName string ) error
46- DetachDisk (ctx context.Context , volKey * meta. Key , instanceZone , instanceName string ) error
47+ AttachDisk (ctx context.Context , volKey * meta.Key , readWrite , diskType , instanceZone , instanceName string ) error
48+ DetachDisk (ctx context.Context , deviceName string , instanceZone , instanceName string ) error
4749 GetDiskSourceURI (volKey * meta.Key ) string
4850 GetDiskTypeURI (volKey * meta.Key , diskType string ) string
4951 WaitForAttach (ctx context.Context , volKey * meta.Key , instanceZone , instanceName string ) error
@@ -59,7 +61,46 @@ type GCECompute interface {
5961 DeleteSnapshot (ctx context.Context , snapshotName string ) error
6062}
6163
64+ // RepairUnderspecifiedVolumeKey will query the cloud provider and check each zone for the disk specified
65+ // by the volume key and return a volume key with a correct zone
66+ func (cloud * CloudProvider ) RepairUnderspecifiedVolumeKey (ctx context.Context , volumeKey * meta.Key ) (* meta.Key , error ) {
67+ region , err := common .GetRegionFromZones ([]string {cloud .zone })
68+ if err != nil {
69+ return nil , fmt .Errorf ("failed to get region from zones: %v" , err )
70+ }
71+ switch volumeKey .Type () {
72+ case meta .Zonal :
73+ if volumeKey .Zone == common .UnspecifiedValue {
74+ // list all zones, try to get disk in each zone
75+ zones , err := cloud .ListZones (ctx , region )
76+ if err != nil {
77+ return nil , err
78+ }
79+ for _ , zone := range zones {
80+ _ , err := cloud .getZonalDiskOrError (ctx , zone , volumeKey .Name )
81+ if err == nil {
82+ // If there is no error we have found a disk
83+ volumeKey .Zone = zone
84+ return volumeKey , nil
85+ }
86+ }
87+ return nil , fmt .Errorf ("volume zone unspecified and unable to find in any of these zones %v" , zones )
88+ }
89+ return volumeKey , nil
90+ case meta .Regional :
91+ if volumeKey .Region == common .UnspecifiedValue {
92+ volumeKey .Region = region
93+ }
94+ return volumeKey , nil
95+ default :
96+ return nil , fmt .Errorf ("key was neither zonal nor regional, got: %v" , volumeKey .String ())
97+ }
98+ }
99+
62100func (cloud * CloudProvider ) ListZones (ctx context.Context , region string ) ([]string , error ) {
101+ if len (cloud .zonesCache [region ]) > 0 {
102+ return cloud .zonesCache [region ], nil
103+ }
63104 zones := []string {}
64105 zoneList , err := cloud .service .Zones .List (cloud .project ).Filter (fmt .Sprintf ("region eq .*%s$" , region )).Do ()
65106 if err != nil {
@@ -68,6 +109,7 @@ func (cloud *CloudProvider) ListZones(ctx context.Context, region string) ([]str
68109 for _ , zone := range zoneList .Items {
69110 zones = append (zones , zone .Name )
70111 }
112+ cloud .zonesCache [region ] = zones
71113 return zones , nil
72114
73115}
@@ -315,7 +357,7 @@ func (cloud *CloudProvider) deleteRegionalDisk(ctx context.Context, region, name
315357 return nil
316358}
317359
318- func (cloud * CloudProvider ) AttachDisk (ctx context.Context , disk * CloudDisk , volKey * meta.Key , readWrite , diskType , instanceZone , instanceName string ) error {
360+ func (cloud * CloudProvider ) AttachDisk (ctx context.Context , volKey * meta.Key , readWrite , diskType , instanceZone , instanceName string ) error {
319361 source := cloud .GetDiskSourceURI (volKey )
320362
321363 deviceName , err := common .GetDeviceName (volKey )
@@ -324,7 +366,7 @@ func (cloud *CloudProvider) AttachDisk(ctx context.Context, disk *CloudDisk, vol
324366 }
325367 attachedDiskV1 := & compute.AttachedDisk {
326368 DeviceName : deviceName ,
327- Kind : disk . GetKind () ,
369+ Kind : diskKind ,
328370 Mode : readWrite ,
329371 Source : source ,
330372 Type : diskType ,
@@ -341,12 +383,7 @@ func (cloud *CloudProvider) AttachDisk(ctx context.Context, disk *CloudDisk, vol
341383 return nil
342384}
343385
344- func (cloud * CloudProvider ) DetachDisk (ctx context.Context , volKey * meta.Key , instanceZone , instanceName string ) error {
345- deviceName , err := common .GetDeviceName (volKey )
346- if err != nil {
347- return err
348- }
349-
386+ func (cloud * CloudProvider ) DetachDisk (ctx context.Context , deviceName , instanceZone , instanceName string ) error {
350387 op , err := cloud .service .Instances .DetachDisk (cloud .project , instanceZone , instanceName , deviceName ).Context (ctx ).Do ()
351388 if err != nil {
352389 return err
0 commit comments