diff --git a/pkg/api/api.go b/pkg/api/api.go index 6058632d73..49d22c2722 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -526,7 +526,7 @@ type ScalewayTokenDefinition struct { // ScalewayTokensDefinition represents a Scaleway Tokens type ScalewayTokensDefinition struct { - Tokens []ScalewayTokenDefinition `json:"tokens"` + Token ScalewayTokenDefinition `json:"token"` } // ScalewayConnectResponse represents the answer from POST /tokens @@ -566,6 +566,10 @@ type ScalewayUserDefinition struct { SSHPublicKeys []ScalewayKeyDefinition `json:"ssh_public_keys"` } +type ScalewayUsersDefinition struct { + User ScalewayUserDefinition `json:"user"` +} + // ScalewayKeyDefinition represents a key type ScalewayKeyDefinition struct { Key string `json:"key"` @@ -1328,11 +1332,11 @@ func (s *ScalewayAPI) CheckCredentials() error { return nil } -// GetUserID returns the UserID +// GetUserID returns the userID func (s *ScalewayAPI) GetUserID() (string, error) { s.EnableAccountAPI() defer s.DisableAccountAPI() - resp, err := s.GetResponse("tokens") + resp, err := s.GetResponse(fmt.Sprintf("tokens/%s", s.Token)) if err != nil { return "", err } @@ -1340,16 +1344,63 @@ func (s *ScalewayAPI) GetUserID() (string, error) { return "", fmt.Errorf("[%d] invalid credentials", resp.StatusCode) } defer resp.Body.Close() - var tokens ScalewayTokensDefinition + var token ScalewayTokensDefinition + decoder := json.NewDecoder(resp.Body) - err = decoder.Decode(&tokens) + err = decoder.Decode(&token) if err != nil { return "", err } - if len(tokens.Tokens) == 0 { - return "", fmt.Errorf("unable to get tokens") + return token.Token.UserID, nil +} + +// GetOrganization returns Organization +func (s *ScalewayAPI) GetOrganization() (*ScalewayOrganizationsDefinition, error) { + s.EnableAccountAPI() + defer s.DisableAccountAPI() + resp, err := s.GetResponse("organizations") + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, fmt.Errorf("[%d] unable to GET", resp.StatusCode) + } + + var data ScalewayOrganizationsDefinition + + defer resp.Body.Close() + decoder := json.NewDecoder(resp.Body) + err = decoder.Decode(&data) + if err != nil { + return nil, err + } + return &data, nil +} + +// GetUser returns the user +func (s *ScalewayAPI) GetUser() (*ScalewayUserDefinition, error) { + userID, err := s.GetUserID() + if err != nil { + return nil, err + } + s.EnableAccountAPI() + defer s.DisableAccountAPI() + resp, err := s.GetResponse(fmt.Sprintf("users/%s", userID)) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, fmt.Errorf("[%d] no such user", resp.StatusCode) + } + defer resp.Body.Close() + var user ScalewayUsersDefinition + + decoder := json.NewDecoder(resp.Body) + err = decoder.Decode(&user) + if err != nil { + return nil, err } - return tokens.Tokens[0].UserID, nil + return &user.User, nil } // diff --git a/pkg/commands/login.go b/pkg/commands/login.go index a0b8dce7b4..941eccf6f0 100644 --- a/pkg/commands/login.go +++ b/pkg/commands/login.go @@ -107,29 +107,16 @@ func getToken(connect api.ScalewayConnect) (string, error) { return data.Token.ID, nil } -func getOrga(token string, email string) (string, error) { +func getOrganization(token string, email string) (string, error) { FakeConnection, err := api.NewScalewayAPI(api.ComputeAPI, api.AccountAPI, "", token) if err != nil { return "", fmt.Errorf("Unable to create a fake ScalewayAPI: %s", err) } - FakeConnection.EnableAccountAPI() - - resp, err := FakeConnection.GetResponse("organizations") + data, err := FakeConnection.GetOrganization() if err != nil { return "", err } - if resp.StatusCode != 200 { - return "", fmt.Errorf("[%d] unable to GET", resp.StatusCode) - } - - var data api.ScalewayOrganizationsDefinition - defer resp.Body.Close() - decoder := json.NewDecoder(resp.Body) - err = decoder.Decode(&data) - if err != nil { - return "", err - } orgaID := "" for _, orga := range data.Organizations { @@ -173,13 +160,36 @@ func connectAPI() (string, string, error) { if err != nil { return "", "", err } - orga, err = getOrga(token, connect.Email) + orga, err = getOrganization(token, connect.Email) if err != nil { return "", "", err } return orga, token, nil } +// uploadSSHKeys uploads an SSH Key +func uploadSSHKeys(apiConnection *api.ScalewayAPI, newKey string) { + user, err := apiConnection.GetUser() + if err != nil { + logrus.Errorf("Unable to contact ScalewayAPI: %s", err) + } else { + user.SSHPublicKeys = append(user.SSHPublicKeys, api.ScalewayKeyDefinition{Key: strings.Trim(newKey, "\n")}) + + SSHKeys := api.ScalewayUserPatchSSHKeyDefinition{ + SSHPublicKeys: user.SSHPublicKeys, + } + + userID, err := apiConnection.GetUserID() + if err != nil { + logrus.Errorf("Unable to get userID: %s", err) + } else { + if err = apiConnection.PatchUserSSHKey(userID, SSHKeys); err != nil { + logrus.Errorf("Unable to patch SSHkey: %v", err) + } + } + } +} + // RunLogin is the handler for 'scw login' func RunLogin(ctx CommandContext, args LoginArgs) error { if args.Organization == "" || args.Token == "" { @@ -211,21 +221,7 @@ func RunLogin(ctx CommandContext, args LoginArgs) error { logrus.Errorf("Unable to select a key: %v", err) } else { if args.SSHKey != "" { - userID, err := apiConnection.GetUserID() - if err != nil { - logrus.Errorf("Unable to contact ScalewayAPI: %s", err) - } else { - - SSHKey := api.ScalewayUserPatchSSHKeyDefinition{ - SSHPublicKeys: []api.ScalewayKeyDefinition{{ - Key: strings.Trim(args.SSHKey, "\n"), - }}, - } - - if err = apiConnection.PatchUserSSHKey(userID, SSHKey); err != nil { - logrus.Errorf("Unable to patch SSHkey: %v", err) - } - } + uploadSSHKeys(apiConnection, args.SSHKey) } } }