@@ -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)
4545
@@ -99,7 +99,7 @@ type GCECompute interface {
9999 GetDefaultZone () string
100100 // Disk Methods
101101 GetDisk (ctx context.Context , project string , volumeKey * meta.Key ) (* CloudDisk , error )
102- RepairUnderspecifiedVolumeKey (ctx context.Context , project string , volumeKey * meta.Key ) (string , * meta.Key , error )
102+ RepairUnderspecifiedVolumeKey (ctx context.Context , project string , volumeKey * meta.Key , fallbackZone string ) (string , * meta.Key , error )
103103 InsertDisk (ctx context.Context , project string , volKey * meta.Key , params common.DiskParameters , capBytes int64 , capacityRange * csi.CapacityRange , replicaZones []string , snapshotID string , volumeContentSourceVolumeID string , multiWriter bool , accessMode string ) error
104104 DeleteDisk (ctx context.Context , project string , volumeKey * meta.Key ) error
105105 UpdateDisk (ctx context.Context , project string , volKey * meta.Key , existingDisk * CloudDisk , params common.ModifyVolumeParameters ) error
@@ -290,26 +290,30 @@ func (cloud *CloudProvider) listInstancesForProject(service *computev1.Service,
290290
291291// RepairUnderspecifiedVolumeKey will query the cloud provider and check each zone for the disk specified
292292// by the volume key and return a volume key with a correct zone
293- func (cloud * CloudProvider ) RepairUnderspecifiedVolumeKey (ctx context.Context , project string , volumeKey * meta.Key ) (string , * meta.Key , error ) {
293+ func (cloud * CloudProvider ) RepairUnderspecifiedVolumeKey (ctx context.Context , project string , volumeKey * meta.Key , fallbackZone string ) (string , * meta.Key , error ) {
294+ return repairUnderspecifiedVolumeKeyWithProvider (ctx , cloud , project , volumeKey , fallbackZone )
295+ }
296+
297+ func repairUnderspecifiedVolumeKeyWithProvider (ctx context.Context , cloud GCECompute , project string , volumeKey * meta.Key , fallbackZone string ) (string , * meta.Key , error ) {
294298 klog .V (5 ).Infof ("Repairing potentially underspecified volume key %v" , volumeKey )
295299 if project == common .UnspecifiedValue {
296- project = cloud .project
300+ project = cloud .GetDefaultProject ()
297301 }
298- region , err := common .GetRegionFromZones ([]string {cloud .zone })
302+ region , err := common .GetRegionFromZones ([]string {cloud .GetDefaultZone () })
299303 if err != nil {
300304 return "" , nil , fmt .Errorf ("failed to get region from zones: %w" , err )
301305 }
302306 switch volumeKey .Type () {
303307 case meta .Zonal :
304- foundZone := ""
305308 if volumeKey .Zone == common .UnspecifiedValue {
306309 // list all zones, try to get disk in each zone
307310 zones , err := cloud .ListZones (ctx , region )
308311 if err != nil {
309312 return "" , nil , err
310313 }
314+ diskZones := []string {}
311315 for _ , zone := range zones {
312- _ , err := cloud .getZonalDiskOrError (ctx , project , zone , volumeKey .Name )
316+ _ , err := cloud .GetDisk (ctx , project , & meta. Key { Name : volumeKey .Name , Zone : zone } )
313317 if err != nil {
314318 if IsGCENotFoundError (err ) {
315319 // Couldn't find the disk in this zone so we keep
@@ -320,16 +324,22 @@ func (cloud *CloudProvider) RepairUnderspecifiedVolumeKey(ctx context.Context, p
320324 // so we return error immediately
321325 return "" , nil , err
322326 }
323- if len (foundZone ) > 0 {
324- return "" , nil , fmt .Errorf ("found disk %s in more than one zone: %s and %s" , volumeKey .Name , foundZone , zone )
325- }
326- foundZone = zone
327+ diskZones = append (diskZones , zone )
327328 }
328329
329- if len (foundZone ) == 0 {
330+ if len (diskZones ) == 0 {
330331 return "" , nil , notFoundError ()
332+ } else if len (diskZones ) > 1 && fallbackZone == "" {
333+ return "" , nil , fmt .Errorf ("found disk %s in more than one zone and no fallback: %v" , volumeKey .Name , diskZones )
334+ } else if len (diskZones ) > 1 && fallbackZone != "" {
335+ if ! slices .Contains (diskZones , fallbackZone ) {
336+ return "" , nil , fmt .Errorf ("found disk %s in more than one zone (%v) but none match fallback zone %s" , volumeKey .Name , diskZones , fallbackZone )
337+ }
338+ volumeKey .Zone = fallbackZone
339+ } else {
340+ volumeKey .Zone = diskZones [0 ]
331341 }
332- volumeKey . Zone = foundZone
342+
333343 return project , volumeKey , nil
334344 }
335345 return project , volumeKey , nil
@@ -392,22 +402,6 @@ func (cloud *CloudProvider) GetDisk(ctx context.Context, project string, key *me
392402 }
393403}
394404
395- func (cloud * CloudProvider ) getZonalDiskOrError (ctx context.Context , project , volumeZone , volumeName string ) (* computev1.Disk , error ) {
396- disk , err := cloud .service .Disks .Get (project , volumeZone , volumeName ).Context (ctx ).Do ()
397- if err != nil {
398- return nil , err
399- }
400- return disk , nil
401- }
402-
403- func (cloud * CloudProvider ) getRegionalDiskOrError (ctx context.Context , project , volumeRegion , volumeName string ) (* computev1.Disk , error ) {
404- disk , err := cloud .service .RegionDisks .Get (project , volumeRegion , volumeName ).Context (ctx ).Do ()
405- if err != nil {
406- return nil , err
407- }
408- return disk , nil
409- }
410-
411405func (cloud * CloudProvider ) getZonalBetaDiskOrError (ctx context.Context , project , volumeZone , volumeName string ) (* computebeta.Disk , error ) {
412406 disk , err := cloud .betaService .Disks .Get (project , volumeZone , volumeName ).Context (ctx ).Do ()
413407 if err != nil {
0 commit comments