Skip to content

Commit

Permalink
Rough out initial alias support for stak and run
Browse files Browse the repository at this point in the history
Adds alias support via flags to the --stak and --run commands. Cache
entries will be made with car + alias for the keys causing possible
duplicate entries if there is a car + acc number cache entry for the
same account + car combo. We can either leave this minor inefficiency or
add another api call to translate between the two (alias <-> number) and
create the appropriate cache entries. Feels like it's better to accept
the minor occasional inefficiency instead of making an additional api
call every time.
  • Loading branch information
codybuell committed Jul 30, 2024
1 parent ee1c818 commit 49a3364
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 16 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,12 @@ OPTIONS
--account val, --acc val, -a val Target account number, used to bypass
prompts, must be passed with --car.
--alias val, --aka val, -l val Target account alias, used to bypass
prompts, must be passed with --car.
--car val, --cloud-access-role val, Target cloud access role, used to bypass
-c val prompts, must be passed with --account.
-c val prompts, must be passed with --account
or --alias.
--region val, -r val Specify which region to target.
Expand Down Expand Up @@ -273,8 +277,11 @@ OPTIONS
--account val, -acc val, -a val Specify which account to target, must be
passed with --car.
--alias val, --aka val, -l val Target account alias, used to bypass
prompts, must be passed with --car.
--car val, -c val Specify which Cloud Access Role to use,
must be passed with --account.
must be passed with --account or --alias.
--region val, -r val Specify which region to target.
Expand Down
20 changes: 19 additions & 1 deletion lib/kion/car.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type CAR struct {
AccountType string `json:"account_type"`
AccountTypeID uint `json:"account_type_id"`
AccountName string `json:"account_name"`
AccountAlias string `json:"account_alias"`
ApplyToAllAccounts bool `json:"apply_to_all_accounts"`
AwsIamPath string `json:"aws_iam_path"`
AwsIamRoleName string `json:"aws_iam_role_name"`
Expand Down Expand Up @@ -153,7 +154,24 @@ func GetCARByNameAndAccount(host string, token string, carName string, accountNu
}
}

return CAR{}, fmt.Errorf("unable to find car %v", carName)
return CAR{}, fmt.Errorf("unable to find car %v with account number %v", carName, accountNumber)
}

// GetCARByNameAndAlias returns a car that matches by name and account alias.
func GetCARByNameAndAlias(host string, token string, carName string, accountAlias string) (CAR, error) {
allCars, err := GetCARS(host, token)
if err != nil {
return CAR{}, err
}

// find our match
for _, car := range allCars {
if car.Name == carName && car.AccountAlias == accountAlias {
return car, nil
}
}

return CAR{}, fmt.Errorf("unable to find car %v with account alias %v", carName, accountAlias)
}

