Skip to content

Commit 3c21d64

Browse files
authored
Merge pull request #995 from synfinatic/no-auto-config
No auto-config check except login/cache
2 parents d351922 + 79b8124 commit 3c21d64

File tree

7 files changed

+105
-66
lines changed

7 files changed

+105
-66
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
* Warnings about invalid accounts/roles in config.yaml are now Debug messages #980
99
* Default ProfileFormat is now the `Friendly` format #992
1010
* `config`, `config-profiles` and `completions` are now sub-commands of `setup` #975
11+
* Only the and `cache` command will auto-update the contents of `~/.aws/config` #974
12+
* `tags` command no longer supports the `--force-update` option
1113

1214
### New Features
1315

cmd/aws-sso/cache_cmd.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ package main
2020

2121
import (
2222
"fmt"
23+
24+
"github.com/synfinatic/aws-sso-cli/internal/awsconfig"
25+
"github.com/synfinatic/aws-sso-cli/internal/url"
2326
)
2427

25-
type CacheCmd struct{}
28+
type CacheCmd struct {
29+
NoConfigCheck bool `kong:"help='Disable automatic ~/.aws/config updates'"`
30+
Threads int `kong:"help='Override number of threads for talking to AWS',default=${DEFAULT_THREADS}"`
31+
}
2632

2733
func (cc *CacheCmd) Run(ctx *RunContext) error {
2834
s, err := ctx.Settings.GetSelectedSSO(ctx.Cli.SSO)
@@ -35,7 +41,7 @@ func (cc *CacheCmd) Run(ctx *RunContext) error {
3541
log.Fatalf(err.Error())
3642
}
3743

38-
err = ctx.Settings.Cache.Refresh(AwsSSO, s, ssoName, ctx.Cli.Threads)
44+
added, deleted, err := ctx.Settings.Cache.Refresh(AwsSSO, s, ssoName, ctx.Cli.Cache.Threads)
3945
if err != nil {
4046
return fmt.Errorf("unable to refresh role cache: %s", err.Error())
4147
}
@@ -46,5 +52,19 @@ func (cc *CacheCmd) Run(ctx *RunContext) error {
4652
return fmt.Errorf("unable to save role cache: %s", err.Error())
4753
}
4854

55+
if added > 0 || deleted > 0 {
56+
log.Infof("Updated cache: %d added, %d deleted", added, deleted)
57+
// should we update our config??
58+
if !ctx.Cli.Cache.NoConfigCheck && ctx.Settings.AutoConfigCheck {
59+
if ctx.Settings.ConfigProfilesUrlAction != url.ConfigProfilesUndef {
60+
action, _ := url.NewAction(string(ctx.Settings.ConfigProfilesUrlAction))
61+
err := awsconfig.UpdateAwsConfig(ctx.Settings, action, "", true, false)
62+
if err != nil {
63+
log.Errorf("Unable to auto-update aws config file: %s", err.Error())
64+
}
65+
}
66+
}
67+
}
68+
4969
return nil
5070
}

cmd/aws-sso/login_cmd.go

+10-15
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ package main
1919
*/
2020

2121
import (
22-
"github.com/synfinatic/aws-sso-cli/internal/awsconfig"
2322
"github.com/synfinatic/aws-sso-cli/internal/sso"
24-
"github.com/synfinatic/aws-sso-cli/internal/url"
2523
)
2624

27-
type LoginCmd struct{}
25+
type LoginCmd struct {
26+
Threads int `kong:"help='Override number of threads for talking to AWS',default=${DEFAULT_THREADS}"`
27+
}
2828

