granted

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2022 License: MIT Imports: 34 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ClearTokensCommand = cli.Command{
	Name:  "clear",
	Usage: "Remove a selected token from the keyring",
	Flags: []cli.Flag{
		&cli.BoolFlag{Name: "all", Aliases: []string{"a"}, Usage: "Remove all saved tokens from keyring"},
	},
	Action: func(c *cli.Context) error {

		if c.Bool("all") {
			err := clearAllTokens()
			if err != nil {
				return err
			}
			fmt.Fprintf(os.Stderr, "Cleared all saved tokens")
			return nil
		}
		var selection string

		if c.Args().First() != "" {
			selection = c.Args().First()
		}

		startUrlMap, err := MapTokens(c.Context)
		if err != nil {
			return err
		}
		if selection == "" {
			var max int
			for k := range startUrlMap {
				if len(k) > max {
					max = len(k)
				}
			}
			selectionsMap := make(map[string]string)
			tokenList := []string{}
			for k, profiles := range startUrlMap {
				stringKey := fmt.Sprintf("%-*s (%s)", max, k, strings.Join(profiles, ", "))
				tokenList = append(tokenList, stringKey)
				selectionsMap[stringKey] = k
			}
			withStdio := survey.WithStdio(os.Stdin, os.Stderr, os.Stderr)
			in := survey.Select{
				Message: "Select a token to remove from keyring",
				Options: tokenList,
			}
			fmt.Fprintln(os.Stderr)
			var out string
			err = testable.AskOne(&in, &out, withStdio)
			if err != nil {
				return err
			}
			selection = selectionsMap[out]
		}

		err = clearToken(selection)
		if err != nil {
			return err
		}
		fmt.Fprintf(os.Stderr, "Cleared %s", selection)
		return nil
	},
}
View Source
var CompletionCommand = cli.Command{
	Name:  "completion",
	Usage: "Add autocomplete to your granted cli installation",
	Flags: flags,
	Action: func(c *cli.Context) (err error) {
		shell := c.String("shell")
		switch shell {
		case "fish":
			err = installFishCompletions(c)
		case "zsh":
			err = installZSHCompletions(c)
		case "bash":
			err = installBashCompletions(c)
		default:
			fmt.Fprintln(color.Error, "To install completions for other shells, please see our docs:")
			fmt.Fprintln(color.Error, "https://granted.dev/autocompletion")
		}
		return err
	},

	Description: "Install completions for fish, zsh, or bash. To install completions for other shells, please see our docs:\nhttps://granted.dev/autocompletion\n",
}
View Source
var CredentialProcess = cli.Command{
	Name:  "credential-process",
	Usage: "Exports AWS session credentials for use with AWS CLI credential_process",
	Flags: []cli.Flag{&cli.StringFlag{Name: "profile", Required: true}, &cli.StringFlag{Name: "url"}},
	Action: func(c *cli.Context) error {

		profileName := c.String("profile")
		profiles, err := cfaws.LoadProfiles()
		if err != nil {
			return err
		}

		profile, err := profiles.LoadInitialisedProfile(c.Context, profileName)
		if err != nil {
			return err
		}

		duration := time.Hour
		if profile.AWSConfig.RoleDurationSeconds != nil {
			duration = *profile.AWSConfig.RoleDurationSeconds
		}

		creds, err := profile.AssumeTerminal(c.Context, cfaws.ConfigOpts{Duration: duration})
		if err != nil {

			fmt.Fprintln(os.Stderr, err)

			os.Exit(1)
		}

		out := awsCredsStdOut{
			Version:         1,
			AccessKeyID:     creds.AccessKeyID,
			SecretAccessKey: creds.SecretAccessKey,
			SessionToken:    creds.SessionToken,
			Expiration:      creds.Expires.Format(time.RFC3339),
		}

		jsonOut, err := json.Marshal(out)
		if err != nil {
			return errors.Wrap(err, "marshalling session credentials")
		}

		fmt.Println(string(jsonOut))
		return nil
	},
}
View Source
var DefaultBrowserCommand = cli.Command{
	Name:        "browser",
	Usage:       "View the web browser that Granted uses to open cloud consoles",
	Subcommands: []*cli.Command{&SetBrowserCommand, &SetSSOBrowserCommand},
	Action: func(c *cli.Context) error {

		conf, err := config.Load()
		if err != nil {
			return err
		}
		fmt.Fprintf(color.Error, "Granted is using %s. To change this run `granted browser set`.\n", conf.DefaultBrowser)

		return nil
	},
}
View Source
var GenerateCommand = cli.Command{
	Name:      "generate",
	Usage:     "Outputs an AWS Config with profiles from accounts and roles available in AWS SSO",
	UsageText: "granted [global options] sso generate [command options] [sso-start-url]",
	Flags:     []cli.Flag{&cli.StringFlag{Name: "prefix", Usage: "Specify a prefix for all generated profile names"}, &cli.StringFlag{Name: "region", Usage: "Specify the SSO region", DefaultText: "us-east-1"}},
	Action: func(c *cli.Context) error {
		options, err := parseCliOptions(c)
		if err != nil {
			return err
		}

		ssoProfiles, err := listSSOProfiles(c.Context, ListSSOProfilesInput{
			StartUrl:  options.StartUrl,
			SSORegion: options.SSORegion,
		})
		if err != nil {
			return err
		}

		config := configparser.New()

		err = mergeSSOProfiles(config, options.Prefix, ssoProfiles)
		if err != nil {
			return err
		}

		for sectionIdx, sectionName := range config.Sections() {
			if sectionIdx != 0 {
				fmt.Fprintln(color.Output)
			}

			fmt.Fprintln(color.Output, "["+sectionName+"]")
			items, err := config.Items(sectionName)
			if err != nil {
				return nil
			}

			for key, value := range items {
				fmt.Fprintln(color.Output, key+" = "+value)
			}
		}

		return nil
	},
}
View Source
var PopulateCommand = cli.Command{
	Name:      "populate",
	Usage:     "Populate your AWS Config with profiles from accounts and roles available in AWS SSO",
	UsageText: "granted [global options] sso populate [command options] [sso-start-url]",
	Flags:     []cli.Flag{&cli.StringFlag{Name: "prefix", Usage: "Specify a prefix for all generated profile names"}, &cli.StringFlag{Name: "region", Usage: "Specify the SSO region", DefaultText: "us-east-1"}},
	Action: func(c *cli.Context) error {
		options, err := parseCliOptions(c)
		if err != nil {
			return err
		}

		ssoProfiles, err := listSSOProfiles(c.Context, ListSSOProfilesInput{
			StartUrl:  options.StartUrl,
			SSORegion: options.SSORegion,
		})
		if err != nil {
			return err
		}

		configFilename := config.DefaultSharedConfigFilename()

		config, err := configparser.NewConfigParserFromFile(configFilename)
		if err != nil {
			if !errors.Is(err, os.ErrNotExist) {
				return err
			}
			config = configparser.New()
		}

		if err := mergeSSOProfiles(config, options.Prefix, ssoProfiles); err != nil {
			return err
		}

		err = config.SaveWithDelimiter(configFilename, "=")
		if err != nil {
			return err
		}
		return nil
	},
}
View Source
var SSOCommand = cli.Command{
	Name:        "sso",
	Usage:       "Manage AWS Config from information available in AWS SSO",
	Subcommands: []*cli.Command{&GenerateCommand, &PopulateCommand},
}
View Source
var SetBrowserCommand = cli.Command{
	Name:  "set",
	Usage: "Change the web browser that Granted uses to open cloud consoles",
	Flags: []cli.Flag{&cli.StringFlag{Name: "browser", Aliases: []string{"b"}, Usage: "Specify a default browser without prompts, e.g `-b firefox`, `-b chrome`"},
		&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Usage: "Specify a path to the browser without prompts, requires -browser to be provided"}},
	Action: func(c *cli.Context) (err error) {
		outcome := c.String("browser")
		path := c.String("path")

		if outcome == "" {
			if path != "" {
				fmt.Fprintln(color.Error, "-path flag must be used with -browser flag, provided path will be ignored.")
			}
			outcome, err = browser.HandleManualBrowserSelection()
			if err != nil {
				return err
			}
		}

		return browser.ConfigureBrowserSelection(outcome, path)
	},
}
View Source
var SetSSOBrowserCommand = cli.Command{
	Name:  "set-sso",
	Usage: "Change the web browser that Granted uses to sso flows",
	Flags: []cli.Flag{&cli.StringFlag{Name: "browser", Aliases: []string{"b"}, Usage: "Specify a default browser without prompts, e.g `-b firefox`, `-b chrome`"},
		&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Usage: "Specify a path to the browser without prompts, requires -browser to be provided"}},
	Action: func(c *cli.Context) (err error) {
		outcome := c.String("browser")
		path := c.String("path")

		conf, err := config.Load()
		if err != nil {
			return err
		}
		var browserPath string

		if outcome == "" {
			if path != "" {
				fmt.Fprintln(color.Error, "-path flag must be used with -browser flag, provided path will be ignored.")
			}
			customBrowserPath, err := browser.AskAndGetBrowserPath()
			if err != nil {
				return err
			}
			browserPath = customBrowserPath

		}

		conf.CustomSSOBrowserPath = browserPath
		err = conf.Save()
		if err != nil {
			return err
		}

		alert := color.New(color.Bold, color.FgGreen).SprintfFunc()

		fmt.Fprintf(color.Error, "\n%s\n", alert("✅  Granted will default to using %s for SSO flows.", browserPath))

		return nil
	},
}
View Source
var TokenCommand = cli.Command{
	Name:        "token",
	Usage:       "Manage aws access tokens",
	Subcommands: []*cli.Command{&TokenListCommand, &ClearTokensCommand},
	Action:      TokenListCommand.Action,
}
View Source
var TokenListCommand = cli.Command{
	Name:  "list",
	Usage: "Lists all access tokens saved in the keyring",
	Action: func(ctx *cli.Context) error {

		startUrlMap, err := MapTokens(ctx.Context)
		if err != nil {
			return err
		}

		var max int
		for k := range startUrlMap {
			if len(k) > max {
				max = len(k)
			}
		}

		tokens, err := credstore.ListKeys()
		if err != nil {
			return err
		}

		for _, token := range tokens {
			fmt.Fprintf(os.Stderr, "%s\n", fmt.Sprintf("%-*s (%s)", max, token, strings.Join(startUrlMap[token], ", ")))
		}
		return nil
	},
}
View Source
var UninstallCommand = cli.Command{
	Name:  "uninstall",
	Usage: "Remove all Granted configuration",
	Action: func(c *cli.Context) error {
		withStdio := survey.WithStdio(os.Stdin, os.Stderr, os.Stderr)
		in := &survey.Confirm{
			Message: "Are you sure you want to remove your Granted config?",
			Default: true,
		}
		var confirm bool
		err := survey.AskOne(in, &confirm, withStdio)
		if err != nil {
			return err
		}
		if confirm {

			err = alias.UninstallDefaultShellAlias()
			if err != nil {
				fmt.Fprintln(color.Error, err)
			}
			grantedFolder, err := config.GrantedConfigFolder()
			if err != nil {
				return err
			}
			err = os.RemoveAll(grantedFolder)
			if err != nil {
				return err
			}

			fmt.Printf("removed Granted config folder %s\n", grantedFolder)
			fmt.Fprintln(color.Error, "[✔] all Granted config has been removed")
		}
		return nil
	},
}

Functions

func GetCliApp

func GetCliApp() *cli.App

func MapTokens added in v0.1.8

func MapTokens(ctx context.Context) (map[string][]string, error)

Types

type AutoCompleteTemplateData added in v0.2.1

type AutoCompleteTemplateData struct {
	Program string
}

type ListSSOProfilesInput added in v0.3.0

type ListSSOProfilesInput struct {
	SSORegion string
	StartUrl  string
}

type SSOCommonOptions added in v0.3.0

type SSOCommonOptions struct {
	Prefix    string
	StartUrl  string
	SSORegion string
}

type SSOProfile added in v0.3.0

type SSOProfile struct {
	// SSO details
	StartUrl  string
	SSORegion string
	// Account and role details
	AccountId   string
	AccountName string
	RoleName    string
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL