From dce048be409a98711deeaee725529021491e1244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Fri, 17 Apr 2020 16:32:21 +0200 Subject: [PATCH 01/37] feat(object): add export config commands for upstream s3 tools --- internal/namespaces/get_commands.go | 2 + internal/namespaces/object/v1/custom.go | 78 ++++++++++++++++++++ internal/namespaces/object/v1/custom_test.go | 1 + 3 files changed, 81 insertions(+) create mode 100644 internal/namespaces/object/v1/custom.go create mode 100644 internal/namespaces/object/v1/custom_test.go diff --git a/internal/namespaces/get_commands.go b/internal/namespaces/get_commands.go index b406a56163..6cc395a71b 100644 --- a/internal/namespaces/get_commands.go +++ b/internal/namespaces/get_commands.go @@ -10,6 +10,7 @@ import ( "github.com/scaleway/scaleway-cli/internal/namespaces/instance/v1" k8s "github.com/scaleway/scaleway-cli/internal/namespaces/k8s/v1" "github.com/scaleway/scaleway-cli/internal/namespaces/marketplace/v1" + "github.com/scaleway/scaleway-cli/internal/namespaces/object/v1" "github.com/scaleway/scaleway-cli/internal/namespaces/registry/v1" versionNamespace "github.com/scaleway/scaleway-cli/internal/namespaces/version" ) @@ -29,6 +30,7 @@ func GetCommands() *core.Commands { commands.Merge(configNamespace.GetCommands()) commands.Merge(account.GetCommands()) commands.Merge(autocompleteNamespace.GetCommands()) + commands.Merge(object.GetCommands()) commands.Merge(versionNamespace.GetCommands()) commands.Merge(registry.GetCommands()) return commands diff --git a/internal/namespaces/object/v1/custom.go b/internal/namespaces/object/v1/custom.go new file mode 100644 index 0000000000..1fdbecbbdb --- /dev/null +++ b/internal/namespaces/object/v1/custom.go @@ -0,0 +1,78 @@ +package object + +import ( + "github.com/scaleway/scaleway-cli/internal/core" +) + +var s3cmd_template = ` +[default] +access_key = {{ .AccessKey }} +bucket_location = {{ .Region }} +host_base = s3.{{ .Region }}.scw.cloud +host_bucket = %(bucket)s.s3.fr-par.scw.cloud +secret_key = {{ .SecretKey }} +use_https = True +` + +var awsCli = `` + +var rclone = `` + +var mc = `` + +func GetCommands() *core.Commands { + return core.NewCommands( + objectRoot(), + getCommand(), + installCommand(), + ) +} + +func objectRoot() *core.Command { + return &core.Command{ + Short: `Object-storage utils`, + Namespace: "object", + } +} + +func objectConfig() *core.Command { + return &core.Command{ + Short: `An image is a backup of an instance`, + Long: `Images are backups of your instances. +You can reuse that image to restore your data or create a series of instances with a predefined configuration. + +An image is a complete backup of your server including all volumes. +`, + Namespace: "object", + } +} + +func getCommand() *core.Command { + return &core.Command{ + Namespace: "object", + Resource: "config", + Verb: "get", + Short: "", + Long: "", + ArgsType: nil, + ArgSpecs: nil, + Examples: nil, + SeeAlsos: nil, + Run: nil, + } +} + +func installCommand() *core.Command { + return &core.Command{ + Namespace: "object", + Resource: "config", + Verb: "install", + Short: "Install a s3 related configuration file", + Long: "", + ArgsType: nil, + ArgSpecs: nil, + Examples: nil, + SeeAlsos: nil, + Run: nil, + } +} diff --git a/internal/namespaces/object/v1/custom_test.go b/internal/namespaces/object/v1/custom_test.go new file mode 100644 index 0000000000..722bd01d19 --- /dev/null +++ b/internal/namespaces/object/v1/custom_test.go @@ -0,0 +1 @@ +package object From 761fa23a1d7c450ad8d0e71d4692515722c3b804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Mon, 20 Apr 2020 17:52:15 +0200 Subject: [PATCH 02/37] Fix --- internal/namespaces/object/v1/custom.go | 253 ++++++++++++++++-- internal/namespaces/object/v1/custom_test.go | 49 ++++ .../testdata/test-config-get-mc.stdout.golden | 1 + .../test-config-get-rclone.stdout.golden | 15 ++ .../test-config-get-s3cmd.stdout.golden | 10 + 5 files changed, 300 insertions(+), 28 deletions(-) create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden diff --git a/internal/namespaces/object/v1/custom.go b/internal/namespaces/object/v1/custom.go index 1fdbecbbdb..014ebba6ae 100644 --- a/internal/namespaces/object/v1/custom.go +++ b/internal/namespaces/object/v1/custom.go @@ -1,28 +1,111 @@ package object import ( + "bytes" + "context" + "encoding/json" + "fmt" + "reflect" + "text/template" + "github.com/scaleway/scaleway-cli/internal/core" + "github.com/scaleway/scaleway-sdk-go/scw" ) -var s3cmd_template = ` +type getRequest struct { + Region scw.Region + Type string +} + +type s3config struct { + AccessKey string + SecretKey string + Region string +} + +func renderTemplate(configFileTemplate string, c s3config) (string, error) { + tmpl, err := template.New("configuration").Parse(configFileTemplate) + if err != nil { + return "", err + } + + var buf bytes.Buffer + err = tmpl.Execute(&buf, c) + if err != nil { + return "", err + } + + return buf.String(), nil +} + +func (c s3config) exportS3cmdConfig() (string, error) { + configFileTemplate := `# Generated by scaleway-cli command +# Configuration file for s3cmd https://s3tools.org/s3cmd +# Default location: $HOME/.s3cfg [default] access_key = {{ .AccessKey }} bucket_location = {{ .Region }} host_base = s3.{{ .Region }}.scw.cloud -host_bucket = %(bucket)s.s3.fr-par.scw.cloud +host_bucket = %(bucket)s.s3.{{ .Region }}.scw.cloud secret_key = {{ .SecretKey }} -use_https = True -` +use_https = True` + + return renderTemplate(configFileTemplate, c) +} -var awsCli = `` +func (c s3config) exportRcloneConfig() (string, error) { + configFileTemplate := `# Generated by scaleway-cli command +# Configuration file for rclone https://rclone.org/s3/#scaleway +# Default location: $HOME/.config/rclone/rclone.conf +[scaleway_{{ .Region }}] +type = s3 +env_auth = false +endpoint = s3.{{ .Region }}.scw.cloud +access_key_id = {{ .AccessKey }} +secret_access_key = {{ .SecretKey }} +region = {{ .Region }} +location_constraint = +acl = private +force_path_style = false +server_side_encryption = +storage_class =` -var rclone = `` + return renderTemplate(configFileTemplate, c) +} -var mc = `` +func (c s3config) exportMcConfig() (string, error) { + type hostconfig struct { + URL string `json:"url"` + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` + API string `json:"api"` + } + type mcconfig struct { + Version string `json:"version"` + Hosts map[string]hostconfig `json:"hosts"` + } + m := mcconfig{ + Version: "9", + Hosts: map[string]hostconfig{ + "scaleway_" + c.Region: { + URL: "https://s3." + c.Region + ".scw.cloud", + AccessKey: c.AccessKey, + SecretKey: c.SecretKey, + API: "S3v2", + }, + }, + } + res, err := json.Marshal(m) + if err != nil { + return "", nil + } + return string(res), nil +} func GetCommands() *core.Commands { return core.NewCommands( objectRoot(), + objectConfig(), getCommand(), installCommand(), ) @@ -37,42 +120,156 @@ func objectRoot() *core.Command { func objectConfig() *core.Command { return &core.Command{ - Short: `An image is a backup of an instance`, - Long: `Images are backups of your instances. -You can reuse that image to restore your data or create a series of instances with a predefined configuration. - -An image is a complete backup of your server including all volumes. -`, + Short: `Manage configuration files for popular S3 tools`, + Long: `Configuration generation for S3 tools.`, Namespace: "object", + Resource: `config`, } } func getCommand() *core.Command { + return &core.Command{ Namespace: "object", Resource: "config", Verb: "get", - Short: "", - Long: "", - ArgsType: nil, - ArgSpecs: nil, - Examples: nil, - SeeAlsos: nil, - Run: nil, + Short: "Generate a S3 related configuration file", + Long: "Generate a S3 related configuration file.", + ArgsType: reflect.TypeOf(getRequest{}), + ArgSpecs: []*core.ArgSpec{ + { + Name: "type", + Short: "Type of tool supported", + Required: true, + EnumValues: []string{"aws-config", "aws-credentials", "rclone", "s3cmd", "mc"}, + }, + core.RegionArgSpec(), + }, + Examples: []*core.Example{ + { + Short: "Generate a s3cmd s3config file for Paris region", + Raw: "scw object config install type=s3cmd region=fr-par", + }, + { + Short: "Generate a rclone s3config file for default region", + Raw: "scw object config install type=rclone", + }, + { + Short: "Generate a mc (minio) s3config file for default region", + Raw: "scw object config install type=mc", + }, + }, + SeeAlsos: []*core.SeeAlso{ + { + Short: "Install a S3 tool configuration file", + Command: "scw object config install", + }, + }, + Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { + requestedType := argsI.(*getRequest) + config := s3config{ + AccessKey: "pouet", + SecretKey: "pouet", + Region: requestedType.Region.String(), + } + + switch requestedType.Type { + case "s3cmd": + res, err := config.exportS3cmdConfig() + if err != nil { + return nil, err + } + return res, nil + case "rclone": + res, err := config.exportRcloneConfig() + if err != nil { + return nil, err + } + return res, nil + case "mc": + res, err := config.exportMcConfig() + if err != nil { + return nil, err + } + return res, nil + default: + fmt.Println("Unknown tool.") + return nil, nil + } + }, } } func installCommand() *core.Command { + type installRequest struct { + Region scw.Region + Type string + } return &core.Command{ Namespace: "object", - Resource: "config", + Resource: "s3config", Verb: "install", - Short: "Install a s3 related configuration file", - Long: "", - ArgsType: nil, - ArgSpecs: nil, - Examples: nil, - SeeAlsos: nil, - Run: nil, + Short: "Install a S3 related configuration file to its default location", + Long: "Install a S3 related configuration file.", + ArgsType: reflect.TypeOf(installRequest{}), + ArgSpecs: []*core.ArgSpec{ + { + Name: "type", + Short: "Type of tool supported", + Required: true, + EnumValues: []string{"aws-cli", "rclone", "s3cmd", "mc"}, + }, + core.RegionArgSpec(), + }, + Examples: []*core.Example{ + { + Short: "Install a s3cmd config file for Paris region", + Raw: "scw object config install type=s3cmd region=fr-par", + }, + { + Short: "Install a rclone config file for default region", + Raw: "scw object config install type=rclone", + }, + + { + Short: "Install a mc (minio) config file for default region", + Raw: "scw object config install type=mc", + }, + }, + SeeAlsos: []*core.SeeAlso{ + { + Short: "Generate a S3 tool configuration file", + Command: "scw object config get", + }, + }, + Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { + requestedType := argsI.(*getRequest) + config := s3config{ + AccessKey: "pouet", + SecretKey: "pouet", + Region: requestedType.Region.String(), + } + + switch requestedType.Type { + case "s3cmd": + _, err := config.exportS3cmdConfig() + if err != nil { + return nil, err + } + case "rclone": + _, err := config.exportRcloneConfig() + if err != nil { + return nil, err + } + case "mc": + _, err := config.exportMcConfig() + if err != nil { + return nil, err + } + default: + fmt.Println("Unknown tool.") + } + return nil, nil + }, } } diff --git a/internal/namespaces/object/v1/custom_test.go b/internal/namespaces/object/v1/custom_test.go index 722bd01d19..24e0647c76 100644 --- a/internal/namespaces/object/v1/custom_test.go +++ b/internal/namespaces/object/v1/custom_test.go @@ -1 +1,50 @@ package object + +import ( + "testing" + + "github.com/scaleway/scaleway-cli/internal/core" +) + +func Test_ConfigGet(t *testing.T) { + t.Run("rclone", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=rclone", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + + t.Run("mc", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=mc", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + + t.Run("s3cmd", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=s3cmd", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) +} + +func Test_ConfigInstall(t *testing.T) { + t.Run("rclone", func(t *testing.T) { + + }) + + t.Run("mc", func(t *testing.T) { + + }) + + t.Run("s3cmd", func(t *testing.T) { + + }) +} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden new file mode 100644 index 0000000000..c17b92f74a --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden @@ -0,0 +1 @@ +{"version":"9","hosts":{"scaleway_":{"url":"https://s3..scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden new file mode 100644 index 0000000000..f7a6779798 --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden @@ -0,0 +1,15 @@ +# Generated by scaleway-cli command +# Configuration file for rclone https://rclone.org/s3/#scaleway +# Default location: $HOME/.config/rclone/rclone.conf +[scaleway_] +type = s3 +env_auth = false +endpoint = s3..scw.cloud +access_key_id = pouet +secret_access_key = pouet +region = +location_constraint = +acl = private +force_path_style = false +server_side_encryption = +storage_class = diff --git a/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden new file mode 100644 index 0000000000..0ac7abdb4a --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden @@ -0,0 +1,10 @@ +# Generated by scaleway-cli command +# Configuration file for s3cmd https://s3tools.org/s3cmd +# Default location: $HOME/.s3cfg +[default] +access_key = pouet +bucket_location = +host_base = s3..scw.cloud +host_bucket = %(bucket)s.s3..scw.cloud +secret_key = pouet +use_https = True From d4a9b879cd5255fc2c4be8d189261d1e6c679dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Mon, 20 Apr 2020 18:47:25 +0200 Subject: [PATCH 03/37] Fix --- internal/namespaces/object/v1/custom.go | 12 ++- internal/namespaces/object/v1/custom_test.go | 84 +++++++++++++------ .../test-config-get-default-mc.stdout.golden | 1 + ...st-config-get-default-rclone.stdout.golden | 15 ++++ ...est-config-get-default-s3cmd.stdout.golden | 10 +++ .../testdata/test-config-get-mc.stdout.golden | 2 +- .../test-config-get-rclone.stdout.golden | 6 +- .../test-config-get-s3cmd.stdout.golden | 6 +- ...st-config-get-with-region-mc.stdout.golden | 1 + ...onfig-get-with-region-rclone.stdout.golden | 15 ++++ ...config-get-with-region-s3cmd.stdout.golden | 10 +++ 11 files changed, 126 insertions(+), 36 deletions(-) create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden diff --git a/internal/namespaces/object/v1/custom.go b/internal/namespaces/object/v1/custom.go index 014ebba6ae..77d2bd4a0b 100644 --- a/internal/namespaces/object/v1/custom.go +++ b/internal/namespaces/object/v1/custom.go @@ -141,7 +141,7 @@ func getCommand() *core.Command { Name: "type", Short: "Type of tool supported", Required: true, - EnumValues: []string{"aws-config", "aws-credentials", "rclone", "s3cmd", "mc"}, + EnumValues: []string{"rclone", "s3cmd", "mc"}, }, core.RegionArgSpec(), }, @@ -167,10 +167,16 @@ func getCommand() *core.Command { }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { requestedType := argsI.(*getRequest) + client := core.ExtractClient(ctx) + region := requestedType.Region.String() + if region == "" { + defaultRegion, _ := client.GetDefaultRegion() + region = defaultRegion.String() + } config := s3config{ AccessKey: "pouet", SecretKey: "pouet", - Region: requestedType.Region.String(), + Region: region, } switch requestedType.Type { @@ -217,7 +223,7 @@ func installCommand() *core.Command { Name: "type", Short: "Type of tool supported", Required: true, - EnumValues: []string{"aws-cli", "rclone", "s3cmd", "mc"}, + EnumValues: []string{"rclone", "s3cmd", "mc"}, }, core.RegionArgSpec(), }, diff --git a/internal/namespaces/object/v1/custom_test.go b/internal/namespaces/object/v1/custom_test.go index 24e0647c76..ae4f49e590 100644 --- a/internal/namespaces/object/v1/custom_test.go +++ b/internal/namespaces/object/v1/custom_test.go @@ -7,32 +7,64 @@ import ( ) func Test_ConfigGet(t *testing.T) { - t.Run("rclone", core.Test(&core.TestConfig{ - Commands: GetCommands(), - Cmd: "scw object config get type=rclone", - Check: core.TestCheckCombine( - core.TestCheckGolden(), - core.TestCheckExitCode(0), - ), - })) - - t.Run("mc", core.Test(&core.TestConfig{ - Commands: GetCommands(), - Cmd: "scw object config get type=mc", - Check: core.TestCheckCombine( - core.TestCheckGolden(), - core.TestCheckExitCode(0), - ), - })) - - t.Run("s3cmd", core.Test(&core.TestConfig{ - Commands: GetCommands(), - Cmd: "scw object config get type=s3cmd", - Check: core.TestCheckCombine( - core.TestCheckGolden(), - core.TestCheckExitCode(0), - ), - })) + t.Run("Default", func(t *testing.T) { + t.Run("rclone", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=rclone", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + + t.Run("mc", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=mc", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + + t.Run("s3cmd", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=s3cmd", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + }) + + t.Run("With region", func(t *testing.T) { + t.Run("rclone", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=rclone region=nl-ams", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + + t.Run("mc", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=mc region=nl-ams", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + + t.Run("s3cmd", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config get type=s3cmd region=nl-ams", + Check: core.TestCheckCombine( + core.TestCheckGolden(), + core.TestCheckExitCode(0), + ), + })) + }) + } func Test_ConfigInstall(t *testing.T) { diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden new file mode 100644 index 0000000000..20b6dc2b8d --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden @@ -0,0 +1 @@ +{"version":"9","hosts":{"scaleway_fr-par":{"url":"https://s3.fr-par.scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden new file mode 100644 index 0000000000..807264c60b --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden @@ -0,0 +1,15 @@ +# Generated by scaleway-cli command +# Configuration file for rclone https://rclone.org/s3/#scaleway +# Default location: $HOME/.config/rclone/rclone.conf +[scaleway_fr-par] +type = s3 +env_auth = false +endpoint = s3.fr-par.scw.cloud +access_key_id = pouet +secret_access_key = pouet +region = fr-par +location_constraint = +acl = private +force_path_style = false +server_side_encryption = +storage_class = diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden new file mode 100644 index 0000000000..0146000a99 --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden @@ -0,0 +1,10 @@ +# Generated by scaleway-cli command +# Configuration file for s3cmd https://s3tools.org/s3cmd +# Default location: $HOME/.s3cfg +[default] +access_key = pouet +bucket_location = fr-par +host_base = s3.fr-par.scw.cloud +host_bucket = %(bucket)s.s3.fr-par.scw.cloud +secret_key = pouet +use_https = True diff --git a/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden index c17b92f74a..20b6dc2b8d 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden @@ -1 +1 @@ -{"version":"9","hosts":{"scaleway_":{"url":"https://s3..scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} +{"version":"9","hosts":{"scaleway_fr-par":{"url":"https://s3.fr-par.scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden index f7a6779798..807264c60b 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden @@ -1,13 +1,13 @@ # Generated by scaleway-cli command # Configuration file for rclone https://rclone.org/s3/#scaleway # Default location: $HOME/.config/rclone/rclone.conf -[scaleway_] +[scaleway_fr-par] type = s3 env_auth = false -endpoint = s3..scw.cloud +endpoint = s3.fr-par.scw.cloud access_key_id = pouet secret_access_key = pouet -region = +region = fr-par location_constraint = acl = private force_path_style = false diff --git a/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden index 0ac7abdb4a..0146000a99 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden @@ -3,8 +3,8 @@ # Default location: $HOME/.s3cfg [default] access_key = pouet -bucket_location = -host_base = s3..scw.cloud -host_bucket = %(bucket)s.s3..scw.cloud +bucket_location = fr-par +host_base = s3.fr-par.scw.cloud +host_bucket = %(bucket)s.s3.fr-par.scw.cloud secret_key = pouet use_https = True diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden new file mode 100644 index 0000000000..85bcfbc01a --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden @@ -0,0 +1 @@ +{"version":"9","hosts":{"scaleway_nl-ams":{"url":"https://s3.nl-ams.scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden new file mode 100644 index 0000000000..689c98cc39 --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden @@ -0,0 +1,15 @@ +# Generated by scaleway-cli command +# Configuration file for rclone https://rclone.org/s3/#scaleway +# Default location: $HOME/.config/rclone/rclone.conf +[scaleway_nl-ams] +type = s3 +env_auth = false +endpoint = s3.nl-ams.scw.cloud +access_key_id = pouet +secret_access_key = pouet +region = nl-ams +location_constraint = +acl = private +force_path_style = false +server_side_encryption = +storage_class = diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden new file mode 100644 index 0000000000..e5e34d4069 --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden @@ -0,0 +1,10 @@ +# Generated by scaleway-cli command +# Configuration file for s3cmd https://s3tools.org/s3cmd +# Default location: $HOME/.s3cfg +[default] +access_key = pouet +bucket_location = nl-ams +host_base = s3.nl-ams.scw.cloud +host_bucket = %(bucket)s.s3.nl-ams.scw.cloud +secret_key = pouet +use_https = True From 72a0f3cdda24fbd059933a59f445f9dfa0f02312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Mon, 20 Apr 2020 19:39:18 +0200 Subject: [PATCH 04/37] Fix --- internal/namespaces/object/v1/custom.go | 118 ++++++++++++++++++++---- 1 file changed, 99 insertions(+), 19 deletions(-) diff --git a/internal/namespaces/object/v1/custom.go b/internal/namespaces/object/v1/custom.go index 77d2bd4a0b..d7e9d4a426 100644 --- a/internal/namespaces/object/v1/custom.go +++ b/internal/namespaces/object/v1/custom.go @@ -5,18 +5,17 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" + "os" + "path" "reflect" "text/template" "github.com/scaleway/scaleway-cli/internal/core" + "github.com/scaleway/scaleway-cli/internal/interactive" "github.com/scaleway/scaleway-sdk-go/scw" ) -type getRequest struct { - Region scw.Region - Type string -} - type s3config struct { AccessKey string SecretKey string @@ -128,6 +127,10 @@ func objectConfig() *core.Command { } func getCommand() *core.Command { + type getRequest struct { + Region scw.Region + Type string + } return &core.Command{ Namespace: "object", @@ -143,7 +146,7 @@ func getCommand() *core.Command { Required: true, EnumValues: []string{"rclone", "s3cmd", "mc"}, }, - core.RegionArgSpec(), + core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, Examples: []*core.Example{ { @@ -213,7 +216,7 @@ func installCommand() *core.Command { } return &core.Command{ Namespace: "object", - Resource: "s3config", + Resource: "config", Verb: "install", Short: "Install a S3 related configuration file to its default location", Long: "Install a S3 related configuration file.", @@ -225,7 +228,7 @@ func installCommand() *core.Command { Required: true, EnumValues: []string{"rclone", "s3cmd", "mc"}, }, - core.RegionArgSpec(), + core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, Examples: []*core.Example{ { @@ -249,29 +252,38 @@ func installCommand() *core.Command { }, }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { - requestedType := argsI.(*getRequest) + requestedType := argsI.(*installRequest) + client := core.ExtractClient(ctx) + region := requestedType.Region.String() + if region == "" { + defaultRegion, _ := client.GetDefaultRegion() + region = defaultRegion.String() + } config := s3config{ AccessKey: "pouet", SecretKey: "pouet", - Region: requestedType.Region.String(), + Region: region, } switch requestedType.Type { case "s3cmd": - _, err := config.exportS3cmdConfig() - if err != nil { - return nil, err + i, err2 := installS3cmd(config) + if err2 != nil { + return i, err2 } + case "rclone": - _, err := config.exportRcloneConfig() - if err != nil { - return nil, err + i, err2 := installRclone(config) + if err2 != nil { + return i, err2 } + case "mc": - _, err := config.exportMcConfig() - if err != nil { - return nil, err + i, err2 := installMc(config) + if err2 != nil { + return i, err2 } + default: fmt.Println("Unknown tool.") } @@ -279,3 +291,71 @@ func installCommand() *core.Command { }, } } + +func installMc(config s3config) (interface{}, error) { + newConfig, err := config.exportMcConfig() + if err != nil { + return nil, err + } + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + mcConfigPath := path.Join(homeDir, ".mc", "config.json") + i, err2, done := ensureFile(mcConfigPath, newConfig) + if done { + return i, err2 + } + return nil, nil +} + +func ensureFile(mcConfigPath string, newConfig string) (interface{}, error, bool) { + // Ask whether to remove previous configuration file if it exists + if _, err := os.Stat(mcConfigPath); err == nil { + _, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ + Prompt: "Do you want to overwrite the existing configuration file (" + mcConfigPath + ")?", + DefaultValue: false, + }) + if err != nil { + return "", err, true + } + return nil, ioutil.WriteFile(mcConfigPath, []byte(newConfig), 0644), true + } + return nil, nil, false +} + +func installS3cmd(config s3config) (interface{}, error) { + newConfig, err := config.exportS3cmdConfig() + if err != nil { + return nil, err + } + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + s3cmdConfigPath := path.Join(homeDir, ".s3cfg") + i, err2, done := ensureFile(s3cmdConfigPath, newConfig) + if done { + return i, err2 + } + return nil, nil +} + +func installRclone(config s3config) (interface{}, error) { + newConfig, err := config.exportRcloneConfig() + if err != nil { + return nil, err + } + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + // `rclone config file` returns the path of the configuration file + rcloneConfigPath := path.Join(homeDir, ".config", "rclone", "rclone.conf") + i, err2, done := ensureFile(rcloneConfigPath, newConfig) + if done { + return i, err2 + } + + return nil, nil +} From f5d89d7a917948d4e320de87bf6b3499859be8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 14:25:13 +0200 Subject: [PATCH 05/37] Fix --- internal/namespaces/object/v1/custom.go | 331 ------------------ .../namespaces/object/v1/custom_config_get.go | 181 ++++++++++ ...stom_test.go => custom_config_get_test.go} | 14 - .../object/v1/custom_config_install.go | 165 +++++++++ .../object/v1/custom_config_install_test.go | 19 + 5 files changed, 365 insertions(+), 345 deletions(-) create mode 100644 internal/namespaces/object/v1/custom_config_get.go rename internal/namespaces/object/v1/{custom_test.go => custom_config_get_test.go} (90%) create mode 100644 internal/namespaces/object/v1/custom_config_install.go create mode 100644 internal/namespaces/object/v1/custom_config_install_test.go diff --git a/internal/namespaces/object/v1/custom.go b/internal/namespaces/object/v1/custom.go index d7e9d4a426..78ce3f3285 100644 --- a/internal/namespaces/object/v1/custom.go +++ b/internal/namespaces/object/v1/custom.go @@ -1,106 +1,9 @@ package object import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path" - "reflect" - "text/template" - "github.com/scaleway/scaleway-cli/internal/core" - "github.com/scaleway/scaleway-cli/internal/interactive" - "github.com/scaleway/scaleway-sdk-go/scw" ) -type s3config struct { - AccessKey string - SecretKey string - Region string -} - -func renderTemplate(configFileTemplate string, c s3config) (string, error) { - tmpl, err := template.New("configuration").Parse(configFileTemplate) - if err != nil { - return "", err - } - - var buf bytes.Buffer - err = tmpl.Execute(&buf, c) - if err != nil { - return "", err - } - - return buf.String(), nil -} - -func (c s3config) exportS3cmdConfig() (string, error) { - configFileTemplate := `# Generated by scaleway-cli command -# Configuration file for s3cmd https://s3tools.org/s3cmd -# Default location: $HOME/.s3cfg -[default] -access_key = {{ .AccessKey }} -bucket_location = {{ .Region }} -host_base = s3.{{ .Region }}.scw.cloud -host_bucket = %(bucket)s.s3.{{ .Region }}.scw.cloud -secret_key = {{ .SecretKey }} -use_https = True` - - return renderTemplate(configFileTemplate, c) -} - -func (c s3config) exportRcloneConfig() (string, error) { - configFileTemplate := `# Generated by scaleway-cli command -# Configuration file for rclone https://rclone.org/s3/#scaleway -# Default location: $HOME/.config/rclone/rclone.conf -[scaleway_{{ .Region }}] -type = s3 -env_auth = false -endpoint = s3.{{ .Region }}.scw.cloud -access_key_id = {{ .AccessKey }} -secret_access_key = {{ .SecretKey }} -region = {{ .Region }} -location_constraint = -acl = private -force_path_style = false -server_side_encryption = -storage_class =` - - return renderTemplate(configFileTemplate, c) -} - -func (c s3config) exportMcConfig() (string, error) { - type hostconfig struct { - URL string `json:"url"` - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` - API string `json:"api"` - } - type mcconfig struct { - Version string `json:"version"` - Hosts map[string]hostconfig `json:"hosts"` - } - m := mcconfig{ - Version: "9", - Hosts: map[string]hostconfig{ - "scaleway_" + c.Region: { - URL: "https://s3." + c.Region + ".scw.cloud", - AccessKey: c.AccessKey, - SecretKey: c.SecretKey, - API: "S3v2", - }, - }, - } - res, err := json.Marshal(m) - if err != nil { - return "", nil - } - return string(res), nil -} - func GetCommands() *core.Commands { return core.NewCommands( objectRoot(), @@ -125,237 +28,3 @@ func objectConfig() *core.Command { Resource: `config`, } } - -func getCommand() *core.Command { - type getRequest struct { - Region scw.Region - Type string - } - - return &core.Command{ - Namespace: "object", - Resource: "config", - Verb: "get", - Short: "Generate a S3 related configuration file", - Long: "Generate a S3 related configuration file.", - ArgsType: reflect.TypeOf(getRequest{}), - ArgSpecs: []*core.ArgSpec{ - { - Name: "type", - Short: "Type of tool supported", - Required: true, - EnumValues: []string{"rclone", "s3cmd", "mc"}, - }, - core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), - }, - Examples: []*core.Example{ - { - Short: "Generate a s3cmd s3config file for Paris region", - Raw: "scw object config install type=s3cmd region=fr-par", - }, - { - Short: "Generate a rclone s3config file for default region", - Raw: "scw object config install type=rclone", - }, - { - Short: "Generate a mc (minio) s3config file for default region", - Raw: "scw object config install type=mc", - }, - }, - SeeAlsos: []*core.SeeAlso{ - { - Short: "Install a S3 tool configuration file", - Command: "scw object config install", - }, - }, - Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { - requestedType := argsI.(*getRequest) - client := core.ExtractClient(ctx) - region := requestedType.Region.String() - if region == "" { - defaultRegion, _ := client.GetDefaultRegion() - region = defaultRegion.String() - } - config := s3config{ - AccessKey: "pouet", - SecretKey: "pouet", - Region: region, - } - - switch requestedType.Type { - case "s3cmd": - res, err := config.exportS3cmdConfig() - if err != nil { - return nil, err - } - return res, nil - case "rclone": - res, err := config.exportRcloneConfig() - if err != nil { - return nil, err - } - return res, nil - case "mc": - res, err := config.exportMcConfig() - if err != nil { - return nil, err - } - return res, nil - default: - fmt.Println("Unknown tool.") - return nil, nil - } - }, - } -} - -func installCommand() *core.Command { - type installRequest struct { - Region scw.Region - Type string - } - return &core.Command{ - Namespace: "object", - Resource: "config", - Verb: "install", - Short: "Install a S3 related configuration file to its default location", - Long: "Install a S3 related configuration file.", - ArgsType: reflect.TypeOf(installRequest{}), - ArgSpecs: []*core.ArgSpec{ - { - Name: "type", - Short: "Type of tool supported", - Required: true, - EnumValues: []string{"rclone", "s3cmd", "mc"}, - }, - core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), - }, - Examples: []*core.Example{ - { - Short: "Install a s3cmd config file for Paris region", - Raw: "scw object config install type=s3cmd region=fr-par", - }, - { - Short: "Install a rclone config file for default region", - Raw: "scw object config install type=rclone", - }, - - { - Short: "Install a mc (minio) config file for default region", - Raw: "scw object config install type=mc", - }, - }, - SeeAlsos: []*core.SeeAlso{ - { - Short: "Generate a S3 tool configuration file", - Command: "scw object config get", - }, - }, - Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { - requestedType := argsI.(*installRequest) - client := core.ExtractClient(ctx) - region := requestedType.Region.String() - if region == "" { - defaultRegion, _ := client.GetDefaultRegion() - region = defaultRegion.String() - } - config := s3config{ - AccessKey: "pouet", - SecretKey: "pouet", - Region: region, - } - - switch requestedType.Type { - case "s3cmd": - i, err2 := installS3cmd(config) - if err2 != nil { - return i, err2 - } - - case "rclone": - i, err2 := installRclone(config) - if err2 != nil { - return i, err2 - } - - case "mc": - i, err2 := installMc(config) - if err2 != nil { - return i, err2 - } - - default: - fmt.Println("Unknown tool.") - } - return nil, nil - }, - } -} - -func installMc(config s3config) (interface{}, error) { - newConfig, err := config.exportMcConfig() - if err != nil { - return nil, err - } - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - mcConfigPath := path.Join(homeDir, ".mc", "config.json") - i, err2, done := ensureFile(mcConfigPath, newConfig) - if done { - return i, err2 - } - return nil, nil -} - -func ensureFile(mcConfigPath string, newConfig string) (interface{}, error, bool) { - // Ask whether to remove previous configuration file if it exists - if _, err := os.Stat(mcConfigPath); err == nil { - _, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ - Prompt: "Do you want to overwrite the existing configuration file (" + mcConfigPath + ")?", - DefaultValue: false, - }) - if err != nil { - return "", err, true - } - return nil, ioutil.WriteFile(mcConfigPath, []byte(newConfig), 0644), true - } - return nil, nil, false -} - -func installS3cmd(config s3config) (interface{}, error) { - newConfig, err := config.exportS3cmdConfig() - if err != nil { - return nil, err - } - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - s3cmdConfigPath := path.Join(homeDir, ".s3cfg") - i, err2, done := ensureFile(s3cmdConfigPath, newConfig) - if done { - return i, err2 - } - return nil, nil -} - -func installRclone(config s3config) (interface{}, error) { - newConfig, err := config.exportRcloneConfig() - if err != nil { - return nil, err - } - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - // `rclone config file` returns the path of the configuration file - rcloneConfigPath := path.Join(homeDir, ".config", "rclone", "rclone.conf") - i, err2, done := ensureFile(rcloneConfigPath, newConfig) - if done { - return i, err2 - } - - return nil, nil -} diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go new file mode 100644 index 0000000000..aed8b9f51f --- /dev/null +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -0,0 +1,181 @@ +package object + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "reflect" + "text/template" + + "github.com/scaleway/scaleway-cli/internal/core" + "github.com/scaleway/scaleway-sdk-go/scw" +) + +func getCommand() *core.Command { + type getRequest struct { + Region scw.Region + Type string + } + + return &core.Command{ + Namespace: "object", + Resource: "config", + Verb: "get", + Short: "Generate a S3 related configuration file", + Long: "Generate a S3 related configuration file.", + ArgsType: reflect.TypeOf(getRequest{}), + ArgSpecs: []*core.ArgSpec{ + { + Name: "type", + Short: "Type of tool supported", + Required: true, + EnumValues: []string{"rclone", "s3cmd", "mc"}, + }, + core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), + }, + Examples: []*core.Example{ + { + Short: "Generate a s3cmd s3config file for Paris region", + Raw: "scw object config install type=s3cmd region=fr-par", + }, + { + Short: "Generate a rclone s3config file for default region", + Raw: "scw object config install type=rclone", + }, + { + Short: "Generate a mc (minio) s3config file for default region", + Raw: "scw object config install type=mc", + }, + }, + SeeAlsos: []*core.SeeAlso{ + { + Short: "Install a S3 tool configuration file", + Command: "scw object config install", + }, + }, + Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { + requestedType := argsI.(*getRequest) + client := core.ExtractClient(ctx) + region := requestedType.Region.String() + if region == "" { + defaultRegion, _ := client.GetDefaultRegion() + region = defaultRegion.String() + } + config := s3config{ + AccessKey: "pouet", + SecretKey: "pouet", + Region: region, + } + + switch requestedType.Type { + case "s3cmd": + res, err := config.exportS3cmdConfig() + if err != nil { + return nil, err + } + return res, nil + case "rclone": + res, err := config.exportRcloneConfig() + if err != nil { + return nil, err + } + return res, nil + case "mc": + res, err := config.exportMcConfig() + if err != nil { + return nil, err + } + return res, nil + default: + fmt.Println("Unknown tool.") + return nil, nil + } + }, + } +} + +type s3config struct { + AccessKey string + SecretKey string + Region string +} + +func renderTemplate(configFileTemplate string, c s3config) (string, error) { + tmpl, err := template.New("configuration").Parse(configFileTemplate) + if err != nil { + return "", err + } + + var buf bytes.Buffer + err = tmpl.Execute(&buf, c) + if err != nil { + return "", err + } + + return buf.String(), nil +} + +func (c s3config) exportS3cmdConfig() (string, error) { + configFileTemplate := `# Generated by scaleway-cli command +# Configuration file for s3cmd https://s3tools.org/s3cmd +# Default location: $HOME/.s3cfg +[default] +access_key = {{ .AccessKey }} +bucket_location = {{ .Region }} +host_base = s3.{{ .Region }}.scw.cloud +host_bucket = %(bucket)s.s3.{{ .Region }}.scw.cloud +secret_key = {{ .SecretKey }} +use_https = True` + + return renderTemplate(configFileTemplate, c) +} + +func (c s3config) exportRcloneConfig() (string, error) { + configFileTemplate := `# Generated by scaleway-cli command +# Configuration file for rclone https://rclone.org/s3/#scaleway +# Default location: $HOME/.config/rclone/rclone.conf +[scaleway_{{ .Region }}] +type = s3 +env_auth = false +endpoint = s3.{{ .Region }}.scw.cloud +access_key_id = {{ .AccessKey }} +secret_access_key = {{ .SecretKey }} +region = {{ .Region }} +location_constraint = +acl = private +force_path_style = false +server_side_encryption = +storage_class =` + + return renderTemplate(configFileTemplate, c) +} + +func (c s3config) exportMcConfig() (string, error) { + type hostconfig struct { + URL string `json:"url"` + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` + API string `json:"api"` + } + type mcconfig struct { + Version string `json:"version"` + Hosts map[string]hostconfig `json:"hosts"` + } + m := mcconfig{ + Version: "9", + Hosts: map[string]hostconfig{ + "scaleway_" + c.Region: { + URL: "https://s3." + c.Region + ".scw.cloud", + AccessKey: c.AccessKey, + SecretKey: c.SecretKey, + API: "S3v2", + }, + }, + } + res, err := json.Marshal(m) + if err != nil { + return "", nil + } + return string(res), nil +} diff --git a/internal/namespaces/object/v1/custom_test.go b/internal/namespaces/object/v1/custom_config_get_test.go similarity index 90% rename from internal/namespaces/object/v1/custom_test.go rename to internal/namespaces/object/v1/custom_config_get_test.go index ae4f49e590..2b93582ded 100644 --- a/internal/namespaces/object/v1/custom_test.go +++ b/internal/namespaces/object/v1/custom_config_get_test.go @@ -66,17 +66,3 @@ func Test_ConfigGet(t *testing.T) { }) } - -func Test_ConfigInstall(t *testing.T) { - t.Run("rclone", func(t *testing.T) { - - }) - - t.Run("mc", func(t *testing.T) { - - }) - - t.Run("s3cmd", func(t *testing.T) { - - }) -} diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go new file mode 100644 index 0000000000..8e49185910 --- /dev/null +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -0,0 +1,165 @@ +package object + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "path" + "reflect" + + "github.com/scaleway/scaleway-cli/internal/core" + "github.com/scaleway/scaleway-cli/internal/interactive" + "github.com/scaleway/scaleway-sdk-go/scw" +) + +func installCommand() *core.Command { + type installRequest struct { + Region scw.Region + Type string + } + return &core.Command{ + Namespace: "object", + Resource: "config", + Verb: "install", + Short: "Install a S3 related configuration file to its default location", + Long: "Install a S3 related configuration file.", + ArgsType: reflect.TypeOf(installRequest{}), + ArgSpecs: []*core.ArgSpec{ + { + Name: "type", + Short: "Type of tool supported", + Required: true, + EnumValues: []string{"rclone", "s3cmd", "mc"}, + }, + core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), + }, + Examples: []*core.Example{ + { + Short: "Install a s3cmd config file for Paris region", + Raw: "scw object config install type=s3cmd region=fr-par", + }, + { + Short: "Install a rclone config file for default region", + Raw: "scw object config install type=rclone", + }, + + { + Short: "Install a mc (minio) config file for default region", + Raw: "scw object config install type=mc", + }, + }, + SeeAlsos: []*core.SeeAlso{ + { + Short: "Generate a S3 tool configuration file", + Command: "scw object config get", + }, + }, + Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { + requestedType := argsI.(*installRequest) + client := core.ExtractClient(ctx) + region := requestedType.Region.String() + if region == "" { + defaultRegion, _ := client.GetDefaultRegion() + region = defaultRegion.String() + } + config := s3config{ + AccessKey: "pouet", + SecretKey: "pouet", + Region: region, + } + + switch requestedType.Type { + case "s3cmd": + i, err2 := installS3cmd(config) + if err2 != nil { + return i, err2 + } + + case "rclone": + i, err2 := installRclone(config) + if err2 != nil { + return i, err2 + } + + case "mc": + i, err2 := installMc(config) + if err2 != nil { + return i, err2 + } + + default: + fmt.Println("Unknown tool.") + } + return nil, nil + }, + } +} + +func ensureFile(mcConfigPath string, newConfig string) (interface{}, error, bool) { + // Ask whether to remove previous configuration file if it exists + if _, err := os.Stat(mcConfigPath); err == nil { + _, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ + Prompt: "Do you want to overwrite the existing configuration file (" + mcConfigPath + ")?", + DefaultValue: false, + }) + if err != nil { + return "", err, true + } + return nil, ioutil.WriteFile(mcConfigPath, []byte(newConfig), 0644), true + } + return nil, nil, false +} + +func installS3cmd(config s3config) (interface{}, error) { + newConfig, err := config.exportS3cmdConfig() + if err != nil { + return nil, err + } + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + s3cmdConfigPath := path.Join(homeDir, ".s3cfg") + i, err2, done := ensureFile(s3cmdConfigPath, newConfig) + if done { + return i, err2 + } + return nil, nil +} + +func installRclone(config s3config) (interface{}, error) { + newConfig, err := config.exportRcloneConfig() + if err != nil { + return nil, err + } + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + // `rclone config file` returns the path of the configuration file + rcloneConfigPath := path.Join(homeDir, ".config", "rclone", "rclone.conf") + i, err2, done := ensureFile(rcloneConfigPath, newConfig) + if done { + return i, err2 + } + + return nil, nil +} + +func installMc(config s3config) (interface{}, error) { + newConfig, err := config.exportMcConfig() + if err != nil { + return nil, err + } + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + mcConfigPath := path.Join(homeDir, ".mc", "config.json") + i, err2, done := ensureFile(mcConfigPath, newConfig) + if done { + return i, err2 + } + return nil, nil +} diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go new file mode 100644 index 0000000000..acb16fc286 --- /dev/null +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -0,0 +1,19 @@ +package object + +import ( + "testing" +) + +func Test_ConfigInstall(t *testing.T) { + t.Run("rclone", func(t *testing.T) { + + }) + + t.Run("mc", func(t *testing.T) { + + }) + + t.Run("s3cmd", func(t *testing.T) { + + }) +} From 3c11ea40152bc6ca8d55a73b1972a519de63d436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 15:21:29 +0200 Subject: [PATCH 06/37] Fix --- go.sum | 11 ----- .../namespaces/object/v1/custom_config_get.go | 45 +++++++++++++++---- .../object/v1/custom_config_install.go | 13 ++---- .../object/v1/custom_config_install_test.go | 11 +++++ .../test-config-get-default-mc.stdout.golden | 2 +- ...st-config-get-default-rclone.stdout.golden | 4 +- ...est-config-get-default-s3cmd.stdout.golden | 4 +- .../testdata/test-config-get-mc.stdout.golden | 1 - .../test-config-get-rclone.stdout.golden | 15 ------- .../test-config-get-s3cmd.stdout.golden | 10 ----- ...st-config-get-with-region-mc.stdout.golden | 2 +- ...onfig-get-with-region-rclone.stdout.golden | 4 +- ...config-get-with-region-s3cmd.stdout.golden | 4 +- 13 files changed, 61 insertions(+), 65 deletions(-) delete mode 100644 internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden delete mode 100644 internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden delete mode 100644 internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden diff --git a/go.sum b/go.sum index 3ac03e674d..30c060cf68 100644 --- a/go.sum +++ b/go.sum @@ -58,17 +58,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6 h1:C1/pvkxkGN/H03mDxLzItaceYJDBk1HdClgR15suAzI= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200331160105-1181c3dc1bcd h1:ICQFQOSIOyt5n1RxOCAg1rq+DFLunpJpAK2ttjdGhUU= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200331160105-1181c3dc1bcd/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403105108-eb943ac1f1dc h1:YJloAPPmGOEF+nufGL4a9Ppj6jnIMs8FjIorEM3ZBoE= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403105108-eb943ac1f1dc/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403173805-25a10631420d h1:oAG5xtIkUri9hwveoJPv0K3JTSREckKG3MfmNmnXAEQ= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403173805-25a10631420d/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200409105057-297e3dbdccb5 h1:QmrgbtSAIDKRTnzAjdpop3yFAqHFO4MEc8W+/0Epu88= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200409105057-297e3dbdccb5/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200414183251-a6244a393e63 h1:8tRzNwnY+PK6TD21bvKU0p334p+kApiKdHRO3xsZgpg= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200414183251-a6244a393e63/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200421151545-c4338a1f64c9 h1:VExNGApruijWPXvqW/ns6wlNwxAFm/8F7KnknJn5pwc= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200421151545-c4338a1f64c9/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200422170208-cd3e8b9e038c h1:/aJXisEbIVbReS1ofNktWS8s1iT1TPP8eTu7b7Qvmxs= diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index aed8b9f51f..9829047fc6 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -56,16 +56,11 @@ func getCommand() *core.Command { }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { requestedType := argsI.(*getRequest) - client := core.ExtractClient(ctx) region := requestedType.Region.String() - if region == "" { - defaultRegion, _ := client.GetDefaultRegion() - region = defaultRegion.String() - } - config := s3config{ - AccessKey: "pouet", - SecretKey: "pouet", - Region: region, + + config, err := createS3Config(ctx, region) + if err != nil { + return "", err } switch requestedType.Type { @@ -95,6 +90,38 @@ func getCommand() *core.Command { } } +func createS3Config(ctx context.Context, region string) (s3config, error) { + client := core.ExtractClient(ctx) + accessKey, accessExists := client.GetAccessKey() + if !accessExists { + return s3config{}, &core.CliError{ + Err: nil, + Message: "", + Details: "", + Hint: "", + } + } + secretKey, secretExists := client.GetSecretKey() + if !secretExists { + return s3config{}, &core.CliError{ + Err: nil, + Message: "", + Details: "", + Hint: "", + } + } + if region == "" { + defaultRegion, _ := client.GetDefaultRegion() + region = defaultRegion.String() + } + config := s3config{ + AccessKey: accessKey, + SecretKey: secretKey, + Region: region, + } + return config, nil +} + type s3config struct { AccessKey string SecretKey string diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 8e49185910..68590959c8 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -57,16 +57,11 @@ func installCommand() *core.Command { }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { requestedType := argsI.(*installRequest) - client := core.ExtractClient(ctx) region := requestedType.Region.String() - if region == "" { - defaultRegion, _ := client.GetDefaultRegion() - region = defaultRegion.String() - } - config := s3config{ - AccessKey: "pouet", - SecretKey: "pouet", - Region: region, + + config, err := createS3Config(ctx, region) + if err != nil { + return "", err } switch requestedType.Type { diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index acb16fc286..2aef947043 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -7,6 +7,17 @@ import ( func Test_ConfigInstall(t *testing.T) { t.Run("rclone", func(t *testing.T) { + //t.Run("simple", core.Test(&core.TestConfig{ + // Commands: GetCommands(), + // Cmd: "scw object config install type=rclone", + // Check: core.TestCheckCombine( + // // no golden tests since it's os specific + // func(t *testing.T, ctx *core.CheckFuncCtx) { + // testIfKubeconfigInFile(t, path.Join(os.TempDir(), "cli-test"), "-"+ctx.Meta["Cluster"].(*k8s.Cluster).ID, ctx.Meta["Kubeconfig"].(*k8s.Kubeconfig)) + // }, + // core.TestCheckExitCode(0), + // ), + //})) }) t.Run("mc", func(t *testing.T) { diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden index 20b6dc2b8d..dd4c1b5ad0 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden @@ -1 +1 @@ -{"version":"9","hosts":{"scaleway_fr-par":{"url":"https://s3.fr-par.scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} +{"version":"9","hosts":{"scaleway_fr-par":{"url":"https://s3.fr-par.scw.cloud","accessKey":"SCWXXXXXXXXXXXXXXXXX","secretKey":"11111111-1111-1111-1111-111111111111","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden index 807264c60b..8a83c732e4 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden @@ -5,8 +5,8 @@ type = s3 env_auth = false endpoint = s3.fr-par.scw.cloud -access_key_id = pouet -secret_access_key = pouet +access_key_id = SCWXXXXXXXXXXXXXXXXX +secret_access_key = 11111111-1111-1111-1111-111111111111 region = fr-par location_constraint = acl = private diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden index 0146000a99..9c4b5a8761 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-s3cmd.stdout.golden @@ -2,9 +2,9 @@ # Configuration file for s3cmd https://s3tools.org/s3cmd # Default location: $HOME/.s3cfg [default] -access_key = pouet +access_key = SCWXXXXXXXXXXXXXXXXX bucket_location = fr-par host_base = s3.fr-par.scw.cloud host_bucket = %(bucket)s.s3.fr-par.scw.cloud -secret_key = pouet +secret_key = 11111111-1111-1111-1111-111111111111 use_https = True diff --git a/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden deleted file mode 100644 index 20b6dc2b8d..0000000000 --- a/internal/namespaces/object/v1/testdata/test-config-get-mc.stdout.golden +++ /dev/null @@ -1 +0,0 @@ -{"version":"9","hosts":{"scaleway_fr-par":{"url":"https://s3.fr-par.scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden deleted file mode 100644 index 807264c60b..0000000000 --- a/internal/namespaces/object/v1/testdata/test-config-get-rclone.stdout.golden +++ /dev/null @@ -1,15 +0,0 @@ -# Generated by scaleway-cli command -# Configuration file for rclone https://rclone.org/s3/#scaleway -# Default location: $HOME/.config/rclone/rclone.conf -[scaleway_fr-par] -type = s3 -env_auth = false -endpoint = s3.fr-par.scw.cloud -access_key_id = pouet -secret_access_key = pouet -region = fr-par -location_constraint = -acl = private -force_path_style = false -server_side_encryption = -storage_class = diff --git a/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden deleted file mode 100644 index 0146000a99..0000000000 --- a/internal/namespaces/object/v1/testdata/test-config-get-s3cmd.stdout.golden +++ /dev/null @@ -1,10 +0,0 @@ -# Generated by scaleway-cli command -# Configuration file for s3cmd https://s3tools.org/s3cmd -# Default location: $HOME/.s3cfg -[default] -access_key = pouet -bucket_location = fr-par -host_base = s3.fr-par.scw.cloud -host_bucket = %(bucket)s.s3.fr-par.scw.cloud -secret_key = pouet -use_https = True diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden index 85bcfbc01a..46bc3af73d 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden @@ -1 +1 @@ -{"version":"9","hosts":{"scaleway_nl-ams":{"url":"https://s3.nl-ams.scw.cloud","accessKey":"pouet","secretKey":"pouet","api":"S3v2"}}} +{"version":"9","hosts":{"scaleway_nl-ams":{"url":"https://s3.nl-ams.scw.cloud","accessKey":"SCWXXXXXXXXXXXXXXXXX","secretKey":"11111111-1111-1111-1111-111111111111","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden index 689c98cc39..003e893a8c 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden @@ -5,8 +5,8 @@ type = s3 env_auth = false endpoint = s3.nl-ams.scw.cloud -access_key_id = pouet -secret_access_key = pouet +access_key_id = SCWXXXXXXXXXXXXXXXXX +secret_access_key = 11111111-1111-1111-1111-111111111111 region = nl-ams location_constraint = acl = private diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden index e5e34d4069..d485b919b7 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-s3cmd.stdout.golden @@ -2,9 +2,9 @@ # Configuration file for s3cmd https://s3tools.org/s3cmd # Default location: $HOME/.s3cfg [default] -access_key = pouet +access_key = SCWXXXXXXXXXXXXXXXXX bucket_location = nl-ams host_base = s3.nl-ams.scw.cloud host_bucket = %(bucket)s.s3.nl-ams.scw.cloud -secret_key = pouet +secret_key = 11111111-1111-1111-1111-111111111111 use_https = True From 176d6638db5814efdd828ef16ca2f9002fbeb977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 15:53:40 +0200 Subject: [PATCH 07/37] Fix --- .../namespaces/object/v1/custom_config_get.go | 8 +- .../object/v1/custom_config_install.go | 77 ++++++++++--------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index 9829047fc6..fd661de375 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/json" - "fmt" "reflect" "text/template" @@ -83,8 +82,11 @@ func getCommand() *core.Command { } return res, nil default: - fmt.Println("Unknown tool.") - return nil, nil + return nil, &core.CliError{ + Message: "", + Details: "", + Hint: "", + } } }, } diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 68590959c8..fd29810bfc 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -63,70 +63,74 @@ func installCommand() *core.Command { if err != nil { return "", err } - + var configPath string switch requestedType.Type { case "s3cmd": - i, err2 := installS3cmd(config) - if err2 != nil { - return i, err2 + configPath, err = installS3cmd(config) + if err != nil { + return nil, err } case "rclone": - i, err2 := installRclone(config) - if err2 != nil { - return i, err2 + configPath, err = installRclone(config) + if err != nil { + return nil, err } case "mc": - i, err2 := installMc(config) - if err2 != nil { - return i, err2 + configPath, err = installMc(config) + if err != nil { + return nil, err } default: - fmt.Println("Unknown tool.") + return nil, &core.CliError{ + Message: "", + Details: "", + Hint: "", + } } - return nil, nil + return fmt.Sprintf("Configuration file successfully installed at %s", configPath), nil }, } } -func ensureFile(mcConfigPath string, newConfig string) (interface{}, error, bool) { +func ensureFile(configPath string, newConfig string) error { // Ask whether to remove previous configuration file if it exists - if _, err := os.Stat(mcConfigPath); err == nil { + if _, err := os.Stat(configPath); err == nil { _, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ - Prompt: "Do you want to overwrite the existing configuration file (" + mcConfigPath + ")?", + Prompt: "Do you want to overwrite the existing configuration file (" + configPath + ")?", DefaultValue: false, }) if err != nil { - return "", err, true + return err } - return nil, ioutil.WriteFile(mcConfigPath, []byte(newConfig), 0644), true + return ioutil.WriteFile(configPath, []byte(newConfig), 0644) } - return nil, nil, false + return ioutil.WriteFile(configPath, []byte(newConfig), 0644) } -func installS3cmd(config s3config) (interface{}, error) { +func installS3cmd(config s3config) (string, error) { newConfig, err := config.exportS3cmdConfig() if err != nil { - return nil, err + return "", err } homeDir, err := os.UserHomeDir() if err != nil { return "", err } s3cmdConfigPath := path.Join(homeDir, ".s3cfg") - i, err2, done := ensureFile(s3cmdConfigPath, newConfig) - if done { - return i, err2 + err = ensureFile(s3cmdConfigPath, newConfig) + if err != nil { + return "", err } - return nil, nil + return s3cmdConfigPath, nil } -func installRclone(config s3config) (interface{}, error) { +func installRclone(config s3config) (string, error) { newConfig, err := config.exportRcloneConfig() if err != nil { - return nil, err + return "", err } homeDir, err := os.UserHomeDir() if err != nil { @@ -134,27 +138,26 @@ func installRclone(config s3config) (interface{}, error) { } // `rclone config file` returns the path of the configuration file rcloneConfigPath := path.Join(homeDir, ".config", "rclone", "rclone.conf") - i, err2, done := ensureFile(rcloneConfigPath, newConfig) - if done { - return i, err2 + err = ensureFile(rcloneConfigPath, newConfig) + if err != nil { + return "", err } - - return nil, nil + return rcloneConfigPath, nil } -func installMc(config s3config) (interface{}, error) { +func installMc(config s3config) (string, error) { newConfig, err := config.exportMcConfig() if err != nil { - return nil, err + return "", err } homeDir, err := os.UserHomeDir() if err != nil { return "", err } mcConfigPath := path.Join(homeDir, ".mc", "config.json") - i, err2, done := ensureFile(mcConfigPath, newConfig) - if done { - return i, err2 + err = ensureFile(mcConfigPath, newConfig) + if err != nil { + return "", err } - return nil, nil + return mcConfigPath, nil } From 546fb6a2b6ec61f77351f05615f4ca2e0543d222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 16:43:31 +0200 Subject: [PATCH 08/37] Fix --- .../object/v1/custom_config_install_test.go | 63 +++++++++++++------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index 2aef947043..56df5fe848 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -1,30 +1,57 @@ package object import ( + "os" + "path" "testing" + + "github.com/scaleway/scaleway-cli/internal/core" ) func Test_ConfigInstall(t *testing.T) { - t.Run("rclone", func(t *testing.T) { - - //t.Run("simple", core.Test(&core.TestConfig{ - // Commands: GetCommands(), - // Cmd: "scw object config install type=rclone", - // Check: core.TestCheckCombine( - // // no golden tests since it's os specific - // func(t *testing.T, ctx *core.CheckFuncCtx) { - // testIfKubeconfigInFile(t, path.Join(os.TempDir(), "cli-test"), "-"+ctx.Meta["Cluster"].(*k8s.Cluster).ID, ctx.Meta["Kubeconfig"].(*k8s.Kubeconfig)) - // }, - // core.TestCheckExitCode(0), - // ), - //})) - }) + tmpDir := os.TempDir() - t.Run("mc", func(t *testing.T) { - - }) + t.Run("NoExistingConfig", func(t *testing.T) { + t.Run("rclone", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config install type=rclone", + Check: core.TestCheckCombine( + func(t *testing.T, ctx *core.CheckFuncCtx) { + os.Stat(path.Join(tmpDir, ".config", "rclone", "rclone.conf")) + }, + core.TestCheckExitCode(0), + ), + OverrideEnv: map[string]string{ + "HOME": tmpDir, + }, + })) - t.Run("s3cmd", func(t *testing.T) { + t.Run("mc", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config install type=mc", + Check: core.TestCheckCombine( + func(t *testing.T, ctx *core.CheckFuncCtx) { + os.Stat(path.Join(tmpDir, ".mc", "config.json")) + }, + core.TestCheckExitCode(0), + ), + OverrideEnv: map[string]string{ + "HOME": tmpDir, + }, + })) + t.Run("s3cmd", core.Test(&core.TestConfig{ + Commands: GetCommands(), + Cmd: "scw object config install type=s3cmd", + Check: core.TestCheckCombine( + func(t *testing.T, ctx *core.CheckFuncCtx) { + os.Stat(path.Join(tmpDir, ".s3cfg")) + }, + core.TestCheckExitCode(0), + ), + OverrideEnv: map[string]string{ + "HOME": tmpDir, + }, + })) }) } From f8e8010a584692e0e48630d2e8aaa88582be6d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 17:36:02 +0200 Subject: [PATCH 09/37] Fix --- internal/namespaces/object/v1/custom.go | 6 ++++++ .../namespaces/object/v1/custom_config_get.go | 21 ++++++++----------- .../object/v1/custom_config_install.go | 8 +++---- .../object/v1/custom_config_install_test.go | 15 ++++++++++--- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/internal/namespaces/object/v1/custom.go b/internal/namespaces/object/v1/custom.go index 78ce3f3285..c90b50799d 100644 --- a/internal/namespaces/object/v1/custom.go +++ b/internal/namespaces/object/v1/custom.go @@ -28,3 +28,9 @@ func objectConfig() *core.Command { Resource: `config`, } } + +var supportedTools = []string{ + "rclone", + "s3cmd", + "mc", +} diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index fd661de375..f0241de0e2 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "reflect" "text/template" @@ -29,7 +30,7 @@ func getCommand() *core.Command { Name: "type", Short: "Type of tool supported", Required: true, - EnumValues: []string{"rclone", "s3cmd", "mc"}, + EnumValues: supportedTools, }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, @@ -83,9 +84,9 @@ func getCommand() *core.Command { return res, nil default: return nil, &core.CliError{ - Message: "", - Details: "", - Hint: "", + Message: "Unknown tool type", + Details: fmt.Sprintf("%s is an unknown tool", requestedType.Type), + Hint: fmt.Sprintf("Try using on the following types: %s", supportedTools), } } }, @@ -97,19 +98,15 @@ func createS3Config(ctx context.Context, region string) (s3config, error) { accessKey, accessExists := client.GetAccessKey() if !accessExists { return s3config{}, &core.CliError{ - Err: nil, - Message: "", - Details: "", - Hint: "", + Message: "No access key found", + Hint: "Try to run `scw init` to set up your configuration.", } } secretKey, secretExists := client.GetSecretKey() if !secretExists { return s3config{}, &core.CliError{ - Err: nil, - Message: "", - Details: "", - Hint: "", + Message: "No secret key found", + Hint: "Try to run `scw init` to set up your configuration.", } } if region == "" { diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index fd29810bfc..375d26acbc 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -30,7 +30,7 @@ func installCommand() *core.Command { Name: "type", Short: "Type of tool supported", Required: true, - EnumValues: []string{"rclone", "s3cmd", "mc"}, + EnumValues: supportedTools, }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, @@ -85,9 +85,9 @@ func installCommand() *core.Command { default: return nil, &core.CliError{ - Message: "", - Details: "", - Hint: "", + Message: "Unknown tool type", + Details: fmt.Sprintf("%s is an unknown tool", requestedType.Type), + Hint: fmt.Sprintf("Try using on the following types: %s", supportedTools), } } return fmt.Sprintf("Configuration file successfully installed at %s", configPath), nil diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index 56df5fe848..103684c52c 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -17,7 +17,10 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=rclone", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - os.Stat(path.Join(tmpDir, ".config", "rclone", "rclone.conf")) + _, err := os.Stat(path.Join(tmpDir, ".config", "rclone", "rclone.conf")) + if err != nil { + t.Fail() + } }, core.TestCheckExitCode(0), ), @@ -31,7 +34,10 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=mc", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - os.Stat(path.Join(tmpDir, ".mc", "config.json")) + _, err := os.Stat(path.Join(tmpDir, ".mc", "config.json")) + if err != nil { + t.Fail() + } }, core.TestCheckExitCode(0), ), @@ -45,7 +51,10 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=s3cmd", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - os.Stat(path.Join(tmpDir, ".s3cfg")) + _, err := os.Stat(path.Join(tmpDir, ".s3cfg")) + if err != nil { + t.Fail() + } }, core.TestCheckExitCode(0), ), From f93ded1e6fbe52c4c8ceea32fba7dd2b8fa265a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 19:35:10 +0200 Subject: [PATCH 10/37] Fix --- internal/namespaces/object/v1/custom.go | 10 +- .../namespaces/object/v1/custom_config_get.go | 183 +++--------------- .../object/v1/custom_config_install.go | 146 ++++---------- internal/namespaces/object/v1/s3configfile.go | 151 +++++++++++++++ 4 files changed, 220 insertions(+), 270 deletions(-) create mode 100644 internal/namespaces/object/v1/s3configfile.go diff --git a/internal/namespaces/object/v1/custom.go b/internal/namespaces/object/v1/custom.go index c90b50799d..76d1fb30b4 100644 --- a/internal/namespaces/object/v1/custom.go +++ b/internal/namespaces/object/v1/custom.go @@ -8,8 +8,8 @@ func GetCommands() *core.Commands { return core.NewCommands( objectRoot(), objectConfig(), - getCommand(), - installCommand(), + configGetCommand(), + configInstallCommand(), ) } @@ -28,9 +28,3 @@ func objectConfig() *core.Command { Resource: `config`, } } - -var supportedTools = []string{ - "rclone", - "s3cmd", - "mc", -} diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index f0241de0e2..a5ab21d533 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -1,21 +1,18 @@ package object import ( - "bytes" "context" - "encoding/json" - "fmt" "reflect" - "text/template" "github.com/scaleway/scaleway-cli/internal/core" "github.com/scaleway/scaleway-sdk-go/scw" ) -func getCommand() *core.Command { - type getRequest struct { +func configGetCommand() *core.Command { + type getArgs struct { Region scw.Region - Type string + Type s3tool + Name string } return &core.Command{ @@ -24,28 +21,36 @@ func getCommand() *core.Command { Verb: "get", Short: "Generate a S3 related configuration file", Long: "Generate a S3 related configuration file.", - ArgsType: reflect.TypeOf(getRequest{}), + ArgsType: reflect.TypeOf(getArgs{}), ArgSpecs: []*core.ArgSpec{ { Name: "type", - Short: "Type of tool supported", + Short: "Type of S3 tool you want to generate a config for", Required: true, EnumValues: supportedTools, }, + { + Name: "name", + Short: "Name of the s3 remote you want to generate", + Required: false, + Default: func() (value string, doc string) { + return "scaleway", "default value" + }, + }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, Examples: []*core.Example{ { - Short: "Generate a s3cmd s3config file for Paris region", - Raw: "scw object config install type=s3cmd region=fr-par", + Short: "Generate a s3cmd config file for Paris region", + Request: `{"type": "s3cmd", "region": "fr-par"}`, }, { - Short: "Generate a rclone s3config file for default region", - Raw: "scw object config install type=rclone", + Short: "Generate a rclone config file for default region", + Request: `{"type": "rclone"}`, }, { - Short: "Generate a mc (minio) s3config file for default region", - Raw: "scw object config install type=mc", + Short: "Generate a mc (minio) config file for default region", + Request: `{"type": "mc"}`, }, }, SeeAlsos: []*core.SeeAlso{ @@ -55,153 +60,15 @@ func getCommand() *core.Command { }, }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { - requestedType := argsI.(*getRequest) - region := requestedType.Region.String() + args := argsI.(*getArgs) + region := args.Region + name := args.Name - config, err := createS3Config(ctx, region) + config, err := newS3Config(ctx, region, name) if err != nil { return "", err } - - switch requestedType.Type { - case "s3cmd": - res, err := config.exportS3cmdConfig() - if err != nil { - return nil, err - } - return res, nil - case "rclone": - res, err := config.exportRcloneConfig() - if err != nil { - return nil, err - } - return res, nil - case "mc": - res, err := config.exportMcConfig() - if err != nil { - return nil, err - } - return res, nil - default: - return nil, &core.CliError{ - Message: "Unknown tool type", - Details: fmt.Sprintf("%s is an unknown tool", requestedType.Type), - Hint: fmt.Sprintf("Try using on the following types: %s", supportedTools), - } - } - }, - } -} - -func createS3Config(ctx context.Context, region string) (s3config, error) { - client := core.ExtractClient(ctx) - accessKey, accessExists := client.GetAccessKey() - if !accessExists { - return s3config{}, &core.CliError{ - Message: "No access key found", - Hint: "Try to run `scw init` to set up your configuration.", - } - } - secretKey, secretExists := client.GetSecretKey() - if !secretExists { - return s3config{}, &core.CliError{ - Message: "No secret key found", - Hint: "Try to run `scw init` to set up your configuration.", - } - } - if region == "" { - defaultRegion, _ := client.GetDefaultRegion() - region = defaultRegion.String() - } - config := s3config{ - AccessKey: accessKey, - SecretKey: secretKey, - Region: region, - } - return config, nil -} - -type s3config struct { - AccessKey string - SecretKey string - Region string -} - -func renderTemplate(configFileTemplate string, c s3config) (string, error) { - tmpl, err := template.New("configuration").Parse(configFileTemplate) - if err != nil { - return "", err - } - - var buf bytes.Buffer - err = tmpl.Execute(&buf, c) - if err != nil { - return "", err - } - - return buf.String(), nil -} - -func (c s3config) exportS3cmdConfig() (string, error) { - configFileTemplate := `# Generated by scaleway-cli command -# Configuration file for s3cmd https://s3tools.org/s3cmd -# Default location: $HOME/.s3cfg -[default] -access_key = {{ .AccessKey }} -bucket_location = {{ .Region }} -host_base = s3.{{ .Region }}.scw.cloud -host_bucket = %(bucket)s.s3.{{ .Region }}.scw.cloud -secret_key = {{ .SecretKey }} -use_https = True` - - return renderTemplate(configFileTemplate, c) -} - -func (c s3config) exportRcloneConfig() (string, error) { - configFileTemplate := `# Generated by scaleway-cli command -# Configuration file for rclone https://rclone.org/s3/#scaleway -# Default location: $HOME/.config/rclone/rclone.conf -[scaleway_{{ .Region }}] -type = s3 -env_auth = false -endpoint = s3.{{ .Region }}.scw.cloud -access_key_id = {{ .AccessKey }} -secret_access_key = {{ .SecretKey }} -region = {{ .Region }} -location_constraint = -acl = private -force_path_style = false -server_side_encryption = -storage_class =` - - return renderTemplate(configFileTemplate, c) -} - -func (c s3config) exportMcConfig() (string, error) { - type hostconfig struct { - URL string `json:"url"` - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` - API string `json:"api"` - } - type mcconfig struct { - Version string `json:"version"` - Hosts map[string]hostconfig `json:"hosts"` - } - m := mcconfig{ - Version: "9", - Hosts: map[string]hostconfig{ - "scaleway_" + c.Region: { - URL: "https://s3." + c.Region + ".scw.cloud", - AccessKey: c.AccessKey, - SecretKey: c.SecretKey, - API: "S3v2", - }, + return config.getConfigFile(args.Type) }, } - res, err := json.Marshal(m) - if err != nil { - return "", nil - } - return string(res), nil } diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 375d26acbc..5fce4fcaec 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "os" - "path" "reflect" "github.com/scaleway/scaleway-cli/internal/core" @@ -13,10 +12,11 @@ import ( "github.com/scaleway/scaleway-sdk-go/scw" ) -func installCommand() *core.Command { - type installRequest struct { +func configInstallCommand() *core.Command { + type installArgs struct { Region scw.Region - Type string + Type s3tool + Name string } return &core.Command{ Namespace: "object", @@ -24,29 +24,37 @@ func installCommand() *core.Command { Verb: "install", Short: "Install a S3 related configuration file to its default location", Long: "Install a S3 related configuration file.", - ArgsType: reflect.TypeOf(installRequest{}), + ArgsType: reflect.TypeOf(installArgs{}), ArgSpecs: []*core.ArgSpec{ { Name: "type", - Short: "Type of tool supported", + Short: "Type of S3 tool you want to generate a config for", Required: true, EnumValues: supportedTools, }, + { + Name: "name", + Short: "Name of the s3 remote you want to generate", + Required: false, + Default: func() (value string, doc string) { + return "scaleway", "default value" + }, + }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, Examples: []*core.Example{ { - Short: "Install a s3cmd config file for Paris region", - Raw: "scw object config install type=s3cmd region=fr-par", + Short: "Install a s3cmd config file for Paris region", + Request: `{"type": "s3cmd", "region": "fr-par"}`, }, { - Short: "Install a rclone config file for default region", - Raw: "scw object config install type=rclone", + Short: "Install a rclone config file for default region", + Request: `{"type": "rclone"}`, }, { - Short: "Install a mc (minio) config file for default region", - Raw: "scw object config install type=mc", + Short: "Install a mc (minio) config file for default region", + Request: `{"type": "mc"}`, }, }, SeeAlsos: []*core.SeeAlso{ @@ -56,108 +64,38 @@ func installCommand() *core.Command { }, }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { - requestedType := argsI.(*installRequest) - region := requestedType.Region.String() + args := argsI.(*installArgs) + region := args.Region + name := args.Name - config, err := createS3Config(ctx, region) + config, err := newS3Config(ctx, region, name) + if err != nil { + return "", err + } + newConfig, err := config.getConfigFile(args.Type) + if err != nil { + return "", err + } + configPath, err := config.getPath(args.Type) if err != nil { return "", err } - var configPath string - switch requestedType.Type { - case "s3cmd": - configPath, err = installS3cmd(config) - if err != nil { - return nil, err - } - - case "rclone": - configPath, err = installRclone(config) - if err != nil { - return nil, err - } - case "mc": - configPath, err = installMc(config) + // Ask whether to remove previous configuration file if it exists + if _, err := os.Stat(configPath); err == nil { + _, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ + Prompt: "Do you want to overwrite the existing configuration file (" + configPath + ")?", + DefaultValue: false, + }) if err != nil { return nil, err } - - default: - return nil, &core.CliError{ - Message: "Unknown tool type", - Details: fmt.Sprintf("%s is an unknown tool", requestedType.Type), - Hint: fmt.Sprintf("Try using on the following types: %s", supportedTools), - } + } + err = ioutil.WriteFile(configPath, []byte(newConfig), 0644) + if err != nil { + return "", err } return fmt.Sprintf("Configuration file successfully installed at %s", configPath), nil }, } } - -func ensureFile(configPath string, newConfig string) error { - // Ask whether to remove previous configuration file if it exists - if _, err := os.Stat(configPath); err == nil { - _, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ - Prompt: "Do you want to overwrite the existing configuration file (" + configPath + ")?", - DefaultValue: false, - }) - if err != nil { - return err - } - return ioutil.WriteFile(configPath, []byte(newConfig), 0644) - } - return ioutil.WriteFile(configPath, []byte(newConfig), 0644) -} - -func installS3cmd(config s3config) (string, error) { - newConfig, err := config.exportS3cmdConfig() - if err != nil { - return "", err - } - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - s3cmdConfigPath := path.Join(homeDir, ".s3cfg") - err = ensureFile(s3cmdConfigPath, newConfig) - if err != nil { - return "", err - } - return s3cmdConfigPath, nil -} - -func installRclone(config s3config) (string, error) { - newConfig, err := config.exportRcloneConfig() - if err != nil { - return "", err - } - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - // `rclone config file` returns the path of the configuration file - rcloneConfigPath := path.Join(homeDir, ".config", "rclone", "rclone.conf") - err = ensureFile(rcloneConfigPath, newConfig) - if err != nil { - return "", err - } - return rcloneConfigPath, nil -} - -func installMc(config s3config) (string, error) { - newConfig, err := config.exportMcConfig() - if err != nil { - return "", err - } - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - mcConfigPath := path.Join(homeDir, ".mc", "config.json") - err = ensureFile(mcConfigPath, newConfig) - if err != nil { - return "", err - } - return mcConfigPath, nil -} diff --git a/internal/namespaces/object/v1/s3configfile.go b/internal/namespaces/object/v1/s3configfile.go new file mode 100644 index 0000000000..e3af0eb827 --- /dev/null +++ b/internal/namespaces/object/v1/s3configfile.go @@ -0,0 +1,151 @@ +package object + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "os" + "path" + "text/template" + + "github.com/scaleway/scaleway-cli/internal/core" + "github.com/scaleway/scaleway-sdk-go/scw" +) + +type s3tool string + +type s3config struct { + AccessKey string + SecretKey string + Region scw.Region + Name string +} + +const ( + rclone = s3tool("rclone") + s3cmd = s3tool("s3cmd") + mc = s3tool("mc") +) + +var supportedTools = []s3tool{ + rclone, + s3cmd, + mc, +} + +const s3cmdTemplate = `# Generated by scaleway-cli command +# Configuration file for s3cmd https://s3tools.org/s3cmd +# Default location: $HOME/.s3cfg +[default] +access_key = {{ .AccessKey }} +bucket_location = {{ .Region }} +host_base = s3.{{ .Region }}.scw.cloud +host_bucket = %(bucket)s.s3.{{ .Region }}.scw.cloud +secret_key = {{ .SecretKey }} +use_https = True` + +const rcloneTemplate = `# Generated by scaleway-cli command +# Configuration file for rclone https://rclone.org/s3/#scaleway +# Default location: $HOME/.config/rclone/rclone.conf +[{{ .Name }}] +type = s3 +env_auth = false +endpoint = s3.{{ .Region }}.scw.cloud +access_key_id = {{ .AccessKey }} +secret_access_key = {{ .SecretKey }} +region = {{ .Region }} +location_constraint = +acl = private +force_path_style = false +server_side_encryption = +storage_class =` + +func newS3Config(ctx context.Context, region scw.Region, name string) (s3config, error) { + client := core.ExtractClient(ctx) + accessKey, accessExists := client.GetAccessKey() + if !accessExists { + return s3config{}, fmt.Errorf("no access key found") + } + secretKey, secretExists := client.GetSecretKey() + if !secretExists { + return s3config{}, fmt.Errorf("no secret key found") + } + config := s3config{ + AccessKey: accessKey, + SecretKey: secretKey, + Region: region, + Name: name, + } + return config, nil +} + +func (c s3config) getPath(tool s3tool) (string, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + switch tool { + case s3cmd: + return path.Join(homeDir, ".s3cfg"), nil + case rclone: + return path.Join(homeDir, ".config", "rclone", "rclone.conf"), nil + case mc: + return path.Join(homeDir, ".mc", "config.json"), nil + default: + return "", fmt.Errorf("unknown tool") + } +} + +func (c s3config) renderTemplate(configFileTemplate string) (string, error) { + tmpl, err := template.New("configuration").Parse(configFileTemplate) + if err != nil { + return "", err + } + + var buf bytes.Buffer + err = tmpl.Execute(&buf, c) + if err != nil { + return "", err + } + + return buf.String(), nil +} + +func (c s3config) getConfigFile(tool s3tool) (string, error) { + switch tool { + case s3cmd: + return c.renderTemplate(s3cmdTemplate) + case rclone: + return c.renderTemplate(rcloneTemplate) + case mc: + type hostconfig struct { + URL string `json:"url"` + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` + API string `json:"api"` + } + type mcconfig struct { + Version string `json:"version"` + Hosts map[string]hostconfig `json:"hosts"` + } + m := mcconfig{ + Version: "9", + Hosts: map[string]hostconfig{ + c.Name: { + URL: "https://s3." + c.Region.String() + ".scw.cloud", + AccessKey: c.AccessKey, + SecretKey: c.SecretKey, + API: "S3v2", + }, + }, + } + res, err := json.Marshal(m) + if err != nil { + return "", nil + } + return string(res), nil + default: + return "", fmt.Errorf("unknown tool") + } +} From 6a382f8ef5bb54d7936b970d2fbd60dcf68680ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 20:20:39 +0200 Subject: [PATCH 11/37] FIx --- ...sage-object-config-get-usage.stderr.golden | 31 +++++++++++++++++++ ...-object-config-install-usage.stderr.golden | 31 +++++++++++++++++++ ...ll-usage-object-config-usage.stderr.golden | 18 +++++++++++ .../test-all-usage-object-usage.stderr.golden | 17 ++++++++++ .../namespaces/object/v1/custom_config_get.go | 8 ++--- .../object/v1/custom_config_install.go | 8 ++--- internal/namespaces/object/v1/s3configfile.go | 8 +++++ .../test-config-get-default-mc.stdout.golden | 2 +- ...st-config-get-default-rclone.stdout.golden | 2 +- ...st-config-get-with-region-mc.stdout.golden | 2 +- ...onfig-get-with-region-rclone.stdout.golden | 2 +- 11 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 cmd/scw/testdata/test-all-usage-object-config-get-usage.stderr.golden create mode 100644 cmd/scw/testdata/test-all-usage-object-config-install-usage.stderr.golden create mode 100644 cmd/scw/testdata/test-all-usage-object-config-usage.stderr.golden create mode 100644 cmd/scw/testdata/test-all-usage-object-usage.stderr.golden diff --git a/cmd/scw/testdata/test-all-usage-object-config-get-usage.stderr.golden b/cmd/scw/testdata/test-all-usage-object-config-get-usage.stderr.golden new file mode 100644 index 0000000000..f98f79e33f --- /dev/null +++ b/cmd/scw/testdata/test-all-usage-object-config-get-usage.stderr.golden @@ -0,0 +1,31 @@ +Generate a S3 tool configuration file. + +USAGE: + scw object config get [arg=value ...] + +EXAMPLES: + Generate a s3cmd config file for Paris region + scw object config get region=fr-par type=s3cmd + + Generate a rclone config file for default region + scw object config get type=rclone + + Generate a mc (minio) config file for default region + scw object config get type=mc + +ARGS: + type Type of S3 tool you want to generate a config for (rclone | s3cmd | mc) + [name=scaleway] Name of the s3 remote you want to generate + [region] Region to target. If none is passed will use default region from the config (fr-par | nl-ams) + +FLAGS: + -h, --help help for get + +GLOBAL FLAGS: + -D, --debug Enable debug mode + -o, --output string Output format: json or human + -p, --profile string The config profile to use + +SEE ALSO: + # Install a S3 tool configuration file + scw object config install diff --git a/cmd/scw/testdata/test-all-usage-object-config-install-usage.stderr.golden b/cmd/scw/testdata/test-all-usage-object-config-install-usage.stderr.golden new file mode 100644 index 0000000000..efed199a2a --- /dev/null +++ b/cmd/scw/testdata/test-all-usage-object-config-install-usage.stderr.golden @@ -0,0 +1,31 @@ +Install a S3 tool configuration file to its default location. + +USAGE: + scw object config install [arg=value ...] + +EXAMPLES: + Install a s3cmd config file for Paris region + scw object config install region=fr-par type=s3cmd + + Install a rclone config file for default region + scw object config install type=rclone + + Install a mc (minio) config file for default region + scw object config install type=mc + +ARGS: + type Type of S3 tool you want to generate a config for (rclone | s3cmd | mc) + [name=scaleway] Name of the s3 remote you want to generate + [region] Region to target. If none is passed will use default region from the config (fr-par | nl-ams) + +FLAGS: + -h, --help help for install + +GLOBAL FLAGS: + -D, --debug Enable debug mode + -o, --output string Output format: json or human + -p, --profile string The config profile to use + +SEE ALSO: + # Generate a S3 tool configuration file + scw object config get diff --git a/cmd/scw/testdata/test-all-usage-object-config-usage.stderr.golden b/cmd/scw/testdata/test-all-usage-object-config-usage.stderr.golden new file mode 100644 index 0000000000..e88be4d96d --- /dev/null +++ b/cmd/scw/testdata/test-all-usage-object-config-usage.stderr.golden @@ -0,0 +1,18 @@ +Configuration generation for S3 tools. + +USAGE: + scw object config + +AVAILABLE COMMANDS: + get Generate a S3 tool configuration file + install Install a S3 tool configuration file to its default location + +FLAGS: + -h, --help help for config + +GLOBAL FLAGS: + -D, --debug Enable debug mode + -o, --output string Output format: json or human + -p, --profile string The config profile to use + +Use "scw object config [command] --help" for more information about a command. diff --git a/cmd/scw/testdata/test-all-usage-object-usage.stderr.golden b/cmd/scw/testdata/test-all-usage-object-usage.stderr.golden new file mode 100644 index 0000000000..c10d8db6d6 --- /dev/null +++ b/cmd/scw/testdata/test-all-usage-object-usage.stderr.golden @@ -0,0 +1,17 @@ +Object-storage utils + +USAGE: + scw object + +AVAILABLE COMMANDS: + config Manage configuration files for popular S3 tools + +FLAGS: + -h, --help help for object + +GLOBAL FLAGS: + -D, --debug Enable debug mode + -o, --output string Output format: json or human + -p, --profile string The config profile to use + +Use "scw object [command] --help" for more information about a command. diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index a5ab21d533..7168882dd2 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -19,22 +19,22 @@ func configGetCommand() *core.Command { Namespace: "object", Resource: "config", Verb: "get", - Short: "Generate a S3 related configuration file", - Long: "Generate a S3 related configuration file.", + Short: "Generate a S3 tool configuration file", + Long: "Generate a S3 tool configuration file.", ArgsType: reflect.TypeOf(getArgs{}), ArgSpecs: []*core.ArgSpec{ { Name: "type", Short: "Type of S3 tool you want to generate a config for", Required: true, - EnumValues: supportedTools, + EnumValues: []string{rclone.String(), s3cmd.String(), mc.String()}, }, { Name: "name", Short: "Name of the s3 remote you want to generate", Required: false, Default: func() (value string, doc string) { - return "scaleway", "default value" + return "scaleway", "scaleway" }, }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 5fce4fcaec..e04b923624 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -22,22 +22,22 @@ func configInstallCommand() *core.Command { Namespace: "object", Resource: "config", Verb: "install", - Short: "Install a S3 related configuration file to its default location", - Long: "Install a S3 related configuration file.", + Short: "Install a S3 tool configuration file to its default location", + Long: "Install a S3 tool configuration file to its default location.", ArgsType: reflect.TypeOf(installArgs{}), ArgSpecs: []*core.ArgSpec{ { Name: "type", Short: "Type of S3 tool you want to generate a config for", Required: true, - EnumValues: supportedTools, + EnumValues: []string{rclone.String(), s3cmd.String(), mc.String()}, }, { Name: "name", Short: "Name of the s3 remote you want to generate", Required: false, Default: func() (value string, doc string) { - return "scaleway", "default value" + return "scaleway", "scaleway" }, }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), diff --git a/internal/namespaces/object/v1/s3configfile.go b/internal/namespaces/object/v1/s3configfile.go index e3af0eb827..4721ca1cee 100644 --- a/internal/namespaces/object/v1/s3configfile.go +++ b/internal/namespaces/object/v1/s3configfile.go @@ -15,6 +15,10 @@ import ( type s3tool string +func (c s3tool) String() string { + return string(c) +} + type s3config struct { AccessKey string SecretKey string @@ -71,6 +75,10 @@ func newS3Config(ctx context.Context, region scw.Region, name string) (s3config, if !secretExists { return s3config{}, fmt.Errorf("no secret key found") } + if region == "" { + defaultRegion, _ := client.GetDefaultRegion() + region = defaultRegion + } config := s3config{ AccessKey: accessKey, SecretKey: secretKey, diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden index dd4c1b5ad0..25185e3ca1 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-mc.stdout.golden @@ -1 +1 @@ -{"version":"9","hosts":{"scaleway_fr-par":{"url":"https://s3.fr-par.scw.cloud","accessKey":"SCWXXXXXXXXXXXXXXXXX","secretKey":"11111111-1111-1111-1111-111111111111","api":"S3v2"}}} +{"version":"9","hosts":{"scaleway":{"url":"https://s3.fr-par.scw.cloud","accessKey":"SCWXXXXXXXXXXXXXXXXX","secretKey":"11111111-1111-1111-1111-111111111111","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden index 8a83c732e4..d565c758e3 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-default-rclone.stdout.golden @@ -1,7 +1,7 @@ # Generated by scaleway-cli command # Configuration file for rclone https://rclone.org/s3/#scaleway # Default location: $HOME/.config/rclone/rclone.conf -[scaleway_fr-par] +[scaleway] type = s3 env_auth = false endpoint = s3.fr-par.scw.cloud diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden index 46bc3af73d..fb71129eca 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-mc.stdout.golden @@ -1 +1 @@ -{"version":"9","hosts":{"scaleway_nl-ams":{"url":"https://s3.nl-ams.scw.cloud","accessKey":"SCWXXXXXXXXXXXXXXXXX","secretKey":"11111111-1111-1111-1111-111111111111","api":"S3v2"}}} +{"version":"9","hosts":{"scaleway":{"url":"https://s3.nl-ams.scw.cloud","accessKey":"SCWXXXXXXXXXXXXXXXXX","secretKey":"11111111-1111-1111-1111-111111111111","api":"S3v2"}}} diff --git a/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden index 003e893a8c..b58e9342ce 100644 --- a/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden +++ b/internal/namespaces/object/v1/testdata/test-config-get-with-region-rclone.stdout.golden @@ -1,7 +1,7 @@ # Generated by scaleway-cli command # Configuration file for rclone https://rclone.org/s3/#scaleway # Default location: $HOME/.config/rclone/rclone.conf -[scaleway_nl-ams] +[scaleway] type = s3 env_auth = false endpoint = s3.nl-ams.scw.cloud From acd983c41de2093e5fa022354550ddea36a7f7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Tue, 21 Apr 2020 20:24:49 +0200 Subject: [PATCH 12/37] FIx --- go.sum | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/go.sum b/go.sum index 30c060cf68..3ac03e674d 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,17 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6 h1:C1/pvkxkGN/H03mDxLzItaceYJDBk1HdClgR15suAzI= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200331160105-1181c3dc1bcd h1:ICQFQOSIOyt5n1RxOCAg1rq+DFLunpJpAK2ttjdGhUU= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200331160105-1181c3dc1bcd/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403105108-eb943ac1f1dc h1:YJloAPPmGOEF+nufGL4a9Ppj6jnIMs8FjIorEM3ZBoE= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403105108-eb943ac1f1dc/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403173805-25a10631420d h1:oAG5xtIkUri9hwveoJPv0K3JTSREckKG3MfmNmnXAEQ= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403173805-25a10631420d/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200409105057-297e3dbdccb5 h1:QmrgbtSAIDKRTnzAjdpop3yFAqHFO4MEc8W+/0Epu88= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200409105057-297e3dbdccb5/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200414183251-a6244a393e63 h1:8tRzNwnY+PK6TD21bvKU0p334p+kApiKdHRO3xsZgpg= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200414183251-a6244a393e63/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200421151545-c4338a1f64c9 h1:VExNGApruijWPXvqW/ns6wlNwxAFm/8F7KnknJn5pwc= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200421151545-c4338a1f64c9/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200422170208-cd3e8b9e038c h1:/aJXisEbIVbReS1ofNktWS8s1iT1TPP8eTu7b7Qvmxs= From 4f80e5a96fbc0dca1ea8541ba131a5b5024ee221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Wed, 22 Apr 2020 16:31:06 +0200 Subject: [PATCH 13/37] Fix --- internal/namespaces/object/v1/custom_config_get.go | 2 +- .../namespaces/object/v1/custom_config_install.go | 2 +- internal/namespaces/object/v1/s3configfile.go | 12 +++++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index 7168882dd2..8182213af9 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -27,7 +27,7 @@ func configGetCommand() *core.Command { Name: "type", Short: "Type of S3 tool you want to generate a config for", Required: true, - EnumValues: []string{rclone.String(), s3cmd.String(), mc.String()}, + EnumValues: supportedTools.ToStringArray(), }, { Name: "name", diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index e04b923624..6cabbc1f35 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -30,7 +30,7 @@ func configInstallCommand() *core.Command { Name: "type", Short: "Type of S3 tool you want to generate a config for", Required: true, - EnumValues: []string{rclone.String(), s3cmd.String(), mc.String()}, + EnumValues: supportedTools.ToStringArray(), }, { Name: "name", diff --git a/internal/namespaces/object/v1/s3configfile.go b/internal/namespaces/object/v1/s3configfile.go index 4721ca1cee..430ab62cdf 100644 --- a/internal/namespaces/object/v1/s3configfile.go +++ b/internal/namespaces/object/v1/s3configfile.go @@ -19,6 +19,16 @@ func (c s3tool) String() string { return string(c) } +type SupportedTool []s3tool + +func (s SupportedTool) ToStringArray() []string { + var res []string + for _, x := range s { + res = append(res, x.String()) + } + return res +} + type s3config struct { AccessKey string SecretKey string @@ -32,7 +42,7 @@ const ( mc = s3tool("mc") ) -var supportedTools = []s3tool{ +var supportedTools = SupportedTool{ rclone, s3cmd, mc, From 98d399a35fc04f03ecf434293129bb58d2fc0237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Wed, 22 Apr 2020 16:35:31 +0200 Subject: [PATCH 14/37] Fix --- cmd/scw/testdata/test-main-usage-usage.stderr.golden | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/scw/testdata/test-main-usage-usage.stderr.golden b/cmd/scw/testdata/test-main-usage-usage.stderr.golden index 3f3530dc83..cd06dcdcf8 100644 --- a/cmd/scw/testdata/test-main-usage-usage.stderr.golden +++ b/cmd/scw/testdata/test-main-usage-usage.stderr.golden @@ -10,6 +10,7 @@ AVAILABLE COMMANDS: config Config file management account This API allows to manage your scaleway account autocomplete Install autocomplete script + object Object-storage utils version Display cli version registry Docker registry API help Help about any command From 47dc2dea3053c7915db82c5c2c4a80a89f554385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Wed, 22 Apr 2020 18:00:32 +0200 Subject: [PATCH 15/37] Fix --- internal/namespaces/object/v1/custom_config_install.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 6cabbc1f35..cc1c980400 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -83,15 +83,18 @@ func configInstallCommand() *core.Command { // Ask whether to remove previous configuration file if it exists if _, err := os.Stat(configPath); err == nil { - _, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ + doIt, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ Prompt: "Do you want to overwrite the existing configuration file (" + configPath + ")?", DefaultValue: false, }) if err != nil { return nil, err } + if !doIt { + return "Installation aborted by user", nil + } } - err = ioutil.WriteFile(configPath, []byte(newConfig), 0644) + err = ioutil.WriteFile(configPath, []byte(newConfig), 0600) if err != nil { return "", err } From 8c6b3f2462a9cb0615368c62cfd614813ccc42bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 10:44:13 +0200 Subject: [PATCH 16/37] Fix --- internal/core/testing.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/core/testing.go b/internal/core/testing.go index 1001b75bc5..a57c1b9542 100644 --- a/internal/core/testing.go +++ b/internal/core/testing.go @@ -146,6 +146,7 @@ func getTestClient(t *testing.T, testConfig *TestConfig) (client *scw.Client, cl scw.WithEnv(), scw.WithUserAgent("cli-e2e-test"), scw.WithDefaultOrganizationID("11111111-1111-1111-1111-111111111111"), + scw.WithAuth("SCWXXXXXXXXXXXXXXXXX", "11111111-1111-1111-1111-111111111111"), } // If client is NOT an E2E client we init http recorder and load configuration. From 2845dd980b7ed747b4becb03edfeaa58e79a6f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 11:43:51 +0200 Subject: [PATCH 17/37] Fix --- .../object/v1/custom_config_install_test.go | 31 ++----------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index 103684c52c..c9a95b78a3 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -2,7 +2,6 @@ package object import ( "os" - "path" "testing" "github.com/scaleway/scaleway-cli/internal/core" @@ -15,15 +14,7 @@ func Test_ConfigInstall(t *testing.T) { t.Run("rclone", core.Test(&core.TestConfig{ Commands: GetCommands(), Cmd: "scw object config install type=rclone", - Check: core.TestCheckCombine( - func(t *testing.T, ctx *core.CheckFuncCtx) { - _, err := os.Stat(path.Join(tmpDir, ".config", "rclone", "rclone.conf")) - if err != nil { - t.Fail() - } - }, - core.TestCheckExitCode(0), - ), + Check: core.TestCheckExitCode(0), OverrideEnv: map[string]string{ "HOME": tmpDir, }, @@ -32,15 +23,7 @@ func Test_ConfigInstall(t *testing.T) { t.Run("mc", core.Test(&core.TestConfig{ Commands: GetCommands(), Cmd: "scw object config install type=mc", - Check: core.TestCheckCombine( - func(t *testing.T, ctx *core.CheckFuncCtx) { - _, err := os.Stat(path.Join(tmpDir, ".mc", "config.json")) - if err != nil { - t.Fail() - } - }, - core.TestCheckExitCode(0), - ), + Check: core.TestCheckExitCode(0), OverrideEnv: map[string]string{ "HOME": tmpDir, }, @@ -49,15 +32,7 @@ func Test_ConfigInstall(t *testing.T) { t.Run("s3cmd", core.Test(&core.TestConfig{ Commands: GetCommands(), Cmd: "scw object config install type=s3cmd", - Check: core.TestCheckCombine( - func(t *testing.T, ctx *core.CheckFuncCtx) { - _, err := os.Stat(path.Join(tmpDir, ".s3cfg")) - if err != nil { - t.Fail() - } - }, - core.TestCheckExitCode(0), - ), + Check: core.TestCheckExitCode(0), OverrideEnv: map[string]string{ "HOME": tmpDir, }, From 494f93937877d40473fc7eb3b5c2a676bd882f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 11:45:44 +0200 Subject: [PATCH 18/37] Revert "Fix" This reverts commit 475ef26f1223dcf3c63cb10df5d0205b33fdc967. --- .../object/v1/custom_config_install_test.go | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index c9a95b78a3..103684c52c 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -2,6 +2,7 @@ package object import ( "os" + "path" "testing" "github.com/scaleway/scaleway-cli/internal/core" @@ -14,7 +15,15 @@ func Test_ConfigInstall(t *testing.T) { t.Run("rclone", core.Test(&core.TestConfig{ Commands: GetCommands(), Cmd: "scw object config install type=rclone", - Check: core.TestCheckExitCode(0), + Check: core.TestCheckCombine( + func(t *testing.T, ctx *core.CheckFuncCtx) { + _, err := os.Stat(path.Join(tmpDir, ".config", "rclone", "rclone.conf")) + if err != nil { + t.Fail() + } + }, + core.TestCheckExitCode(0), + ), OverrideEnv: map[string]string{ "HOME": tmpDir, }, @@ -23,7 +32,15 @@ func Test_ConfigInstall(t *testing.T) { t.Run("mc", core.Test(&core.TestConfig{ Commands: GetCommands(), Cmd: "scw object config install type=mc", - Check: core.TestCheckExitCode(0), + Check: core.TestCheckCombine( + func(t *testing.T, ctx *core.CheckFuncCtx) { + _, err := os.Stat(path.Join(tmpDir, ".mc", "config.json")) + if err != nil { + t.Fail() + } + }, + core.TestCheckExitCode(0), + ), OverrideEnv: map[string]string{ "HOME": tmpDir, }, @@ -32,7 +49,15 @@ func Test_ConfigInstall(t *testing.T) { t.Run("s3cmd", core.Test(&core.TestConfig{ Commands: GetCommands(), Cmd: "scw object config install type=s3cmd", - Check: core.TestCheckExitCode(0), + Check: core.TestCheckCombine( + func(t *testing.T, ctx *core.CheckFuncCtx) { + _, err := os.Stat(path.Join(tmpDir, ".s3cfg")) + if err != nil { + t.Fail() + } + }, + core.TestCheckExitCode(0), + ), OverrideEnv: map[string]string{ "HOME": tmpDir, }, From 12785a3c5205bca4014a1c5c866f62dc2753c8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 16:24:01 +0200 Subject: [PATCH 19/37] Fix --- .../namespaces/object/v1/custom_config_install.go | 11 ++++++++++- .../object/v1/custom_config_install_test.go | 12 +++++++++--- internal/namespaces/object/v1/s3configfile.go | 9 +++------ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index cc1c980400..fa3fc2db15 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "reflect" "github.com/scaleway/scaleway-cli/internal/core" @@ -76,7 +77,7 @@ func configInstallCommand() *core.Command { if err != nil { return "", err } - configPath, err := config.getPath(args.Type) + configPath, err := config.getPath(args.Type, ctx) if err != nil { return "", err } @@ -94,6 +95,14 @@ func configInstallCommand() *core.Command { return "Installation aborted by user", nil } } + + // Ensure the subfolders for the configuration files are all created + err = os.MkdirAll(filepath.Dir(configPath), 755) + if err != nil { + return "", err + } + + // Write the configuration file err = ioutil.WriteFile(configPath, []byte(newConfig), 0600) if err != nil { return "", err diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index 103684c52c..5007ee61cc 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -17,8 +17,10 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=rclone", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - _, err := os.Stat(path.Join(tmpDir, ".config", "rclone", "rclone.conf")) + filePath := path.Join(tmpDir, ".config", "rclone", "rclone.conf") + _, err := os.Stat(filePath) if err != nil { + t.Logf("No file at %s", filePath) t.Fail() } }, @@ -34,8 +36,10 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=mc", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - _, err := os.Stat(path.Join(tmpDir, ".mc", "config.json")) + filePath := path.Join(tmpDir, ".mc", "config.json") + _, err := os.Stat(filePath) if err != nil { + t.Logf("No file at %s", filePath) t.Fail() } }, @@ -51,8 +55,10 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=s3cmd", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - _, err := os.Stat(path.Join(tmpDir, ".s3cfg")) + filePath := path.Join(tmpDir, ".s3cfg") + _, err := os.Stat(filePath) if err != nil { + t.Logf("No file at %s", filePath) t.Fail() } }, diff --git a/internal/namespaces/object/v1/s3configfile.go b/internal/namespaces/object/v1/s3configfile.go index 430ab62cdf..1e7e59974d 100644 --- a/internal/namespaces/object/v1/s3configfile.go +++ b/internal/namespaces/object/v1/s3configfile.go @@ -5,7 +5,6 @@ import ( "context" "encoding/json" "fmt" - "os" "path" "text/template" @@ -98,11 +97,9 @@ func newS3Config(ctx context.Context, region scw.Region, name string) (s3config, return config, nil } -func (c s3config) getPath(tool s3tool) (string, error) { - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } +func (c s3config) getPath(tool s3tool, ctx context.Context) (string, error) { + homeDir := core.ExtractUserHomeDir(ctx) + switch tool { case s3cmd: return path.Join(homeDir, ".s3cfg"), nil From 91bf0d093b5a6ea8aab81324a16861b6d3960a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 16:46:18 +0200 Subject: [PATCH 20/37] Fix --- go.sum | 13 ------------- internal/core/testing.go | 8 ++++++-- .../object/v1/custom_config_install_test.go | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/go.sum b/go.sum index 3ac03e674d..2202b71791 100644 --- a/go.sum +++ b/go.sum @@ -58,19 +58,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6 h1:C1/pvkxkGN/H03mDxLzItaceYJDBk1HdClgR15suAzI= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200331160105-1181c3dc1bcd h1:ICQFQOSIOyt5n1RxOCAg1rq+DFLunpJpAK2ttjdGhUU= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200331160105-1181c3dc1bcd/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403105108-eb943ac1f1dc h1:YJloAPPmGOEF+nufGL4a9Ppj6jnIMs8FjIorEM3ZBoE= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403105108-eb943ac1f1dc/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403173805-25a10631420d h1:oAG5xtIkUri9hwveoJPv0K3JTSREckKG3MfmNmnXAEQ= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200403173805-25a10631420d/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200409105057-297e3dbdccb5 h1:QmrgbtSAIDKRTnzAjdpop3yFAqHFO4MEc8W+/0Epu88= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200409105057-297e3dbdccb5/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200414183251-a6244a393e63 h1:8tRzNwnY+PK6TD21bvKU0p334p+kApiKdHRO3xsZgpg= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200414183251-a6244a393e63/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200421151545-c4338a1f64c9 h1:VExNGApruijWPXvqW/ns6wlNwxAFm/8F7KnknJn5pwc= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200421151545-c4338a1f64c9/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200422170208-cd3e8b9e038c h1:/aJXisEbIVbReS1ofNktWS8s1iT1TPP8eTu7b7Qvmxs= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200422170208-cd3e8b9e038c/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= diff --git a/internal/core/testing.go b/internal/core/testing.go index a57c1b9542..9cbad04e3e 100644 --- a/internal/core/testing.go +++ b/internal/core/testing.go @@ -118,6 +118,9 @@ type TestConfig struct { // OverrideEnv contains environment variables that will be overridden during the test. OverrideEnv map[string]string + + // Custom client + Client *scw.Client } // getTestFilePath returns a valid filename path based on the go test name and suffix. (Take care of non fs friendly char) @@ -146,7 +149,6 @@ func getTestClient(t *testing.T, testConfig *TestConfig) (client *scw.Client, cl scw.WithEnv(), scw.WithUserAgent("cli-e2e-test"), scw.WithDefaultOrganizationID("11111111-1111-1111-1111-111111111111"), - scw.WithAuth("SCWXXXXXXXXXXXXXXXXX", "11111111-1111-1111-1111-111111111111"), } // If client is NOT an E2E client we init http recorder and load configuration. @@ -172,7 +174,9 @@ func getTestClient(t *testing.T, testConfig *TestConfig) (client *scw.Client, cl clientOpts = append(clientOpts, scw.WithDefaultZone(testConfig.DefaultZone)) } - client, err = scw.NewClient(clientOpts...) + if testConfig.Client == nil { + client, err = scw.NewClient(clientOpts...) + } require.NoError(t, err) // If client is an E2E client we must register and use returned credential. diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index 5007ee61cc..ce8b2a8998 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -6,10 +6,24 @@ import ( "testing" "github.com/scaleway/scaleway-cli/internal/core" + "github.com/scaleway/scaleway-sdk-go/scw" ) func Test_ConfigInstall(t *testing.T) { tmpDir := os.TempDir() + clientOpts := []scw.ClientOption{ + scw.WithDefaultRegion(scw.RegionFrPar), + scw.WithDefaultZone(scw.ZoneFrPar1), + scw.WithEnv(), + scw.WithUserAgent("cli-e2e-test"), + scw.WithDefaultOrganizationID("11111111-1111-1111-1111-111111111111"), + scw.WithAuth("SCWXXXXXXXXXXXXXXXXX", "11111111-1111-1111-1111-111111111111"), + } + + client, err := scw.NewClient(clientOpts...) + if err != nil { + t.Fail() + } t.Run("NoExistingConfig", func(t *testing.T) { t.Run("rclone", core.Test(&core.TestConfig{ @@ -29,6 +43,7 @@ func Test_ConfigInstall(t *testing.T) { OverrideEnv: map[string]string{ "HOME": tmpDir, }, + Client: client, })) t.Run("mc", core.Test(&core.TestConfig{ @@ -48,6 +63,7 @@ func Test_ConfigInstall(t *testing.T) { OverrideEnv: map[string]string{ "HOME": tmpDir, }, + Client: client, })) t.Run("s3cmd", core.Test(&core.TestConfig{ @@ -67,6 +83,7 @@ func Test_ConfigInstall(t *testing.T) { OverrideEnv: map[string]string{ "HOME": tmpDir, }, + Client: client, })) }) } From 6a1f43e9d89444c104b62d2d9139fee5c66c55e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:11:27 +0200 Subject: [PATCH 21/37] Fix --- internal/core/testing.go | 16 ++++++++++------ .../object/v1/custom_config_install_test.go | 12 +++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/internal/core/testing.go b/internal/core/testing.go index 9cbad04e3e..b2c573c767 100644 --- a/internal/core/testing.go +++ b/internal/core/testing.go @@ -138,7 +138,7 @@ func getTestFilePath(t *testing.T, suffix string) string { return filepath.Join(".", "testdata", fileName) } -func getTestClient(t *testing.T, testConfig *TestConfig) (client *scw.Client, cleanup func()) { +func createTestClient(t *testing.T, testConfig *TestConfig) (client *scw.Client, cleanup func()) { var err error cleanup = func() {} @@ -174,9 +174,7 @@ func getTestClient(t *testing.T, testConfig *TestConfig) (client *scw.Client, cl clientOpts = append(clientOpts, scw.WithDefaultZone(testConfig.DefaultZone)) } - if testConfig.Client == nil { - client, err = scw.NewClient(clientOpts...) - } + client, err = scw.NewClient(clientOpts...) require.NoError(t, err) // If client is an E2E client we must register and use returned credential. @@ -204,8 +202,14 @@ func Test(config *TestConfig) func(t *testing.T) { return "few seconds ago", nil }) - client, cleanup := getTestClient(t, config) - defer cleanup() + // We try to use the client provided in the config + // if no client is provided in the config we create a test client + client := config.Client + if client == nil { + var cleanup func() + client, cleanup = createTestClient(t, config) + defer cleanup() + } meta := map[string]interface{}{} diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index ce8b2a8998..eada99b5d8 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -1,29 +1,26 @@ package object import ( + "fmt" "os" "path" "testing" "github.com/scaleway/scaleway-cli/internal/core" "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/stretchr/testify/require" ) func Test_ConfigInstall(t *testing.T) { tmpDir := os.TempDir() clientOpts := []scw.ClientOption{ - scw.WithDefaultRegion(scw.RegionFrPar), scw.WithDefaultZone(scw.ZoneFrPar1), - scw.WithEnv(), - scw.WithUserAgent("cli-e2e-test"), - scw.WithDefaultOrganizationID("11111111-1111-1111-1111-111111111111"), + scw.WithDefaultRegion(scw.RegionFrPar), scw.WithAuth("SCWXXXXXXXXXXXXXXXXX", "11111111-1111-1111-1111-111111111111"), } client, err := scw.NewClient(clientOpts...) - if err != nil { - t.Fail() - } + require.NoError(t, err) t.Run("NoExistingConfig", func(t *testing.T) { t.Run("rclone", core.Test(&core.TestConfig{ @@ -31,6 +28,7 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=rclone", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { + fmt.Println(ctx.Err) filePath := path.Join(tmpDir, ".config", "rclone", "rclone.conf") _, err := os.Stat(filePath) if err != nil { From b607b89811002961066f80758fed27fee237056a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:14:22 +0200 Subject: [PATCH 22/37] Fix --- internal/core/testing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/core/testing.go b/internal/core/testing.go index b2c573c767..3f00b28988 100644 --- a/internal/core/testing.go +++ b/internal/core/testing.go @@ -119,7 +119,7 @@ type TestConfig struct { // OverrideEnv contains environment variables that will be overridden during the test. OverrideEnv map[string]string - // Custom client + // Custom client to use for test, if none are provided will create one automatically Client *scw.Client } From fb8f719b83e648a230995923ec7684ca5b939828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:16:05 +0200 Subject: [PATCH 23/37] Fix --- internal/namespaces/object/v1/custom_config_get.go | 4 +--- internal/namespaces/object/v1/custom_config_install.go | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index 8182213af9..864db9d34a 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -33,9 +33,7 @@ func configGetCommand() *core.Command { Name: "name", Short: "Name of the s3 remote you want to generate", Required: false, - Default: func() (value string, doc string) { - return "scaleway", "scaleway" - }, + Default: core.DefaultValueSetter("scaleway"), }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index fa3fc2db15..890568e467 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -37,9 +37,7 @@ func configInstallCommand() *core.Command { Name: "name", Short: "Name of the s3 remote you want to generate", Required: false, - Default: func() (value string, doc string) { - return "scaleway", "scaleway" - }, + Default: core.DefaultValueSetter("scaleway"), }, core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms), }, From 43f791cf0cfec424b39b6ad12d21ba8cab109bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:23:04 +0200 Subject: [PATCH 24/37] Fix --- internal/namespaces/object/v1/custom_config_get.go | 4 +--- internal/namespaces/object/v1/custom_config_install.go | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_get.go b/internal/namespaces/object/v1/custom_config_get.go index 864db9d34a..e0f941f47c 100644 --- a/internal/namespaces/object/v1/custom_config_get.go +++ b/internal/namespaces/object/v1/custom_config_get.go @@ -59,10 +59,8 @@ func configGetCommand() *core.Command { }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { args := argsI.(*getArgs) - region := args.Region - name := args.Name - config, err := newS3Config(ctx, region, name) + config, err := newS3Config(ctx, args.Region, args.Name) if err != nil { return "", err } diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 890568e467..0465926841 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -64,10 +64,8 @@ func configInstallCommand() *core.Command { }, Run: func(ctx context.Context, argsI interface{}) (interface{}, error) { args := argsI.(*installArgs) - region := args.Region - name := args.Name - config, err := newS3Config(ctx, region, name) + config, err := newS3Config(ctx, args.Region, args.Name) if err != nil { return "", err } From 2f3c5545afaf70d8b2f5742a412c14db31bb7843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:25:41 +0200 Subject: [PATCH 25/37] Fix --- .../object/v1/custom_config_get_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/internal/namespaces/object/v1/custom_config_get_test.go b/internal/namespaces/object/v1/custom_config_get_test.go index 2b93582ded..57550f7c0a 100644 --- a/internal/namespaces/object/v1/custom_config_get_test.go +++ b/internal/namespaces/object/v1/custom_config_get_test.go @@ -4,9 +4,20 @@ import ( "testing" "github.com/scaleway/scaleway-cli/internal/core" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/stretchr/testify/require" ) func Test_ConfigGet(t *testing.T) { + clientOpts := []scw.ClientOption{ + scw.WithDefaultZone(scw.ZoneFrPar1), + scw.WithDefaultRegion(scw.RegionFrPar), + scw.WithAuth("SCWXXXXXXXXXXXXXXXXX", "11111111-1111-1111-1111-111111111111"), + } + + client, err := scw.NewClient(clientOpts...) + require.NoError(t, err) + t.Run("Default", func(t *testing.T) { t.Run("rclone", core.Test(&core.TestConfig{ Commands: GetCommands(), @@ -15,6 +26,7 @@ func Test_ConfigGet(t *testing.T) { core.TestCheckGolden(), core.TestCheckExitCode(0), ), + Client: client, })) t.Run("mc", core.Test(&core.TestConfig{ @@ -24,6 +36,7 @@ func Test_ConfigGet(t *testing.T) { core.TestCheckGolden(), core.TestCheckExitCode(0), ), + Client: client, })) t.Run("s3cmd", core.Test(&core.TestConfig{ @@ -33,6 +46,7 @@ func Test_ConfigGet(t *testing.T) { core.TestCheckGolden(), core.TestCheckExitCode(0), ), + Client: client, })) }) @@ -44,6 +58,7 @@ func Test_ConfigGet(t *testing.T) { core.TestCheckGolden(), core.TestCheckExitCode(0), ), + Client: client, })) t.Run("mc", core.Test(&core.TestConfig{ @@ -53,6 +68,7 @@ func Test_ConfigGet(t *testing.T) { core.TestCheckGolden(), core.TestCheckExitCode(0), ), + Client: client, })) t.Run("s3cmd", core.Test(&core.TestConfig{ @@ -62,6 +78,7 @@ func Test_ConfigGet(t *testing.T) { core.TestCheckGolden(), core.TestCheckExitCode(0), ), + Client: client, })) }) From 9760591b7709a8fd9eea9269eaefd023faecb6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:30:32 +0200 Subject: [PATCH 26/37] Fix --- internal/namespaces/object/v1/custom_config_install.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 0465926841..9a587b4cd2 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -88,12 +88,12 @@ func configInstallCommand() *core.Command { return nil, err } if !doIt { - return "Installation aborted by user", nil + return nil, fmt.Errorf("installation aborted by user") } } // Ensure the subfolders for the configuration files are all created - err = os.MkdirAll(filepath.Dir(configPath), 755) + err = os.MkdirAll(filepath.Dir(configPath), 0755) if err != nil { return "", err } From e1d49d558ed81c856dbd1ee0a2e905edf9e6aa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:37:41 +0200 Subject: [PATCH 27/37] Fix --- internal/namespaces/object/v1/custom_config_install.go | 5 +++-- internal/namespaces/object/v1/s3configfile.go | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 9a587b4cd2..f374e35686 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -73,7 +73,7 @@ func configInstallCommand() *core.Command { if err != nil { return "", err } - configPath, err := config.getPath(args.Type, ctx) + configPath, err := config.getPath(args.Type) if err != nil { return "", err } @@ -103,7 +103,8 @@ func configInstallCommand() *core.Command { if err != nil { return "", err } - return fmt.Sprintf("Configuration file successfully installed at %s", configPath), nil + return core.SuccessResult{ + Message: fmt.Sprintf("Configuration file successfully installed at %s", configPath)}, nil }, } } diff --git a/internal/namespaces/object/v1/s3configfile.go b/internal/namespaces/object/v1/s3configfile.go index 1e7e59974d..c0f851a0e0 100644 --- a/internal/namespaces/object/v1/s3configfile.go +++ b/internal/namespaces/object/v1/s3configfile.go @@ -33,6 +33,7 @@ type s3config struct { SecretKey string Region scw.Region Name string + ctx context.Context } const ( @@ -93,12 +94,13 @@ func newS3Config(ctx context.Context, region scw.Region, name string) (s3config, SecretKey: secretKey, Region: region, Name: name, + ctx: ctx, } return config, nil } -func (c s3config) getPath(tool s3tool, ctx context.Context) (string, error) { - homeDir := core.ExtractUserHomeDir(ctx) +func (c s3config) getPath(tool s3tool) (string, error) { + homeDir := core.ExtractUserHomeDir(c.ctx) switch tool { case s3cmd: From ae47db1ff6ec9e786dfec1d0b9f243f762cd7408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:56:22 +0200 Subject: [PATCH 28/37] Fix --- internal/core/testing.go | 80 ++++++++++++------- .../object/v1/custom_config_install_test.go | 25 +++--- 2 files changed, 62 insertions(+), 43 deletions(-) diff --git a/internal/core/testing.go b/internal/core/testing.go index 3f00b28988..19d700eb7b 100644 --- a/internal/core/testing.go +++ b/internal/core/testing.go @@ -54,6 +54,9 @@ type CheckFuncCtx struct { // Scaleway client Client *scw.Client + + // OverrideEnv passed in the TestConfig + OverrideEnv map[string]string } // TestCheck is a function that perform assertion on a CheckFuncCtx @@ -64,18 +67,20 @@ type BeforeFunc func(ctx *BeforeFuncCtx) error type AfterFunc func(ctx *AfterFuncCtx) error type BeforeFuncCtx struct { - T *testing.T - Client *scw.Client - ExecuteCmd func(args []string) interface{} - Meta map[string]interface{} + T *testing.T + Client *scw.Client + ExecuteCmd func(args []string) interface{} + Meta map[string]interface{} + OverrideEnv map[string]string } type AfterFuncCtx struct { - T *testing.T - Client *scw.Client - ExecuteCmd func(args []string) interface{} - Meta map[string]interface{} - CmdResult interface{} + T *testing.T + Client *scw.Client + ExecuteCmd func(args []string) interface{} + Meta map[string]interface{} + CmdResult interface{} + OverrideEnv map[string]string } // TestConfig contain configuration that can be used with the Test function @@ -116,6 +121,10 @@ type TestConfig struct { // Fake build info for this test. BuildInfo BuildInfo + // If set, it will create a temporary home directory during the tests. + // Get this folder with ExtractUserHomeDir() + MockHomeDir bool + // OverrideEnv contains environment variables that will be overridden during the test. OverrideEnv map[string]string @@ -212,6 +221,20 @@ func Test(config *TestConfig) func(t *testing.T) { } meta := map[string]interface{}{} + overideEnv := config.OverrideEnv + if overideEnv == nil { + overideEnv = map[string]string{} + } + + if config.MockHomeDir { + dir, err := ioutil.TempDir(os.TempDir(), "scw") + require.NoError(t, err) + defer func() { + err = os.RemoveAll(dir) + assert.NoError(t, err) + }() + overideEnv["HOME"] = dir + } executeCmd := func(args []string) interface{} { stdoutBuffer := &bytes.Buffer{} @@ -225,7 +248,7 @@ func Test(config *TestConfig) func(t *testing.T) { Stderr: stderrBuffer, Client: client, DisableTelemetry: true, - OverrideEnv: config.OverrideEnv, + OverrideEnv: overideEnv, }) require.NoError(t, err, "stdout: %s\nstderr: %s", stdoutBuffer.String(), stderrBuffer.String()) @@ -235,10 +258,11 @@ func Test(config *TestConfig) func(t *testing.T) { // Run config.BeforeFunc if config.BeforeFunc != nil { require.NoError(t, config.BeforeFunc(&BeforeFuncCtx{ - T: t, - Client: client, - ExecuteCmd: executeCmd, - Meta: meta, + T: t, + Client: client, + ExecuteCmd: executeCmd, + Meta: meta, + OverrideEnv: overideEnv, })) } @@ -262,29 +286,31 @@ func Test(config *TestConfig) func(t *testing.T) { Stderr: stderr, Client: client, DisableTelemetry: true, - OverrideEnv: config.OverrideEnv, + OverrideEnv: overideEnv, }) meta["CmdResult"] = result config.Check(t, &CheckFuncCtx{ - ExitCode: exitCode, - Stdout: stdout.Bytes(), - Stderr: stderr.Bytes(), - Meta: meta, - Result: result, - Err: err, - Client: client, + ExitCode: exitCode, + Stdout: stdout.Bytes(), + Stderr: stderr.Bytes(), + Meta: meta, + Result: result, + Err: err, + Client: client, + OverrideEnv: overideEnv, }) } // Run config.AfterFunc if config.AfterFunc != nil { require.NoError(t, config.AfterFunc(&AfterFuncCtx{ - T: t, - Client: client, - ExecuteCmd: executeCmd, - Meta: meta, - CmdResult: result, + T: t, + Client: client, + ExecuteCmd: executeCmd, + Meta: meta, + CmdResult: result, + OverrideEnv: overideEnv, })) } } diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index eada99b5d8..5815ad12cf 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -12,7 +12,6 @@ import ( ) func Test_ConfigInstall(t *testing.T) { - tmpDir := os.TempDir() clientOpts := []scw.ClientOption{ scw.WithDefaultZone(scw.ZoneFrPar1), scw.WithDefaultRegion(scw.RegionFrPar), @@ -29,7 +28,7 @@ func Test_ConfigInstall(t *testing.T) { Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { fmt.Println(ctx.Err) - filePath := path.Join(tmpDir, ".config", "rclone", "rclone.conf") + filePath := path.Join(ctx.OverrideEnv["HOME"], ".config", "rclone", "rclone.conf") _, err := os.Stat(filePath) if err != nil { t.Logf("No file at %s", filePath) @@ -38,10 +37,8 @@ func Test_ConfigInstall(t *testing.T) { }, core.TestCheckExitCode(0), ), - OverrideEnv: map[string]string{ - "HOME": tmpDir, - }, - Client: client, + MockHomeDir: true, + Client: client, })) t.Run("mc", core.Test(&core.TestConfig{ @@ -49,7 +46,7 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=mc", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - filePath := path.Join(tmpDir, ".mc", "config.json") + filePath := path.Join(ctx.OverrideEnv["HOME"], ".mc", "config.json") _, err := os.Stat(filePath) if err != nil { t.Logf("No file at %s", filePath) @@ -58,10 +55,8 @@ func Test_ConfigInstall(t *testing.T) { }, core.TestCheckExitCode(0), ), - OverrideEnv: map[string]string{ - "HOME": tmpDir, - }, - Client: client, + MockHomeDir: true, + Client: client, })) t.Run("s3cmd", core.Test(&core.TestConfig{ @@ -69,7 +64,7 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=s3cmd", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - filePath := path.Join(tmpDir, ".s3cfg") + filePath := path.Join(ctx.OverrideEnv["HOME"], ".s3cfg") _, err := os.Stat(filePath) if err != nil { t.Logf("No file at %s", filePath) @@ -78,10 +73,8 @@ func Test_ConfigInstall(t *testing.T) { }, core.TestCheckExitCode(0), ), - OverrideEnv: map[string]string{ - "HOME": tmpDir, - }, - Client: client, + MockHomeDir: true, + Client: client, })) }) } From 69f12571beeb7fe2534b2ec9de8c97eef72d5a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:58:25 +0200 Subject: [PATCH 29/37] Fix --- internal/core/testing.go | 4 ++-- .../object/v1/custom_config_install_test.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/core/testing.go b/internal/core/testing.go index 19d700eb7b..dd1cc4e995 100644 --- a/internal/core/testing.go +++ b/internal/core/testing.go @@ -123,7 +123,7 @@ type TestConfig struct { // If set, it will create a temporary home directory during the tests. // Get this folder with ExtractUserHomeDir() - MockHomeDir bool + TmpHomeDir bool // OverrideEnv contains environment variables that will be overridden during the test. OverrideEnv map[string]string @@ -226,7 +226,7 @@ func Test(config *TestConfig) func(t *testing.T) { overideEnv = map[string]string{} } - if config.MockHomeDir { + if config.TmpHomeDir { dir, err := ioutil.TempDir(os.TempDir(), "scw") require.NoError(t, err) defer func() { diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index 5815ad12cf..4c3dc70fb1 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -37,8 +37,8 @@ func Test_ConfigInstall(t *testing.T) { }, core.TestCheckExitCode(0), ), - MockHomeDir: true, - Client: client, + TmpHomeDir: true, + Client: client, })) t.Run("mc", core.Test(&core.TestConfig{ @@ -55,8 +55,8 @@ func Test_ConfigInstall(t *testing.T) { }, core.TestCheckExitCode(0), ), - MockHomeDir: true, - Client: client, + TmpHomeDir: true, + Client: client, })) t.Run("s3cmd", core.Test(&core.TestConfig{ @@ -73,8 +73,8 @@ func Test_ConfigInstall(t *testing.T) { }, core.TestCheckExitCode(0), ), - MockHomeDir: true, - Client: client, + TmpHomeDir: true, + Client: client, })) }) } From e87a6fe8413ebe65934e85c27d95c0232849699c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 17:59:24 +0200 Subject: [PATCH 30/37] Fix --- internal/core/testing.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/core/testing.go b/internal/core/testing.go index dd1cc4e995..86a63b1a62 100644 --- a/internal/core/testing.go +++ b/internal/core/testing.go @@ -221,6 +221,7 @@ func Test(config *TestConfig) func(t *testing.T) { } meta := map[string]interface{}{} + overideEnv := config.OverrideEnv if overideEnv == nil { overideEnv = map[string]string{} From 893bfd06e8d58d62686a37a77325aaf8d590a9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 18:01:07 +0200 Subject: [PATCH 31/37] Fix --- internal/namespaces/object/v1/custom_config_install.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index f374e35686..53867c65f5 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -104,7 +104,8 @@ func configInstallCommand() *core.Command { return "", err } return core.SuccessResult{ - Message: fmt.Sprintf("Configuration file successfully installed at %s", configPath)}, nil + Message: fmt.Sprintf("Configuration file successfully installed at %s", configPath), + }, nil }, } } From 145f07f8862201de37a0142a00ce9bc4f37b9996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 18:02:57 +0200 Subject: [PATCH 32/37] Fix --- .../object/v1/custom_config_install_test.go | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index 4c3dc70fb1..bed45abbe5 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -1,13 +1,12 @@ package object import ( - "fmt" - "os" "path" "testing" "github.com/scaleway/scaleway-cli/internal/core" "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -27,13 +26,8 @@ func Test_ConfigInstall(t *testing.T) { Cmd: "scw object config install type=rclone", Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { - fmt.Println(ctx.Err) filePath := path.Join(ctx.OverrideEnv["HOME"], ".config", "rclone", "rclone.conf") - _, err := os.Stat(filePath) - if err != nil { - t.Logf("No file at %s", filePath) - t.Fail() - } + assert.FileExists(t, filePath) }, core.TestCheckExitCode(0), ), @@ -47,11 +41,7 @@ func Test_ConfigInstall(t *testing.T) { Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".mc", "config.json") - _, err := os.Stat(filePath) - if err != nil { - t.Logf("No file at %s", filePath) - t.Fail() - } + assert.FileExists(t, filePath) }, core.TestCheckExitCode(0), ), @@ -65,11 +55,7 @@ func Test_ConfigInstall(t *testing.T) { Check: core.TestCheckCombine( func(t *testing.T, ctx *core.CheckFuncCtx) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".s3cfg") - _, err := os.Stat(filePath) - if err != nil { - t.Logf("No file at %s", filePath) - t.Fail() - } + assert.FileExists(t, filePath) }, core.TestCheckExitCode(0), ), From e154e5bc256ccec3be294a7fc399c58aaeef4295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 18:04:44 +0200 Subject: [PATCH 33/37] Fix --- internal/namespaces/object/v1/s3configfile.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/namespaces/object/v1/s3configfile.go b/internal/namespaces/object/v1/s3configfile.go index c0f851a0e0..b196e34f08 100644 --- a/internal/namespaces/object/v1/s3configfile.go +++ b/internal/namespaces/object/v1/s3configfile.go @@ -18,9 +18,9 @@ func (c s3tool) String() string { return string(c) } -type SupportedTool []s3tool +type supportedTool []s3tool -func (s SupportedTool) ToStringArray() []string { +func (s supportedTool) ToStringArray() []string { var res []string for _, x := range s { res = append(res, x.String()) @@ -42,7 +42,7 @@ const ( mc = s3tool("mc") ) -var supportedTools = SupportedTool{ +var supportedTools = supportedTool{ rclone, s3cmd, mc, From 236b97d3b2bfbd94491c6b7676ee89f3b227c360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 18:10:15 +0200 Subject: [PATCH 34/37] Fix --- internal/namespaces/object/v1/s3configfile.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/namespaces/object/v1/s3configfile.go b/internal/namespaces/object/v1/s3configfile.go index b196e34f08..0393ba19df 100644 --- a/internal/namespaces/object/v1/s3configfile.go +++ b/internal/namespaces/object/v1/s3configfile.go @@ -142,11 +142,10 @@ func (c s3config) getConfigFile(tool s3tool) (string, error) { SecretKey string `json:"secretKey"` API string `json:"api"` } - type mcconfig struct { + m := struct { Version string `json:"version"` Hosts map[string]hostconfig `json:"hosts"` - } - m := mcconfig{ + }{ Version: "9", Hosts: map[string]hostconfig{ c.Name: { From 479c3426bf7923fc9335fcfea773d09d0bb2b7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 18:13:11 +0200 Subject: [PATCH 35/37] Fix --- internal/namespaces/object/v1/custom_config_install_test.go | 3 +++ .../test-config-install-no-existing-config-mc.stdout.golden | 4 ++++ ...est-config-install-no-existing-config-rclone.stdout.golden | 4 ++++ ...test-config-install-no-existing-config-s3cmd.stdout.golden | 4 ++++ 4 files changed, 15 insertions(+) create mode 100644 internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden create mode 100644 internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index bed45abbe5..e6665af998 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -29,6 +29,7 @@ func Test_ConfigInstall(t *testing.T) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".config", "rclone", "rclone.conf") assert.FileExists(t, filePath) }, + core.TestCheckGolden(), core.TestCheckExitCode(0), ), TmpHomeDir: true, @@ -43,6 +44,7 @@ func Test_ConfigInstall(t *testing.T) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".mc", "config.json") assert.FileExists(t, filePath) }, + core.TestCheckGolden(), core.TestCheckExitCode(0), ), TmpHomeDir: true, @@ -57,6 +59,7 @@ func Test_ConfigInstall(t *testing.T) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".s3cfg") assert.FileExists(t, filePath) }, + core.TestCheckGolden(), core.TestCheckExitCode(0), ), TmpHomeDir: true, diff --git a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden new file mode 100644 index 0000000000..d220a02bc0 --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden @@ -0,0 +1,4 @@ +message Configuration file successfully installed at /var/folders/sm/h3cw_xsj0279j12fnhv6bzd40000gn/T/scw091702730/.mc/config.json +details - +resource - +verb - diff --git a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden new file mode 100644 index 0000000000..5efc2c26b0 --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden @@ -0,0 +1,4 @@ +message Configuration file successfully installed at /var/folders/sm/h3cw_xsj0279j12fnhv6bzd40000gn/T/scw951233240/.config/rclone/rclone.conf +details - +resource - +verb - diff --git a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden new file mode 100644 index 0000000000..60237a9fec --- /dev/null +++ b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden @@ -0,0 +1,4 @@ +message Configuration file successfully installed at /var/folders/sm/h3cw_xsj0279j12fnhv6bzd40000gn/T/scw613144151/.s3cfg +details - +resource - +verb - From 362ce3d2fd27b27370eb3230a8f6afd3a74a5c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 18:14:06 +0200 Subject: [PATCH 36/37] Fix --- internal/namespaces/object/v1/custom_config_install.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/namespaces/object/v1/custom_config_install.go b/internal/namespaces/object/v1/custom_config_install.go index 53867c65f5..ee0c51e75e 100644 --- a/internal/namespaces/object/v1/custom_config_install.go +++ b/internal/namespaces/object/v1/custom_config_install.go @@ -103,7 +103,7 @@ func configInstallCommand() *core.Command { if err != nil { return "", err } - return core.SuccessResult{ + return &core.SuccessResult{ Message: fmt.Sprintf("Configuration file successfully installed at %s", configPath), }, nil }, From e6f35e8b1b579c17c4d88393a3f6def8b576b417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 23 Apr 2020 18:17:31 +0200 Subject: [PATCH 37/37] Fix --- internal/namespaces/object/v1/custom_config_install_test.go | 3 --- .../test-config-install-no-existing-config-mc.stdout.golden | 4 ---- ...est-config-install-no-existing-config-rclone.stdout.golden | 4 ---- ...test-config-install-no-existing-config-s3cmd.stdout.golden | 4 ---- 4 files changed, 15 deletions(-) delete mode 100644 internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden delete mode 100644 internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden delete mode 100644 internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden diff --git a/internal/namespaces/object/v1/custom_config_install_test.go b/internal/namespaces/object/v1/custom_config_install_test.go index e6665af998..bed45abbe5 100644 --- a/internal/namespaces/object/v1/custom_config_install_test.go +++ b/internal/namespaces/object/v1/custom_config_install_test.go @@ -29,7 +29,6 @@ func Test_ConfigInstall(t *testing.T) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".config", "rclone", "rclone.conf") assert.FileExists(t, filePath) }, - core.TestCheckGolden(), core.TestCheckExitCode(0), ), TmpHomeDir: true, @@ -44,7 +43,6 @@ func Test_ConfigInstall(t *testing.T) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".mc", "config.json") assert.FileExists(t, filePath) }, - core.TestCheckGolden(), core.TestCheckExitCode(0), ), TmpHomeDir: true, @@ -59,7 +57,6 @@ func Test_ConfigInstall(t *testing.T) { filePath := path.Join(ctx.OverrideEnv["HOME"], ".s3cfg") assert.FileExists(t, filePath) }, - core.TestCheckGolden(), core.TestCheckExitCode(0), ), TmpHomeDir: true, diff --git a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden deleted file mode 100644 index d220a02bc0..0000000000 --- a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-mc.stdout.golden +++ /dev/null @@ -1,4 +0,0 @@ -message Configuration file successfully installed at /var/folders/sm/h3cw_xsj0279j12fnhv6bzd40000gn/T/scw091702730/.mc/config.json -details - -resource - -verb - diff --git a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden deleted file mode 100644 index 5efc2c26b0..0000000000 --- a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-rclone.stdout.golden +++ /dev/null @@ -1,4 +0,0 @@ -message Configuration file successfully installed at /var/folders/sm/h3cw_xsj0279j12fnhv6bzd40000gn/T/scw951233240/.config/rclone/rclone.conf -details - -resource - -verb - diff --git a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden b/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden deleted file mode 100644 index 60237a9fec..0000000000 --- a/internal/namespaces/object/v1/testdata/test-config-install-no-existing-config-s3cmd.stdout.golden +++ /dev/null @@ -1,4 +0,0 @@ -message Configuration file successfully installed at /var/folders/sm/h3cw_xsj0279j12fnhv6bzd40000gn/T/scw613144151/.s3cfg -details - -resource - -verb -