Documentation ¶
Index ¶
- Constants
- Variables
- func CheckoutRef(ref string, repoDirPath string) error
- func Contains(arr []string, s string) bool
- func IsOutdatedConfig() bool
- func SaveKey(gConf *grantedConfig.Config, key string, value string) error
- func SaveKeys(gConf *grantedConfig.Config, ansmap map[string]interface{}) error
- func Sync(r *Registry, awsConfigFile *ini.File, opts syncOpts) error
- func SyncProfileRegistries(shouldSilentLog bool, promptUserIfProfileDuplication bool, ...) error
- type ConfigTemplateVariables
- type Registry
- type SyncError
Constants ¶
const AUTO_GENERATED_MSG string = `` /* 414-byte string literal not displayed */
const (
// permission for user to read/write/execute.
USER_READ_WRITE_PERM = 0700
)
Variables ¶
var AddCommand = cli.Command{ Name: "add", Description: "Add a Profile Registry that you want to sync with aws config file", Usage: "Provide git repository you want to sync with aws config file", Flags: []cli.Flag{ &cli.StringFlag{Name: "name", Required: true, Usage: "name is used to uniquely identify profile registries", Aliases: []string{"n"}}, &cli.StringFlag{Name: "url", Required: true, Usage: "git url for the remote repository", Aliases: []string{"u"}}, &cli.StringFlag{Name: "path", Usage: "provide path if only the subfolder needs to be synced", Aliases: []string{"p"}}, &cli.StringFlag{Name: "filename", Aliases: []string{"f"}, Usage: "provide filename if yml file is not granted.yml", DefaultText: "granted.yml"}, &cli.IntFlag{Name: "priority", Usage: "profile registry will be sorted by priority descending", Value: 0}, &cli.StringFlag{Name: "ref", Hidden: true}, &cli.BoolFlag{Name: "prefix-all-profiles", Aliases: []string{"pap"}, Usage: "provide this flag if you want to append registry name to all profiles"}, &cli.BoolFlag{Name: "prefix-duplicate-profiles", Aliases: []string{"pdp"}, Usage: "provide this flag if you want to append registry name to duplicate profiles"}, &cli.StringSliceFlag{Name: "required-key", Aliases: []string{"r", "requiredKey"}, Usage: "used to bypass the prompt or override user specific values"}}, ArgsUsage: "--name <registry_name> --url <repository_url>", Action: func(c *cli.Context) error { gConf, err := grantedConfig.Load() if err != nil { return err } name := c.String("name") gitURL := c.String("url") pathFlag := c.String("path") configFileName := c.String("filename") ref := c.String("ref") prefixAllProfiles := c.Bool("prefix-all-profiles") prefixDuplicateProfiles := c.Bool("prefix-duplicate-profiles") requiredKey := c.StringSlice("required-key") priority := c.Int("priority") for _, r := range gConf.ProfileRegistry.Registries { if r.Name == name { clio.Errorf("profile registry with name '%s' already exists. Name is required to be unique. Try adding with different name.\n", name) return nil } } registry := NewProfileRegistry(registryOptions{ name: name, path: pathFlag, configFileName: configFileName, url: gitURL, ref: ref, priority: priority, prefixAllProfiles: prefixAllProfiles, prefixDuplicateProfiles: prefixDuplicateProfiles, }) repoDirPath, err := getRegistryLocation(registry.Config) if err != nil { return err } if _, err = os.Stat(repoDirPath); err != nil { err = gitClone(gitURL, repoDirPath) if err != nil { return err } } else { err = gitPull(repoDirPath, false) if err != nil { return err } } err = registry.Parse() if err != nil { return err } err = registry.PromptRequiredKeys(requiredKey, false) if err != nil { return err } awsConfigPath, err := getDefaultAWSConfigLocation() if err != nil { return err } if _, err := os.Stat(awsConfigPath); os.IsNotExist(err) { clio.Debugf("%s file does not exist. Creating an empty file\n", awsConfigPath) err := os.MkdirAll(path.Dir(awsConfigPath), USER_READ_WRITE_PERM) if err != nil { return err } _, err = os.Create(awsConfigPath) if err != nil { return fmt.Errorf("unable to create : %s", err) } } isFirstSection := false allRegistries, err := GetProfileRegistries() if err != nil { return err } if len(allRegistries) == 0 { isFirstSection = true } awsConfigFile, filepath, err := loadAWSConfigFile() if err != nil { return err } if err := Sync(®istry, awsConfigFile, syncOpts{ isFirstSection: isFirstSection, promptUserIfProfileDuplication: true, shouldSilentLog: false, shouldFailForRequiredKeys: false, }); err != nil { return err } gConf, err = grantedConfig.Load() if err != nil { return err } gConf.ProfileRegistry.Registries = append(gConf.ProfileRegistry.Registries, registry.Config) err = gConf.Save() if err != nil { return err } if priority > 0 { allRegistries, err = GetProfileRegistries() if err != nil { return err } if len(allRegistries) > 1 { var currentHighest int = 0 if allRegistries[1].Config.Priority != nil { currentHighest = *allRegistries[1].Config.Priority } if currentHighest < priority { err = removeAutogeneratedProfiles(awsConfigFile, filepath) if err != nil { return err } clio.Debugf("New Registry has higher priority, resyncing all registries in new order...") err = SyncProfileRegistries(false, false, false) if err != nil { return err } return nil } } } err = awsConfigFile.SaveTo(filepath) if err != nil { return err } return nil }, }
var MigrateCommand = cli.Command{ Name: "migrate", Description: "Migrate Profile Registry Configuration", Usage: "Migrate Profile Registry Configuration", Action: func(c *cli.Context) error { gConf, err := grantedConfig.Load() if err != nil { clio.Debug(err.Error()) } if len(gConf.ProfileRegistryURLS) > 0 { var registries []grantedConfig.Registry for i, u := range gConf.ProfileRegistryURLS { var msg survey.Input if i > 0 { msg = survey.Input{Message: fmt.Sprintf("Enter a registry name for %s", u), Default: fmt.Sprintf("granted-registry-%d", i)} } else { msg = survey.Input{Message: fmt.Sprintf("Enter a registry name for %s", u), Default: "granted-registry"} } var selected string err := testable.AskOne(&msg, &selected) if err != nil { return err } registries = append(registries, grantedConfig.Registry{ Name: selected, URL: u, }) } gConf.ProfileRegistry.Registries = registries gConf.ProfileRegistryURLS = nil err = gConf.Save() if err != nil { clio.Debug(err.Error()) return err } clio.Success("Successfully migrated your configuration.") return nil } clio.Infof("Your Profile Registry already has the latest configuration. No action required.") return nil }, }
Profile Registry data structure has been updated to accomodate different registry level options. If any user is using the previous configuration then prompt user to update the registry values.
var ProfileRegistryCommand = cli.Command{ Name: "registry", Usage: "Manage Profile Registries", Description: "Profile Registries allow you to easily share AWS profile configuration in a team.", Subcommands: []*cli.Command{&AddCommand, &SyncCommand, &RemoveCommand, &MigrateCommand, &SetupCommand}, Action: func(c *cli.Context) error { registries, err := GetProfileRegistries() if err != nil { return err } if len(registries) == 0 { clio.Warn("You haven't connected any Profile Registries yet.") clio.Info("Connect to a Profile Registry by running 'granted registry add -n <registry_name> -u <your_repo>'") return nil } clio.Info("Granted is currently synced with following registries:") for i, r := range registries { clio.Logf("\t %d: %s with name '%s'", (i + 1), r.Config.URL, r.Config.Name) } clio.NewLine() clio.Info("To add new registry use 'granted registry add <your_repo>'") clio.Info("To remove a registry use 'granted registry remove' and select from the options") clio.Info("To sync a registry use 'granted registry sync'") return nil }, }
var RemoveCommand = cli.Command{ Name: "remove", Description: "Unsubscribe from a Profile Registry", Usage: "Unsubscribe from a Profile Registry", Action: func(c *cli.Context) error { gConf, err := grantedConfig.Load() if err != nil { return err } if len(gConf.ProfileRegistry.Registries) == 0 { clio.Error("There are no profile registries configured currently.\n Please use 'granted registry add <https://github.com/your-org/your-registry.git>' to add a new registry") return nil } registriesWithNames := []string{} for _, r := range gConf.ProfileRegistry.Registries { registriesWithNames = append(registriesWithNames, r.Name) } in := survey.Select{Message: "Please select the git repository you would like to unsubscribe:", Options: registriesWithNames} var out string err = testable.AskOne(&in, &out) if err != nil { return err } var selectedRegistry grantedConfig.Registry for _, r := range gConf.ProfileRegistry.Registries { if r.Name == out { selectedRegistry = r } } repoDir, err := getRegistryLocation(selectedRegistry) if err != nil { return err } err = removeAutogeneratedProfileByName(out) if err != nil { return err } err = os.RemoveAll(repoDir) if err != nil { return err } err = remove(gConf, out) if err != nil { return err } err = gConf.Save() if err != nil { return err } clio.Successf("Successfully unsubscribed from %s", out) return nil }, }
var SetupCommand = cli.Command{ Name: "setup", Usage: "Setup a Profile Registry repository", Description: "Setup a granted registry repository", Subcommands: []*cli.Command{}, Flags: []cli.Flag{&cli.PathFlag{Name: "dir", Aliases: []string{"d"}, Usage: "Directory to setup the Profile Registry", Value: "granted-registry"}}, Action: func(c *cli.Context) error { dir := c.Path("dir") err := ensureConfigDoesntExist(c, dir) if err != nil { return err } err = os.Mkdir(dir, 0755) if err != nil { return err } configFile, _, err := loadAWSConfigFile() if err != nil { return err } var confirm bool s := &survey.Confirm{ Message: "Are you sure you want to copy all of the profiles from your AWS config file?", Default: true, } err = survey.AskOne(s, &confirm) if err != nil { return err } if !confirm { clio.Info("Cancelled registry setup") return nil } err = configFile.SaveTo(path.Join(dir, "config")) if err != nil { return err } f, err := os.Create(path.Join(dir, "granted.yml")) if err != nil { return err } defer f.Close() err = gitInit(dir) if err != nil { return err } _, err = f.WriteString(`awsConfig: - ./config`) if err != nil { return err } clio.Infof("Successfully created valid profile registry 'granted-registry' in %s.", dir) clio.Info("Now push this repository to remote origin so that your team-members can sync to it.") return nil }, }
var SyncCommand = cli.Command{ Name: "sync", Usage: "Pull the latest change from remote origin and sync aws profiles in aws config files", Description: "Pull the latest change from remote origin and sync aws profiles in aws config files", Action: func(c *cli.Context) error { if err := SyncProfileRegistries(false, true, false); err != nil { return err } return nil }, }
Functions ¶
func CheckoutRef ¶
set the path of the repo before checking out if a specific ref is passed we will checkout that ref can be a git hash, tag, or branch name. In that order
func IsOutdatedConfig ¶ added in v0.6.0
func IsOutdatedConfig() bool
func SaveKey ¶ added in v0.6.0
func SaveKey(gConf *grantedConfig.Config, key string, value string) error
This is used when user passed the required value through flag.
func SaveKeys ¶ added in v0.6.0
func SaveKeys(gConf *grantedConfig.Config, ansmap map[string]interface{}) error
This is used when user enters the required key through cli prompts.
func Sync ¶
Sync function will load all the configs provided in the clonedFile. and generated a new section in the ~/.aws/profile file.
func SyncProfileRegistries ¶
func SyncProfileRegistries(shouldSilentLog bool, promptUserIfProfileDuplication bool, shouldFailForRequiredKeys bool) error
Wrapper around sync func. Check if profile registry is configured, pull the latest changes and call sync func. promptUserIfProfileDuplication if true will automatically prefix the duplicate profiles and won't prompt users this is useful when new registry with higher priority is added and there is duplication with lower priority registry.
Types ¶
type ConfigTemplateVariables ¶ added in v0.6.0
type Registry ¶
type Registry struct { Config grantedConfig.Registry AwsConfigPaths []string `yaml:"awsConfig"` TemplateValues []map[string][]map[string]string `yaml:"templateValues"` }
func GetProfileRegistries ¶ added in v0.6.0
func NewProfileRegistry ¶ added in v0.6.0
func NewProfileRegistry(rOpts registryOptions) Registry