From 0927eda19c85bd0d05bade72a434176934cf0e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Wed, 19 Jul 2023 09:33:22 +0200 Subject: [PATCH] chore: purge old account support (#3290) --- .../test-main-usage-usage.cassette.yaml | 35 +++ internal/namespaces/account/v2/account_cli.go | 228 -------------- internal/namespaces/account/v2/custom.go | 9 - .../account/v2alpha1/account_cli.go | 295 ------------------ .../namespaces/account/v2alpha1/custom.go | 104 ------ .../account/v2alpha1/custom_test.go | 72 ----- internal/namespaces/account/v2alpha1/error.go | 21 -- .../account/v2alpha1/helpers_test.go | 14 - .../test-init-command-simple.cassette.yaml | 86 ----- .../testdata/test-init-command-simple.golden | 8 - ...t-ssh-key-add-command-simple.cassette.yaml | 71 ----- .../test-ssh-key-add-command-simple.golden | 29 -- ...-ssh-key-init-command-simple.cassette.yaml | 82 ----- ...sh-key-remove-command-simple.cassette.yaml | 71 ----- .../test-ssh-key-remove-command-simple.golden | 8 - internal/namespaces/account/v3/custom.go | 8 +- .../namespaces/iam/v1alpha1/custom_test.go | 4 +- ...-with-ssh-key-command-simple.cassette.yaml | 100 +++--- ...st-init-with-ssh-key-command-simple.golden | 7 +- 19 files changed, 99 insertions(+), 1153 deletions(-) create mode 100644 cmd/scw/testdata/test-main-usage-usage.cassette.yaml delete mode 100644 internal/namespaces/account/v2/account_cli.go delete mode 100644 internal/namespaces/account/v2/custom.go delete mode 100644 internal/namespaces/account/v2alpha1/account_cli.go delete mode 100644 internal/namespaces/account/v2alpha1/custom.go delete mode 100644 internal/namespaces/account/v2alpha1/custom_test.go delete mode 100644 internal/namespaces/account/v2alpha1/error.go delete mode 100644 internal/namespaces/account/v2alpha1/helpers_test.go delete mode 100644 internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.cassette.yaml delete mode 100644 internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.golden delete mode 100644 internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.cassette.yaml delete mode 100644 internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.golden delete mode 100644 internal/namespaces/account/v2alpha1/testdata/test-ssh-key-init-command-simple.cassette.yaml delete mode 100644 internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.cassette.yaml delete mode 100644 internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.golden diff --git a/cmd/scw/testdata/test-main-usage-usage.cassette.yaml b/cmd/scw/testdata/test-main-usage-usage.cassette.yaml new file mode 100644 index 0000000000..f0b1939dcd --- /dev/null +++ b/cmd/scw/testdata/test-main-usage-usage.cassette.yaml @@ -0,0 +1,35 @@ +--- +version: 1 +interactions: +- request: + body: '{"message":"authentication is denied","method":"api_key","reason":"not_found","type":"denied_authentication"}' + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.20.6; darwin; amd64) cli-e2e-test + url: https://api.scaleway.com/iam/v1alpha1/api-keys/SCWXXXXXXXXXXXXXXXXX + method: GET + response: + body: '{"message":"authentication is denied","method":"api_key","reason":"not_found","type":"denied_authentication"}' + headers: + Content-Length: + - "109" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Mon, 17 Jul 2023 13:11:02 GMT + Server: + - Scaleway API-Gateway + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 4dbd3c92-0639-4c2b-8cca-9106da810d5c + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/internal/namespaces/account/v2/account_cli.go b/internal/namespaces/account/v2/account_cli.go deleted file mode 100644 index cbf965280c..0000000000 --- a/internal/namespaces/account/v2/account_cli.go +++ /dev/null @@ -1,228 +0,0 @@ -// This file was automatically generated. DO NOT EDIT. -// If you have any remark or suggestion do not hesitate to open an issue. - -package account - -import ( - "context" - "reflect" - - "github.com/scaleway/scaleway-cli/v2/internal/core" - "github.com/scaleway/scaleway-sdk-go/api/account/v2" - "github.com/scaleway/scaleway-sdk-go/scw" -) - -// always import dependencies -var ( - _ = scw.RegionFrPar -) - -func GetGeneratedCommands() *core.Commands { - return core.NewCommands( - accountRoot(), - accountProject(), - accountProjectCreate(), - accountProjectList(), - accountProjectGet(), - accountProjectDelete(), - accountProjectUpdate(), - ) -} -func accountRoot() *core.Command { - return &core.Command{ - Short: `User related data`, - Long: `This API allows you to manage projects.`, - Namespace: "account", - } -} - -func accountProject() *core.Command { - return &core.Command{ - Short: `Project management commands`, - Long: `Project management commands.`, - Namespace: "account", - Resource: "project", - } -} - -func accountProjectCreate() *core.Command { - return &core.Command{ - Short: `Create a new Project for an Organization`, - Long: `Deprecated in favor of Account API v3. -Generate a new Project for an Organization, specifying its configuration including name and description.`, - Namespace: "account", - Resource: "project", - Verb: "create", - // Deprecated: true, - ArgsType: reflect.TypeOf(account.CreateProjectRequest{}), - ArgSpecs: core.ArgSpecs{ - { - Name: "name", - Short: `Name of the Project`, - Required: false, - Deprecated: false, - Positional: false, - Default: core.RandomValueGenerator("proj"), - }, - { - Name: "description", - Short: `Description of the Project`, - Required: false, - Deprecated: false, - Positional: false, - }, - core.OrganizationIDArgSpec(), - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.CreateProjectRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - return api.CreateProject(request) - - }, - } -} - -func accountProjectList() *core.Command { - return &core.Command{ - Short: `List all Projects of an Organization`, - Long: `Deprecated in favor of Account API v3. -List all Projects of an Organization. The response will include the total number of Projects as well as their associated Organizations, names and IDs. Other information include the creation and update date of the Project.`, - Namespace: "account", - Resource: "project", - Verb: "list", - // Deprecated: true, - ArgsType: reflect.TypeOf(account.ListProjectsRequest{}), - ArgSpecs: core.ArgSpecs{ - { - Name: "name", - Short: `Name of the Project`, - Required: false, - Deprecated: false, - Positional: false, - }, - { - Name: "order-by", - Short: `Sort order of the returned Projects`, - Required: false, - Deprecated: false, - Positional: false, - EnumValues: []string{"created_at_asc", "created_at_desc", "name_asc", "name_desc"}, - }, - { - Name: "project-ids.{index}", - Short: `Project IDs to filter for. The results will be limited to any Projects with an ID in this array`, - Required: false, - Deprecated: false, - Positional: false, - }, - core.OrganizationIDArgSpec(), - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.ListProjectsRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - opts := []scw.RequestOption{scw.WithAllPages()} - resp, err := api.ListProjects(request, opts...) - if err != nil { - return nil, err - } - return resp.Projects, nil - - }, - } -} - -func accountProjectGet() *core.Command { - return &core.Command{ - Short: `Get an existing Project`, - Long: `Deprecated in favor of Account API v3. -Retrieve information about an existing Project, specified by its Project ID. Its full details, including ID, name and description, are returned in the response object.`, - Namespace: "account", - Resource: "project", - Verb: "get", - // Deprecated: true, - ArgsType: reflect.TypeOf(account.GetProjectRequest{}), - ArgSpecs: core.ArgSpecs{ - core.ProjectIDArgSpec(), - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.GetProjectRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - return api.GetProject(request) - - }, - } -} - -func accountProjectDelete() *core.Command { - return &core.Command{ - Short: `Delete an existing Project`, - Long: `Deprecated in favor of Account API v3. -Delete an existing Project, specified by its Project ID. The Project needs to be empty (meaning there are no resources left in it) to be deleted effectively. Note that deleting a Project is permanent, and cannot be undone.`, - Namespace: "account", - Resource: "project", - Verb: "delete", - // Deprecated: true, - ArgsType: reflect.TypeOf(account.DeleteProjectRequest{}), - ArgSpecs: core.ArgSpecs{ - core.ProjectIDArgSpec(), - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.DeleteProjectRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - e = api.DeleteProject(request) - if e != nil { - return nil, e - } - return &core.SuccessResult{ - Resource: "project", - Verb: "delete", - }, nil - }, - } -} - -func accountProjectUpdate() *core.Command { - return &core.Command{ - Short: `Update Project`, - Long: `Deprecated in favor of Account API v3. -Update the parameters of an existing Project, specified by its Project ID. These parameters include the name and description.`, - Namespace: "account", - Resource: "project", - Verb: "update", - // Deprecated: true, - ArgsType: reflect.TypeOf(account.UpdateProjectRequest{}), - ArgSpecs: core.ArgSpecs{ - core.ProjectIDArgSpec(), - { - Name: "name", - Short: `Name of the Project`, - Required: false, - Deprecated: false, - Positional: false, - }, - { - Name: "description", - Short: `Description of the Project`, - Required: false, - Deprecated: false, - Positional: false, - }, - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.UpdateProjectRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - return api.UpdateProject(request) - - }, - } -} diff --git a/internal/namespaces/account/v2/custom.go b/internal/namespaces/account/v2/custom.go deleted file mode 100644 index b70df2c894..0000000000 --- a/internal/namespaces/account/v2/custom.go +++ /dev/null @@ -1,9 +0,0 @@ -package account - -import "github.com/scaleway/scaleway-cli/v2/internal/core" - -func GetCommands() *core.Commands { - cmds := GetGeneratedCommands() - - return cmds -} diff --git a/internal/namespaces/account/v2alpha1/account_cli.go b/internal/namespaces/account/v2alpha1/account_cli.go deleted file mode 100644 index c4a3b5a35b..0000000000 --- a/internal/namespaces/account/v2alpha1/account_cli.go +++ /dev/null @@ -1,295 +0,0 @@ -// This file was automatically generated. DO NOT EDIT. -// If you have any remark or suggestion do not hesitate to open an issue. - -package account - -import ( - "context" - "reflect" - - "github.com/scaleway/scaleway-cli/v2/internal/core" - "github.com/scaleway/scaleway-sdk-go/api/account/v2alpha1" - "github.com/scaleway/scaleway-sdk-go/scw" -) - -// always import dependencies -var ( - _ = scw.RegionFrPar -) - -func GetGeneratedCommands() *core.Commands { - return core.NewCommands( - accountRoot(), - accountSSHKey(), - accountSSHKeyList(), - accountSSHKeyAdd(), - accountSSHKeyGet(), - accountSSHKeyUpdate(), - accountSSHKeyRemove(), - ) -} -func accountRoot() *core.Command { - return &core.Command{ - Short: `Account API`, - Long: `Account API.`, - Namespace: "account", - } -} - -func accountSSHKey() *core.Command { - return &core.Command{ - Short: `SSH keys management commands`, - Long: `SSH keys management commands.`, - Namespace: "account", - Resource: "ssh-key", - } -} - -func accountSSHKeyList() *core.Command { - return &core.Command{ - Short: `List all SSH keys of your project`, - Long: `List all SSH keys of your project.`, - Namespace: "account", - Resource: "ssh-key", - Verb: "list", - // Deprecated: false, - ArgsType: reflect.TypeOf(account.ListSSHKeysRequest{}), - ArgSpecs: core.ArgSpecs{ - { - Name: "order-by", - Required: false, - Deprecated: false, - Positional: false, - EnumValues: []string{"created_at_asc", "created_at_desc", "updated_at_asc", "updated_at_desc", "name_asc", "name_desc"}, - }, - { - Name: "name", - Required: false, - Deprecated: false, - Positional: false, - }, - { - Name: "project-id", - Required: false, - Deprecated: false, - Positional: false, - }, - { - Name: "organization-id", - Required: false, - Deprecated: false, - Positional: false, - }, - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.ListSSHKeysRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - opts := []scw.RequestOption{scw.WithAllPages()} - resp, err := api.ListSSHKeys(request, opts...) - if err != nil { - return nil, err - } - return resp.SSHKeys, nil - - }, - View: &core.View{Fields: []*core.ViewField{ - { - FieldName: "ID", - }, - { - FieldName: "Name", - }, - { - FieldName: "CreatedAt", - }, - { - FieldName: "UpdatedAt", - }, - { - FieldName: "ProjectID", - }, - { - FieldName: "CreationInfo.Address", - }, - { - FieldName: "CreationInfo.CountryCode", - }, - { - FieldName: "CreationInfo.UserAgent", - }, - { - FieldName: "OrganizationID", - }, - }}, - } -} - -func accountSSHKeyAdd() *core.Command { - return &core.Command{ - Short: `Add an SSH key to your project`, - Long: `Add an SSH key to your project.`, - Namespace: "account", - Resource: "ssh-key", - Verb: "add", - // Deprecated: false, - ArgsType: reflect.TypeOf(account.CreateSSHKeyRequest{}), - ArgSpecs: core.ArgSpecs{ - { - Name: "name", - Short: `The name of the SSH key`, - Required: false, - Deprecated: false, - Positional: false, - }, - { - Name: "public-key", - Short: `SSH public key. Currently ssh-rsa, ssh-dss (DSA), ssh-ed25519 and ecdsa keys with NIST curves are supported`, - Required: true, - Deprecated: false, - Positional: false, - }, - core.ProjectIDArgSpec(), - core.OrganizationIDArgSpec(), - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.CreateSSHKeyRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - return api.CreateSSHKey(request) - - }, - Examples: []*core.Example{ - { - Short: "Add a given ssh key", - Raw: `scw account ssh-key add name=foobar public-key="$(cat )"`, - }, - }, - SeeAlsos: []*core.SeeAlso{ - { - Command: "scw account ssh-key list", - Short: "List all SSH keys", - }, - { - Command: "scw account ssh-key remove", - Short: "Remove an SSH key", - }, - }, - } -} - -func accountSSHKeyGet() *core.Command { - return &core.Command{ - Short: `Get an SSH key from your project`, - Long: `Get an SSH key from your project.`, - Namespace: "account", - Resource: "ssh-key", - Verb: "get", - // Deprecated: false, - ArgsType: reflect.TypeOf(account.GetSSHKeyRequest{}), - ArgSpecs: core.ArgSpecs{ - { - Name: "ssh-key-id", - Short: `The ID of the SSH key`, - Required: true, - Deprecated: false, - Positional: true, - }, - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.GetSSHKeyRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - return api.GetSSHKey(request) - - }, - } -} - -func accountSSHKeyUpdate() *core.Command { - return &core.Command{ - Short: `Update an SSH key on your project`, - Long: `Update an SSH key on your project.`, - Namespace: "account", - Resource: "ssh-key", - Verb: "update", - // Deprecated: false, - ArgsType: reflect.TypeOf(account.UpdateSSHKeyRequest{}), - ArgSpecs: core.ArgSpecs{ - { - Name: "ssh-key-id", - Required: true, - Deprecated: false, - Positional: true, - }, - { - Name: "name", - Short: `Name of the SSH key`, - Required: false, - Deprecated: false, - Positional: false, - }, - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.UpdateSSHKeyRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - return api.UpdateSSHKey(request) - - }, - } -} - -func accountSSHKeyRemove() *core.Command { - return &core.Command{ - Short: `Remove an SSH key from your project`, - Long: `Remove an SSH key from your project.`, - Namespace: "account", - Resource: "ssh-key", - Verb: "remove", - // Deprecated: false, - ArgsType: reflect.TypeOf(account.DeleteSSHKeyRequest{}), - ArgSpecs: core.ArgSpecs{ - { - Name: "ssh-key-id", - Required: true, - Deprecated: false, - Positional: true, - }, - }, - Run: func(ctx context.Context, args interface{}) (i interface{}, e error) { - request := args.(*account.DeleteSSHKeyRequest) - - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - e = api.DeleteSSHKey(request) - if e != nil { - return nil, e - } - return &core.SuccessResult{ - Resource: "ssh-key", - Verb: "remove", - }, nil - }, - Examples: []*core.Example{ - { - Short: "Remove a given SSH key", - ArgsJSON: `{"ssh_key_id":"11111111-1111-1111-1111-111111111111"}`, - }, - }, - SeeAlsos: []*core.SeeAlso{ - { - Command: "scw account ssh-key list", - Short: "List all SSH keys", - }, - { - Command: "scw account ssh-key add", - Short: "Add a SSH key", - }, - }, - } -} diff --git a/internal/namespaces/account/v2alpha1/custom.go b/internal/namespaces/account/v2alpha1/custom.go deleted file mode 100644 index c6d9bf09ee..0000000000 --- a/internal/namespaces/account/v2alpha1/custom.go +++ /dev/null @@ -1,104 +0,0 @@ -package account - -import ( - "context" - "os" - "path" - "reflect" - "strings" - - "github.com/scaleway/scaleway-cli/v2/internal/args" - "github.com/scaleway/scaleway-cli/v2/internal/core" - "github.com/scaleway/scaleway-cli/v2/internal/interactive" - account "github.com/scaleway/scaleway-sdk-go/api/account/v2alpha1" - "github.com/scaleway/scaleway-sdk-go/scw" -) - -func GetCommands() *core.Commands { - commands := GetGeneratedCommands() - - commands.Merge(core.NewCommands( - initCommand(), - )) - return commands -} - -func initCommand() *core.Command { - return &core.Command{ - Short: `Initialize SSH key`, - Long: `Initialize SSH key.`, - Namespace: "account", - Resource: "ssh-key", - Verb: "init", - Groups: []string{"workflow"}, - ArgsType: reflect.TypeOf(args.RawArgs{}), - ArgSpecs: core.ArgSpecs{}, - Run: InitRun, - } -} - -func InitRun(ctx context.Context, _ interface{}) (i interface{}, e error) { - // Get default local SSH key - var shortenedFilename string - var err error - var localSSHKeyContent []byte - for _, keyName := range [3]string{"id_ecdsa.pub", "id_ed25519.pub", "id_rsa.pub"} { - // element is the element from someSlice for where we are - relativePath := path.Join(".ssh", keyName) - filename := path.Join(core.ExtractUserHomeDir(ctx), relativePath) - shortenedFilename = "~/" + relativePath - localSSHKeyContent, err = os.ReadFile(filename) - // If we managed to load an ssh key, let's stop there - if err == nil { - break - } - } - addKeyInstructions := `scw account ssh-key add name=my-key key="$(cat path/to/my/key.pub)"` - if err != nil && os.IsNotExist(err) { - return nil, sshKeyNotFound(shortenedFilename, addKeyInstructions) - } - - // Get all SSH keys from Scaleway - client := core.ExtractClient(ctx) - api := account.NewAPI(client) - listSSHKeysResponse, err := api.ListSSHKeys(&account.ListSSHKeysRequest{}, scw.WithAllPages()) - if err != nil { - return nil, err - } - - // Early exit if the SSH key is present locally and on Scaleway - for _, SSHKey := range listSSHKeysResponse.SSHKeys { - if strings.TrimSpace(SSHKey.PublicKey) == strings.TrimSpace(string(localSSHKeyContent)) { - _, _ = interactive.Println("Looks like your local SSH key " + shortenedFilename + " is already present in your Scaleway account.") - return nil, nil - } - } - - // Ask user - _, _ = interactive.Println("An SSH key is required if you want to connect to a server. More info at https://www.scaleway.com/en/docs/configure-new-ssh-key") - addSSHKey, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ - Ctx: ctx, - Prompt: "We found an SSH key in " + shortenedFilename + ". Do you want to add it to your Scaleway account?", - DefaultValue: true, - }) - if err != nil { - return nil, err - } - - // Early exit if user doesn't want to add the key - if !addSSHKey { - return nil, installationCanceled(addKeyInstructions) - } - - // Add key - _, err = api.CreateSSHKey(&account.CreateSSHKeyRequest{ - PublicKey: string(localSSHKeyContent), - }) - if err != nil { - return nil, err - } - - return &core.SuccessResult{ - Message: "Key " + shortenedFilename + " successfully added", - }, nil -} diff --git a/internal/namespaces/account/v2alpha1/custom_test.go b/internal/namespaces/account/v2alpha1/custom_test.go deleted file mode 100644 index 521b13d437..0000000000 --- a/internal/namespaces/account/v2alpha1/custom_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package account - -import ( - "os" - "path" - "testing" - - "github.com/scaleway/scaleway-cli/v2/internal/core" - account "github.com/scaleway/scaleway-sdk-go/api/account/v2alpha1" -) - -func Test_initCommand(t *testing.T) { - tmpDir := os.TempDir() - t.Run("simple", core.Test(&core.TestConfig{ - Commands: GetCommands(), - BeforeFunc: func(ctx *core.BeforeFuncCtx) error { - pathToPublicKey := path.Join(tmpDir, ".ssh", "id_rsa.pub") - _, err := os.Stat(pathToPublicKey) - if err != nil { - content := "ssh-rsa AAAAB3NzaC1yc2EAAAEDAQABAAABAQC/wF8Q8LjEexuWDc8TfKmWVZ1CiiHK6KvO0E/Rk9+d6ssqbrvtbJWRsJXZFC8+DGWVM0UFFicmOfTwEjDWzuQPFkYhmpXrD1UiLx9Viku1g1qEJgcsyH2uAwwW3OnsH1W44D6Ni/zOzMButFeKZgPeD8H9YNkpbZBZ9QrKFiAhvEyJDYSY0bsbH1/qR5DE+dLNuGlJ/g3kUMVaXSI6dHNcBHTbK0Mse23Uopk2U3BSpvX9JdbcLaYtHDOytwd16rNYui7el3uOmlR8oUpAXkeKQxBPoxgy3qI/P8/l44L9RFpbklkmdiw2ph2ymiSkRSYCWdvEVIK/A+0D8VFjGXOb email" - err := os.MkdirAll(path.Join(tmpDir, ".ssh"), 0755) - if err != nil { - return err - } - err = os.WriteFile(pathToPublicKey, []byte(content), 0644) - return err - } - return err - }, - Cmd: `scw account ssh-key init with-ssh-key=true`, - Check: core.TestCheckCombine( - core.TestCheckGolden(), - core.TestCheckExitCode(0), - ), - OverrideEnv: map[string]string{ - "HOME": tmpDir, - }, - })) -} - -func Test_SSHKeyAddCommand(t *testing.T) { - key := `ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= foobar@foobar` - t.Run("simple", core.Test(&core.TestConfig{ - Commands: GetCommands(), - Args: []string{ - "scw", "account", "ssh-key", "add", "name=foobar", "public-key=" + key, - }, - Check: core.TestCheckCombine( - core.TestCheckGolden(), - core.TestCheckExitCode(0), - ), - AfterFunc: func(ctx *core.AfterFuncCtx) error { - api := account.NewAPI(ctx.Client) - return api.DeleteSSHKey(&account.DeleteSSHKeyRequest{ - SSHKeyID: ctx.CmdResult.(*account.SSHKey).ID, - }) - }, - })) -} - -func Test_SSHKeyRemoveCommand(t *testing.T) { - key := `ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGh9rvkJKMu5ljnevB4oRu4i/EnxGS734/UJ6fSDvXGIvT08jIglahc7tM5dvo02abPVXsbiazO25avZZtL6fjo= foobar@foobar` - t.Run("simple", core.Test(&core.TestConfig{ - Commands: GetCommands(), - BeforeFunc: addSSHKey("Key", key), - Cmd: "scw account ssh-key remove {{ .Key.ID }}", - Check: core.TestCheckCombine( - core.TestCheckGolden(), - core.TestCheckExitCode(0), - ), - })) -} diff --git a/internal/namespaces/account/v2alpha1/error.go b/internal/namespaces/account/v2alpha1/error.go deleted file mode 100644 index cc3571b2c2..0000000000 --- a/internal/namespaces/account/v2alpha1/error.go +++ /dev/null @@ -1,21 +0,0 @@ -package account - -import ( - "fmt" - - "github.com/scaleway/scaleway-cli/v2/internal/core" -) - -func installationCanceled(addKeyInstructions string) *core.CliError { - return &core.CliError{ - Err: fmt.Errorf("installation of SSH key canceled"), - Hint: "You can add it later using " + addKeyInstructions, - } -} - -func sshKeyNotFound(filename string, addKeyInstructions string) *core.CliError { - return &core.CliError{ - Err: fmt.Errorf("could not find an SSH key at " + filename), - Hint: "You can add one later using " + addKeyInstructions, - } -} diff --git a/internal/namespaces/account/v2alpha1/helpers_test.go b/internal/namespaces/account/v2alpha1/helpers_test.go deleted file mode 100644 index 9032798147..0000000000 --- a/internal/namespaces/account/v2alpha1/helpers_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package account - -import ( - "github.com/scaleway/scaleway-cli/v2/internal/core" -) - -func addSSHKey(metaKey string, key string) core.BeforeFunc { - return func(ctx *core.BeforeFuncCtx) error { - ctx.Meta[metaKey] = ctx.ExecuteCmd([]string{ - "scw", "account", "ssh-key", "add", "public-key=" + key, - }) - return nil - } -} diff --git a/internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.cassette.yaml b/internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.cassette.yaml deleted file mode 100644 index b3c2f33ab6..0000000000 --- a/internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.cassette.yaml +++ /dev/null @@ -1,86 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: "" - form: {} - headers: - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.13.1; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-keys?order_by=created_at_asc&page=1 - method: GET - response: - body: '{"ssh_keys":[{"id":"1ef19b65-53c9-4789-a760-0e0d2e26cf35","name":"scw-test","public_key":"ssh-rsa - AAAAB3NzaC1yc2EAAAADAQABAAACAQDfEI5h63XLQTu7sQKJjjBXe1S4//qsYPhWv09P0n5dLyae5oaAuS15p4o7TTx2tEi5/cixiNbkvnR5TCoxU0VWJN0X09t+LILLHefEFhGocyQ94pw79QZVKAcw2gwE+jq8/PDCwdyi4bVLi4AcvLbx9z2kn182MBkz4pwkS0rpWN2v8Lcjk9/neoxxlxyHJsGZPPql67N/XcNJtUUoagJZEwkf+/etuLqJqB8P5YKyrORrPJFNiiBqQQCkVEX40uR4dBVmRPe+oWsJY+NfGgOqjTjaaRXmfhrQnu2pM1fIDt7Zh4BbabHms7qGQuDqQTbeJ/0AVE+HhVXZ+dNiMm4/70vfX3Cuoia2swEJCbVoLSV7I1I7ojlPGYEAt0Ka6jW3Jdr2D/BratRpeNRMdMRuVYpwx8uXakAizpG8mfn/k56LL9PziKxDG6Q6GccdPszMWsVcSOaA9Kt03ZS8+T+r4VBVy89PSs3Vwh541eVjuVQ8QxB0PjQ2usY8xN6mIbLtb/Ezlp7uHlJccfjPNvZ+01YMqVugAj+oNKfVUIj3HBIh+VvAsQDXN04cl4YsOpNmhc6MFG5EhF119BK2mpu3Df/it7rf/RJNLM1NOlW3ZBMvfsV63CARMXaDncAQNZqC4HpX0rr+l58F2MY/H/Vrq8wr2UJKecZoQYPsTD2Znw== - lbourgois@scw-loic-mac.local","fingerprint":"4096 MD5:a6:97:64:f1:92:5b:2c:68:b6:b8:bb:cc:4c:30:f2:1e - lbourgois@scw-loic-mac.local (ssh-rsa)","created_at":"2020-03-06T13:36:01.678719Z","updated_at":"2020-03-06T13:36:01.678719Z","creation_info":{"address":"195.154.229.35","user_agent":"Mozilla/5.0 - (Macintosh; Intel Mac OS X 10.15; rv:73.0) Gecko/20100101 Firefox/73.0","country_code":"FR"},"organization_id":"aba2d0d0-b01d-4d88-b322-935edc96d0fd"},{"id":"4719404d-3056-41c5-b5e4-1db2d4d0238f","name":"","public_key":"ssh-rsa - AAAAB3NzaC1yc2EAAAADAQABAAABAQC/wF8Q8LjEexuWDc8YfKmWVZ1CiiHK6KvO0E/Rk9+d6szqbrvtbJWRsJXZFC8+DGWVM0UFFicmOfTwEjDWzuQPFkYhmpXrD1UiLx9Viku1g1qEJgcsyH2uAwwW3OnsH1W44D6Ni/zOzMButFeKZgPeD8H9YNkpbZBZ9QrKFiAhvEyJDYSY0bsbH1/qR5DE+dLNuGlJ/g3kUMVaXSI6dHNcBHTbK0Mse23Uopk2U3BSpvX9JdbcLaYtHDOytwd16rNYui7el3uOmlR8oUpAXkeKQxBPoxgy3qI/P8/l44L9RFpbklkmdiw2ph2ymiSkRSYCWdvEVIK/A+0D8VFjGXOb - lbourgois@MacBook-Pro-de-Loic.local\n","fingerprint":"2048 MD5:6c:4b:6c:7f:ca:16:46:7a:61:3d:e5:bd:5b:2f:02:9e - lbourgois@MacBook-Pro-de-Loic.local (ssh-rsa)","created_at":"2020-03-10T10:31:12.749497Z","updated_at":"2020-03-10T10:31:12.749497Z","creation_info":{"address":"","user_agent":"","country_code":""},"organization_id":"aba2d0d0-b01d-4d88-b322-935edc96d0fd"},{"id":"6ff5bb48-add1-458a-95bf-a3f5eda3767c","name":"","public_key":"ssh-rsa - AAAAB3NzaC1yc2EAAAADAQABAAABAQC/wF8Q8LjEexuWDc8TfKmWVZ1CiiHK6KvO0E/Rk9+d6szqbrvtbJWRsJXZFC8+DGWVM0UFFicmOfTwEjDWzuQPFkYhmpXrD1UiLx9Viku1g1qEJgcsyH2uAwwW3OnsH1W44D6Ni/zOzMButFeKZgPeD8H9YNkpbZBZ9QrKFiAhvEyJDYSY0bsbH1/qR5DE+dLNuGlJ/g3kUMVaXSI6dHNcBHTbK0Mse23Uopk2U3BSpvX9JdbcLaYtHDOytwd16rNYui7el3uOmlR8oUpAXkeKQxBPoxgy3qI/P8/l44L9RFpbklkmdiw2ph2ymiSkRSYCWdvEVIK/A+0D8VFjGXOb - lbourgois@MacBook-Pro-de-Loic.local\n","fingerprint":"2048 MD5:de:57:c6:c4:a5:4a:cc:cd:6f:00:33:99:94:7a:8b:08 - lbourgois@MacBook-Pro-de-Loic.local (ssh-rsa)","created_at":"2020-03-20T14:00:34.537763Z","updated_at":"2020-03-20T14:00:34.537763Z","creation_info":{"address":"","user_agent":"","country_code":""},"organization_id":"aba2d0d0-b01d-4d88-b322-935edc96d0fd"},{"id":"695899a9-2b74-4dd1-b806-4d56bd5828bd","name":"","public_key":"ssh-rsa - AAAAB3NzaC1yc2EAAAADAQABAAABAQC/wF8Q8LjEexuWDc8TfKmWVZ1CiiHK6KvO0E/Rk9+d6ssqbrvtbJWRsJXZFC8+DGWVM0UFFicmOfTwEjDWzuQPFkYhmpXrD1UiLx9Viku1g1qEJgcsyH2uAwwW3OnsH1W44D6Ni/zOzMButFeKZgPeD8H9YNkpbZBZ9QrKFiAhvEyJDYSY0bsbH1/qR5DE+dLNuGlJ/g3kUMVaXSI6dHNcBHTbK0Mse23Uopk2U3BSpvX9JdbcLaYtHDOytwd16rNYui7el3uOmlR8oUpAXkeKQxBPoxgy3qI/P8/l44L9RFpbklkmdiw2ph2ymiSkRSYCWdvEVIK/A+0D8VFjGXOb - email","fingerprint":"2048 MD5:b4:9f:bd:7b:fc:66:66:cc:b3:33:41:72:fc:be:05:c8 - email (ssh-rsa)","created_at":"2020-03-20T16:30:55.236831Z","updated_at":"2020-03-20T16:30:55.236831Z","creation_info":{"address":"","user_agent":"","country_code":""},"organization_id":"aba2d0d0-b01d-4d88-b322-935edc96d0fd"}],"total_count":4}' - headers: - Content-Length: - - "3670" - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Mon, 23 Mar 2020 18:00:13 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - 4115f527-fef6-4baf-97c7-ab5dc93c5b15 - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"name":"","public_key":"ssh-rsa AAAAB3NzaC1yc2EAAAEDAQABAAABAQC/wF8Q8LjEexuWDc8TfKmWVZ1CiiHK6KvO0E/Rk9+d6ssqbrvtbJWRsJXZFC8+DGWVM0UFFicmOfTwEjDWzuQPFkYhmpXrD1UiLx9Viku1g1qEJgcsyH2uAwwW3OnsH1W44D6Ni/zOzMButFeKZgPeD8H9YNkpbZBZ9QrKFiAhvEyJDYSY0bsbH1/qR5DE+dLNuGlJ/g3kUMVaXSI6dHNcBHTbK0Mse23Uopk2U3BSpvX9JdbcLaYtHDOytwd16rNYui7el3uOmlR8oUpAXkeKQxBPoxgy3qI/P8/l44L9RFpbklkmdiw2ph2ymiSkRSYCWdvEVIK/A+0D8VFjGXOb - email","organization_id":"aba2d0d0-b01d-4d88-b322-935edc96d0fd"}' - form: {} - headers: - Content-Type: - - application/json - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.13.1; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-keys - method: POST - response: - body: '{"id":"901636bc-37e5-4678-bcbf-e4606cf41238","name":"","public_key":"ssh-rsa - AAAAB3NzaC1yc2EAAAEDAQABAAABAQC/wF8Q8LjEexuWDc8TfKmWVZ1CiiHK6KvO0E/Rk9+d6ssqbrvtbJWRsJXZFC8+DGWVM0UFFicmOfTwEjDWzuQPFkYhmpXrD1UiLx9Viku1g1qEJgcsyH2uAwwW3OnsH1W44D6Ni/zOzMButFeKZgPeD8H9YNkpbZBZ9QrKFiAhvEyJDYSY0bsbH1/qR5DE+dLNuGlJ/g3kUMVaXSI6dHNcBHTbK0Mse23Uopk2U3BSpvX9JdbcLaYtHDOytwd16rNYui7el3uOmlR8oUpAXkeKQxBPoxgy3qI/P8/l44L9RFpbklkmdiw2ph2ymiSkRSYCWdvEVIK/A+0D8VFjGXOb - email","fingerprint":"None MD5:9e:19:2e:19:40:88:a9:58:7e:ca:ec:00:1b:36:96:57 - email (ssh-rsa)","created_at":"2020-03-23T18:00:14.135950Z","updated_at":"2020-03-23T18:00:14.135950Z","creation_info":{"address":"","user_agent":"","country_code":""},"organization_id":"aba2d0d0-b01d-4d88-b322-935edc96d0fd"}' - headers: - Content-Length: - - "754" - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Mon, 23 Mar 2020 18:00:14 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - 284c68f3-2c62-4592-9b57-c5b15e50df04 - status: 200 OK - code: 200 - duration: "" diff --git a/internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.golden b/internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.golden deleted file mode 100644 index 265f81d640..0000000000 --- a/internal/namespaces/account/v2alpha1/testdata/test-init-command-simple.golden +++ /dev/null @@ -1,8 +0,0 @@ -🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 -🟩🟩🟩 STDOUT️ 🟩🟩🟩️ -βœ… Key ~/.ssh/id_rsa.pub successfully added. -🟩🟩🟩 JSON STDOUT 🟩🟩🟩 -{ - "message": "Key ~/.ssh/id_rsa.pub successfully added", - "details": "" -} diff --git a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.cassette.yaml b/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.cassette.yaml deleted file mode 100644 index 1a7b132821..0000000000 --- a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.cassette.yaml +++ /dev/null @@ -1,71 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"name":"foobar","public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= - foobar@foobar","organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"}' - form: {} - headers: - Content-Type: - - application/json - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.14.2; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-keys - method: POST - response: - body: '{"id":"29e8be8f-ad33-4299-b816-72b8d45b2fb0","name":"foobar","public_key":"ecdsa-sha2-nistp256 - AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= - foobar@foobar","fingerprint":"256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 - foobar@foobar (ecdsa-sha2-nistp256)","created_at":"2020-04-14T12:35:03.168556Z","updated_at":"2020-04-16T11:44:22.498681Z","creation_info":{"address":"","user_agent":"","country_code":""},"organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"}' - headers: - Content-Length: - - "567" - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Thu, 16 Apr 2020 11:44:22 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - 4ec75443-8a78-4d75-bf92-900571aac288 - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.14.2; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-key/29e8be8f-ad33-4299-b816-72b8d45b2fb0 - method: DELETE - response: - body: "" - headers: - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Thu, 16 Apr 2020 11:44:22 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - b9fae350-70b2-44ff-a022-70eb018ffc94 - status: 204 No Content - code: 204 - duration: "" diff --git a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.golden b/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.golden deleted file mode 100644 index b83d16af1a..0000000000 --- a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-add-command-simple.golden +++ /dev/null @@ -1,29 +0,0 @@ -🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 -🟩🟩🟩 STDOUT️ 🟩🟩🟩️ -ID 29e8be8f-ad33-4299-b816-72b8d45b2fb0 -Name foobar -PublicKey ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= foobar@foobar -Fingerprint 256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 foobar@foobar (ecdsa-sha2-nistp256) -CreatedAt few seconds ago -UpdatedAt few seconds ago -CreationInfo.Address - -CreationInfo.UserAgent - -CreationInfo.CountryCode - -OrganizationID 951df375-e094-4d26-97c1-ba548eeb9c42 -ProjectID - -🟩🟩🟩 JSON STDOUT 🟩🟩🟩 -{ - "id": "29e8be8f-ad33-4299-b816-72b8d45b2fb0", - "name": "foobar", - "public_key": "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= foobar@foobar", - "fingerprint": "256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 foobar@foobar (ecdsa-sha2-nistp256)", - "created_at": "1970-01-01T00:00:00.0Z", - "updated_at": "1970-01-01T00:00:00.0Z", - "creation_info": { - "address": "", - "user_agent": "", - "country_code": "" - }, - "organization_id": "951df375-e094-4d26-97c1-ba548eeb9c42", - "project_id": "" -} diff --git a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-init-command-simple.cassette.yaml b/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-init-command-simple.cassette.yaml deleted file mode 100644 index 02ca2f6475..0000000000 --- a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-init-command-simple.cassette.yaml +++ /dev/null @@ -1,82 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: "" - form: {} - headers: - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.14.2; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-keys?order_by=created_at_asc&page=1 - method: GET - response: - body: '{"ssh_keys":[{"id":"9bf6c340-687c-4f31-8aad-6a525761d8cd","name":"sieben-macbook","public_key":"ssh-rsa - AAAAB3NzaC1yc2EAAAADAQABAAACAQDZrUk+hFs8hYZVu6PVzXIZH83glJfiqZU7gzxw9zSkinCNHZnJ0KViZmol/XUEvGPu0toWOnM5t9MUVRq3xMldo6TKOZ7tvqBDoYD/hMHSBZb+b5f12l7i43wV7dunypy+nKtlb+rv9YJdMdbVaXy29K5EPaQujYTZTvXFEB9b8P0NXt0jA+qsUEf6/TK7dONdh2PFrUFiLXtNxkw21n/q6JGfR78etQ3mIaDKffjoVYHKgMv2edGWpjAkZeM5eBg6U6kb7CMMstpxPfOPADkXu4hbWhMGG5TC4tuizfq8YAeE8t2nyfB+xq8MtQe5jTPLK1/B+NVuKvp+3WLDSrai6dbsMpFsZDXJL34BkoY7XsRf8FeaPiy5Z3ScD6YLTl986rztAPyLCKJrfPSSc2tAOgne9cGFVUPS+tehqtW+VPeD4qu00h7H9hX/x+hefqYL5cfS3h/qgpcUFw+69rVK6r1zcBwJyJAI9gUQ08628iirYku3KkUQ0VdlavrYYfB9wyStQ4VBUYpXKMhKgk5gCRRkEuJ2gETffj+nLZAqL13yFPm8lCOgRztp06S+K9Xq/cYVvAnDh8R2IsBGbs4KmpKMM7PA7mYf3XMI1KzAWXqc6RCv1a+PUwMK/AIKqnk040n2Q0yxuJSOufcVE6mWxVywHag9Ucww1FuSR54i7w== - rleone@scaleway.com","fingerprint":"4096 43:ba:7c:ec:66:6b:cc:fe:02:91:04:29:32:19:30:bf rleone@scaleway.com - (RSA)","created_at":"2019-05-02T08:26:01.304954Z","updated_at":"2020-02-26T12:46:33.737392Z","creation_info":{"address":"195.154.228.158","user_agent":"ansible - 2.7.0.dev0 Python 2.7.16","country_code":"FR"},"organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"},{"id":"cffa1bb1-57f0-4ad8-be20-f335df743b27","name":"juliencastets-macbook","public_key":"ssh-rsa - AAAAB3NzaC1yc2EAAAADAQABAAABAQDMiV5DEMsYihbdS3kCJwzSBLgGO7L2j5z2/9+HVbJbzDvAz0HcUQ+sKOlvzEUzDgtNKNP+zs7C9sMcDKKUPsVzx2jpZgGN0hP9taDzWuMX+A4B4CBftTQHtZBV8dg+EVeI5Xv6HmY/WtAWC1Xfb8mvz5z+a/8D0u9IVURqiZy/n8moQwhjpK9+m634GorgMwduMZX1pPskSVL1m2ocaP8NFq8oV9L6zf9kSi7/Jwgci1TTsGYGsRSbpc665nP7MgyxZqpP0oQK8f6VW1ndFjsSgE1fT83/1WH8ro2Ou0Esh/FTs0Wxt2A5vIShYJIO+o680rNjbIhoWHLg5tU9+ip1 - macbook","fingerprint":"2048 MD5:00:43:dc:7f:26:64:70:a2:b9:cd:06:77:35:f2:f6:f6 - macbook (ssh-rsa)","created_at":"2020-02-26T12:46:58.241993Z","updated_at":"2020-02-26T12:46:58.241993Z","creation_info":{"address":"195.154.229.35","user_agent":"Mozilla/5.0 - (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 - Safari/537.36","country_code":"FR"},"organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"}],"total_count":2}' - headers: - Content-Length: - - "2130" - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Tue, 14 Apr 2020 14:12:16 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - af941d7d-2847-4053-8581-0b7c3f05e7ae - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"name":"","public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLFaYS65Fb6Z77wm4bwUlUOCCbKFU/tRDJkaTFJVNtkIGm6ub1ael54v+UI9qWYxyo1+qLfjloKN6sUCrMkU8/I= - foobar@foobar","organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"}' - form: {} - headers: - Content-Type: - - application/json - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.14.2; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-keys - method: POST - response: - body: '{"id":"454410ec-ea49-40c6-a6e8-4e7f8c176062","name":"","public_key":"ecdsa-sha2-nistp256 - AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLFaYS65Fb6Z77wm4bwUlUOCCbKFU/tRDJkaTFJVNtkIGm6ub1ael54v+UI9qWYxyo1+qLfjloKN6sUCrMkU8/I= - foobar@foobar","fingerprint":"256 MD5:fe:48:15:f4:4c:ce:55:1f:fb:bf:f7:48:06:17:d7:a5 - foobar@foobar (ecdsa-sha2-nistp256)","created_at":"2020-04-14T14:10:41.164654Z","updated_at":"2020-04-14T14:12:16.412485Z","creation_info":{"address":"","user_agent":"","country_code":""},"organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"}' - headers: - Content-Length: - - "561" - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Tue, 14 Apr 2020 14:12:16 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - 30f6162c-df13-4c23-bd4b-8902b51bc2d4 - status: 200 OK - code: 200 - duration: "" diff --git a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.cassette.yaml b/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.cassette.yaml deleted file mode 100644 index d74661a858..0000000000 --- a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.cassette.yaml +++ /dev/null @@ -1,71 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"name":"","public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGh9rvkJKMu5ljnevB4oRu4i/EnxGS734/UJ6fSDvXGIvT08jIglahc7tM5dvo02abPVXsbiazO25avZZtL6fjo= - foobar@foobar","organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"}' - form: {} - headers: - Content-Type: - - application/json - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.14.2; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-keys - method: POST - response: - body: '{"id":"b8043e18-be9b-4aea-b747-9e3ae08f7a33","name":"","public_key":"ecdsa-sha2-nistp256 - AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGh9rvkJKMu5ljnevB4oRu4i/EnxGS734/UJ6fSDvXGIvT08jIglahc7tM5dvo02abPVXsbiazO25avZZtL6fjo= - foobar@foobar","fingerprint":"256 MD5:66:2f:05:a4:64:d2:22:89:b6:ad:e8:a9:3e:38:22:95 - foobar@foobar (ecdsa-sha2-nistp256)","created_at":"2020-04-14T14:13:49.613484Z","updated_at":"2020-04-16T11:44:34.164918Z","creation_info":{"address":"","user_agent":"","country_code":""},"organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42"}' - headers: - Content-Length: - - "561" - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Thu, 16 Apr 2020 11:44:33 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - 7600e382-edd7-411f-abf2-9d4e0e50c5e7 - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.6+dev (go1.14.2; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/account/v2alpha1/ssh-key/b8043e18-be9b-4aea-b747-9e3ae08f7a33 - method: DELETE - response: - body: "" - headers: - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Thu, 16 Apr 2020 11:44:33 GMT - Server: - - scaleway_api - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - 3b76b3f3-d44a-4ebd-a415-3f08114a9b47 - status: 204 No Content - code: 204 - duration: "" diff --git a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.golden b/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.golden deleted file mode 100644 index 87818d7a08..0000000000 --- a/internal/namespaces/account/v2alpha1/testdata/test-ssh-key-remove-command-simple.golden +++ /dev/null @@ -1,8 +0,0 @@ -🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 -🟩🟩🟩 STDOUT️ 🟩🟩🟩️ -βœ… Success. -🟩🟩🟩 JSON STDOUT 🟩🟩🟩 -{ - "message": "Success", - "details": "" -} diff --git a/internal/namespaces/account/v3/custom.go b/internal/namespaces/account/v3/custom.go index b70df2c894..183ebb09e5 100644 --- a/internal/namespaces/account/v3/custom.go +++ b/internal/namespaces/account/v3/custom.go @@ -1,9 +1,11 @@ package account -import "github.com/scaleway/scaleway-cli/v2/internal/core" +import ( + "github.com/scaleway/scaleway-cli/v2/internal/core" +) func GetCommands() *core.Commands { - cmds := GetGeneratedCommands() + commands := GetGeneratedCommands() - return cmds + return commands } diff --git a/internal/namespaces/iam/v1alpha1/custom_test.go b/internal/namespaces/iam/v1alpha1/custom_test.go index 35051a6df5..31d610e8a4 100644 --- a/internal/namespaces/iam/v1alpha1/custom_test.go +++ b/internal/namespaces/iam/v1alpha1/custom_test.go @@ -11,11 +11,11 @@ import ( func Test_initWithSSHKeyCommand(t *testing.T) { tmpDir := os.TempDir() - key := `ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= foobar@foobar` + key := `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBn9mGL7LGZ6/RTIVP7GExiD5gOwgl63MbJGlL7a6U3x foo@foobar.com` t.Run("simple", core.Test(&core.TestConfig{ Commands: GetCommands(), BeforeFunc: func(ctx *core.BeforeFuncCtx) error { - pathToPublicKey := path.Join(tmpDir, ".ssh", "id_rsa.pub") + pathToPublicKey := path.Join(tmpDir, ".ssh", "id_ed25519.pub") _, err := os.Stat(pathToPublicKey) if err != nil { err := os.MkdirAll(path.Join(tmpDir, ".ssh"), 0755) diff --git a/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.cassette.yaml b/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.cassette.yaml index 62d40ff3e7..45c4ef9657 100644 --- a/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.cassette.yaml +++ b/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.cassette.yaml @@ -2,24 +2,74 @@ version: 1 interactions: - request: - body: "" + body: '{"ssh_keys":[{"id":"495d0e9f-a22b-4ff5-8324-0cb4746c57dc", "name":"rleone@scaleway.com", + "public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6Lfs9IrfEUsw2oALOKucAqjeJo3vdADJAZS0BrJ4Vl + rleone@scaleway.com", "fingerprint":"256 MD5:0d:6d:20:43:4c:0f:38:a3:65:de:8f:72:77:70:26:55 + rleone@scaleway.com (ssh-ed25519)", "created_at":"2022-03-29T07:50:11.839583Z", + "updated_at":"2022-03-29T07:50:17.762922Z", "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "disabled":false}, {"id":"e2e9d140-c387-43e8-af1b-5b133f8fe90d", + "name":"leila''s ssh-key", "public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIG4S+vO03k8VY0qdhRThHbyiDFbIqvzH+94x24b4hbQ + lmarabese", "fingerprint":"256 MD5:69:c9:cf:52:7d:07:cc:ff:a4:58:e4:7e:96:77:18:63 + lmarabese (ssh-ed25519)", "created_at":"2023-02-07T10:19:17.608707Z", "updated_at":"2023-02-07T10:19:17.608707Z", + "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "disabled":false}, {"id":"1f5abae8-78f7-41a2-a787-780166d3f736", "name":"foobar", + "public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= + foobar@foobar", "fingerprint":"256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 + foobar@foobar (ecdsa-sha2-nistp256)", "created_at":"2023-07-17T14:47:52.688903Z", + "updated_at":"2023-07-17T14:47:52.688903Z", "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "disabled":false}, {"id":"459e72de-56f0-4177-a3fd-f8bf47571915", + "name":"foobar", "public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= + foobar@foobar", "fingerprint":"256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 + foobar@foobar (ecdsa-sha2-nistp256)", "created_at":"2023-07-17T14:47:55.834080Z", + "updated_at":"2023-07-17T14:47:55.834080Z", "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "disabled":false}, {"id":"e4572020-36e1-41fc-9bbc-2faa56c12e93", + "name":"key-elastic-allen", "public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBn9mGL7LGZ6/RTIVP7GExiD5gOwgl63MbJGlL7a6U3x + foo@foobar.com", "fingerprint":"256 MD5:1e:f8:f7:cb:c4:b7:a8:6d:96:20:49:d0:d0:af:a0:9e + foo@foobar.com (ssh-ed25519)", "created_at":"2023-07-17T15:05:30.415306Z", "updated_at":"2023-07-17T15:05:30.415306Z", + "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "disabled":false}], "total_count":5}' form: {} headers: User-Agent: - - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.19; darwin; amd64) cli-e2e-test + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.20.6; darwin; amd64) cli-e2e-test url: https://api.scaleway.com/iam/v1alpha1/ssh-keys?order_by=created_at_asc&page=1 method: GET response: - body: '{"ssh_keys":[],"total_count":0}' + body: '{"ssh_keys":[{"id":"495d0e9f-a22b-4ff5-8324-0cb4746c57dc", "name":"rleone@scaleway.com", + "public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6Lfs9IrfEUsw2oALOKucAqjeJo3vdADJAZS0BrJ4Vl + rleone@scaleway.com", "fingerprint":"256 MD5:0d:6d:20:43:4c:0f:38:a3:65:de:8f:72:77:70:26:55 + rleone@scaleway.com (ssh-ed25519)", "created_at":"2022-03-29T07:50:11.839583Z", + "updated_at":"2022-03-29T07:50:17.762922Z", "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "disabled":false}, {"id":"e2e9d140-c387-43e8-af1b-5b133f8fe90d", + "name":"leila''s ssh-key", "public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIG4S+vO03k8VY0qdhRThHbyiDFbIqvzH+94x24b4hbQ + lmarabese", "fingerprint":"256 MD5:69:c9:cf:52:7d:07:cc:ff:a4:58:e4:7e:96:77:18:63 + lmarabese (ssh-ed25519)", "created_at":"2023-02-07T10:19:17.608707Z", "updated_at":"2023-02-07T10:19:17.608707Z", + "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "disabled":false}, {"id":"1f5abae8-78f7-41a2-a787-780166d3f736", "name":"foobar", + "public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= + foobar@foobar", "fingerprint":"256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 + foobar@foobar (ecdsa-sha2-nistp256)", "created_at":"2023-07-17T14:47:52.688903Z", + "updated_at":"2023-07-17T14:47:52.688903Z", "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "disabled":false}, {"id":"459e72de-56f0-4177-a3fd-f8bf47571915", + "name":"foobar", "public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= + foobar@foobar", "fingerprint":"256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 + foobar@foobar (ecdsa-sha2-nistp256)", "created_at":"2023-07-17T14:47:55.834080Z", + "updated_at":"2023-07-17T14:47:55.834080Z", "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "disabled":false}, {"id":"e4572020-36e1-41fc-9bbc-2faa56c12e93", + "name":"key-elastic-allen", "public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBn9mGL7LGZ6/RTIVP7GExiD5gOwgl63MbJGlL7a6U3x + foo@foobar.com", "fingerprint":"256 MD5:1e:f8:f7:cb:c4:b7:a8:6d:96:20:49:d0:d0:af:a0:9e + foo@foobar.com (ssh-ed25519)", "created_at":"2023-07-17T15:05:30.415306Z", "updated_at":"2023-07-17T15:05:30.415306Z", + "organization_id":"951df375-e094-4d26-97c1-ba548eeb9c42", "project_id":"951df375-e094-4d26-97c1-ba548eeb9c42", + "disabled":false}], "total_count":5}' headers: Content-Length: - - "3508" + - "2710" Content-Security-Policy: - default-src 'none'; frame-ancestors 'none' Content-Type: - application/json Date: - - Wed, 15 Feb 2023 16:02:46 GMT + - Mon, 17 Jul 2023 15:18:21 GMT Server: - Scaleway API-Gateway Strict-Transport-Security: @@ -29,45 +79,7 @@ interactions: X-Frame-Options: - DENY X-Request-Id: - - 6139b965-ed34-498c-8e8d-ad77b24e9c4d - status: 200 OK - code: 200 - duration: "" -- request: - body: '{"name":"key-keen-elgamal","public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= - foobar@foobar","project_id":"63a66ec9-a385-4194-bc15-04aa6921274a"}' - form: {} - headers: - Content-Type: - - application/json - User-Agent: - - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.19; darwin; amd64) cli-e2e-test - url: https://api.scaleway.com/iam/v1alpha1/ssh-keys - method: POST - response: - body: '{"id":"70581bce-87f3-4625-b481-f75b24e52a3b","name":"key-keen-elgamal","public_key":"ecdsa-sha2-nistp256 - AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBieay3nO9wViPkuvFVgGGaA1IRlkFrr946yqvg9LxZIRhsnZ61yLCPmIOhvUAZ/gTxZGmhgtMDxkenSUTsG3F0= - foobar@foobar","fingerprint":"256 MD5:19:ec:90:3b:95:c6:d8:93:ac:e1:14:4c:0e:cb:ea:44 - foobar@foobar (ecdsa-sha2-nistp256)","created_at":"2023-02-15T16:02:46.819741Z","updated_at":"2023-02-15T16:02:46.819741Z","organization_id":"63a66ec9-a385-4194-bc15-04aa6921274a","project_id":"63a66ec9-a385-4194-bc15-04aa6921274a","disabled":false}' - headers: - Content-Length: - - "581" - Content-Security-Policy: - - default-src 'none'; frame-ancestors 'none' - Content-Type: - - application/json - Date: - - Wed, 15 Feb 2023 16:02:46 GMT - Server: - - Scaleway API-Gateway - Strict-Transport-Security: - - max-age=63072000 - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - X-Request-Id: - - 953b4083-ca64-4997-9450-55127c9cc88f + - c75be1c4-288c-486f-86af-5737738288b6 status: 200 OK code: 200 duration: "" diff --git a/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.golden b/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.golden index 265f81d640..71e96cc5a1 100644 --- a/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.golden +++ b/internal/namespaces/iam/v1alpha1/testdata/test-init-with-ssh-key-command-simple.golden @@ -1,8 +1,3 @@ 🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 🟩🟩🟩 STDOUT️ 🟩🟩🟩️ -βœ… Key ~/.ssh/id_rsa.pub successfully added. -🟩🟩🟩 JSON STDOUT 🟩🟩🟩 -{ - "message": "Key ~/.ssh/id_rsa.pub successfully added", - "details": "" -} +-