Documentation ¶
Index ¶
Constants ¶
View Source
const (
SyncTempDirPrefix = "granted-registry-sync"
)
View Source
const (
// permission for user to read/write/execute.
USER_READ_WRITE_PERM = 0700
)
Variables ¶
View Source
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: "A unique name for the profile registry", Aliases: []string{"n"}}, &cli.StringFlag{Name: "url", Required: true, Usage: "The URL for the registry", Aliases: []string{"u"}}, &cli.StringFlag{Name: "path", Usage: "For git registries: provide path if only the subfolder needs to be synced", Aliases: []string{"p"}}, &cli.StringFlag{Name: "filename", Aliases: []string{"f"}, Usage: "For git registries: provide filename if yml file is not granted.yml", DefaultText: "granted.yml"}, &cli.IntFlag{Name: "priority", Usage: "The priority for the profile registry", 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.BoolFlag{Name: "write-on-sync-failure", Aliases: []string{"wosf"}, Usage: "Always overwrite AWS config, even if sync fails (DEPRECATED)"}, &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 { ctx := c.Context gConf, err := grantedConfig.Load() if err != nil { return err } if c.Bool("write-on-sync-failure") { return errors.New("'--write-on-sync-failure' has been deprecated. Please raise an issue if this has affected your workflows: https://github.com/common-fate/granted/issues/new") } 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 } } registryConfig := grantedConfig.Registry{ Name: name, URL: gitURL, Path: pathFlag, Filename: configFileName, Ref: ref, Priority: priority, PrefixDuplicateProfiles: prefixDuplicateProfiles, PrefixAllProfiles: prefixAllProfiles, } registry, err := gitregistry.New(gitregistry.Opts{ Name: name, URL: gitURL, Path: pathFlag, Filename: configFileName, RequiredKeys: requiredKey, Interactive: true, }) if err != nil { return err } src, err := registry.AWSProfiles(ctx) if err != nil { return err } dst, filepath, err := loadAWSConfigFile() if err != nil { return err } m := awsmerge.Merger{} merged, err := m.WithRegistry(src, dst, awsmerge.RegistryOpts{ Name: name, PrefixAllProfiles: prefixAllProfiles, PrefixDuplicateProfiles: prefixDuplicateProfiles, }) var dpe awsmerge.DuplicateProfileError if errors.As(err, &dpe) { clio.Warnf(err.Error()) const ( DUPLICATE = "Add registry name as prefix to all duplicate profiles for this registry" ABORT = "Abort, I will manually fix this" ) options := []string{DUPLICATE, ABORT} in := survey.Select{Message: "Please select which option would you like to choose to resolve: ", Options: options} var selected string err = testable.AskOne(&in, &selected) if err != nil { return err } if selected == ABORT { return fmt.Errorf("aborting sync for registry %s", name) } registryConfig.PrefixDuplicateProfiles = true merged, err = m.WithRegistry(src, dst, awsmerge.RegistryOpts{ Name: name, PrefixAllProfiles: prefixAllProfiles, PrefixDuplicateProfiles: true, }) if err != nil { return fmt.Errorf("error after trying to merge profiles again: %w", err) } } gConf.ProfileRegistry.Registries = append(gConf.ProfileRegistry.Registries, registryConfig) err = gConf.Save() if err != nil { return err } err = merged.SaveTo(filepath) if err != nil { return err } return nil }, }
View Source
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.
View Source
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(true) 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 }, }
View Source
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 } } reg, err := gitregistry.New(gitregistry.Opts{ Name: selectedRegistry.Name, URL: selectedRegistry.URL, Path: selectedRegistry.Path, Filename: selectedRegistry.Filename, }) if err != nil { return err } m := awsmerge.Merger{} configFile, awsConfigPath, err := loadAWSConfigFile() if err != nil { return err } m.RemoveRegistry(configFile, selectedRegistry.Name) err = configFile.SaveTo(awsConfigPath) if err != nil { return err } err = reg.Delete() 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 }, }
View Source
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(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 = git.Init(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 }, }
View Source
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(c.Context, true); err != nil { return err } return nil }, }
Functions ¶
func GetProfileRegistries ¶ added in v0.6.0
func IsOutdatedConfig ¶ added in v0.6.0
func IsOutdatedConfig() bool
func SyncProfileRegistries ¶
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 ¶
Source Files ¶
Click to show internal directories.
Click to hide internal directories.