Skip to content

cli: prompt for organization on login #19107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 57 additions & 15 deletions components/local-app/cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/gitpod-io/local-app/pkg/auth"
"github.com/gitpod-io/local-app/pkg/config"
"github.com/gitpod-io/local-app/pkg/prettyprint"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)

Expand All @@ -27,6 +28,7 @@ var loginOpts struct {
Host string
ContextName string
OrganizationID string
NonInteractive bool
}

// loginCmd represents the login command
Expand All @@ -51,15 +53,19 @@ var loginCmd = &cobra.Command{
token = os.Getenv("GITPOD_TOKEN")
}
if token == "" {
var err error
token, err = auth.Login(context.Background(), auth.LoginOpts{
GitpodURL: loginOpts.Host,
AuthTimeout: 5 * time.Minute,
// Request CLI scopes (extended compared to the local companion app)
ExtendScopes: true,
})
if err != nil {
return err
if loginOpts.NonInteractive {
return fmt.Errorf("no token provided")
} else {
var err error
token, err = auth.Login(context.Background(), auth.LoginOpts{
GitpodURL: loginOpts.Host,
AuthTimeout: 5 * time.Minute,
// Request CLI scopes (extended compared to the local companion app)
ExtendScopes: true,
})
if err != nil {
return err
}
}
}

Expand Down Expand Up @@ -91,6 +97,9 @@ var loginCmd = &cobra.Command{
if err != nil {
return fmt.Errorf("cannot connect to Gitpod with this context: %w", err)
}
if !loginOpts.NonInteractive {
fmt.Println("loading your organizations...")
}
orgsList, err := clnt.Teams.ListTeams(cmd.Context(), connect.NewRequest(&v1.ListTeamsRequest{}))
if err != nil {
var (
Expand All @@ -117,15 +126,47 @@ var loginCmd = &cobra.Command{
}
}

orgs := orgsList.Msg.GetTeams()
fmt.Print("\033[A\033[K")

resolutions := []string{
"pass an organization ID using --organization-id",
}

var orgID string
switch len(orgsList.Msg.GetTeams()) {
switch len(orgs) {
case 0:
return fmt.Errorf("no organizations found. Please pass an organization ID using --organization-id")
return prettyprint.AddResolution(fmt.Errorf("no organizations found"), resolutions...)
case 1:
orgID = orgsList.Msg.GetTeams()[0].Id
orgID = orgs[0].Id
default:
orgID = orgsList.Msg.GetTeams()[0].Id
slog.Info("found more than one organization and choose the first one", "org", orgID)
if loginOpts.NonInteractive {
resolutions = append(resolutions,
"omit --non-interactive and select an organization interactively",
)
return prettyprint.AddResolution(fmt.Errorf("found more than one organization"), resolutions...)
}

var orgNames []string
for _, org := range orgs {
orgNames = append(orgNames, org.Name)
}

prompt := promptui.Select{
Label: "What organization would you like to use?",
Items: orgNames,
Templates: &promptui.SelectTemplates{
Selected: "Selected organization {{ . }}",
},
}
selectedIndex, selectedValue, err := prompt.Run()
if selectedValue == "" {
return fmt.Errorf("no organization selected")
}
if err != nil {
return err
}
orgID = orgs[selectedIndex].Id
}
cfg.Contexts[contextName].OrganizationID = orgID
}
Expand All @@ -144,7 +185,7 @@ var loginCmd = &cobra.Command{
return err
}

slog.Info("Login succesfull")
slog.Info("login successful")
fmt.Println()
return WriteTabular(who, formatOpts{}, prettyprint.WriterFormatNarrow)
},
Expand All @@ -161,4 +202,5 @@ func init() {
loginCmd.Flags().StringVar(&loginOpts.Token, "token", "", "The token to use for authentication (defaults to $GITPOD_TOKEN)")
loginCmd.Flags().StringVarP(&loginOpts.ContextName, "context-name", "n", "default", "The name of the context to create")
loginCmd.Flags().StringVar(&loginOpts.OrganizationID, "org", "", "The organization ID to use for the context")
loginCmd.Flags().BoolVar(&loginOpts.NonInteractive, "non-interactive", false, "Disable opening the browser and prompt to select an organization")
}
2 changes: 2 additions & 0 deletions components/local-app/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
github.com/gookit/color v1.5.4
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf
github.com/lmittmann/tint v1.0.3
github.com/manifoldco/promptui v0.9.0
github.com/mattn/go-isatty v0.0.17
github.com/sagikazarmark/slog-shim v0.1.0
github.com/spf13/cobra v1.7.0
Expand All @@ -45,6 +46,7 @@ require (
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
Expand Down
9 changes: 9 additions & 0 deletions components/local-app/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion components/local-app/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.1
0.1.2