From 2e53e0f4716bce638d685e2cb8266e3aea4ab735 Mon Sep 17 00:00:00 2001 From: Integralist Date: Tue, 14 Nov 2023 14:12:53 +0000 Subject: [PATCH] feat: add --enable-sso flag --- pkg/app/run.go | 20 +++++++++++--------- pkg/app/usage.go | 8 +++++--- pkg/cmd/cmd.go | 6 ++++++ pkg/global/global.go | 31 +++++++++++++++++++++++-------- 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/pkg/app/run.go b/pkg/app/run.go index 024cfd185..375cb3a86 100644 --- a/pkg/app/run.go +++ b/pkg/app/run.go @@ -291,10 +291,10 @@ func configureKingpin(data *global.Data) *kingpin.Application { // error states and output control flow. app.Terminate(nil) - // WARNING: kingpin has no way of decorating flags as being "global" - // therefore if you add/remove a global flag you will also need to update - // the globalFlags map in pkg/app/usage.go which is used for usage rendering. - // You should also update `IsGlobalFlagsOnly` in ../cmd/cmd.go + // IMPORTANT: Kingpin doesn't support global flags. + // Any flags defined below must also be added to two other places: + // 1. ./usage.go (`globalFlags` map). + // 2. ../cmd/cmd.go (`IsGlobalFlagsOnly` function). // // NOTE: Global flags (long and short) MUST be unique. // A subcommand can't define a flag that is already global. @@ -304,8 +304,10 @@ func configureKingpin(data *global.Data) *kingpin.Application { app.Flag("accept-defaults", "Accept default options for all interactive prompts apart from Yes/No confirmations").Short('d').BoolVar(&data.Flags.AcceptDefaults) app.Flag("account", "Fastly Accounts endpoint").Hidden().StringVar(&data.Flags.Account) app.Flag("auto-yes", "Answer yes automatically to all Yes/No confirmations. This may suppress security warnings").Short('y').BoolVar(&data.Flags.AutoYes) - // IMPORTANT: `--debug` is a built-in Kingpin flag so we can't use that. + // IMPORTANT: `--debug` is a built-in Kingpin flag so we must use `debug-mode`. app.Flag("debug-mode", "Print API request and response details (NOTE: can disrupt the normal CLI flow output formatting)").BoolVar(&data.Flags.Debug) + // IMPORTANT: `--sso` causes a Kingpin runtime panic 🤦 so we use `enable-sso`. + app.Flag("enable-sso", "Enable Single-Sign On (SSO) for current profile execution (see also: 'fastly sso')").Hidden().BoolVar(&data.Flags.SSO) app.Flag("endpoint", "Fastly API endpoint").Hidden().StringVar(&data.Flags.Endpoint) app.Flag("non-interactive", "Do not prompt for user input - suitable for CI processes. Equivalent to --accept-defaults and --auto-yes").Short('i').BoolVar(&data.Flags.NonInteractive) app.Flag("profile", "Switch account profile for single command execution (see also: 'fastly profile switch')").Short('o').StringVar(&data.Flags.Profile) @@ -490,19 +492,19 @@ func checkProfileToken( // shouldSkipSSO identifies if a config is a pre-v5 config and, if it is, // informs the user how they can use the SSO flow. It checks if the SSO -// environment variable has been set and enables the SSO flow if so. +// environment variable (or flag) has been set and enables the SSO flow if so. func shouldSkipSSO(profileName string, pd *config.Profile, data *global.Data) bool { if noSSOToken(pd) { - return data.Env.UseSSO != "1" + return data.Env.UseSSO != "1" && !data.Flags.SSO // FIXME: Put back messaging once SSO is GA. - // if data.Env.UseSSO == "1" { + // if data.Env.UseSSO == "1" || data.Flags.SSO { // return false // don't skip SSO // } // if !data.Flags.Quiet { // if data.Flags.Verbose { // text.Break(data.Output) // } - // text.Important(data.Output, "The Fastly API token used by the current '%s' profile is not a Fastly SSO (Single Sign-On) generated token. SSO-based tokens offer more security and convenience. To update your token, set `FASTLY_USE_SSO=1` before invoking the Fastly CLI. This will ensure the current profile is switched to using an SSO generated API token. Once the token has been switched over you no longer need to set `FASTLY_USE_SSO` for this profile (--token and FASTLY_API_TOKEN can still be used as overrides).\n\n", profileName) + // text.Important(data.Output, "The Fastly API token used by the current '%s' profile is not a Fastly SSO (Single Sign-On) generated token. SSO-based tokens offer more security and convenience. To update your token, either set `FASTLY_USE_SSO=1` or pass `--enable-sso` before invoking the Fastly CLI. This will ensure the current profile is switched to using an SSO generated API token. Once the token has been switched over you no longer need to set `FASTLY_USE_SSO` for this profile (--token and FASTLY_API_TOKEN can still be used as overrides).\n\n", profileName) // } // return true // skip SSO } diff --git a/pkg/app/usage.go b/pkg/app/usage.go index c485dc1dc..75ca1fd1e 100644 --- a/pkg/app/usage.go +++ b/pkg/app/usage.go @@ -140,15 +140,17 @@ var UsageTemplateFuncs = template.FuncMap{ }, } -// WARNING: kingpin has no way of decorating flags as being "global" therefore -// if you add/remove a global flag you will also need to update the app.Flag() -// bindings in pkg/app/run.go. +// IMPORTANT: Kingpin doesn't support global flags. +// We hack a solution in ./run.go (`configureKingpin` function). // // NOTE: This map is used to help populate the CLI 'usage' template renderer. var globalFlags = map[string]bool{ "accept-defaults": true, + "account": true, "auto-yes": true, "debug-mode": true, + "enable-sso": true, + "endpoint": true, "help": true, "non-interactive": true, "profile": true, diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 2120ee5aa..48005f11f 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -253,13 +253,19 @@ func IsVerboseAndQuiet(args []string) bool { // // args: [--verbose -v --endpoint ... --token ... -t ... --endpoint ...] 10 // total: 10 +// +// IMPORTANT: Kingpin doesn't support global flags. +// We hack a solution in ../app/run.go (`configureKingpin` function). func IsGlobalFlagsOnly(args []string) bool { // Global flags are defined in ../app/run.go globals := map[string]int{ "--accept-defaults": 0, "-d": 0, + "--account": 1, "--auto-yes": 0, "-y": 0, + "--debug-mode": 0, + "--enable-sso": 0, "--endpoint": 1, "--help": 0, "--non-interactive": 0, diff --git a/pkg/global/global.go b/pkg/global/global.go index 2091fa25b..7a1eb973c 100644 --- a/pkg/global/global.go +++ b/pkg/global/global.go @@ -177,15 +177,30 @@ func (d *Data) AccountEndpoint() (string, lookup.Source) { // Flags represents all of the configuration parameters that can be set with // explicit flags. Consumers should bind their flag values to these fields // directly. +// +// IMPORTANT: Kingpin doesn't support global flags. +// We hack a solution in ../app/run.go (`configureKingpin` function). type Flags struct { + // AcceptDefaults auto-resolves prompts with a default defined. AcceptDefaults bool - Account string - AutoYes bool - Debug bool - Endpoint string + // Account is the authentication host address. + Account string + // AutoYes auto-resolves Yes/No prompts by answering "Yes". + AutoYes bool + // Debug enables the CLI's debug mode. + Debug bool + // Endpoint is the Fastly API address. + Endpoint string + // NonInteractive auto-resolves all prompts. NonInteractive bool - Profile string - Quiet bool - Token string - Verbose bool + // Profile indicates the profile to use (consequently the 'token' used). + Profile string + // Quiet silences all output except direct command output. + Quiet bool + // SSO enables to SSO authentication tokens for the current profile. + SSO bool + // Token is an override for a profile (when passed SSO is disabled). + Token string + // Verbose prints additional output. + Verbose bool }