From 34b21d9d9e312a7123d7a883ea429e2bf478fa83 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Sun, 14 Jul 2024 16:45:13 -0700 Subject: [PATCH 1/3] Continue work on login command - login is not needed for all commands. - process command doesn't open URLs anymore so... - Remove `--open` flag from `process` command - Remove `ConfigProfilesUrlAction` config option Refs: #291 --- CHANGELOG.md | 6 +++++- cmd/aws-sso/cache_cmd.go | 3 +-- cmd/aws-sso/main.go | 9 ++++----- cmd/aws-sso/process_cmd.go | 7 +------ cmd/aws-sso/setup_profiles_cmd.go | 23 ++--------------------- docs/commands.md | 12 +----------- docs/config.md | 24 ------------------------ internal/awsconfig/config.go | 15 +++++++-------- internal/awsconfig/config_test.go | 17 ++++++++--------- internal/sso/settings.go | 3 +-- internal/sso/settings_test.go | 7 +++---- 11 files changed, 33 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d1b7a3a..ade60a7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,11 @@ * No longer show help for sub-commands by default * Warnings about invalid accounts/roles in config.yaml are now Debug messages #980 * Default ProfileFormat is now the `Friendly` format #992 - * `config`, `config-profiles` and `completions` are now sub-commands of `setup` #975 + * Refactor commands under `setup`: #975 + * `config` is now `setup wizard` and `ConfigProfilesUrlAction` config option is no longer used + * `config-profiles` is now `setup profiles` + * `completions` is now `setup completions` + * Remove `--open` option from `process` command #291 * Only the and `cache` command will auto-update the contents of `~/.aws/config` #974 * `tags` command no longer supports the `--force-update` option * Change default log level from `warn` to `info` diff --git a/cmd/aws-sso/cache_cmd.go b/cmd/aws-sso/cache_cmd.go index b656e7d3..5da0b49a 100644 --- a/cmd/aws-sso/cache_cmd.go +++ b/cmd/aws-sso/cache_cmd.go @@ -57,8 +57,7 @@ func (cc *CacheCmd) Run(ctx *RunContext) error { // should we update our config?? if !ctx.Cli.Cache.NoConfigCheck && ctx.Settings.AutoConfigCheck { if ctx.Settings.ConfigProfilesUrlAction != url.ConfigProfilesUndef { - action, _ := url.NewAction(string(ctx.Settings.ConfigProfilesUrlAction)) - err := awsconfig.UpdateAwsConfig(ctx.Settings, action, "", true, false) + err := awsconfig.UpdateAwsConfig(ctx.Settings, "", true, false) if err != nil { log.Errorf("Unable to auto-update aws config file: %s", err.Error()) } diff --git a/cmd/aws-sso/main.go b/cmd/aws-sso/main.go index c5ff808b..e57966bc 100644 --- a/cmd/aws-sso/main.go +++ b/cmd/aws-sso/main.go @@ -84,7 +84,6 @@ var DEFAULT_CONFIG map[string]interface{} = map[string]interface{}{ "PromptColors.SuggestionTextColor": "White", "AutoConfigCheck": false, "CacheRefresh": 168, // 7 days in hours - "ConfigProfilesUrlAction": "open", "ConsoleDuration": 60, "DefaultRegion": "us-east-1", "DefaultSSO": "Default", @@ -113,7 +112,6 @@ type CLI struct { // Commands Cache CacheCmd `kong:"cmd,help='Force reload of cached AWS SSO role info and config.yaml'"` - Setup SetupCmd `kong:"cmd,help='Setup Wizard, Completions, etc'"` Console ConsoleCmd `kong:"cmd,help='Open AWS Console using specificed AWS role/profile'"` Credentials CredentialsCmd `kong:"cmd,help='Generate static AWS credentials for use with AWS CLI'"` Default DefaultCmd `kong:"cmd,hidden,default='1'"` // list command without args @@ -124,7 +122,8 @@ type CLI struct { Login LoginCmd `kong:"cmd,help='Login to an AWS Identity Center instance'"` Logout LogoutCmd `kong:"cmd,help='Logout from an AWS Identity Center instance and invalidate all credentials'"` ListSSORoles ListSSORolesCmd `kong:"cmd,hidden,help='List AWS SSO Roles (debugging)'"` - Process ProcessCmd `kong:"cmd,help='Generate JSON for credential_process in ~/.aws/config'"` + Process ProcessCmd `kong:"cmd,help='Generate JSON for AWS SDK credential_process command'"` + Setup SetupCmd `kong:"cmd,help='Setup Wizard, Completions, Profiles, etc'"` Tags TagsCmd `kong:"cmd,help='List tags'"` Time TimeCmd `kong:"cmd,help='Print how much time before current STS Token expires'"` Version VersionCmd `kong:"cmd,help='Print version and exit'"` @@ -162,7 +161,7 @@ func main() { log.Fatalf("%s", err.Error()) } return - case "ecs server": + case "ecs server", "ecs list", "ecs unload", "ecs profile": // side-step the rest of the setup... if err = ctx.Run(&runCtx); err != nil { log.Fatalf("%s", err.Error()) @@ -192,7 +191,7 @@ func main() { } switch ctx.Command() { - case "list", "login", "ecs list", "ecs unload", "ecs profile": + case "list", "login", "tags": // Initialize our AwsSSO variable & SecureStore c := &runCtx s, err := c.Settings.GetSelectedSSO(c.Cli.SSO) diff --git a/cmd/aws-sso/process_cmd.go b/cmd/aws-sso/process_cmd.go index 444094c1..00fd7faa 100644 --- a/cmd/aws-sso/process_cmd.go +++ b/cmd/aws-sso/process_cmd.go @@ -38,11 +38,6 @@ type ProcessCmd struct { func (cc *ProcessCmd) Run(ctx *RunContext) error { var err error - switch ctx.Cli.UrlAction { - case "print", "printurl": - return fmt.Errorf("unsupported --url-action=print|printurl option") - } - role := ctx.Cli.Process.Role account := ctx.Cli.Process.AccountId @@ -63,7 +58,7 @@ func (cc *ProcessCmd) Run(ctx *RunContext) error { } if role == "" || account == 0 { - return fmt.Errorf("Please specify --arn or --account and --role") + return fmt.Errorf("please specify --arn or --account and --role") } return credentialProcess(ctx, account, role) diff --git a/cmd/aws-sso/setup_profiles_cmd.go b/cmd/aws-sso/setup_profiles_cmd.go index f0caaeef..c818b7b0 100644 --- a/cmd/aws-sso/setup_profiles_cmd.go +++ b/cmd/aws-sso/setup_profiles_cmd.go @@ -19,10 +19,7 @@ package main */ import ( - "fmt" - "github.com/synfinatic/aws-sso-cli/internal/awsconfig" - "github.com/synfinatic/aws-sso-cli/internal/url" ) const ( @@ -37,28 +34,12 @@ credential_process = {{ $profile.BinaryPath }} -u {{ $profile.Open }} -S "{{ $pr type SetupProfilesCmd struct { Diff bool `kong:"help='Print a diff of changes to the config file instead of modifying it',xor='action'"` Force bool `kong:"help='Write a new config file without prompting'"` - Open string `kong:"help='Specify how to open URLs: [clip|exec|open|granted-containers|open-url-in-container]'"` Print bool `kong:"help='Print profile entries instead of modifying config file',xor='action'"` AwsConfig string `kong:"help='Path to AWS config file',env='AWS_CONFIG_FILE',default='~/.aws/config'"` } func (cc *SetupProfilesCmd) Run(ctx *RunContext) error { var err error - var action url.ConfigProfilesAction - - if ctx.Cli.Setup.Profiles.Open != "" { - if action, err = url.NewConfigProfilesAction(ctx.Cli.Setup.Profiles.Open); err != nil { - return err - } - } else { - action = ctx.Settings.ConfigProfilesUrlAction - } - - if action == url.ConfigProfilesUndef { - return fmt.Errorf("%s", "please specify --open [clip|exec|open|granted-containers|open-url-in-container]") - } - - urlAction, _ := url.NewAction(string(action)) // always refresh our cache c := &CacheCmd{} @@ -67,8 +48,8 @@ func (cc *SetupProfilesCmd) Run(ctx *RunContext) error { } if ctx.Cli.Setup.Profiles.Print { - return awsconfig.PrintAwsConfig(ctx.Settings, urlAction) + return awsconfig.PrintAwsConfig(ctx.Settings) } - return awsconfig.UpdateAwsConfig(ctx.Settings, urlAction, ctx.Cli.Setup.Profiles.AwsConfig, + return awsconfig.UpdateAwsConfig(ctx.Settings, ctx.Cli.Setup.Profiles.AwsConfig, ctx.Cli.Setup.Profiles.Diff, ctx.Cli.Setup.Profiles.Force) } diff --git a/docs/commands.md b/docs/commands.md index ed5e9e57..6495752d 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -295,7 +295,6 @@ for every role accessible via AWS SSO CLI. Flags: * `--diff` -- Print a diff of changes to the config file instead of modifying it - * `--open` -- Specify how to open URls: [clip|exec|open|granted-containers|open-url-in-container] * `--print` -- Print profile entries instead of modifying config file * `--force` -- Write a new config file without prompting * `--aws-config` -- Override path to `~/.aws/config` file @@ -317,18 +316,9 @@ _automatically refresh_. This means, if you do not have a valid AWS SSO token, you will be prompted to authentiate via your SSO provider and subsequent requests to obtain new IAM STS credentials will automatically happen as needed. -**Note:** Due to a limitation in the AWS tooling, `print` and `printurl` are not -supported values for `--url-action`. Hence, you must use `open` or `exec` to -auto-open URLs in your browser (recommended) or `clip` to automatically copy -URLs to your clipboard. _No user prompting is possible._ - **Note:** You should run this command any time your list of AWS roles changes in order to update the `~/.aws/config` file or enable [AutoConfigCheck]( -config.md#autoconfigcheck) and [ConfigProfilesUrlAction]( -config.md#configprofilesurlaction). - -**Note:** If `ConfigProfilesUrlAction` is set, then `--open` is optional, -otherwise it is required. +config.md#autoconfigcheck). **Note:** It is important that you do _NOT_ remove the `# BEGIN_AWS_SSO_CLI` and `# END_AWS_SSO_CLI` lines from your config file! These markers are used to track diff --git a/docs/config.md b/docs/config.md index cbf1a6a1..e784d18a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -53,7 +53,6 @@ MaxBackoff: Browser: UrlAction: [clip|exec|print|printurl|open|granted-containers|open-url-in-container] -ConfigProfilesUrlAction: [clip|exec|open|granted-containers|open-url-in-container] ConfigProfilesBinaryPath: UrlExecCommand: - @@ -357,27 +356,6 @@ https://docs.aws.amazon.com/singlesignon/latest/userguide/howtosessionduration.h ### AWS_PROFILE Integration -#### ConfigProfilesUrlAction - -The `aws-sso config-profiles` command by default will use the same action -to open URL's as defined in [UrlAction](#authurlaction--browser--urlaction--urlexeccommand), -but you can override it via the `ConfigProfilesUrlAction`. - -If `UrlAction` is `print` or `printurl`, then this settings will default to `open`. - -Due to limitations with the AWS SDK, only the following options are valid: - - * `clip` - * `exec` - * `open` - * `granted-containers` - * `open-url-in-container` - -**Note:** This option is required if you also want to use [AutoConfigCheck](#autoconfigcheck). - -**Note:** This config option was previously known as `ConfigUrlAction` which -has been deprecated. - #### ConfigProfilesBinaryPath Override execution path for `aws-sso` when generating named AWS profiles via the @@ -553,8 +531,6 @@ When set to `True`, when your AWS SSO roles are automatically refreshed (see [CacheRefresh](#cacherefresh)) `aws-sso` will also check to see if any changes are warranted in your `~/.aws/config`. -**Note:** This option requires you to also set [ConfigProfilesUrlAction](#configprofilesurlaction). - **Note:** This option can be disabled temporarily on the command line by passing the `--no-config-check` flag. diff --git a/internal/awsconfig/config.go b/internal/awsconfig/config.go index b799b2e0..ffff3e9a 100644 --- a/internal/awsconfig/config.go +++ b/internal/awsconfig/config.go @@ -22,7 +22,6 @@ import ( "os" "github.com/synfinatic/aws-sso-cli/internal/sso" - "github.com/synfinatic/aws-sso-cli/internal/url" "github.com/synfinatic/aws-sso-cli/internal/utils" ) @@ -30,7 +29,7 @@ const ( AWS_CONFIG_FILE = "~/.aws/config" CONFIG_TEMPLATE = `{{range $sso, $struct := . }}{{ range $arn, $profile := $struct }} [profile {{ $profile.Profile }}] -credential_process = {{ $profile.BinaryPath }} -u {{ $profile.Open }} -S "{{ $profile.Sso }}" process --arn {{ $profile.Arn }} +credential_process = {{ $profile.BinaryPath }} -S "{{ $profile.Sso }}" process --arn {{ $profile.Arn }} {{ if len $profile.DefaultRegion }}region = {{ printf "%s\n" $profile.DefaultRegion }}{{ end -}} {{ range $key, $value := $profile.ConfigVariables }}{{ $key }} = {{ $value }} {{end}}{{end}}{{end}}` @@ -49,8 +48,8 @@ func AwsConfigFile(cfile string) string { var stdout = os.Stdout // PrintAwsConfig just prints what our new AWS config file block would look like -func PrintAwsConfig(s *sso.Settings, action url.Action) error { - profiles, err := getProfileMap(s, action) +func PrintAwsConfig(s *sso.Settings) error { + profiles, err := getProfileMap(s) if err != nil { return err } @@ -65,8 +64,8 @@ func PrintAwsConfig(s *sso.Settings, action url.Action) error { // UpdateAwsConfig updates our AWS config file, optionally presenting a diff for // review or possibly making the change without prompting -func UpdateAwsConfig(s *sso.Settings, action url.Action, cfile string, diff, force bool) error { - profiles, err := getProfileMap(s, action) +func UpdateAwsConfig(s *sso.Settings, cfile string, diff, force bool) error { + profiles, err := getProfileMap(s) if err != nil { return err } @@ -82,8 +81,8 @@ func UpdateAwsConfig(s *sso.Settings, action url.Action, cfile string, diff, for } // getProfileMap returns our validated sso.ProfileMap -func getProfileMap(s *sso.Settings, action url.Action) (*sso.ProfileMap, error) { - profiles, err := s.GetAllProfiles(action) +func getProfileMap(s *sso.Settings) (*sso.ProfileMap, error) { + profiles, err := s.GetAllProfiles() if err != nil { return profiles, err } diff --git a/internal/awsconfig/config_test.go b/internal/awsconfig/config_test.go index 01dc8bea..3de38890 100644 --- a/internal/awsconfig/config_test.go +++ b/internal/awsconfig/config_test.go @@ -25,7 +25,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/synfinatic/aws-sso-cli/internal/sso" - "github.com/synfinatic/aws-sso-cli/internal/url" "github.com/synfinatic/aws-sso-cli/internal/utils" ) @@ -68,7 +67,7 @@ func TestGetProfileMap(t *testing.T) { }, } - profiles, err := getProfileMap(s, url.Open) + profiles, err := getProfileMap(s) p := *profiles assert.NoError(t, err) assert.Equal(t, 1, len(p)) @@ -90,7 +89,7 @@ func TestGetProfileMap(t *testing.T) { }, }, } - _, err = getProfileMap(s, url.Open) + _, err = getProfileMap(s) assert.Error(t, err) } @@ -126,7 +125,7 @@ func TestPrintAwsConfig(t *testing.T) { fname := stdout.Name() defer os.Remove(fname) - err = PrintAwsConfig(s, url.Open) + err = PrintAwsConfig(s) assert.NoError(t, err) _, err = stdout.Seek(0, 0) @@ -137,7 +136,7 @@ func TestPrintAwsConfig(t *testing.T) { assert.Error(t, err) assert.Less(t, 300, len) assert.Contains(t, string(buf), "[profile 000000012345:Bar]") - assert.Regexp(t, regexp.MustCompile(`credential_process = /[^ ]+/awsconfig.test -u open -S "Default" process --arn aws:arn:iam::12345:role/Bar`), string(buf)) + assert.Regexp(t, regexp.MustCompile(`credential_process = /[^ ]+/awsconfig.test -S "Default" process --arn aws:arn:iam::12345:role/Bar`), string(buf)) assert.Regexp(t, regexp.MustCompile(`# BEGIN_AWS_SSO_CLI`), string(buf)) assert.Regexp(t, regexp.MustCompile(`# END_AWS_SSO_CLI`), string(buf)) stdout.Close() @@ -159,7 +158,7 @@ func TestPrintAwsConfig(t *testing.T) { }, } - err = PrintAwsConfig(s, url.Open) + err = PrintAwsConfig(s) assert.Error(t, err) } @@ -195,7 +194,7 @@ func TestUpdateAwsConfig(t *testing.T) { defer os.Remove(fname) cfile.Close() - err = UpdateAwsConfig(s, url.Open, fname, false, true) + err = UpdateAwsConfig(s, fname, false, true) assert.NoError(t, err) cfile, err = os.Open(fname) @@ -206,7 +205,7 @@ func TestUpdateAwsConfig(t *testing.T) { assert.NoError(t, err) assert.Less(t, 300, len) assert.Contains(t, string(buf), "[profile 000000012345:Bar]") - assert.Regexp(t, regexp.MustCompile(`credential_process = /[^ ]+/awsconfig.test -u open -S "Default" process --arn aws:arn:iam::12345:role/Bar`), string(buf)) + assert.Regexp(t, regexp.MustCompile(`credential_process = /[^ ]+/awsconfig.test -S "Default" process --arn aws:arn:iam::12345:role/Bar`), string(buf)) assert.Regexp(t, regexp.MustCompile(`# BEGIN_AWS_SSO_CLI`), string(buf)) assert.Regexp(t, regexp.MustCompile(`# END_AWS_SSO_CLI`), string(buf)) @@ -227,6 +226,6 @@ func TestUpdateAwsConfig(t *testing.T) { }, } - err = UpdateAwsConfig(s, url.Open, fname, false, true) + err = UpdateAwsConfig(s, fname, false, true) assert.Error(t, err) } diff --git a/internal/sso/settings.go b/internal/sso/settings.go index a7d21ff5..fcea6d63 100644 --- a/internal/sso/settings.go +++ b/internal/sso/settings.go @@ -434,7 +434,7 @@ var getExecutable func() (string, error) = func() (string, error) { // GetAllProfiles returns a map of the ProfileConfig for each SSOConfig. // takes the binary path to `open` URL with if set -func (s *Settings) GetAllProfiles(open url.Action) (*ProfileMap, error) { +func (s *Settings) GetAllProfiles() (*ProfileMap, error) { profiles := ProfileMap{} var err error @@ -462,7 +462,6 @@ func (s *Settings) GetAllProfiles(open url.Action) (*ProfileMap, error) { BinaryPath: binaryPath, ConfigVariables: s.ConfigVariables, DefaultRegion: role.DefaultRegion, - Open: string(open), Profile: profile, Sso: ssoName, } diff --git a/internal/sso/settings_test.go b/internal/sso/settings_test.go index 3f4c5423..c115ba3c 100644 --- a/internal/sso/settings_test.go +++ b/internal/sso/settings_test.go @@ -260,12 +260,12 @@ func (suite *SettingsTestSuite) TestGetAllProfiles() { t := suite.T() getExecutable = func() (string, error) { return "", fmt.Errorf("failed") } - _, err := suite.settings.GetAllProfiles("open firefox") + _, err := suite.settings.GetAllProfiles() assert.Error(t, err) getExecutable = os.Executable - profiles, err := suite.settings.GetAllProfiles("open firefox") + profiles, err := suite.settings.GetAllProfiles() assert.NoError(t, err) assert.Len(t, *profiles, 1) @@ -281,7 +281,6 @@ func (suite *SettingsTestSuite) TestGetAllProfiles() { assert.Equal(t, x.Arn, "arn:aws:iam::833365043586:role/AWSAdministratorAccess") assert.NotEmpty(t, x.BinaryPath) assert.Equal(t, map[string]interface{}(nil), x.ConfigVariables) - assert.Equal(t, "open firefox", x.Open) assert.Equal(t, "Log archive/AWSAdministratorAccess", x.Profile) assert.Equal(t, "Default", x.Sso) @@ -300,7 +299,7 @@ func (suite *SettingsTestSuite) TestGetAllProfiles() { assert.Error(t, profiles.UniqueCheck(suite.settings)) suite.settings.ProfileFormat = "{{ .GetAllProfilesFailure }}" - _, err = suite.settings.GetAllProfiles("open firefox") + _, err = suite.settings.GetAllProfiles() assert.Error(t, err) suite.settings.ProfileFormat = oldFormat From 81f9b5c14c3221c92db8206e5411be817a71b231 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Mon, 15 Jul 2024 21:03:05 -0700 Subject: [PATCH 2/3] move common flags to their specific commands --url-action --sts-refresh also break up commands that require login from those that don't in help --- cmd/aws-sso/console_cmd.go | 21 ++++++++++++++----- cmd/aws-sso/credentials_cmd.go | 2 +- cmd/aws-sso/ecs_client_cmd.go | 11 +++++----- cmd/aws-sso/exec_cmd.go | 13 ++++++------ cmd/aws-sso/login_cmd.go | 13 ++++++++++-- cmd/aws-sso/main.go | 37 ++++++++++++++++++---------------- cmd/aws-sso/process_cmd.go | 11 +++++----- docs/commands.md | 9 +++++++-- internal/sso/settings.go | 5 ----- 9 files changed, 74 insertions(+), 48 deletions(-) diff --git a/cmd/aws-sso/console_cmd.go b/cmd/aws-sso/console_cmd.go index caa110d2..2b897e74 100644 --- a/cmd/aws-sso/console_cmd.go +++ b/cmd/aws-sso/console_cmd.go @@ -34,6 +34,7 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/sts" + // "github.com/davecgh/go-spew/spew" "github.com/synfinatic/aws-sso-cli/internal/storage" "github.com/synfinatic/aws-sso-cli/internal/url" @@ -42,9 +43,11 @@ import ( type ConsoleCmd struct { // Console actually should honor the --region flag - Duration int32 `kong:"short='d',help='AWS Session duration in minutes (default 60)'"` // default stored in DEFAULT_CONFIG - Prompt bool `kong:"short='P',help='Force interactive prompt to select role'"` - Region string `kong:"help='AWS Region',env='AWS_DEFAULT_REGION',predictor='region'"` + Duration int32 `kong:"short='d',help='AWS Session duration in minutes (default 60)'"` // default stored in DEFAULT_CONFIG + Prompt bool `kong:"short='P',help='Force interactive prompt to select role'"` + Region string `kong:"help='AWS Region',env='AWS_DEFAULT_REGION',predictor='region'"` + STSRefresh bool `kong:"help='Force refresh of STS Token Credentials'"` + UrlAction string `kong:"short='u',help='How to handle URLs [clip|exec|open|print|printurl|granted-containers|open-url-in-container] (default: open)'"` Arn string `kong:"short='a',help='ARN of role to assume',env='AWS_SSO_ROLE_ARN',predictor='arn'"` AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to assume',env='AWS_SSO_ACCOUNT_ID',predictor='accountId'"` @@ -235,7 +238,7 @@ func openConsole(ctx *RunContext, accountid int64, role string) error { log.WithError(err).Warnf("Unable to update cache") } - creds := GetRoleCredentials(ctx, AwsSSO, accountid, role) + creds := GetRoleCredentials(ctx, AwsSSO, ctx.Cli.Console.STSRefresh, accountid, role) return openConsoleAccessKey(ctx, creds, duration, region, accountid, role) } @@ -287,7 +290,15 @@ func openConsoleAccessKey(ctx *RunContext, creds *storage.RoleCredentials, SigninToken: loginResponse.SigninToken, } - urlOpener := url.NewHandleUrl(ctx.Settings.UrlAction, login.GetUrl(), + action, err := url.NewAction(ctx.Cli.Console.UrlAction) + if err != nil { + log.Fatalf("Invalid --url-action %s", ctx.Cli.Console.UrlAction) + } + if action == "" { + action = ctx.Settings.UrlAction + } + + urlOpener := url.NewHandleUrl(action, login.GetUrl(), ctx.Settings.Browser, ctx.Settings.UrlExecCommand) urlOpener.ContainerSettings(containerParams(ctx, accountId, role)) diff --git a/cmd/aws-sso/credentials_cmd.go b/cmd/aws-sso/credentials_cmd.go index ea86274a..8e5ee877 100644 --- a/cmd/aws-sso/credentials_cmd.go +++ b/cmd/aws-sso/credentials_cmd.go @@ -23,7 +23,7 @@ func (cc *CredentialsCmd) Run(ctx *RunContext) error { return err } - pCreds := GetRoleCredentials(ctx, AwsSSO, roleFlat.AccountId, roleFlat.RoleName) + pCreds := GetRoleCredentials(ctx, AwsSSO, ctx.Cli.Console.STSRefresh, roleFlat.AccountId, roleFlat.RoleName) creds = append(creds, awsconfig.ProfileCredentials{ Profile: profile, diff --git a/cmd/aws-sso/ecs_client_cmd.go b/cmd/aws-sso/ecs_client_cmd.go index f92535e5..309681fa 100644 --- a/cmd/aws-sso/ecs_client_cmd.go +++ b/cmd/aws-sso/ecs_client_cmd.go @@ -33,10 +33,11 @@ import ( type EcsLoadCmd struct { // AWS Params - Arn string `kong:"short='a',help='ARN of role to load',env='AWS_SSO_ROLE_ARN',predictor='arn'"` - AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to load',env='AWS_SSO_ACCOUNT_ID',predictor='accountId',xor='account'"` - Role string `kong:"short='R',help='Name of AWS Role to load',env='AWS_SSO_ROLE_NAME',predictor='role',xor='role'"` - Profile string `kong:"short='p',help='Name of AWS Profile to load',predictor='profile',xor='account,role'"` + Arn string `kong:"short='a',help='ARN of role to load',env='AWS_SSO_ROLE_ARN',predictor='arn'"` + AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to load',env='AWS_SSO_ACCOUNT_ID',predictor='accountId',xor='account'"` + Role string `kong:"short='R',help='Name of AWS Role to load',env='AWS_SSO_ROLE_NAME',predictor='role',xor='role'"` + Profile string `kong:"short='p',help='Name of AWS Profile to load',predictor='profile',xor='account,role'"` + STSRefresh bool `kong:"help='Force refresh of STS Token Credentials'"` // Other params Server string `kong:"help='Endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` @@ -82,7 +83,7 @@ func (cc *EcsProfileCmd) Run(ctx *RunContext) error { func ecsLoadCmd(ctx *RunContext, accountId int64, role string) error { c := newClient(ctx.Cli.Ecs.Load.Server, ctx) - creds := GetRoleCredentials(ctx, AwsSSO, accountId, role) + creds := GetRoleCredentials(ctx, AwsSSO, ctx.Cli.Ecs.Load.STSRefresh, accountId, role) cache := ctx.Settings.Cache.GetSSO() rFlat, err := cache.Roles.GetRole(accountId, role) diff --git a/cmd/aws-sso/exec_cmd.go b/cmd/aws-sso/exec_cmd.go index 49b54a9f..e6e5ea53 100644 --- a/cmd/aws-sso/exec_cmd.go +++ b/cmd/aws-sso/exec_cmd.go @@ -31,11 +31,12 @@ import ( type ExecCmd struct { // AWS Params - Arn string `kong:"short='a',help='ARN of role to assume',env='AWS_SSO_ROLE_ARN',predictor='arn'"` - AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to assume',env='AWS_SSO_ACCOUNT_ID',predictor='accountId'"` - Role string `kong:"short='R',help='Name of AWS Role to assume',env='AWS_SSO_ROLE_NAME',predictor='role'"` - Profile string `kong:"short='p',help='Name of AWS Profile to assume',predictor='profile'"` - NoRegion bool `kong:"short='n',help='Do not set AWS_DEFAULT_REGION from config.yaml'"` + Arn string `kong:"short='a',help='ARN of role to assume',env='AWS_SSO_ROLE_ARN',predictor='arn'"` + AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to assume',env='AWS_SSO_ACCOUNT_ID',predictor='accountId'"` + Role string `kong:"short='R',help='Name of AWS Role to assume',env='AWS_SSO_ROLE_NAME',predictor='role'"` + Profile string `kong:"short='p',help='Name of AWS Profile to assume',predictor='profile'"` + NoRegion bool `kong:"short='n',help='Do not set AWS_DEFAULT_REGION from config.yaml'"` + STSRefresh bool `kong:"help='Force refresh of STS Token Credentials'"` // Exec Params Cmd string `kong:"arg,optional,name='command',help='Command to execute',env='SHELL'"` @@ -93,7 +94,7 @@ func execCmd(ctx *RunContext, accountid int64, role string) error { func execShellEnvs(ctx *RunContext, accountid int64, role, region string) map[string]string { var err error - credsPtr := GetRoleCredentials(ctx, AwsSSO, accountid, role) + credsPtr := GetRoleCredentials(ctx, AwsSSO, ctx.Cli.Exec.STSRefresh, accountid, role) creds := *credsPtr ssoName, _ := ctx.Settings.GetSelectedSSOName(ctx.Cli.SSO) diff --git a/cmd/aws-sso/login_cmd.go b/cmd/aws-sso/login_cmd.go index ce2ff161..c289a782 100644 --- a/cmd/aws-sso/login_cmd.go +++ b/cmd/aws-sso/login_cmd.go @@ -20,10 +20,12 @@ package main import ( "github.com/synfinatic/aws-sso-cli/internal/sso" + "github.com/synfinatic/aws-sso-cli/internal/url" ) type LoginCmd struct { - Threads int `kong:"help='Override number of threads for talking to AWS',default=${DEFAULT_THREADS}"` + UrlAction string `kong:"short='u',help='How to handle URLs [clip|exec|open|print|printurl|granted-containers|open-url-in-container] (default: open)'"` + Threads int `kong:"help='Override number of threads for talking to AWS',default=${DEFAULT_THREADS}"` } func (cc *LoginCmd) Run(ctx *RunContext) error { @@ -55,7 +57,14 @@ func doAuth(ctx *RunContext) { return } - err := AwsSSO.Authenticate(ctx.Settings.UrlAction, ctx.Settings.Browser) + action, err := url.NewAction(ctx.Cli.Login.UrlAction) + if err != nil { + log.Fatalf("Invalid --url-action %s", ctx.Cli.Login.UrlAction) + } + if action == "" { + action = ctx.Settings.UrlAction + } + err = AwsSSO.Authenticate(action, ctx.Settings.Browser) if err != nil { log.WithError(err).Fatalf("Unable to authenticate") } diff --git a/cmd/aws-sso/main.go b/cmd/aws-sso/main.go index e57966bc..2ad06863 100644 --- a/cmd/aws-sso/main.go +++ b/cmd/aws-sso/main.go @@ -84,6 +84,7 @@ var DEFAULT_CONFIG map[string]interface{} = map[string]interface{}{ "PromptColors.SuggestionTextColor": "White", "AutoConfigCheck": false, "CacheRefresh": 168, // 7 days in hours + "ConfigProfilesUrlAction": "open", "ConsoleDuration": 60, "DefaultRegion": "us-east-1", "DefaultSSO": "Default", @@ -106,27 +107,27 @@ type CLI struct { ConfigFile string `kong:"name='config',default='${CONFIG_FILE}',help='Config file',env='AWS_SSO_CONFIG',predict='allFiles'"` LogLevel string `kong:"short='L',name='level',help='Logging level [error|warn|info|debug|trace] (default: info)'"` Lines bool `kong:"help='Print line number in logs'"` - UrlAction string `kong:"short='u',help='How to handle URLs [clip|exec|open|print|printurl|granted-containers|open-url-in-container] (default: open)'"` SSO string `kong:"short='S',help='Override default AWS SSO Instance',env='AWS_SSO',predictor='sso'"` - STSRefresh bool `kong:"help='Force refresh of STS Token Credentials'"` // Commands - Cache CacheCmd `kong:"cmd,help='Force reload of cached AWS SSO role info and config.yaml'"` - Console ConsoleCmd `kong:"cmd,help='Open AWS Console using specificed AWS role/profile'"` - Credentials CredentialsCmd `kong:"cmd,help='Generate static AWS credentials for use with AWS CLI'"` Default DefaultCmd `kong:"cmd,hidden,default='1'"` // list command without args Ecs EcsCmd `kong:"cmd,help='ECS server/client commands'"` - Eval EvalCmd `kong:"cmd,help='Print AWS environment vars for use with eval $(aws-sso eval ...)'"` - Exec ExecCmd `kong:"cmd,help='Execute command using specified IAM role in a new shell'"` List ListCmd `kong:"cmd,help='List all accounts / roles (default command)'"` Login LoginCmd `kong:"cmd,help='Login to an AWS Identity Center instance'"` - Logout LogoutCmd `kong:"cmd,help='Logout from an AWS Identity Center instance and invalidate all credentials'"` ListSSORoles ListSSORolesCmd `kong:"cmd,hidden,help='List AWS SSO Roles (debugging)'"` - Process ProcessCmd `kong:"cmd,help='Generate JSON for AWS SDK credential_process command'"` Setup SetupCmd `kong:"cmd,help='Setup Wizard, Completions, Profiles, etc'"` Tags TagsCmd `kong:"cmd,help='List tags'"` Time TimeCmd `kong:"cmd,help='Print how much time before current STS Token expires'"` Version VersionCmd `kong:"cmd,help='Print version and exit'"` + + // Login Commands + Cache CacheCmd `kong:"cmd,help='Force reload of cached AWS SSO role info and config.yaml',group='login-required'"` + Console ConsoleCmd `kong:"cmd,help='Open AWS Console using specificed AWS role/profile',group='login-required'"` + Credentials CredentialsCmd `kong:"cmd,help='Generate static AWS credentials for use with AWS CLI',group='login-required'"` + Eval EvalCmd `kong:"cmd,help='Print AWS environment vars for use with eval $(aws-sso eval ...)',group='login-required'"` + Exec ExecCmd `kong:"cmd,help='Execute command using specified IAM role in a new shell',group='login-required'"` + Logout LogoutCmd `kong:"cmd,help='Logout from an AWS Identity Center instance and invalidate all credentials',group='login-required'"` + Process ProcessCmd `kong:"cmd,help='Generate JSON for AWS SDK credential_process command',group='login-required'"` } func main() { @@ -258,12 +259,20 @@ func parseArgs(cli *CLI) (*kong.Context, sso.OverrideSettings) { NoExpandSubcommands: true, } + groups := []kong.Group{ + { + Title: "Commands requiring login:", + Key: "login-required", + }, + } + parser := kong.Must( cli, kong.Name("aws-sso"), kong.Description("Securely manage temporary AWS API Credentials issued via AWS SSO"), kong.ConfigureHelp(help), vars, + kong.ExplicitGroups(groups), ) p := predictor.NewPredictor(config.InsecureCacheFile(true), config.ConfigFile(true)) @@ -286,11 +295,6 @@ func parseArgs(cli *CLI) (*kong.Context, sso.OverrideSettings) { ctx, err := parser.Parse(os.Args[1:]) parser.FatalIfErrorf(err) - action, err := url.NewAction(cli.UrlAction) - if err != nil { - log.Fatalf("Invalid --url-action %s", cli.UrlAction) - } - threads := 0 if cli.Cache.Threads != DEFAULT_THREADS { threads = cli.Cache.Threads @@ -304,7 +308,6 @@ func parseArgs(cli *CLI) (*kong.Context, sso.OverrideSettings) { LogLevel: cli.LogLevel, LogLines: cli.Lines, Threads: threads, // must be > 0 to override config - UrlAction: action, } log.SetFormatter(&logrus.TextFormatter{ @@ -330,13 +333,13 @@ func (cc *VersionCmd) Run(ctx *RunContext) error { } // Get our RoleCredentials from the secure store or from AWS SSO -func GetRoleCredentials(ctx *RunContext, awssso *sso.AWSSSO, accountid int64, role string) *storage.RoleCredentials { +func GetRoleCredentials(ctx *RunContext, awssso *sso.AWSSSO, refreshSTS bool, accountid int64, role string) *storage.RoleCredentials { creds := storage.RoleCredentials{} // First look for our creds in the secure store, if we're not forcing a refresh arn := utils.MakeRoleARN(accountid, role) log.Debugf("Getting role credentials for %s", arn) - if !ctx.Cli.STSRefresh { + if !refreshSTS { if roleFlat, err := ctx.Settings.Cache.GetRole(arn); err == nil { if !roleFlat.IsExpired() { if err := ctx.Store.GetRoleCredentials(arn, &creds); err == nil { diff --git a/cmd/aws-sso/process_cmd.go b/cmd/aws-sso/process_cmd.go index 00fd7faa..9097821c 100644 --- a/cmd/aws-sso/process_cmd.go +++ b/cmd/aws-sso/process_cmd.go @@ -29,10 +29,11 @@ import ( type ProcessCmd struct { // AWS Params - Arn string `kong:"short='a',help='ARN of role to assume',xor='arn-1',xor='arn-2',predictor='arn'"` - AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to assume',xor='arn-1',predictor='accountId'"` - Role string `kong:"short='R',help='Name of AWS Role to assume',xor='arn-2',predictor='role'"` - Profile string `kong:"short='p',help='Name of AWS Profile to assume',xor='arn-1',xor='arn-2',predictor='profile'"` + Arn string `kong:"short='a',help='ARN of role to assume',xor='arn-1',xor='arn-2',predictor='arn'"` + AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to assume',xor='arn-1',predictor='accountId'"` + Role string `kong:"short='R',help='Name of AWS Role to assume',xor='arn-2',predictor='role'"` + Profile string `kong:"short='p',help='Name of AWS Profile to assume',xor='arn-1',xor='arn-2',predictor='profile'"` + STSRefresh bool `kong:"help='Force refresh of STS Token Credentials'"` } func (cc *ProcessCmd) Run(ctx *RunContext) error { @@ -93,7 +94,7 @@ func (cpo *CredentialProcessOutput) Output() (string, error) { } func credentialProcess(ctx *RunContext, accountId int64, role string) error { - creds := GetRoleCredentials(ctx, AwsSSO, accountId, role) + creds := GetRoleCredentials(ctx, AwsSSO, ctx.Cli.Process.STSRefresh, accountId, role) cpo := NewCredentialsProcessOutput(creds) out, err := cpo.Output() diff --git a/docs/commands.md b/docs/commands.md index 6495752d..cad38b94 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -7,9 +7,7 @@ * `--config ` -- Specify alternative config file (`$AWS_SSO_CONFIG`) * `--level `, `-L` -- Change default log level: [error|warn|info|debug|trace] * `--lines` -- Print file number with logs - * `--url-action`, `-u` -- How to handle URLs for your SSO provider * `--sso `, `-S` -- Specify non-default AWS SSO instance to use (`$AWS_SSO`) - * `--sts-refresh` -- Force refresh of STS Token Credentials ## Commands @@ -48,6 +46,8 @@ Flags: * `--account `, `-A` -- AWS AccountID of role to assume (`$AWS_SSO_ACCOUNT_ID`) * `--role `, `-R` -- Name of AWS Role to assume (requires `--account`) (`$AWS_SSO_ROLE_NAME`) * `--profile `, `-p` -- Name of AWS Profile to assume + * `--url-action`, `-u` -- How to handle URLs for your SSO provider + * `--sts-refresh` -- Force refresh of STS Token Credentials The generated URL is good for 15 minutes after it is created. @@ -81,6 +81,7 @@ Flags: * `--file `, `-f` -- Specify the file to generate. Default is to print to STDOUT ($AWS_SHARED_CREDENTIALS_FILE). * `--append`, `-a` -- Append to the file instead of overwriting it. * `--profile ,...`, `-p` -- One or more profiles to include in the output. + * `--sts-refresh` -- Force refresh of STS Token Credentials **Note:** This command honors the same [$AWS_SHARED_CREDENTIALS_FILE](https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-envvars.html) that is supported by the AWS SDK to load credentials. Since these credentials are temporary, it is @@ -163,6 +164,7 @@ Flags: * `--role `, `-R` -- Name of AWS Role to assume (`$AWS_SSO_ROLE_NAME`) * `--profile `, `-p` -- Name of AWS Profile to assume * `--no-region` -- Do not set the [AWS_DEFAULT_REGION](config.md#DefaultRegion) from config.yaml + * `--sts-refresh` -- Force refresh of STS Token Credentials Arguments: `[] [ ...]` @@ -192,6 +194,7 @@ Flags: * `--account `, `-A` -- AWS AccountID of role to assume * `--role `, `-R` -- Name of AWS Role to assume (requires `--account`) * `--profile `, `-p` -- Name of AWS Profile to assume + * `--sts-refresh` -- Force refresh of STS Token Credentials Priority is given to: @@ -251,6 +254,8 @@ used to fetch IAM Role credentials. Flags: * `--no-config-check` -- Disable automatic updating of `~/.aws/config` + * `--url-action`, `-u` -- How to handle URLs for your SSO provider + * `--sts-refresh` -- Force refresh of STS Token Credentials * `--threads ` -- Number of threads to use with AWS (default: 5) --- diff --git a/internal/sso/settings.go b/internal/sso/settings.go index fcea6d63..495d1510 100644 --- a/internal/sso/settings.go +++ b/internal/sso/settings.go @@ -130,7 +130,6 @@ type OverrideSettings struct { DefaultSSO string LogLevel string LogLines bool - UrlAction url.Action Threads int } @@ -339,10 +338,6 @@ func (s *Settings) setOverrides(override OverrideSettings) { s.DefaultSSO = override.DefaultSSO } - if override.UrlAction != "" { - s.UrlAction = override.UrlAction - } - if override.Threads > 0 { s.Threads = override.Threads } From 84dfcf5b02213dd80ef6775353d760c8e7ec1a59 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Mon, 15 Jul 2024 21:35:36 -0700 Subject: [PATCH 3/3] refactor ecs ssl commands to be just flags --- CHANGELOG.md | 2 ++ cmd/aws-sso/ecs_cmd.go | 52 ++++++++++++++--------------------- cmd/aws-sso/main.go | 4 +++ docs/ecs-commands.md | 17 ++---------- internal/sso/settings_test.go | 2 -- 5 files changed, 30 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ade60a7b..94e3ada3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ * `config` is now `setup wizard` and `ConfigProfilesUrlAction` config option is no longer used * `config-profiles` is now `setup profiles` * `completions` is now `setup completions` + * Make `--url-action` and `--sts-refresh` command specific options + * Refactor `ecs ssl` commands to be just flags. * Remove `--open` option from `process` command #291 * Only the and `cache` command will auto-update the contents of `~/.aws/config` #974 * `tags` command no longer supports the `--force-update` option diff --git a/cmd/aws-sso/ecs_cmd.go b/cmd/aws-sso/ecs_cmd.go index fef92983..6792c175 100644 --- a/cmd/aws-sso/ecs_cmd.go +++ b/cmd/aws-sso/ecs_cmd.go @@ -62,54 +62,44 @@ func (cc *EcsAuthCmd) Run(ctx *RunContext) error { } type EcsSSLCmd struct { - Delete EcsSSLDeleteCmd `kong:"cmd,help='Delete the current SSL certificate/private key'"` - Print EcsSSLPrintCmd `kong:"cmd,help='Print the current SSL certificate'"` - Save EcsSSLSaveCmd `kong:"cmd,help='Save a new SSL certificate/private key'"` -} - -type EcsSSLSaveCmd struct { - Certificate string `kong:"short=c,type='existingfile',help='Path to certificate chain PEM file',predictor='allFiles',required"` - PrivateKey string `kong:"short=p,type='existingfile',help='Path to private key file PEM file',predictor='allFiles'"` + Delete bool `kong:"short=d,help='Disable SSL and delete the current SSL cert/key',xor='flag,cert,key'"` + Print bool `kong:"short=p,help='Print the current SSL certificate',xor='flag,cert,key'"` + Certificate string `kong:"short=c,type='existingfile',help='Path to certificate chain PEM file',predictor='allFiles',group='add-ssl',xor='cert'"` + PrivateKey string `kong:"short=k,type='existingfile',help='Path to private key file PEM file',predictor='allFiles',group='add-ssl',xor='key'"` Force bool `kong:"hidden,help='Force loading the certificate'"` } -type EcsSSLDeleteCmd struct{} - -func (cc *EcsSSLDeleteCmd) Run(ctx *RunContext) error { - return ctx.Store.DeleteEcsSslKeyPair() -} - -type EcsSSLPrintCmd struct{} - -func (cc *EcsSSLPrintCmd) Run(ctx *RunContext) error { - cert, err := ctx.Store.GetEcsSslCert() - if err != nil { - return err - } - if cert == "" { - return fmt.Errorf("no certificate found") +func (cc *EcsSSLCmd) Run(ctx *RunContext) error { + if ctx.Cli.Ecs.SSL.Delete { + return ctx.Store.DeleteEcsSslKeyPair() + } else if ctx.Cli.Ecs.SSL.Print { + cert, err := ctx.Store.GetEcsSslCert() + if err != nil { + return err + } + if cert == "" { + return fmt.Errorf("no certificate found") + } + fmt.Println(cert) + return nil } - fmt.Println(cert) - return nil -} -func (cc *EcsSSLSaveCmd) Run(ctx *RunContext) error { var privateKey, certChain []byte var err error - if !ctx.Cli.Ecs.SSL.Save.Force { + if !ctx.Cli.Ecs.SSL.Force { log.Warn("This feature is experimental and may not work as expected.") log.Warn("Please read https://github.com/synfinatic/aws-sso-cli/issues/936 before contiuing.") log.Fatal("Use `--force` to continue anyways.") } - certChain, err = os.ReadFile(ctx.Cli.Ecs.SSL.Save.Certificate) + certChain, err = os.ReadFile(ctx.Cli.Ecs.SSL.Certificate) if err != nil { return fmt.Errorf("failed to read certificate chain file: %w", err) } - if ctx.Cli.Ecs.SSL.Save.PrivateKey != "" { - privateKey, err = os.ReadFile(ctx.Cli.Ecs.SSL.Save.PrivateKey) + if ctx.Cli.Ecs.SSL.PrivateKey != "" { + privateKey, err = os.ReadFile(ctx.Cli.Ecs.SSL.PrivateKey) if err != nil { return fmt.Errorf("failed to read private key file: %w", err) } diff --git a/cmd/aws-sso/main.go b/cmd/aws-sso/main.go index 2ad06863..ac8a935c 100644 --- a/cmd/aws-sso/main.go +++ b/cmd/aws-sso/main.go @@ -264,6 +264,10 @@ func parseArgs(cli *CLI) (*kong.Context, sso.OverrideSettings) { Title: "Commands requiring login:", Key: "login-required", }, + { + Title: "Add SSL Certificate/Key:", + Key: "add-ssl", + }, } parser := kong.Must( diff --git a/docs/ecs-commands.md b/docs/ecs-commands.md index 859bb765..7d41b2fa 100644 --- a/docs/ecs-commands.md +++ b/docs/ecs-commands.md @@ -79,7 +79,7 @@ Flags: --- -### ecs ssl save +### ecs ssl Configures the SSL Certificate and Private Key to enable SSL/TLS. Saves the SSL certificate and private key to the SecureStore. @@ -89,24 +89,13 @@ Flags: Flags: + * `--delete` -- Disables SSL and deletes both the SSL certificate and private key from the Secure Store + * `--print` -- Prints the SSL certificate * `--certificate` -- Path to SSL certificate file in PEM format * `--private-key` -- Path to SSL private key in PEM format --- -### ecs ssl delete - -Delete the SSL certificate and private key from the Secure Store and disables -SSL/TLS for the ECS Server. - ---- - -### ecs ssl print - -Prints the SSL public certificate stored in the SecureStore. - ---- - ### ecs server Starts the ECS Server in the foreground. diff --git a/internal/sso/settings_test.go b/internal/sso/settings_test.go index c115ba3c..1df47975 100644 --- a/internal/sso/settings_test.go +++ b/internal/sso/settings_test.go @@ -323,7 +323,6 @@ func (suite *SettingsTestSuite) TestSetOverrides() { LogLines: true, Browser: "my-browser", DefaultSSO: "hello", - UrlAction: url.PrintUrl, Threads: 10, } @@ -333,7 +332,6 @@ func (suite *SettingsTestSuite) TestSetOverrides() { assert.True(t, log.ReportCaller) assert.Equal(t, "my-browser", s.Browser) assert.Equal(t, "hello", s.DefaultSSO) - assert.Equal(t, url.PrintUrl, s.UrlAction) assert.Equal(t, 10, s.Threads) }