From 13e7ebbddf7c756e7326eb65d9b3d50602b482f0 Mon Sep 17 00:00:00 2001 From: Ayush Rangwala Date: Tue, 8 Aug 2023 22:14:05 +0530 Subject: [PATCH] Consider both project and user API token and populate default org id and project id accordingly --- internal/init/init.go | 65 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/internal/init/init.go b/internal/init/init.go index 16ea9ff8..78453d64 100644 --- a/internal/init/init.go +++ b/internal/init/init.go @@ -29,10 +29,11 @@ import ( "syscall" metal "github.com/equinix-labs/metal-go/metal/v1" - pager "github.com/equinix/metal-cli/internal/pagination" "github.com/spf13/cobra" "golang.org/x/term" "sigs.k8s.io/yaml" + + pager "github.com/equinix/metal-cli/internal/pagination" ) type Client struct { @@ -91,34 +92,49 @@ func (c *Client) NewCommand() *cobra.Command { c.UserService = *metalGoClient.UsersApi c.ProjectService = *metalGoClient.ProjectsApi - user, _, err := c.UserService.FindCurrentUser(context.Background()).Execute() + var defaultOrgId, defaultProjectId string + project, isProjectToken, err := getDefaultProjectOK(c.ProjectService) if err != nil { return err } - organization := user.GetDefaultOrganizationId() - project := user.GetDefaultProjectId() - fmt.Printf("Organization ID [%s]: ", organization) + if project != nil { + defaultProjectId = project.GetId() + defaultOrgId = project.Organization.GetId() + } + + if !isProjectToken { + // API token provided is user token + user, _, err := c.UserService.FindCurrentUser(context.Background()).Execute() + if err != nil { + return err + } + + defaultOrgId = user.GetDefaultOrganizationId() + defaultProjectId = user.GetDefaultProjectId() + } + fmt.Printf("Organization ID [%s]: ", defaultOrgId) userOrg := "" fmt.Scanln(&userOrg) if userOrg == "" { - userOrg = organization + userOrg = defaultOrgId } // Choose the first project in the preferred org - if project == "" { - project, err = getFirstProjectID(c.ProjectService, userOrg) + // Donot try to get projects again when + if defaultProjectId == "" && !isProjectToken { + defaultProjectId, err = getFirstProjectID(c.ProjectService, userOrg) if err != nil { return err } } - fmt.Printf("Project ID [%s]: ", project) + fmt.Printf("Project ID [%s]: ", defaultProjectId) userProj := "" fmt.Scanln(&userProj) if userProj == "" { - userProj = project + userProj = defaultProjectId } b, err = formatConfig(userProj, userOrg, token) @@ -132,10 +148,35 @@ func (c *Client) NewCommand() *cobra.Command { return initCmd } -func getFirstProjectID(s metal.ProjectsApiService, userOrg string) (string, error) { +func getDefaultProjectOK(service metal.ProjectsApiService) (*metal.Project, bool, error) { + isProjectToken := false + projects, err := getAllProjects(service) + if err != nil { + return nil, isProjectToken, err + } + + if len(projects) > 1 { + return nil, isProjectToken, nil + } + + // Project API Token provided + isProjectToken = true + if len(projects) == 1 { + return &projects[0], isProjectToken, nil + } + + fmt.Println("WARN: No available projects found with the provided API Token") + return nil, isProjectToken, nil +} + +func getAllProjects(service metal.ProjectsApiService) ([]metal.Project, error) { include := []string{"organization"} // []string | Nested attributes to include. Included objects will return their full attributes. Attribute names can be dotted (up to 3 levels) to included deeply nested objects. (optional) exclude := []string{"devices", "members", "memberships", "invitations", "ssh_keys", "volumes", "backend_transfer_enabled", "updated_at", "customdata", "event_alert_configuration"} - projects, err := pager.GetAllProjects(s, include, exclude) + return pager.GetAllProjects(service, include, exclude) +} + +func getFirstProjectID(s metal.ProjectsApiService, userOrg string) (string, error) { + projects, err := getAllProjects(s) if err != nil { return "", err }