// GetAllCARsByName returns a slice of cars that matches a given name.
Expand Down
76 changes: 63 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,12 +447,20 @@ func genStaks(cCtx *cli.Context) error {
var stak kion.STAK

// set vars for easier access
var cacheKey string
endpoint := config.Kion.Url
carName := cCtx.String("car")
account := cCtx.String("account")
cacheKey := fmt.Sprintf("%s-%s", carName, account)
accNum := cCtx.String("account")
accAlias := cCtx.String("alias")
region := cCtx.String("region")

// fail fast if we have a bad combo of flags
if (accNum != "" || accAlias != "") && carName == "" {
return errors.New("must specify --car parameter when using --account or --alias")
} else if carName != "" && accNum == "" && accAlias == "" {
return errors.New("must specify --account OR --alias parameter when using --car")
}

// grab the command usage [stak, s, setenv, savecreds, etc]
cmdUsed := cCtx.Lineage()[1].Args().Slice()[0]

Expand All @@ -474,7 +482,14 @@ func genStaks(cCtx *cli.Context) error {
}

// if we have what we need go look stuff up without prompts do it
if account != "" && carName != "" {
if (accNum != "" || accAlias != "") && carName != "" {
// set the cache key based on what was passed
if accNum != "" {
cacheKey = fmt.Sprintf("%s-%s", carName, accNum)
} else {
cacheKey = fmt.Sprintf("%s-%s", carName, accAlias)
}

// determine if we have a valid cached entry
cachedSTAK, found, err := c.GetStak(cacheKey)
if err != nil {
Expand All @@ -484,7 +499,8 @@ func genStaks(cCtx *cli.Context) error {
if found && cachedSTAK.Expiration.After(time.Now().Add(-buffer*time.Second)) {
// cached stak found and is still valid
stak = cachedSTAK
if action != "subshell" {
if action != "subshell" && action != "save" {
// skip getting the car for everything but subshell and save
getCar = false
}
}
Expand All @@ -497,9 +513,16 @@ func genStaks(cCtx *cli.Context) error {
return err
}

car, err = kion.GetCARByNameAndAccount(endpoint, config.Kion.ApiKey, carName, account)
if err != nil {
return err
if accNum != "" {
car, err = kion.GetCARByNameAndAccount(endpoint, config.Kion.ApiKey, carName, accNum)
if err != nil {
return err
}
} else {
car, err = kion.GetCARByNameAndAlias(endpoint, config.Kion.ApiKey, carName, accAlias)
if err != nil {
return err
}
}
}
} else {
Expand Down Expand Up @@ -727,26 +750,28 @@ func listFavorites(cCtx *cli.Context) error {
// provided command with said credentials set.
func runCommand(cCtx *cli.Context) error {
// set vars for easier access
var cacheKey string
endpoint := config.Kion.Url
favName := cCtx.String("favorite")
accNum := cCtx.String("account")
accAlias := cCtx.String("alias")
carName := cCtx.String("car")
region := cCtx.String("region")

// fail fast if we don't have what we need
if favName == "" && (accNum == "" || carName == "") {
return errors.New("must specify either --fav OR --account and --car parameters")
if favName == "" && ((accNum == "" && accAlias == "") || carName == "") {
return errors.New("must specify either --fav OR --account and --car OR --alias and --car parameters")
}

// placeholder for our stak
var stak kion.STAK

// prefer favorites if specified, else use account and car
// prefer favorites if specified, else use account/alias and car
if favName != "" {
// map our favorites for ease of use
_, fMap := helper.MapFavs(config.Favorites)

// if arg passed is a valid favorite use it else prompt
// if arg passed is a valid favorite use it else error out
var fav string
var err error
if fMap[favName] != (structs.Favorite{}) {
Expand All @@ -759,7 +784,7 @@ func runCommand(cCtx *cli.Context) error {
favorite := fMap[fav]

// check if we have a valid cached stak else grab a new one
cacheKey := fmt.Sprintf("%s-%s", favorite.CAR, favorite.Account)
cacheKey = fmt.Sprintf("%s-%s", favorite.CAR, favorite.Account)
cachedSTAK, found, err := c.GetStak(cacheKey)
if err != nil {
return err
Expand Down Expand Up @@ -798,8 +823,14 @@ func runCommand(cCtx *cli.Context) error {
return err
}
} else {
// set the cache key based on what was passed
if accNum != "" {
cacheKey = fmt.Sprintf("%s-%s", carName, accNum)
} else {
cacheKey = fmt.Sprintf("%s-%s", carName, accAlias)
}

// check if we have a valid cached stak else grab a new one
cacheKey := fmt.Sprintf("%s-%s", carName, accNum)
cachedSTAK, found, err := c.GetStak(cacheKey)
if err != nil {
return err
Expand All @@ -813,6 +844,15 @@ func runCommand(cCtx *cli.Context) error {
return err
}

// grab car if alias used since we need the account number to run GenSTAK
if accAlias != "" {
car, err := kion.GetCARByNameAndAlias(endpoint, config.Kion.ApiKey, carName, accAlias)
if err != nil {
return err
}
accNum = car.AccountNumber
}

// grab a new stak
stak, err = kion.GetSTAK(endpoint, config.Kion.ApiKey, carName, accNum)
if err != nil {
Expand Down Expand Up @@ -1009,6 +1049,11 @@ func main() {
Aliases: []string{"acc", "a"},
Usage: "target account number, must be passed with car",
},
&cli.StringFlag{
Name: "alias",
Aliases: []string{"aka", "l"},
Usage: "account alias",
},
&cli.StringFlag{
Name: "car",
Aliases: []string{"cloud-access-role", "c"},
Expand Down Expand Up @@ -1095,6 +1140,11 @@ func main() {
Aliases: []string{"acc", "a"},
Usage: "account number",
},
&cli.StringFlag{
Name: "alias",
Aliases: []string{"aka", "l"},
Usage: "account alias",
},
&cli.StringFlag{
Name: "car",
Aliases: []string{"c"},
Expand Down

0 comments on commit 49a3364

Please sign in to comment.