github.com/versent/saml2aws@v2.17.0+incompatible/cmd/saml2aws/main.go (about)

     1  package main
     2  
     3  import (
     4  	"crypto/tls"
     5  	"fmt"
     6  	"net/http"
     7  	"os"
     8  
     9  	"github.com/alecthomas/kingpin"
    10  	"github.com/sirupsen/logrus"
    11  	"github.com/versent/saml2aws/cmd/saml2aws/commands"
    12  	"github.com/versent/saml2aws/pkg/flags"
    13  )
    14  
    15  var (
    16  	// Version app version
    17  	Version = "1.0.0"
    18  )
    19  
    20  // The `cmdLineList` type is used to make a `[]string` meet the requirements
    21  // of the kingpin.Value interface
    22  type cmdLineList []string
    23  
    24  func (i *cmdLineList) Set(value string) error {
    25  	*i = append(*i, value)
    26  
    27  	return nil
    28  }
    29  
    30  func (i *cmdLineList) String() string {
    31  	return ""
    32  }
    33  
    34  func (i *cmdLineList) IsCumulative() bool {
    35  	return true
    36  }
    37  
    38  func buildCmdList(s kingpin.Settings) (target *[]string) {
    39  	target = new([]string)
    40  	s.SetValue((*cmdLineList)(target))
    41  	return
    42  }
    43  
    44  func main() {
    45  
    46  	app := kingpin.New("saml2aws", "A command line tool to help with SAML access to the AWS token service.")
    47  	app.Version(Version)
    48  
    49  	// Settings not related to commands
    50  	verbose := app.Flag("verbose", "Enable verbose logging").Bool()
    51  	provider := app.Flag("provider", "This flag is obsolete. See: https://github.com/Versent/saml2aws#configuring-idp-accounts").Short('i').Enum("AzureAD", "ADFS", "ADFS2", "Ping", "JumpCloud", "Okta", "OneLogin", "PSU", "KeyCloak")
    52  
    53  	// Common (to all commands) settings
    54  	commonFlags := new(flags.CommonFlags)
    55  	app.Flag("idp-account", "The name of the configured IDP account. (env: SAML2AWS_IDP_ACCOUNT)").Envar("SAML2AWS_IDP_ACCOUNT").Short('a').Default("default").StringVar(&commonFlags.IdpAccount)
    56  	app.Flag("idp-provider", "The configured IDP provider. (env: SAML2AWS_IDP_PROVIDER)").Envar("SAML2AWS_IDP_PROVIDER").EnumVar(&commonFlags.IdpProvider, "AzureAD", "ADFS", "ADFS2", "Ping", "JumpCloud", "Okta", "OneLogin", "PSU", "KeyCloak", "F5APM", "Shibboleth")
    57  	app.Flag("mfa", "The name of the mfa. (env: SAML2AWS_MFA)").Envar("SAML2AWS_MFA").StringVar(&commonFlags.MFA)
    58  	app.Flag("skip-verify", "Skip verification of server certificate. (env: SAML2AWS_SKIP_VERIFY)").Envar("SAML2AWS_SKIP_VERIFY").Short('s').BoolVar(&commonFlags.SkipVerify)
    59  	app.Flag("url", "The URL of the SAML IDP server used to login. (env: SAML2AWS_URL)").Envar("SAML2AWS_URL").StringVar(&commonFlags.URL)
    60  	app.Flag("username", "The username used to login. (env: SAML2AWS_USERNAME)").Envar("SAML2AWS_USERNAME").StringVar(&commonFlags.Username)
    61  	app.Flag("password", "The password used to login. (env: SAML2AWS_PASSWORD)").Envar("SAML2AWS_PASSWORD").StringVar(&commonFlags.Password)
    62  	app.Flag("mfa-token", "The current MFA token (supported in Keycloak, ADFS). (env: SAML2AWS_MFA_TOKEN)").Envar("SAML2AWS_MFA_TOKEN").StringVar(&commonFlags.MFAToken)
    63  	app.Flag("role", "The ARN of the role to assume. (env: SAML2AWS_ROLE)").Envar("SAML2AWS_ROLE").StringVar(&commonFlags.RoleArn)
    64  	app.Flag("aws-urn", "The URN used by SAML when you login. (env: SAML2AWS_AWS_URN)").Envar("SAML2AWS_AWS_URN").StringVar(&commonFlags.AmazonWebservicesURN)
    65  	app.Flag("skip-prompt", "Skip prompting for parameters during login.").BoolVar(&commonFlags.SkipPrompt)
    66  	app.Flag("session-duration", "The duration of your AWS Session. (env: SAML2AWS_SESSION_DURATION)").Envar("SAML2AWS_SESSION_DURATION").IntVar(&commonFlags.SessionDuration)
    67  
    68  	// `configure` command and settings
    69  	cmdConfigure := app.Command("configure", "Configure a new IDP account.")
    70  	cmdConfigure.Flag("app-id", "OneLogin app id required for SAML assertion. (env: ONELOGIN_APP_ID)").Envar("ONELOGIN_APP_ID").StringVar(&commonFlags.AppID)
    71  	cmdConfigure.Flag("client-id", "OneLogin client id, used to generate API access token. (env: ONELOGIN_CLIENT_ID)").Envar("ONELOGIN_CLIENT_ID").StringVar(&commonFlags.ClientID)
    72  	cmdConfigure.Flag("client-secret", "OneLogin client secret, used to generate API access token. (env: ONELOGIN_CLIENT_SECRET)").Envar("ONELOGIN_CLIENT_SECRET").StringVar(&commonFlags.ClientSecret)
    73  	cmdConfigure.Flag("subdomain", "OneLogin subdomain of your company account. (env: ONELOGIN_SUBDOMAIN)").Envar("ONELOGIN_SUBDOMAIN").StringVar(&commonFlags.Subdomain)
    74  	cmdConfigure.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Envar("SAML2AWS_PROFILE").Short('p').StringVar(&commonFlags.Profile)
    75  	cmdConfigure.Flag("resource-id", "F5APM SAML resource ID of your company account. (env: SAML2AWS_F5APM_RESOURCE_ID)").Envar("SAML2AWS_F5APM_RESOURCE_ID").StringVar(&commonFlags.ResourceID)
    76  	cmdConfigure.Flag("config", "Path/filename of saml2aws config file (env: SAML2AWS_CONFIGFILE)").Envar("SAML2AWS_CONFIGFILE").StringVar(&commonFlags.ConfigFile)
    77  	configFlags := commonFlags
    78  
    79  	// `login` command and settings
    80  	cmdLogin := app.Command("login", "Login to a SAML 2.0 IDP and convert the SAML assertion to an STS token.")
    81  	loginFlags := new(flags.LoginExecFlags)
    82  	loginFlags.CommonFlags = commonFlags
    83  	cmdLogin.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Short('p').Envar("SAML2AWS_PROFILE").StringVar(&commonFlags.Profile)
    84  	cmdLogin.Flag("duo-mfa-option", "The MFA option you want to use to authenticate with").Envar("SAML2AWS_DUO_MFA_OPTION").EnumVar(&loginFlags.DuoMFAOption, "Passcode", "Duo Push")
    85  	cmdLogin.Flag("force", "Refresh credentials even if not expired.").BoolVar(&loginFlags.Force)
    86  
    87  	// `exec` command and settings
    88  	cmdExec := app.Command("exec", "Exec the supplied command with env vars from STS token.")
    89  	execFlags := new(flags.LoginExecFlags)
    90  	execFlags.CommonFlags = commonFlags
    91  	cmdExec.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Envar("SAML2AWS_PROFILE").Short('p').StringVar(&commonFlags.Profile)
    92  	cmdExec.Flag("exec-profile", "The AWS profile to utilize for command execution. Useful to allow the aws cli to perform secondary role assumption. (env: SAML2AWS_EXEC_PROFILE)").Envar("SAML2AWS_EXEC_PROFILE").StringVar(&execFlags.ExecProfile)
    93  	cmdLine := buildCmdList(cmdExec.Arg("command", "The command to execute."))
    94  
    95  
    96  	// `list` command and settings
    97  	cmdListRoles := app.Command("list-roles", "List available role ARNs.")
    98  	listRolesFlags := new(flags.LoginExecFlags)
    99  	listRolesFlags.CommonFlags = commonFlags
   100  
   101  	// `script` command and settings
   102  	cmdScript := app.Command("script", "Emit a script that will export environment variables.")
   103  	scriptFlags := new(flags.LoginExecFlags)
   104  	scriptFlags.CommonFlags = commonFlags
   105  	cmdScript.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Envar("SAML2AWS_PROFILE").Short('p').StringVar(&commonFlags.Profile)
   106  	var shell string
   107  	cmdScript.
   108  		Flag("shell", "Type of shell environment. Options include: bash, powershell, fish").
   109  		Default("bash").
   110  		EnumVar(&shell, "bash", "powershell", "fish")
   111  
   112  	// Trigger the parsing of the command line inputs via kingpin
   113  	command := kingpin.MustParse(app.Parse(os.Args[1:]))
   114  
   115  	// will leave this here for a while during upgrade process
   116  	if *provider != "" {
   117  		fmt.Println("The --provider flag has been replaced with a new configure command. See https://github.com/Versent/saml2aws#adding-idp-accounts")
   118  		os.Exit(1)
   119  	}
   120  
   121  	errtpl := "%v\n"
   122  	if *verbose {
   123  		logrus.SetLevel(logrus.DebugLevel)
   124  		errtpl = "%+v\n"
   125  	}
   126  
   127  	// Set the default transport settings so all http clients will pick them up.
   128  	http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: commonFlags.SkipVerify}
   129  	http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
   130  
   131  	logrus.WithField("command", command).Debug("Running")
   132  
   133  	var err error
   134  	switch command {
   135  	case cmdScript.FullCommand():
   136  		err = commands.Script(scriptFlags, shell)
   137  	case cmdLogin.FullCommand():
   138  		err = commands.Login(loginFlags)
   139  	case cmdExec.FullCommand():
   140  		err = commands.Exec(execFlags, *cmdLine)
   141  	case cmdListRoles.FullCommand():
   142  		err = commands.ListRoles(listRolesFlags)
   143  	case cmdConfigure.FullCommand():
   144  		err = commands.Configure(configFlags)
   145  	}
   146  
   147  	if err != nil {
   148  		fmt.Printf(errtpl, err)
   149  		os.Exit(1)
   150  	}
   151  }
   152