@@ -21,6 +21,7 @@ import (
2121	"fmt" 
2222	"net/http" 
2323	"regexp" 
24+ 	"slices" 
2425	"strings" 
2526	"time" 
2627
@@ -39,7 +40,6 @@ import (
3940	"google.golang.org/grpc/status" 
4041	"k8s.io/apimachinery/pkg/util/wait" 
4142	"k8s.io/klog/v2" 
42- 	"k8s.io/utils/strings/slices" 
4343	"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/common" 
4444	"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/constants" 
4545	"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/parameters" 
@@ -101,7 +101,7 @@ type GCECompute interface {
101101	GetDefaultZone () string 
102102	// Disk Methods 
103103	GetDisk (ctx  context.Context , project  string , volumeKey  * meta.Key ) (* CloudDisk , error )
104- 	RepairUnderspecifiedVolumeKey (ctx  context.Context , project  string , volumeKey  * meta.Key ) (string , * meta.Key , error )
104+ 	RepairUnderspecifiedVolumeKey (ctx  context.Context , project  string , volumeKey  * meta.Key ,  fallbackZone   string ) (string , * meta.Key , error )
105105	InsertDisk (ctx  context.Context , project  string , volKey  * meta.Key , params  parameters.DiskParameters , capBytes  int64 , capacityRange  * csi.CapacityRange , replicaZones  []string , snapshotID  string , volumeContentSourceVolumeID  string , multiWriter  bool , accessMode  string ) error 
106106	DeleteDisk (ctx  context.Context , project  string , volumeKey  * meta.Key ) error 
107107	UpdateDisk (ctx  context.Context , project  string , volKey  * meta.Key , existingDisk  * CloudDisk , params  parameters.ModifyVolumeParameters ) error 
@@ -292,26 +292,30 @@ func (cloud *CloudProvider) listInstancesForProject(service *computev1.Service,
292292
293293// RepairUnderspecifiedVolumeKey will query the cloud provider and check each zone for the disk specified 
294294// by the volume key and return a volume key with a correct zone 
295- func  (cloud  * CloudProvider ) RepairUnderspecifiedVolumeKey (ctx  context.Context , project  string , volumeKey  * meta.Key ) (string , * meta.Key , error ) {
295+ func  (cloud  * CloudProvider ) RepairUnderspecifiedVolumeKey (ctx  context.Context , project  string , volumeKey  * meta.Key , fallbackZone  string ) (string , * meta.Key , error ) {
296+ 	return  repairUnderspecifiedVolumeKeyWithProvider (ctx , cloud , project , volumeKey , fallbackZone )
297+ }
298+ 
299+ func  repairUnderspecifiedVolumeKeyWithProvider (ctx  context.Context , cloud  GCECompute , project  string , volumeKey  * meta.Key , fallbackZone  string ) (string , * meta.Key , error ) {
296300	klog .V (5 ).Infof ("Repairing potentially underspecified volume key %v" , volumeKey )
297301	if  project  ==  constants .UnspecifiedValue  {
298- 		project  =  cloud .project 
302+ 		project  =  cloud .GetDefaultProject () 
299303	}
300- 	region , err  :=  common .GetRegionFromZones ([]string {cloud .zone })
304+ 	region , err  :=  common .GetRegionFromZones ([]string {cloud .GetDefaultZone () })
301305	if  err  !=  nil  {
302306		return  "" , nil , fmt .Errorf ("failed to get region from zones: %w" , err )
303307	}
304308	switch  volumeKey .Type () {
305309	case  meta .Zonal :
306- 		foundZone  :=  "" 
307310		if  volumeKey .Zone  ==  constants .UnspecifiedValue  {
308311			// list all zones, try to get disk in each zone 
309312			zones , err  :=  cloud .ListZones (ctx , region )
310313			if  err  !=  nil  {
311314				return  "" , nil , err 
312315			}
316+ 			diskZones  :=  []string {}
313317			for  _ , zone  :=  range  zones  {
314- 				_ , err  :=  cloud .getZonalDiskOrError (ctx , project , zone ,  volumeKey .Name )
318+ 				_ , err  :=  cloud .GetDisk (ctx , project , & meta. Key { Name :  volumeKey .Name ,  Zone :  zone } )
315319				if  err  !=  nil  {
316320					if  IsGCENotFoundError (err ) {
317321						// Couldn't find the disk in this zone so we keep 
@@ -322,16 +326,22 @@ func (cloud *CloudProvider) RepairUnderspecifiedVolumeKey(ctx context.Context, p
322326					// so we return error immediately 
323327					return  "" , nil , err 
324328				}
325- 				if  len (foundZone ) >  0  {
326- 					return  "" , nil , fmt .Errorf ("found disk %s in more than one zone: %s and %s" , volumeKey .Name , foundZone , zone )
327- 				}
328- 				foundZone  =  zone 
329+ 				diskZones  =  append (diskZones , zone )
329330			}
330331
331- 			if  len (foundZone ) ==  0  {
332+ 			if  len (diskZones ) ==  0  {
332333				return  "" , nil , notFoundError ()
334+ 			} else  if  len (diskZones ) >  1  &&  fallbackZone  ==  ""  {
335+ 				return  "" , nil , fmt .Errorf ("found disk %s in more than one zone and no fallback: %v" , volumeKey .Name , diskZones )
336+ 			} else  if  len (diskZones ) >  1  &&  fallbackZone  !=  ""  {
337+ 				if  ! slices .Contains (diskZones , fallbackZone ) {
338+ 					return  "" , nil , fmt .Errorf ("found disk %s in more than one zone (%v) but none match fallback zone %s" , volumeKey .Name , diskZones , fallbackZone )
339+ 				}
340+ 				volumeKey .Zone  =  fallbackZone 
341+ 			} else  {
342+ 				volumeKey .Zone  =  diskZones [0 ]
333343			}
334- 			 volumeKey . Zone   =   foundZone 
344+ 
335345			return  project , volumeKey , nil 
336346		}
337347		return  project , volumeKey , nil 
@@ -394,22 +404,6 @@ func (cloud *CloudProvider) GetDisk(ctx context.Context, project string, key *me
394404	}
395405}
396406
397- func  (cloud  * CloudProvider ) getZonalDiskOrError (ctx  context.Context , project , volumeZone , volumeName  string ) (* computev1.Disk , error ) {
398- 	disk , err  :=  cloud .service .Disks .Get (project , volumeZone , volumeName ).Context (ctx ).Do ()
399- 	if  err  !=  nil  {
400- 		return  nil , err 
401- 	}
402- 	return  disk , nil 
403- }
404- 
405- func  (cloud  * CloudProvider ) getRegionalDiskOrError (ctx  context.Context , project , volumeRegion , volumeName  string ) (* computev1.Disk , error ) {
406- 	disk , err  :=  cloud .service .RegionDisks .Get (project , volumeRegion , volumeName ).Context (ctx ).Do ()
407- 	if  err  !=  nil  {
408- 		return  nil , err 
409- 	}
410- 	return  disk , nil 
411- }
412- 
413407func  (cloud  * CloudProvider ) getZonalBetaDiskOrError (ctx  context.Context , project , volumeZone , volumeName  string ) (* computebeta.Disk , error ) {
414408	disk , err  :=  cloud .betaService .Disks .Get (project , volumeZone , volumeName ).Context (ctx ).Do ()
415409	if  err  !=  nil  {
0 commit comments