@@ -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