From 192727f082f184212659fd19a9a22c3b03d1d23a Mon Sep 17 00:00:00 2001 From: Gero Posmyk-Leinemann Date: Tue, 17 Sep 2024 13:59:03 +0200 Subject: [PATCH] [gp] Add helpful message in case "gp env --scope=user" fails because of missing create permission (#20227) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [gp] Add helpful message in case "gp env --scope=user" fails because of missing create permission * Fix typo Co-authored-by: Filip Troníček * another typo --------- Co-authored-by: Filip Troníček --- components/gitpod-cli/cmd/env.go | 33 +++++++++++++++++++++------ components/gitpod-cli/cmd/validate.go | 2 +- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/components/gitpod-cli/cmd/env.go b/components/gitpod-cli/cmd/env.go index bf294eacca4eaf..cee561f3fffc0d 100644 --- a/components/gitpod-cli/cmd/env.go +++ b/components/gitpod-cli/cmd/env.go @@ -8,12 +8,14 @@ import ( "context" "fmt" "io" + "net/http" "os" "strings" "sync" "time" log "github.com/sirupsen/logrus" + "github.com/sourcegraph/jsonrpc2" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" "golang.org/x/xerrors" @@ -36,6 +38,17 @@ var ( envScopeUser envScope = "user" ) +func envScopeFromString(s string) envScope { + switch s { + case string(envScopeRepo): + return envScopeRepo + case string(envScopeUser): + return envScopeUser + default: + return envScopeRepo + } +} + // envCmd represents the env command var envCmd = &cobra.Command{ Use: "env", @@ -75,8 +88,8 @@ delete environment variables with a repository pattern of */foo, foo/* or */*. if unsetEnvs { err = deleteEnvs(ctx, args) } else { - scopeUser := scope == string(envScopeUser) - err = setEnvs(ctx, scopeUser, args) + setEnvScope := envScopeFromString(scope) + err = setEnvs(ctx, setEnvScope, args) } } else { err = getEnvs(ctx) @@ -89,6 +102,7 @@ type connectToServerResult struct { repositoryPattern string wsInfo *supervisorapi.WorkspaceInfoResponse client *serverapi.APIoverJSONRPC + gitpodHost string } type connectToServerOptions struct { @@ -96,7 +110,7 @@ type connectToServerOptions struct { wsInfo *api.WorkspaceInfoResponse log *log.Entry - setEnvScopeUser bool + setEnvScope envScope } func connectToServer(ctx context.Context, options *connectToServerOptions) (*connectToServerResult, error) { @@ -133,7 +147,7 @@ func connectToServer(ctx context.Context, options *connectToServerOptions) (*con repositoryPattern := wsinfo.Repository.Owner + "/" + wsinfo.Repository.Name operations := "create/get/update/delete" - if options != nil && options.setEnvScopeUser { + if options != nil && options.setEnvScope == envScopeUser { // Updating user env vars requires a different token with a special scope repositoryPattern = "*/*" operations = "update" @@ -166,7 +180,7 @@ func connectToServer(ctx context.Context, options *connectToServerOptions) (*con if err != nil { return nil, xerrors.Errorf("failed connecting to server: %w", err) } - return &connectToServerResult{repositoryPattern, wsinfo, client}, nil + return &connectToServerResult{repositoryPattern, wsinfo, client, wsinfo.GitpodHost}, nil } func getWorkspaceEnvs(ctx context.Context, options *connectToServerOptions) ([]*serverapi.EnvVar, error) { @@ -192,9 +206,9 @@ func getEnvs(ctx context.Context) error { return nil } -func setEnvs(ctx context.Context, scopeUser bool, args []string) error { +func setEnvs(ctx context.Context, setEnvScope envScope, args []string) error { options := connectToServerOptions{ - setEnvScopeUser: scopeUser, + setEnvScope: setEnvScope, } result, err := connectToServer(ctx, &options) if err != nil { @@ -213,6 +227,11 @@ func setEnvs(ctx context.Context, scopeUser bool, args []string) error { g.Go(func() error { err = result.client.SetEnvVar(ctx, v) if err != nil { + if ferr, ok := err.(*jsonrpc2.Error); ok && ferr.Code == http.StatusForbidden && setEnvScope == envScopeUser { + return fmt.Errorf(""+ + "Can't automatically create env var `%s` for security reasons.\n"+ + "Please create the var manually under %s/user/variables using Name=%s, Scope=*/*, Value=foobar", v.Name, result.gitpodHost, v.Name) + } return err } printVar(v.Name, v.Value, exportEnvs) diff --git a/components/gitpod-cli/cmd/validate.go b/components/gitpod-cli/cmd/validate.go index 5cb843547cd24e..049ba15bdabee8 100644 --- a/components/gitpod-cli/cmd/validate.go +++ b/components/gitpod-cli/cmd/validate.go @@ -238,7 +238,7 @@ func runRebuild(ctx context.Context, supervisorClient *supervisor.SupervisorClie serverLog := logrus.NewEntry(logrus.New()) serverLog.Logger.SetLevel(logLevel) setLoggerFormatter(serverLog.Logger) - workspaceEnvs, err := getWorkspaceEnvs(ctx, &connectToServerOptions{supervisorClient, wsInfo, serverLog, false}) + workspaceEnvs, err := getWorkspaceEnvs(ctx, &connectToServerOptions{supervisorClient, wsInfo, serverLog, envScopeRepo}) if err != nil { return err }