diff --git a/tool/tctl/common/plugin/awsic.go b/tool/tctl/common/plugin/awsic.go index 17de71389555e..bb9d16e797dbb 100644 --- a/tool/tctl/common/plugin/awsic.go +++ b/tool/tctl/common/plugin/awsic.go @@ -35,22 +35,30 @@ import ( icutils "github.com/gravitational/teleport/lib/utils/aws/identitycenterutils" ) -type awsICArgs struct { - cmd *kingpin.CmdClause - defaultOwners []string - scimToken string - scimURL *url.URL - forceSCIMURL bool - region string - arn string - useSystemCredentials bool - assumeRoleARN string - userOrigins []string - userLabels []string - groupNameFilters []string - accountNameFilters []string - accountIDFilters []string +const ( + defaultAWSICPluginName = apicommon.OriginAWSIdentityCenter + awsicPluginNameFlag = "plugin-name" + awsicPluginNameHelp = "Name of the AWS Identity Center integration instance to update. Defaults to " + apicommon.OriginAWSIdentityCenter + "." + awsicRolesSyncModeFlag = "roles-sync-mode" + awsicRolesSyncModeHelp = "Control account-assignment role creation. ALL creates roles for all possible account assignments. NONE creates no roles, and also implies a totally-exclusive group import filter." +) +type awsICArgs struct { + cmd *kingpin.CmdClause + defaultOwners []string + scimToken string + scimURL *url.URL + forceSCIMURL bool + region string + arn string + useSystemCredentials bool + assumeRoleARN string + userOrigins []string + userLabels []string + groupNameFilters []string + accountNameFilters []string + accountIDFilters []string + rolesSyncMode string excludeGroupNameFilters []string excludeAccountNameFilters []string excludeAccountIDFilters []string @@ -226,6 +234,10 @@ func (p *PluginsCommand) initInstallAWSIC(parent *kingpin.CmdClause) { StringsVar(&p.install.awsIC.excludeAccountNameFilters) cmd.Flag("exclude-account-id", "Exclude AWS account from import list by ID."). StringsVar(&p.install.awsIC.excludeAccountIDFilters) + + cmd.Flag("roles-sync-mode", "Control account-assignment role creation. ALL creates Teleport Roles for all possible account assignments. NONE creates no Teleport Roles, and also implies a totally-exclusive group import filter."). + Default(types.AWSICRolesSyncModeAll). + EnumVar(&p.install.awsIC.rolesSyncMode, types.AWSICRolesSyncModeAll, types.AWSICRolesSyncModeNone) } // InstallAWSIC installs AWS Identity Center plugin. @@ -245,6 +257,15 @@ func (p *PluginsCommand) InstallAWSIC(ctx context.Context, args installPluginArg return trace.Wrap(err) } + if awsICArgs.rolesSyncMode == types.AWSICRolesSyncModeNone { + if len(groupFilters) != 0 { + return trace.BadParameter("specifying group import filers is incompatible with --roles-sync-mode NONE") + } + groupFilters = append(groupFilters, &types.AWSICResourceFilter{ + Exclude: &types.AWSICResourceFilter_ExcludeNameRegex{ExcludeNameRegex: "*"}, + }) + } + accountFilters, err := awsICArgs.parseAccountFilters() if err != nil { return trace.Wrap(err) @@ -260,6 +281,7 @@ func (p *PluginsCommand) InstallAWSIC(ctx context.Context, args installPluginArg UserSyncFilters: userFilters, GroupSyncFilters: groupFilters, AwsAccountsFilters: accountFilters, + RolesSyncMode: awsICArgs.rolesSyncMode, } if awsICArgs.useSystemCredentials { @@ -315,3 +337,48 @@ func (p *PluginsCommand) InstallAWSIC(ctx context.Context, args installPluginArg return nil } + +type awsICEditArgs struct { + cmd *kingpin.CmdClause + pluginName string + rolesSyncMode string +} + +func (p *PluginsCommand) initEditAWSIC(parent *kingpin.CmdClause) { + p.edit.awsIC.cmd = parent.Command("awsic", "Edit an AWS IAM Identity Center integration's settings.") + cmd := p.edit.awsIC.cmd + + cmd.Flag(awsicPluginNameFlag, awsicPluginNameHelp). + Default(defaultAWSICPluginName). + StringVar(&p.edit.awsIC.pluginName) + + cmd.Flag(awsicRolesSyncModeFlag, awsicRolesSyncModeHelp). + EnumVar(&p.edit.awsIC.rolesSyncMode, types.AWSICRolesSyncModeAll, types.AWSICRolesSyncModeNone) +} + +func (p *PluginsCommand) EditAWSIC(ctx context.Context, args installPluginArgs) error { + plugin, err := args.plugins.GetPlugin(ctx, &pluginspb.GetPluginRequest{ + Name: p.edit.awsIC.pluginName, + }) + if err != nil { + return trace.Wrap(err) + } + + icSettings := plugin.Spec.GetAwsIc() + if icSettings == nil { + return trace.BadParameter("%q is not an AWS Identity Center integration", p.edit.awsIC.pluginName) + } + + cliArgs := &p.edit.awsIC + if cliArgs.rolesSyncMode != "" { + icSettings.RolesSyncMode = cliArgs.rolesSyncMode + } + + _, err = args.plugins.UpdatePlugin(ctx, &pluginspb.UpdatePluginRequest{ + Plugin: plugin, + }) + if err != nil { + return trace.Wrap(err) + } + return nil +} diff --git a/tool/tctl/common/plugin/plugins_command.go b/tool/tctl/common/plugin/plugins_command.go index 15a49a8a55c15..f458f0a049422 100644 --- a/tool/tctl/common/plugin/plugins_command.go +++ b/tool/tctl/common/plugin/plugins_command.go @@ -52,6 +52,11 @@ type pluginInstallArgs struct { awsIC awsICArgs } +type pluginEditArgs struct { + cmd *kingpin.CmdClause + awsIC awsICEditArgs +} + type scimArgs struct { cmd *kingpin.CmdClause connector string @@ -72,6 +77,7 @@ type PluginsCommand struct { dryRun bool install pluginInstallArgs delete pluginDeleteArgs + edit pluginEditArgs } // Initialize creates the plugins command and subcommands @@ -87,6 +93,7 @@ func (p *PluginsCommand) Initialize(app *kingpin.Application, _ *tctlcfg.GlobalC p.initInstall(pluginsCommand, config) p.initDelete(pluginsCommand) + p.initEdit(pluginsCommand) } func (p *PluginsCommand) initInstall(parent *kingpin.CmdClause, config *servicecfg.Config) { @@ -106,6 +113,11 @@ func (p *PluginsCommand) initDelete(parent *kingpin.CmdClause) { StringVar(&p.delete.name) } +func (p *PluginsCommand) initEdit(parent *kingpin.CmdClause) { + p.edit.cmd = parent.Command("edit", "Edits a plugin's or an integration's settings") + p.initEditAWSIC(p.edit.cmd) +} + // Delete implements `tctl plugins delete`, deleting a plugin from the Teleport cluster func (p *PluginsCommand) Delete(ctx context.Context, args installPluginArgs) error { log := p.config.Logger.With("plugin", p.delete.name) @@ -211,6 +223,8 @@ func (p *PluginsCommand) TryRun(ctx context.Context, cmd string, clientFunc comm commandFunc = p.InstallAWSIC case p.delete.cmd.FullCommand(): commandFunc = p.Delete + case p.edit.awsIC.cmd.FullCommand(): + commandFunc = p.EditAWSIC default: return false, nil }