From bba4cc979a7a4575de4efdcb849f75a68958446a Mon Sep 17 00:00:00 2001 From: Jules Casteran Date: Mon, 10 Jul 2023 14:44:45 +0200 Subject: [PATCH 1/2] fix(instance): ssh-config-install invalid zone or all --- .../instance/v1/custom_ssh_config.go | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/internal/namespaces/instance/v1/custom_ssh_config.go b/internal/namespaces/instance/v1/custom_ssh_config.go index 15bde59831..076c1610b5 100644 --- a/internal/namespaces/instance/v1/custom_ssh_config.go +++ b/internal/namespaces/instance/v1/custom_ssh_config.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "reflect" + "strings" "github.com/scaleway/scaleway-cli/v2/internal/core" "github.com/scaleway/scaleway-cli/v2/internal/interactive" @@ -33,12 +34,15 @@ func (s sshConfigServer) InPrivateNetwork(id string) bool { return false } -type sshConfigRequest struct { +type sshConfigInstallRequest struct { Zone scw.Zone ProjectID *string } func sshConfigInstallCommand() *core.Command { + availableZones := ((*instance.API)(nil)).Zones() + availableZones = append(availableZones, scw.Zone(core.AllLocalities)) + return &core.Command{ Namespace: "instance", Resource: "ssh", @@ -46,32 +50,32 @@ func sshConfigInstallCommand() *core.Command { Short: `Install a ssh config with all your servers as host It generate hosts for instance servers, baremetal, apple-silicon and bastions`, Long: "Path of the config will be $HOME/.ssh/scaleway.config", - ArgsType: reflect.TypeOf(sshConfigRequest{}), + ArgsType: reflect.TypeOf(sshConfigInstallRequest{}), ArgSpecs: core.ArgSpecs{ core.ProjectIDArgSpec(), - core.ZoneArgSpec(((*instance.API)(nil)).Zones()...), + core.ZoneArgSpec(availableZones...), }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { - args := argsI.(*sshConfigRequest) + args := argsI.(*sshConfigInstallRequest) homeDir := core.ExtractUserHomeDir(ctx) // Start server list with instances servers, err := sshConfigListServers(ctx, args) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list instance servers: %w", err) } // Add baremetal servers baremetalServers, err := sshConfigListBaremetalServers(ctx, args) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list baremetal servers: %w", err) } servers = append(servers, baremetalServers...) // Add Apple-Silicon servers siliconServers, err := sshConfigListAppleSiliconServers(ctx, args) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list apple-silicon servers: %w", err) } servers = append(servers, siliconServers...) @@ -150,12 +154,13 @@ Do you want the include statement to be added at the beginning of your file ?`, } } -func sshConfigListServers(ctx context.Context, args *sshConfigRequest) ([]sshConfigServer, error) { +func sshConfigListServers(ctx context.Context, args *sshConfigInstallRequest) ([]sshConfigServer, error) { instanceAPI := instance.NewAPI(core.ExtractClient(ctx)) reqOpts := []scw.RequestOption{scw.WithAllPages()} if args.Zone == scw.Zone(core.AllLocalities) { reqOpts = append(reqOpts, scw.WithZones(instanceAPI.Zones()...)) + args.Zone = "" } listServers, err := instanceAPI.ListServers(&instance.ListServersRequest{ @@ -189,13 +194,14 @@ func sshConfigListServers(ctx context.Context, args *sshConfigRequest) ([]sshCon return servers, nil } -func sshConfigListBaremetalServers(ctx context.Context, args *sshConfigRequest) ([]sshConfigServer, error) { +func sshConfigListBaremetalServers(ctx context.Context, args *sshConfigInstallRequest) ([]sshConfigServer, error) { baremetalAPI := baremetal.NewAPI(core.ExtractClient(ctx)) baremetalPNAPI := baremetal.NewPrivateNetworkAPI(core.ExtractClient(ctx)) reqOpts := []scw.RequestOption{scw.WithAllPages()} if args.Zone == scw.Zone(core.AllLocalities) { reqOpts = append(reqOpts, scw.WithZones(baremetalAPI.Zones()...)) + args.Zone = "" } listServers, err := baremetalAPI.ListServers(&baremetal.ListServersRequest{ @@ -203,6 +209,9 @@ func sshConfigListBaremetalServers(ctx context.Context, args *sshConfigRequest) ProjectID: args.ProjectID, }, reqOpts...) if err != nil { + if strings.Contains(err.Error(), "unknown service") { + return nil, nil + } // TODO: check permissions and print warning return nil, err } @@ -239,12 +248,13 @@ func sshConfigListBaremetalServers(ctx context.Context, args *sshConfigRequest) return servers, nil } -func sshConfigListAppleSiliconServers(ctx context.Context, args *sshConfigRequest) ([]sshConfigServer, error) { +func sshConfigListAppleSiliconServers(ctx context.Context, args *sshConfigInstallRequest) ([]sshConfigServer, error) { siliconAPI := applesilicon.NewAPI(core.ExtractClient(ctx)) reqOpts := []scw.RequestOption{scw.WithAllPages()} if args.Zone == scw.Zone(core.AllLocalities) { reqOpts = append(reqOpts, scw.WithZones(siliconAPI.Zones()...)) + args.Zone = "" } listServers, err := siliconAPI.ListServers(&applesilicon.ListServersRequest{ @@ -252,6 +262,9 @@ func sshConfigListAppleSiliconServers(ctx context.Context, args *sshConfigReques ProjectID: args.ProjectID, }, reqOpts...) if err != nil { + if strings.Contains(err.Error(), "unknown service") { + return nil, nil + } return nil, err } @@ -267,7 +280,7 @@ func sshConfigListAppleSiliconServers(ctx context.Context, args *sshConfigReques return servers, nil } -func sshConfigBastionHosts(ctx context.Context, args *sshConfigRequest, servers []sshConfigServer) ([]sshconfig.Host, error) { +func sshConfigBastionHosts(ctx context.Context, args *sshConfigInstallRequest, servers []sshConfigServer) ([]sshconfig.Host, error) { gwAPI := vpcgw.NewAPI(core.ExtractClient(ctx)) reqOpts := []scw.RequestOption{scw.WithAllPages()} From cda051a2b48156da158d0761b32f2087e5ff7775 Mon Sep 17 00:00:00 2001 From: Jules Casteran Date: Mon, 10 Jul 2023 15:14:33 +0200 Subject: [PATCH 2/2] update doc --- .../test-all-usage-instance-ssh-install-config-usage.golden | 2 +- docs/commands/instance.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/scw/testdata/test-all-usage-instance-ssh-install-config-usage.golden b/cmd/scw/testdata/test-all-usage-instance-ssh-install-config-usage.golden index 3677c24881..e7c0ce6252 100644 --- a/cmd/scw/testdata/test-all-usage-instance-ssh-install-config-usage.golden +++ b/cmd/scw/testdata/test-all-usage-instance-ssh-install-config-usage.golden @@ -7,7 +7,7 @@ USAGE: ARGS: [project-id] Project ID to use. If none is passed the default project ID will be used - [zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | fr-par-3 | nl-ams-1 | nl-ams-2 | nl-ams-3 | pl-waw-1 | pl-waw-2) + [zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | fr-par-3 | nl-ams-1 | nl-ams-2 | nl-ams-3 | pl-waw-1 | pl-waw-2 | all) FLAGS: -h, --help help for install-config diff --git a/docs/commands/instance.md b/docs/commands/instance.md index a60664dcfe..4262a5fa1e 100644 --- a/docs/commands/instance.md +++ b/docs/commands/instance.md @@ -2655,7 +2655,7 @@ scw instance ssh install-config [arg=value ...] | Name | | Description | |------|---|-------------| | project-id | | Project ID to use. If none is passed the default project ID will be used | -| zone | Default: `fr-par-1`
One of: `fr-par-1`, `fr-par-2`, `fr-par-3`, `nl-ams-1`, `nl-ams-2`, `nl-ams-3`, `pl-waw-1`, `pl-waw-2` | Zone to target. If none is passed will use default zone from the config | +| zone | Default: `fr-par-1`
One of: `fr-par-1`, `fr-par-2`, `fr-par-3`, `nl-ams-1`, `nl-ams-2`, `nl-ams-3`, `pl-waw-1`, `pl-waw-2`, `all` | Zone to target. If none is passed will use default zone from the config |