@@ -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,29 @@ 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+ 				match  :=  false 
338+ 				for  _ , z  :=  range  diskZones  {
339+ 					if  z  ==  fallbackZone  {
340+ 						match  =  true 
341+ 						break 
342+ 					}
343+ 				}
344+ 				if  ! match  {
345+ 					return  "" , nil , fmt .Errorf ("found disk %s in more than one zone (%v) but none match fallback zone %s" , volumeKey .Name , diskZones , fallbackZone )
346+ 				}
347+ 				volumeKey .Zone  =  fallbackZone 
348+ 			} else  {
349+ 				volumeKey .Zone  =  diskZones [0 ]
333350			}
334- 			 volumeKey . Zone   =   foundZone 
351+ 
335352			return  project , volumeKey , nil 
336353		}
337354		return  project , volumeKey , nil 
@@ -394,22 +411,6 @@ func (cloud *CloudProvider) GetDisk(ctx context.Context, project string, key *me
394411	}
395412}
396413
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- 
413414func  (cloud  * CloudProvider ) getZonalBetaDiskOrError (ctx  context.Context , project , volumeZone , volumeName  string ) (* computebeta.Disk , error ) {
414415	disk , err  :=  cloud .betaService .Disks .Get (project , volumeZone , volumeName ).Context (ctx ).Do ()
415416	if  err  !=  nil  {
0 commit comments