diff --git a/CHANGELOG.md b/CHANGELOG.md index 538adecfb..93c4cad89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Prompting for validation before deleting deployments and models (dedicated-inference) - Ability to delete multiple deployments and models at once (dedicated-inference) - Add IPv6 public IP assignment support for SKS Nodepools #774 +- Avoid redundant calls to `list-zones` #775 ## 1.88.0 diff --git a/cmd/compute/blockstorage/blockstorage_list.go b/cmd/compute/blockstorage/blockstorage_list.go index f59125003..47339d373 100644 --- a/cmd/compute/blockstorage/blockstorage_list.go +++ b/cmd/compute/blockstorage/blockstorage_list.go @@ -10,6 +10,7 @@ import ( exocmd "github.com/exoscale/cli/cmd" "github.com/exoscale/cli/pkg/globalstate" "github.com/exoscale/cli/pkg/output" + "github.com/exoscale/cli/utils" v3 "github.com/exoscale/egoscale/v3" ) @@ -54,20 +55,10 @@ func (c *blockStorageListCmd) CmdRun(_ *cobra.Command, _ []string) error { client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - resp, err := client.ListZones(ctx) + zones, err := utils.AllZonesV3(ctx, client, c.Zone) if err != nil { return err } - zones := resp.Zones - - if c.Zone != "" { - endpoint, err := client.GetZoneAPIEndpoint(ctx, c.Zone) - if err != nil { - return err - } - - zones = []v3.Zone{{APIEndpoint: endpoint}} - } output := make(blockStorageListOutput, 0) for _, zone := range zones { diff --git a/cmd/compute/deploy_target/deploy_target_list.go b/cmd/compute/deploy_target/deploy_target_list.go index 1fd145851..88d62176c 100644 --- a/cmd/compute/deploy_target/deploy_target_list.go +++ b/cmd/compute/deploy_target/deploy_target_list.go @@ -15,10 +15,10 @@ import ( ) type deployTargetListItemOutput struct { - Zone string `json:"zone"` - ID string `json:"id"` - Name string `json:"name"` - Type string `json:"type"` + Zone v3.ZoneName `json:"zone"` + ID v3.UUID `json:"id"` + Name string `json:"name"` + Type string `json:"type"` } type deployTargetListOutput []deployTargetListItemOutput @@ -32,7 +32,7 @@ type deployTargetListCmd struct { _ bool `cli-cmd:"list"` - Zone string `cli-short:"z" cli-usage:"zone to filter results to"` + Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"` } func (c *deployTargetListCmd) CmdAliases() []string { return nil } @@ -51,20 +51,12 @@ func (c *deployTargetListCmd) CmdPreRun(cmd *cobra.Command, args []string) error } func (c *deployTargetListCmd) CmdRun(_ *cobra.Command, _ []string) error { - var zones []v3.ZoneName + client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - if c.Zone != "" { - zones = []v3.ZoneName{v3.ZoneName(c.Zone)} - } else { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(c.Zone)) - if err != nil { - return err - } - zones, err = utils.AllZonesV3(ctx, client) - if err != nil { - return err - } + zones, err := utils.AllZonesV3(ctx, client, c.Zone) + if err != nil { + return err } out := make(deployTargetListOutput, 0) @@ -77,24 +69,20 @@ func (c *deployTargetListCmd) CmdRun(_ *cobra.Command, _ []string) error { } done <- struct{}{} }() - err := utils.ForEachZone(zones, func(zone v3.ZoneName) error { - - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(zone)) - if err != nil { - return err - } - list, err := client.ListDeployTargets(ctx) + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + c := client.WithEndpoint(zone.APIEndpoint) + list, err := c.ListDeployTargets(ctx) if err != nil { return fmt.Errorf("unable to list Deploy Targets in zone %s: %w", zone, err) } for _, dt := range list.DeployTargets { res <- deployTargetListItemOutput{ - ID: dt.ID.String(), + ID: dt.ID, Name: dt.Name, Type: string(dt.Type), - Zone: string(zone), + Zone: zone.Name, } } diff --git a/cmd/compute/elastic_ip/elastic_ip_list.go b/cmd/compute/elastic_ip/elastic_ip_list.go index 819dbe72b..e8c8fe529 100644 --- a/cmd/compute/elastic_ip/elastic_ip_list.go +++ b/cmd/compute/elastic_ip/elastic_ip_list.go @@ -15,9 +15,9 @@ import ( ) type elasticIPListItemOutput struct { - ID string `json:"id"` - IPAddress string `json:"ip_address"` - Zone string `json:"zone"` + ID v3.UUID `json:"id"` + IPAddress string `json:"ip_address"` + Zone v3.ZoneName `json:"zone"` } type elasticIPListOutput []elasticIPListItemOutput @@ -31,7 +31,7 @@ type elasticIPListCmd struct { _ bool `cli-cmd:"list"` - Zone string `cli-short:"z" cli-usage:"zone to filter results to"` + Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"` } func (c *elasticIPListCmd) CmdAliases() []string { return exocmd.GListAlias } @@ -50,20 +50,12 @@ func (c *elasticIPListCmd) CmdPreRun(cmd *cobra.Command, args []string) error { } func (c *elasticIPListCmd) CmdRun(_ *cobra.Command, _ []string) error { - var zones []v3.ZoneName + client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - if c.Zone != "" { - zones = []v3.ZoneName{v3.ZoneName(c.Zone)} - } else { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(c.Zone)) - if err != nil { - return err - } - zones, err = utils.AllZonesV3(ctx, client) - if err != nil { - return err - } + zones, err := utils.AllZonesV3(ctx, client, c.Zone) + if err != nil { + return err } out := make(elasticIPListOutput, 0) @@ -76,13 +68,10 @@ func (c *elasticIPListCmd) CmdRun(_ *cobra.Command, _ []string) error { } done <- struct{}{} }() - err := utils.ForEachZone(zones, func(zone v3.ZoneName) error { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(zone)) - if err != nil { - return err - } + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + c := client.WithEndpoint(zone.APIEndpoint) + list, err := c.ListElasticIPS(ctx) - list, err := client.ListElasticIPS(ctx) if err != nil { return fmt.Errorf("unable to list Elastic IP addresses in zone %s: %w", zone, err) } @@ -90,9 +79,9 @@ func (c *elasticIPListCmd) CmdRun(_ *cobra.Command, _ []string) error { if list != nil { for _, e := range list.ElasticIPS { res <- elasticIPListItemOutput{ - ID: e.ID.String(), + ID: e.ID, IPAddress: e.IP, - Zone: string(zone), + Zone: zone.Name, } } diff --git a/cmd/compute/instance/instance_list.go b/cmd/compute/instance/instance_list.go index c967f9a1c..043501676 100644 --- a/cmd/compute/instance/instance_list.go +++ b/cmd/compute/instance/instance_list.go @@ -17,13 +17,13 @@ import ( ) type instanceListItemOutput struct { - ID string `json:"id"` - Name string `json:"name"` - Zone string `json:"zone"` - Type string `json:"type"` - IPAddress string `json:"ip_address"` - IPv6Address string `json:"ipv6_address"` - State string `json:"state"` + ID v3.UUID `json:"id"` + Name string `json:"name"` + Zone v3.ZoneName `json:"zone"` + Type string `json:"type"` + IPAddress string `json:"ip_address"` + IPv6Address string `json:"ipv6_address"` + State string `json:"state"` } type instanceListOutput []instanceListItemOutput @@ -46,9 +46,9 @@ func (o *instanceListOutput) ToTable() { for _, instance := range *o { t.Append([]string{ - instance.ID, + string(instance.ID), instance.Name, - instance.Zone, + string(instance.Zone), instance.Type, instance.IPAddress, instance.IPv6Address, @@ -62,7 +62,7 @@ type instanceListCmd struct { _ bool `cli-cmd:"list"` - Zone string `cli-short:"z" cli-usage:"zone to filter results to"` + Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"` } func (c *instanceListCmd) CmdAliases() []string { return exocmd.GListAlias } @@ -81,20 +81,12 @@ func (c *instanceListCmd) CmdPreRun(cmd *cobra.Command, args []string) error { } func (c *instanceListCmd) CmdRun(_ *cobra.Command, _ []string) error { - var zones []v3.ZoneName + client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - if c.Zone != "" { - zones = []v3.ZoneName{v3.ZoneName(c.Zone)} - } else { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(c.Zone)) - if err != nil { - return err - } - zones, err = utils.AllZonesV3(ctx, client) - if err != nil { - return err - } + zones, err := utils.AllZonesV3(ctx, client, c.Zone) + if err != nil { + return err } out := make(instanceListOutput, 0) @@ -109,14 +101,11 @@ func (c *instanceListCmd) CmdRun(_ *cobra.Command, _ []string) error { } done <- struct{}{} }() - err := utils.ForEachZone(zones, func(zone v3.ZoneName) error { - ctx := exocmd.GContext - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(zone)) - if err != nil { - return err - } + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + + c := client.WithEndpoint(zone.APIEndpoint) + instances, err := c.ListInstances(ctx) - instances, err := client.ListInstances(ctx) if err != nil { return err } @@ -138,9 +127,9 @@ func (c *instanceListCmd) CmdRun(_ *cobra.Command, _ []string) error { } res <- instanceListItemOutput{ - ID: i.ID.String(), + ID: i.ID, Name: i.Name, - Zone: string(zone), + Zone: zone.Name, Type: fmt.Sprintf("%s.%s", instanceType.Family, instanceType.Size), IPAddress: utils.DefaultIP(&i.PublicIP, utils.EmptyIPAddressVisualization), IPv6Address: utils.DefaultIP(i.Ipv6Address, utils.EmptyIPAddressVisualization), @@ -150,6 +139,7 @@ func (c *instanceListCmd) CmdRun(_ *cobra.Command, _ []string) error { return nil }) + if err != nil { _, _ = fmt.Fprintf(os.Stderr, "warning: errors during listing, results might be incomplete.\n%s\n", err) // nolint:golint diff --git a/cmd/compute/instance/instance_snapshot_list.go b/cmd/compute/instance/instance_snapshot_list.go index e2408535b..c7b9d2c4a 100644 --- a/cmd/compute/instance/instance_snapshot_list.go +++ b/cmd/compute/instance/instance_snapshot_list.go @@ -16,11 +16,11 @@ import ( ) type instanceSnapshotListItemOutput struct { - ID string `json:"id"` - CreationDate string `json:"creation_date"` - Instance string `json:"instance"` - State string `json:"state"` - Zone string `json:"zone"` + ID v3.UUID `json:"id"` + CreationDate string `json:"creation_date"` + Instance string `json:"instance"` + State string `json:"state"` + Zone v3.ZoneName `json:"zone"` } type instanceSnapshotListOutput []instanceSnapshotListItemOutput @@ -34,7 +34,7 @@ type instanceSnapshotListCmd struct { _ bool `cli-cmd:"list"` - Zone string `cli-short:"z" cli-usage:"zone to filter results to"` + Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"` } func (c *instanceSnapshotListCmd) CmdAliases() []string { return nil } @@ -53,20 +53,12 @@ func (c *instanceSnapshotListCmd) CmdPreRun(cmd *cobra.Command, args []string) e } func (c *instanceSnapshotListCmd) CmdRun(_ *cobra.Command, _ []string) error { - var zones []v3.ZoneName + client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - if c.Zone != "" { - zones = []v3.ZoneName{v3.ZoneName(c.Zone)} - } else { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(c.Zone)) - if err != nil { - return err - } - zones, err = utils.AllZonesV3(ctx, client) - if err != nil { - return err - } + zones, err := utils.AllZonesV3(ctx, client, c.Zone) + if err != nil { + return err } out := make(instanceSnapshotListOutput, 0) @@ -81,14 +73,9 @@ func (c *instanceSnapshotListCmd) CmdRun(_ *cobra.Command, _ []string) error { } done <- struct{}{} }() - err := utils.ForEachZone(zones, func(zone v3.ZoneName) error { - ctx := exocmd.GContext - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(zone)) - if err != nil { - return err - } - - snapshots, err := client.ListSnapshots(ctx) + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + c := client.WithEndpoint(zone.APIEndpoint) + snapshots, err := c.ListSnapshots(ctx) if err != nil { return err } @@ -107,11 +94,11 @@ func (c *instanceSnapshotListCmd) CmdRun(_ *cobra.Command, _ []string) error { } res <- instanceSnapshotListItemOutput{ - ID: s.ID.String(), + ID: s.ID, CreationDate: s.CreatedAT.String(), Instance: instance.Name, State: string(s.State), - Zone: string(zone), + Zone: zone.Name, } } diff --git a/cmd/compute/instance_pool/instance_pool_list.go b/cmd/compute/instance_pool/instance_pool_list.go index 81c62822a..0c9e0c436 100644 --- a/cmd/compute/instance_pool/instance_pool_list.go +++ b/cmd/compute/instance_pool/instance_pool_list.go @@ -15,11 +15,11 @@ import ( ) type instancePoolListItemOutput struct { - ID string `json:"id"` - Name string `json:"name"` - Zone string `json:"zone"` - Size int64 `json:"size"` - State string `json:"state"` + ID v3.UUID `json:"id"` + Name string `json:"name"` + Zone v3.ZoneName `json:"zone"` + Size int64 `json:"size"` + State string `json:"state"` } type instancePoolListOutput []instancePoolListItemOutput @@ -33,7 +33,7 @@ type instancePoolListCmd struct { _ bool `cli-cmd:"list"` - Zone string `cli-short:"z" cli-usage:"zone to filter results to"` + Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"` } func (c *instancePoolListCmd) CmdAliases() []string { return exocmd.GListAlias } @@ -52,20 +52,12 @@ func (c *instancePoolListCmd) CmdPreRun(cmd *cobra.Command, args []string) error } func (c *instancePoolListCmd) CmdRun(_ *cobra.Command, _ []string) error { - var zones []v3.ZoneName + client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - if c.Zone != "" { - zones = []v3.ZoneName{v3.ZoneName(c.Zone)} - } else { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(c.Zone)) - if err != nil { - return err - } - zones, err = utils.AllZonesV3(ctx, client) - if err != nil { - return err - } + zones, err := utils.AllZonesV3(ctx, client, c.Zone) + if err != nil { + return err } out := make(instancePoolListOutput, 0) @@ -78,22 +70,19 @@ func (c *instancePoolListCmd) CmdRun(_ *cobra.Command, _ []string) error { } done <- struct{}{} }() - err := utils.ForEachZone(zones, func(zone v3.ZoneName) error { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, zone) - if err != nil { - return err - } + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + c := client.WithEndpoint(zone.APIEndpoint) + list, err := c.ListInstancePools(ctx) - list, err := client.ListInstancePools(ctx) if err != nil { return fmt.Errorf("unable to list Instance Pools in zone %s: %w", zone, err) } for _, i := range list.InstancePools { res <- instancePoolListItemOutput{ - ID: i.ID.String(), + ID: i.ID, Name: i.Name, - Zone: string(zone), + Zone: zone.Name, Size: i.Size, State: string(i.State), } diff --git a/cmd/compute/load_balancer/nlb_list.go b/cmd/compute/load_balancer/nlb_list.go index 9a9eb6eec..f5ae1d9c7 100644 --- a/cmd/compute/load_balancer/nlb_list.go +++ b/cmd/compute/load_balancer/nlb_list.go @@ -32,7 +32,7 @@ type nlbListCmd struct { _ bool `cli-cmd:"list"` - Zone string `cli-short:"z" cli-usage:"zone to filter results to"` + Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"` } func (c *nlbListCmd) CmdAliases() []string { return exocmd.GListAlias } @@ -51,20 +51,12 @@ func (c *nlbListCmd) CmdPreRun(cmd *cobra.Command, args []string) error { } func (c *nlbListCmd) CmdRun(_ *cobra.Command, _ []string) error { - var zones []v3.ZoneName + client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - if c.Zone != "" { - zones = []v3.ZoneName{v3.ZoneName(c.Zone)} - } else { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(c.Zone)) - if err != nil { - return err - } - zones, err = utils.AllZonesV3(ctx, client) - if err != nil { - return err - } + zones, err := utils.AllZonesV3(ctx, client, c.Zone) + if err != nil { + return err } out := make(nlbListOutput, 0) @@ -77,13 +69,9 @@ func (c *nlbListCmd) CmdRun(_ *cobra.Command, _ []string) error { } done <- struct{}{} }() - err := utils.ForEachZone(zones, func(zone v3.ZoneName) error { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(zone)) - if err != nil { - return err - } - - list, err := client.ListLoadBalancers(ctx) + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + c := client.WithEndpoint(zone.APIEndpoint) + list, err := c.ListLoadBalancers(ctx) if err != nil { return fmt.Errorf("unable to list Network Load Balancers in zone %s: %w", zone, err) } @@ -92,7 +80,7 @@ func (c *nlbListCmd) CmdRun(_ *cobra.Command, _ []string) error { res <- nlbListItemOutput{ ID: nlb.ID, Name: nlb.Name, - Zone: v3.ZoneName(zone), + Zone: zone.Name, IPAddress: nlb.IP.String(), } } diff --git a/cmd/compute/private_network/private_network_list.go b/cmd/compute/private_network/private_network_list.go index 4bec67c27..b25ec0704 100644 --- a/cmd/compute/private_network/private_network_list.go +++ b/cmd/compute/private_network/private_network_list.go @@ -53,19 +53,10 @@ func (c *privateNetworkListCmd) CmdRun(_ *cobra.Command, _ []string) error { client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - resp, err := client.ListZones(ctx) + zones, err := utils.AllZonesV3(ctx, client, c.Zone) if err != nil { return err } - zones := resp.Zones - - if c.Zone != "" { - endpoint, err := client.GetZoneAPIEndpoint(ctx, c.Zone) - if err != nil { - return err - } - zones = []v3.Zone{{APIEndpoint: endpoint}} - } out := make(privateNetworkListOutput, 0) res := make(chan privateNetworkListItemOutput) @@ -79,7 +70,7 @@ func (c *privateNetworkListCmd) CmdRun(_ *cobra.Command, _ []string) error { }() err = utils.ForEveryZone(zones, func(zone v3.Zone) error { - c := client.WithEndpoint((zone.APIEndpoint)) + c := client.WithEndpoint(zone.APIEndpoint) resp, err := c.ListPrivateNetworks(ctx) if err != nil { return fmt.Errorf("unable to list Private Networks in zone %s: %w", zone, err) diff --git a/cmd/compute/security_group/security_group_show.go b/cmd/compute/security_group/security_group_show.go index 89921a6ed..408e21a54 100644 --- a/cmd/compute/security_group/security_group_show.go +++ b/cmd/compute/security_group/security_group_show.go @@ -43,7 +43,7 @@ type securityGroupShowOutput struct { type securityGroupInstanceOutput struct { Name string `json:"name"` PublicIP string `json:"public_ip"` - ID string `json:"id"` + ID v3.UUID `json:"id"` Zone v3.ZoneName `json:"zone"` } @@ -105,7 +105,7 @@ func (o *securityGroupShowOutput) ToTable() { at.SetAlignment(tablewriter.ALIGN_LEFT) for _, instance := range instances { - r := []string{instance.Name, instance.ID} + r := []string{instance.Name, string(instance.ID)} r = append(r, instance.PublicIP) r = append(r, string(instance.Zone)) @@ -226,15 +226,15 @@ func (c *securityGroupShowCmd) CmdRun(_ *cobra.Command, _ []string) error { } } - zones := utils.AllZones + zones, err := utils.AllZonesV3(ctx, client, "") + if err != nil { + return err + } - err = utils.ForEachZone(zones, func(zone string) error { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(zone)) - if err != nil { - return err - } + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + c := client.WithEndpoint(zone.APIEndpoint) + instancesResp, err := c.ListInstances(ctx) - instancesResp, err := client.ListInstances(ctx) if err != nil { return err } @@ -251,8 +251,8 @@ func (c *securityGroupShowCmd) CmdRun(_ *cobra.Command, _ []string) error { out.Instances = append(out.Instances, securityGroupInstanceOutput{ Name: utils.DefaultString(&instance.Name, "-"), PublicIP: publicIP, - ID: instance.ID.String(), - Zone: v3.ZoneName(zone), + ID: instance.ID, + Zone: zone.Name, }) } diff --git a/cmd/dbaas/dbaas_list.go b/cmd/dbaas/dbaas_list.go index b4bd1efc7..f7eb891ec 100644 --- a/cmd/dbaas/dbaas_list.go +++ b/cmd/dbaas/dbaas_list.go @@ -15,10 +15,10 @@ import ( ) type dbaasServiceListItemOutput struct { - Name string `json:"name"` - Type string `json:"type"` - Plan string `json:"plan"` - Zone string `json:"zone"` + Name string `json:"name"` + Type string `json:"type"` + Plan string `json:"plan"` + Zone v3.ZoneName `json:"zone"` } type dbaasServiceListOutput []dbaasServiceListItemOutput @@ -32,7 +32,7 @@ type dbaasServiceListCmd struct { _ bool `cli-cmd:"list"` - Zone string `cli-short:"z" cli-usage:"zone to filter results to"` + Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"` } func (c *dbaasServiceListCmd) CmdAliases() []string { return exocmd.GListAlias } @@ -51,20 +51,12 @@ func (c *dbaasServiceListCmd) CmdPreRun(cmd *cobra.Command, args []string) error } func (c *dbaasServiceListCmd) CmdRun(_ *cobra.Command, _ []string) error { - var zones []v3.ZoneName + client := globalstate.EgoscaleV3Client ctx := exocmd.GContext - if c.Zone != "" { - zones = []v3.ZoneName{v3.ZoneName(c.Zone)} - } else { - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(c.Zone)) - if err != nil { - return err - } - zones, err = utils.AllZonesV3(ctx, client) - if err != nil { - return err - } + zones, err := utils.AllZonesV3(ctx, client, c.Zone) + if err != nil { + return err } out := make(dbaasServiceListOutput, 0) @@ -77,14 +69,10 @@ func (c *dbaasServiceListCmd) CmdRun(_ *cobra.Command, _ []string) error { } done <- struct{}{} }() - err := utils.ForEachZone(zones, func(zone v3.ZoneName) error { - ctx := exocmd.GContext - client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, v3.ZoneName(zone)) - if err != nil { - return err - } + err = utils.ForEveryZone(zones, func(zone v3.Zone) error { + c := client.WithEndpoint((zone.APIEndpoint)) + list, err := c.ListDBAASServices(ctx) - list, err := client.ListDBAASServices(ctx) if err != nil { return fmt.Errorf("unable to list Database Services in zone %s: %w", zone, err) } @@ -94,7 +82,7 @@ func (c *dbaasServiceListCmd) CmdRun(_ *cobra.Command, _ []string) error { Name: string(dbService.Name), Type: string(dbService.Type), Plan: dbService.Plan, - Zone: string(zone), + Zone: zone.Name, } } diff --git a/utils/utils.go b/utils/utils.go index 4707638ce..70dd8f425 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -31,19 +31,22 @@ var ( } ) -func AllZonesV3(ctx context.Context, client *v3.Client) ([]v3.ZoneName, error) { - zones, err := client.ListZones(ctx) +func AllZonesV3(ctx context.Context, client *v3.Client, zoneName v3.ZoneName) ([]v3.Zone, error) { + resp, err := client.ListZones(ctx) if err != nil { return nil, err } + zones := resp.Zones - zoneNames := make([]v3.ZoneName, len(zones.Zones)) - - for i, z := range zones.Zones { - zoneNames[i] = z.Name + if zoneName != "" { + zone, err := resp.FindZone(string(zoneName)) + if err != nil { + return nil, fmt.Errorf("get zone api endpoint: find zone: %w", err) + } + zones = []v3.Zone{zone} } - return zoneNames, nil + return zones, nil } const ( @@ -219,31 +222,12 @@ func VersionsAreEquivalent(a, b string) bool { return (VersionMajor(b) == VersionMajor(a) && VersionMinor(b) == VersionMinor(a)) } -// ForEachZone executes the function f for each specified zone, and return a multierror.Error containing all -// errors that may have occurred during execution. -func ForEachZone[T any](zones []T, f func(zone T) error) error { - meg := new(multierror.Group) - - for _, zone := range zones { - zone := zone - meg.Go(func() error { - return f(zone) - }) - } - - return meg.Wait().ErrorOrNil() -} - // ForEveryZone executes the function f for every specified zone, and returns a multierror.Error containing all // errors that may have occurred during execution. - -// TODO: This is a copy paste from the function above, but suitable for egoscale v3 calls. -// Remove the old one after the migration. func ForEveryZone(zones []v3.Zone, f func(zone v3.Zone) error) error { meg := new(multierror.Group) for _, zone := range zones { - zone := zone meg.Go(func() error { return f(zone) })