2929
func (cc *LoginCmd) Run(ctx *RunContext) error {
3030
doAuth(ctx)
@@ -71,22 +71,17 @@ func doAuth(ctx *RunContext) {
7171
if err != nil {
7272
log.Fatalf(err.Error())
7373
}
74-
if err = ctx.Settings.Cache.Refresh(AwsSSO, s, ssoName, ctx.Cli.Threads); err != nil {
74+
added, deleted, err := ctx.Settings.Cache.Refresh(AwsSSO, s, ssoName, ctx.Cli.Login.Threads)
75+
if err != nil {
7576
log.WithError(err).Fatalf("Unable to refresh cache")
7677
}
77-
if err = ctx.Settings.Cache.Save(true); err != nil {
78-
log.WithError(err).Errorf("Unable to save cache")
78+
79+
if added > 0 || deleted > 0 {
80+
log.Infof("Updated cache: %d added, %d deleted", added, deleted)
7981
}
8082

81-
// should we update our config??
82-
if !ctx.Cli.NoConfigCheck && ctx.Settings.AutoConfigCheck {
83-
if ctx.Settings.ConfigProfilesUrlAction != url.ConfigProfilesUndef {
84-
action, _ := url.NewAction(string(ctx.Settings.ConfigProfilesUrlAction))
85-
err := awsconfig.UpdateAwsConfig(ctx.Settings, action, "", true, false)
86-
if err != nil {
87-
log.Errorf("Unable to auto-update aws config file: %s", err.Error())
88-
}
89-
}
83+
if err = ctx.Settings.Cache.Save(true); err != nil {
84+
log.WithError(err).Errorf("Unable to save cache")
9085
}
9186
}
9287
}

cmd/aws-sso/main.go

+20-13
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ type RunContext struct {
6060
}
6161

6262
const (
63-
DEFAULT_STORE = "file"
64-
COPYRIGHT_YEAR = "2021-2024"
63+
DEFAULT_STORE = "file"
64+
COPYRIGHT_YEAR = "2021-2024"
65+
DEFAULT_THREADS = 5
6566
)
6667

6768
var DEFAULT_CONFIG map[string]interface{} = map[string]interface{}{
@@ -95,22 +96,20 @@ var DEFAULT_CONFIG map[string]interface{} = map[string]interface{}{
9596
"UrlAction": "open",
9697
"LogLevel": "warn",
9798
"ProfileFormat": NICE_PROFILE_FORMAT,
98-
"Threads": 5,
99+
"Threads": DEFAULT_THREADS,
99100
"MaxBackoff": 5, // seconds
100101
"MaxRetry": 10,
101102
}
102103

103104
type CLI struct {
104105
// Common Arguments
105-
Browser string `kong:"short='b',help='Path to browser to open URLs with',env='AWS_SSO_BROWSER'"`
106-
ConfigFile string `kong:"name='config',default='${CONFIG_FILE}',help='Config file',env='AWS_SSO_CONFIG',predict='allFiles'"`
107-
LogLevel string `kong:"short='L',name='level',help='Logging level [error|warn|info|debug|trace] (default: warn)'"`
108-
Lines bool `kong:"help='Print line number in logs'"`
109-
UrlAction string `kong:"short='u',help='How to handle URLs [clip|exec|open|print|printurl|granted-containers|open-url-in-container] (default: open)'"`
110-
SSO string `kong:"short='S',help='Override default AWS SSO Instance',env='AWS_SSO',predictor='sso'"`
111-
STSRefresh bool `kong:"help='Force refresh of STS Token Credentials'"`
112-
NoConfigCheck bool `kong:"help='Disable automatic ~/.aws/config updates'"`
113-
Threads int `kong:"help='Override number of threads for talking to AWS (default: 5)'"`
106+
Browser string `kong:"short='b',help='Path to browser to open URLs with',env='AWS_SSO_BROWSER'"`
107+
ConfigFile string `kong:"name='config',default='${CONFIG_FILE}',help='Config file',env='AWS_SSO_CONFIG',predict='allFiles'"`
108+
LogLevel string `kong:"short='L',name='level',help='Logging level [error|warn|info|debug|trace] (default: warn)'"`
109+
Lines bool `kong:"help='Print line number in logs'"`
110+
UrlAction string `kong:"short='u',help='How to handle URLs [clip|exec|open|print|printurl|granted-containers|open-url-in-container] (default: open)'"`
111+
SSO string `kong:"short='S',help='Override default AWS SSO Instance',env='AWS_SSO',predictor='sso'"`
112+
STSRefresh bool `kong:"help='Force refresh of STS Token Credentials'"`
114113

115114
// Commands
116115
Cache CacheCmd `kong:"cmd,help='Force reload of cached AWS SSO role info and config.yaml'"`
@@ -251,6 +250,7 @@ func parseArgs(cli *CLI) (*kong.Context, sso.OverrideSettings) {
251250
"CONFIG_DIR": config.ConfigDir(false),
252251
"CONFIG_FILE": config.ConfigFile(false),
253252
"DEFAULT_STORE": DEFAULT_STORE,
253+
"DEFAULT_THREADS": fmt.Sprintf("%d", DEFAULT_THREADS),
254254
"JSON_STORE_FILE": config.JsonStoreFile(false),
255255
"VERSION": Version,
256256
}
@@ -292,12 +292,19 @@ func parseArgs(cli *CLI) (*kong.Context, sso.OverrideSettings) {
292292
log.Fatalf("Invalid --url-action %s", cli.UrlAction)
293293
}
294294

295+
threads := 0
296+
if cli.Cache.Threads != DEFAULT_THREADS {
297+
threads = cli.Cache.Threads
298+
} else if cli.Login.Threads != DEFAULT_THREADS {
299+
threads = cli.Login.Threads
300+
}
301+
295302
override := sso.OverrideSettings{
296303
Browser: cli.Browser,
297304
DefaultSSO: cli.SSO,
298305
LogLevel: cli.LogLevel,
299306
LogLines: cli.Lines,
300-
Threads: cli.Threads,
307+
Threads: threads, // must be > 0 to override config
301308
UrlAction: action,
302309
}
303310

cmd/aws-sso/tags_cmd.go

+10-29
Original file line numberDiff line numberDiff line change
@@ -26,43 +26,24 @@ import (
2626
)
2727

2828
type TagsCmd struct {
29-
AccountId int64 `kong:"name='account',short='A',help='Filter results based on AWS AccountID'"`
30-
Role string `kong:"short='R',help='Filter results based on AWS Role Name'"`
31-
ForceUpdate bool `kong:"help='Force account/role cache update'"`
29+
AccountId int64 `kong:"name='account',short='A',help='Filter results based on AWS AccountID'"`
30+
Role string `kong:"short='R',help='Filter results based on AWS Role Name'"`
3231
}
3332

3433
func (cc *TagsCmd) Run(ctx *RunContext) error {
3534
set := ctx.Settings
3635
cache := ctx.Settings.Cache.GetSSO()
37-
if ctx.Cli.Tags.ForceUpdate {
38-
s := set.SSO[ctx.Cli.SSO]
39-
40-
ssoName, err := ctx.Settings.GetSelectedSSOName(ctx.Cli.SSO)
41-
if err != nil {
42-
log.Fatalf(err.Error())
43-
}
36+
s, err := ctx.Settings.GetSelectedSSO(ctx.Cli.SSO)
37+
if err != nil {
38+
return err
39+
}
4440

45-
err = set.Cache.Refresh(AwsSSO, s, ssoName, ctx.Cli.Threads)
46-
if err != nil {
47-
log.WithError(err).Fatalf("Unable to refresh role cache")
48-
}
49-
err = set.Cache.Save(true)
50-
if err != nil {
51-
log.WithError(err).Errorf("Unable to save cache")
52-
}
53-
} else {
54-
s, err := ctx.Settings.GetSelectedSSO(ctx.Cli.SSO)
55-
if err != nil {
41+
if err := set.Cache.Expired(s); err != nil {
42+
log.Warn(err.Error())
43+
c := &CacheCmd{}
44+
if err = c.Run(ctx); err != nil {
5645
return err
5746
}
58-
59-
if err := set.Cache.Expired(s); err != nil {
60-
log.Warn(err.Error())
61-
c := &CacheCmd{}
62-
if err = c.Run(ctx); err != nil {
63-
return err
64-
}
65-
}
6647
}
6748
roles := []*sso.AWSRoleFlat{}
6849

docs/commands.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
* `--url-action`, `-u` -- How to handle URLs for your SSO provider
1111
* `--sso <name>`, `-S` -- Specify non-default AWS SSO instance to use (`$AWS_SSO`)
1212
* `--sts-refresh` -- Force refresh of STS Token Credentials
13-
* `--no-config-check` -- Disable automatic updating of `~/.aws/config`
14-
* `--threads <int>` -- Number of threads to use with AWS (default: 5)
1513

1614
## Commands
1715

@@ -24,6 +22,11 @@ hours, but you can force this data to be refreshed immediately.
2422
Cache data is also automatically updated anytime the `config.yaml` file is
2523
modified.
2624

25+
Flags:
26+
27+
* `--no-config-check` -- Disable automatic updating of `~/.aws/config`
28+
* `--threads <int>` -- Number of threads to use with AWS (default: 5)
29+
2730
---
2831

2932
### console
@@ -245,6 +248,11 @@ case-sensitive manner.
245248
Login via AWS IAM Identity Center (AWS SSO) and retrieve a security token
246249
used to fetch IAM Role credentials.
247250

251+
Flags:
252+
253+
* `--no-config-check` -- Disable automatic updating of `~/.aws/config`
254+
* `--threads <int>` -- Number of threads to use with AWS (default: 5)
255+
248256
---
249257

250258
### logout

internal/sso/cache.go

+31-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"encoding/json"
2323
"fmt"
2424
"os"
25+
"slices"
2526
"strconv"
2627
"strings"
2728
"time"
@@ -277,11 +278,11 @@ func (c *Cache) deleteOldHistory() {
277278
}
278279

279280
// Refresh updates our cached Roles based on AWS SSO & our Config
280-
// but does not save this data!
281-
func (c *Cache) Refresh(sso *AWSSSO, config *SSOConfig, ssoName string, threads int) error {
281+
// but does not save this data! Returns the number of roles added/deleted
282+
func (c *Cache) Refresh(sso *AWSSSO, config *SSOConfig, ssoName string, threads int) (int, int, error) {
282283
// Only refresh once per execution
283284
if c.refreshed {
284-
return nil
285+
return 0, 0, nil
285286
}
286287
c.refreshed = true
287288
log.Debugf("refreshing %s SSO cache", ssoName)
@@ -311,16 +312,41 @@ func (c *Cache) Refresh(sso *AWSSSO, config *SSOConfig, ssoName string, threads
311312
}
312313

313314
// zero out our current roles cache entries so they don't get merged
315+
oldRoles := cache.Roles.GetAllRoles()
316+
oldRoleArns := []string{}
317+
for _, role := range oldRoles {
318+
oldRoleArns = append(oldRoleArns, role.Arn)
319+
}
320+
314321
c.SSO[ssoName].Roles = &Roles{}
315322
c.SSO[ssoName].ConfigHash = config.GetConfigHash(c.settings.ProfileFormat)
316323

317324
// load our AWSSSO & Config
318325
r, err := c.NewRoles(sso, config, threads)
319326
if err != nil {
320-
return err
327+
return 0, 0, err
321328
}
322329
c.SSO[ssoName].Roles = r
323330

331+
// figure out what roles were added/deleted
332+
newRoles := c.SSO[ssoName].Roles.GetAllRoles()
333+
newRoleArns := []string{}
334+
for _, role := range newRoles {
335+
newRoleArns = append(newRoleArns, role.Arn)
336+
}
337+
338+
added, deleted := 0, 0
339+
for _, arn := range newRoleArns {
340+
if !slices.Contains(oldRoleArns, arn) {
341+
added++
342+
}
343+
}
344+
for _, arn := range oldRoleArns {
345+
if !slices.Contains(newRoleArns, arn) {
346+
deleted++
347+
}
348+
}
349+
324350
// restore our history tags & expires
325351
for _, account := range c.SSO[ssoName].Roles.Accounts {
326352
for _, role := range account.Roles {
@@ -333,7 +359,7 @@ func (c *Cache) Refresh(sso *AWSSSO, config *SSOConfig, ssoName string, threads
333359
}
334360
}
335361
c.ConfigCreatedAt = config.CreatedAt()
336-
return nil
362+
return added, deleted, nil
337363
}
338364

339365
// pruneSSO removes any SSO instances that are no longer configured

0 commit comments

Comments
 (0)