diff --git a/cmd/iam_access_key.go b/cmd/iam_access_key.go deleted file mode 100644 index e26d9166..00000000 --- a/cmd/iam_access_key.go +++ /dev/null @@ -1,47 +0,0 @@ -package cmd - -import ( - "fmt" - "strings" - - "github.com/spf13/cobra" - - egoscale "github.com/exoscale/egoscale/v2" -) - -var iamAccessKeyCmd = &cobra.Command{ - Use: "access-key", - Aliases: []string{"key"}, - Short: "IAM access keys management", -} - -// parseIAMAccessKeyResource parses a string-encoded IAM access key resource formatted such as -// DOMAIN/TYPE:NAME and deserializes it into an egoscale.IAMAccessKeyResource struct. -func parseIAMAccessKeyResource(v string) (*egoscale.IAMAccessKeyResource, error) { - var iamAccessKeyResource egoscale.IAMAccessKeyResource - - parts := strings.SplitN(v, ":", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid format") - } - iamAccessKeyResource.ResourceName = parts[1] - - parts = strings.SplitN(parts[0], "/", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid format") - } - iamAccessKeyResource.Domain = parts[0] - iamAccessKeyResource.ResourceType = parts[1] - - if iamAccessKeyResource.Domain == "" || - iamAccessKeyResource.ResourceType == "" || - iamAccessKeyResource.ResourceName == "" { - return nil, fmt.Errorf("invalid format") - } - - return &iamAccessKeyResource, nil -} - -func init() { - iamCmd.AddCommand(iamAccessKeyCmd) -} diff --git a/cmd/iam_access_key_create.go b/cmd/iam_access_key_create.go deleted file mode 100644 index 4df1197a..00000000 --- a/cmd/iam_access_key_create.go +++ /dev/null @@ -1,107 +0,0 @@ -package cmd - -import ( - "fmt" - "strings" - - "github.com/spf13/cobra" - - "github.com/exoscale/cli/pkg/account" - "github.com/exoscale/cli/pkg/globalstate" - "github.com/exoscale/cli/pkg/output" - egoscale "github.com/exoscale/egoscale/v2" - exoapi "github.com/exoscale/egoscale/v2/api" -) - -type iamAccessKeyCreateCmd struct { - cliCommandSettings `cli-cmd:"-"` - - _ bool `cli-cmd:"create"` - - Name string `cli-arg:"#"` - - Operations []string `cli-flag:"operation" cli-usage:"API operation to restrict the access key to. Can be repeated multiple times."` - Resources []string `cli-flag:"resource" cli-usage:"API resource to restrict the access key to (format: DOMAIN/TYPE:NAME). Can be repeated multiple times."` - Tags []string `cli-flag:"tag" cli-usage:"API operations tag to restrict the access key to. Can be repeated multiple times."` -} - -func (c *iamAccessKeyCreateCmd) cmdAliases() []string { return gCreateAlias } - -func (c *iamAccessKeyCreateCmd) cmdShort() string { - return "Create an IAM access key" -} - -func (c *iamAccessKeyCreateCmd) cmdLong() string { - return fmt.Sprintf(`This command creates an IAM access key. - -Supported output template annotations: %s`, - strings.Join(output.TemplateAnnotations(&iamAccessKeyShowOutput{}), ", ")) -} - -func (c *iamAccessKeyCreateCmd) cmdPreRun(cmd *cobra.Command, args []string) error { - return cliCommandDefaultPreRun(c, cmd, args) -} - -func (c *iamAccessKeyCreateCmd) cmdRun(_ *cobra.Command, _ []string) error { - zone := account.CurrentAccount.DefaultZone - - ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, zone)) - - opts := make([]egoscale.CreateIAMAccessKeyOpt, 0) - - if len(c.Operations) > 0 { - opts = append(opts, egoscale.CreateIAMAccessKeyWithOperations(c.Operations)) - } - - if len(c.Resources) > 0 { - resources := make([]egoscale.IAMAccessKeyResource, len(c.Resources)) - for i, rs := range c.Resources { - r, err := parseIAMAccessKeyResource(rs) - if err != nil { - return fmt.Errorf("invalid API resource %q", rs) - } - resources[i] = *r - } - opts = append(opts, egoscale.CreateIAMAccessKeyWithResources(resources)) - } - - if len(c.Tags) > 0 { - opts = append(opts, egoscale.CreateIAMAccessKeyWithTags(c.Tags)) - } - - iamAccessKey, err := globalstate.EgoscaleClient.CreateIAMAccessKey(ctx, zone, c.Name, opts...) - if err != nil { - return fmt.Errorf("unable to create a new IAM access key: %w", err) - } - - out := iamAccessKeyShowOutput{ - Name: *iamAccessKey.Name, - APIKey: *iamAccessKey.Key, - APISecret: iamAccessKey.Secret, - Operations: iamAccessKey.Operations, - Resources: func() *[]string { - if iamAccessKey.Resources != nil { - list := make([]string, len(*iamAccessKey.Resources)) - for i, r := range *iamAccessKey.Resources { - list[i] = fmt.Sprintf("%s/%s:%s", r.Domain, r.ResourceType, r.ResourceName) - } - return &list - } - return nil - }(), - Tags: iamAccessKey.Tags, - Type: *iamAccessKey.Type, - } - - if !globalstate.Quiet { - return c.outputFunc(&out, nil) - } - - return nil -} - -func init() { - cobra.CheckErr(registerCLICommand(iamAccessKeyCmd, &iamAccessKeyCreateCmd{ - cliCommandSettings: defaultCLICmdSettings(), - })) -} diff --git a/cmd/iam_access_key_list.go b/cmd/iam_access_key_list.go deleted file mode 100644 index 626f4842..00000000 --- a/cmd/iam_access_key_list.go +++ /dev/null @@ -1,75 +0,0 @@ -package cmd - -import ( - "fmt" - "strings" - - "github.com/spf13/cobra" - - "github.com/exoscale/cli/pkg/account" - "github.com/exoscale/cli/pkg/globalstate" - "github.com/exoscale/cli/pkg/output" - exoapi "github.com/exoscale/egoscale/v2/api" -) - -type iamAccessKeyListItemOutput struct { - Key string `json:"key"` - Name string `json:"name"` - Type string `json:"type"` -} - -type iamAccessKeyListOutput []iamAccessKeyListItemOutput - -func (o *iamAccessKeyListOutput) ToJSON() { output.JSON(o) } -func (o *iamAccessKeyListOutput) ToText() { output.Text(o) } -func (o *iamAccessKeyListOutput) ToTable() { output.Table(o) } - -type iamAccessKeyListCmd struct { - cliCommandSettings `cli-cmd:"-"` - - _ bool `cli-cmd:"list"` -} - -func (c *iamAccessKeyListCmd) cmdAliases() []string { return gListAlias } - -func (c *iamAccessKeyListCmd) cmdShort() string { return "List IAM access keys" } - -func (c *iamAccessKeyListCmd) cmdLong() string { - return fmt.Sprintf(`This command lists existing IAM access keys. - -Supported output template annotations: %s`, - strings.Join(output.TemplateAnnotations(&iamAccessKeyListOutput{}), ", ")) -} - -func (c *iamAccessKeyListCmd) cmdPreRun(cmd *cobra.Command, args []string) error { - return cliCommandDefaultPreRun(c, cmd, args) -} - -func (c *iamAccessKeyListCmd) cmdRun(_ *cobra.Command, _ []string) error { - zone := account.CurrentAccount.DefaultZone - - ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, zone)) - - iamAccessKeys, err := globalstate.EgoscaleClient.ListIAMAccessKeys(ctx, zone) - if err != nil { - return err - } - - out := make(iamAccessKeyListOutput, 0) - - for _, k := range iamAccessKeys { - out = append(out, iamAccessKeyListItemOutput{ - Name: *k.Name, - Key: *k.Key, - Type: *k.Type, - }) - } - - return c.outputFunc(&out, err) -} - -func init() { - cobra.CheckErr(registerCLICommand(iamAccessKeyCmd, &iamAccessKeyListCmd{ - cliCommandSettings: defaultCLICmdSettings(), - })) -} diff --git a/cmd/iam_access_key_listoperations.go b/cmd/iam_access_key_listoperations.go deleted file mode 100644 index f597ec68..00000000 --- a/cmd/iam_access_key_listoperations.go +++ /dev/null @@ -1,116 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "sort" - "strings" - - "github.com/spf13/cobra" - - "github.com/exoscale/cli/pkg/account" - "github.com/exoscale/cli/pkg/globalstate" - "github.com/exoscale/cli/pkg/output" - "github.com/exoscale/cli/table" - egoscale "github.com/exoscale/egoscale/v2" - exoapi "github.com/exoscale/egoscale/v2/api" -) - -type iamAccessKeyListOperationsItemOutput struct { - Operation string `json:"operation"` - Tags []string `json:"tags"` -} - -type iamAccessKeyListOperationsOutput []iamAccessKeyListOperationsItemOutput - -func (o *iamAccessKeyListOperationsOutput) ToJSON() { output.JSON(o) } -func (o *iamAccessKeyListOperationsOutput) ToText() { output.Text(o) } -func (o *iamAccessKeyListOperationsOutput) ToTable() { - operationByTag := make(map[string][]string) - - for _, op := range *o { - for _, tag := range op.Tags { - if _, ok := operationByTag[tag]; !ok { - operationByTag[tag] = make([]string, 0) - } - operationByTag[tag] = append(operationByTag[tag], op.Operation) - } - } - - t := table.NewTable(os.Stdout) - defer t.Render() - - t.SetHeader([]string{"Tag", "Operations"}) - - sortedTags := make([]string, 0) - for tag := range operationByTag { - sortedTags = append(sortedTags, tag) - } - sort.Strings(sortedTags) - - for _, tag := range sortedTags { - operations := operationByTag[tag] - sort.Strings(operations) - t.Append([]string{tag, strings.Join(operations, "\n")}) - } -} - -type iamAccessKeyListOperationsCmd struct { - cliCommandSettings `cli-cmd:"-"` - - _ bool `cli-cmd:"list-operations"` - - Mine bool `cli-usage:"only report operations available to the IAM access key used to perform the API request"` -} - -func (c *iamAccessKeyListOperationsCmd) cmdAliases() []string { return gListAlias } - -func (c *iamAccessKeyListOperationsCmd) cmdShort() string { return "List IAM access keys operations" } - -func (c *iamAccessKeyListOperationsCmd) cmdLong() string { - return fmt.Sprintf(`This command lists operations available to IAM access keys. - -Supported output template annotations: %s`, - strings.Join(output.TemplateAnnotations(&iamAccessKeyListOperationsOutput{}), ", ")) -} - -func (c *iamAccessKeyListOperationsCmd) cmdPreRun(cmd *cobra.Command, args []string) error { - return cliCommandDefaultPreRun(c, cmd, args) -} - -func (c *iamAccessKeyListOperationsCmd) cmdRun(_ *cobra.Command, _ []string) error { - var ( - iamAccessKeyOperations []*egoscale.IAMAccessKeyOperation - err error - ) - - zone := account.CurrentAccount.DefaultZone - - ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, zone)) - - if c.Mine { - iamAccessKeyOperations, err = globalstate.EgoscaleClient.ListMyIAMAccessKeyOperations(ctx, zone) - } else { - iamAccessKeyOperations, err = globalstate.EgoscaleClient.ListIAMAccessKeyOperations(ctx, zone) - } - if err != nil { - return err - } - - out := make(iamAccessKeyListOperationsOutput, 0) - - for _, o := range iamAccessKeyOperations { - out = append(out, iamAccessKeyListOperationsItemOutput{ - Operation: o.Name, - Tags: o.Tags, - }) - } - - return c.outputFunc(&out, err) -} - -func init() { - cobra.CheckErr(registerCLICommand(iamAccessKeyCmd, &iamAccessKeyListOperationsCmd{ - cliCommandSettings: defaultCLICmdSettings(), - })) -} diff --git a/cmd/iam_access_key_revoke.go b/cmd/iam_access_key_revoke.go deleted file mode 100644 index c01a66d4..00000000 --- a/cmd/iam_access_key_revoke.go +++ /dev/null @@ -1,62 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/exoscale/cli/pkg/account" - "github.com/exoscale/cli/pkg/globalstate" - egoscale "github.com/exoscale/egoscale/v2" - exoapi "github.com/exoscale/egoscale/v2/api" -) - -type iamAccessKeyRevokeCmd struct { - cliCommandSettings `cli-cmd:"-"` - - _ bool `cli-cmd:"revoke"` - - APIKey string `cli-arg:"#"` - - Force bool `cli-short:"f" cli-usage:"don't prompt for confirmation"` -} - -func (c *iamAccessKeyRevokeCmd) cmdAliases() []string { return gCreateAlias } - -func (c *iamAccessKeyRevokeCmd) cmdShort() string { - return "Revoke an IAM access key" -} - -func (c *iamAccessKeyRevokeCmd) cmdLong() string { return "" } - -func (c *iamAccessKeyRevokeCmd) cmdPreRun(cmd *cobra.Command, args []string) error { - return cliCommandDefaultPreRun(c, cmd, args) -} - -func (c *iamAccessKeyRevokeCmd) cmdRun(_ *cobra.Command, _ []string) error { - zone := account.CurrentAccount.DefaultZone - - ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, zone)) - - if !c.Force { - if !askQuestion(fmt.Sprintf("Are you sure you want to revoke IAM access key IP %s?", c.APIKey)) { - return nil - } - } - - var err error - decorateAsyncOperation(fmt.Sprintf("Revoking IAM access key %s...", c.APIKey), func() { - err = globalstate.EgoscaleClient.RevokeIAMAccessKey(ctx, zone, &egoscale.IAMAccessKey{Key: &c.APIKey}) - }) - if err != nil { - return err - } - - return nil -} - -func init() { - cobra.CheckErr(registerCLICommand(iamAccessKeyCmd, &iamAccessKeyRevokeCmd{ - cliCommandSettings: defaultCLICmdSettings(), - })) -} diff --git a/cmd/iam_access_key_show.go b/cmd/iam_access_key_show.go deleted file mode 100644 index cf1f7652..00000000 --- a/cmd/iam_access_key_show.go +++ /dev/null @@ -1,122 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "strings" - - "github.com/spf13/cobra" - - "github.com/exoscale/cli/pkg/account" - "github.com/exoscale/cli/pkg/globalstate" - "github.com/exoscale/cli/pkg/output" - "github.com/exoscale/cli/table" - "github.com/exoscale/cli/utils" - exoapi "github.com/exoscale/egoscale/v2/api" -) - -type iamAccessKeyShowOutput struct { - Name string `json:"name"` - Type string `json:"type"` - APIKey string `json:"api_key"` - APISecret *string `json:"api_secret,omitempty"` - Operations *[]string `json:"operations,omitempty"` - Tags *[]string `json:"tags,omitempty"` - Resources *[]string `json:"resources,omitempty"` -} - -func (o *iamAccessKeyShowOutput) ToJSON() { output.JSON(o) } -func (o *iamAccessKeyShowOutput) ToText() { output.Text(o) } -func (o *iamAccessKeyShowOutput) ToTable() { - if o.APISecret != nil { - defer fmt.Fprint(os.Stderr, ` -/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ -/!\ Ensure to save your API Secret somewhere, /!\ -/!\ as there is no way to recover it afterwards /!\ -/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ -`) - } - - t := table.NewTable(os.Stdout) - t.SetHeader([]string{"IAM Access Key"}) - defer t.Render() - - t.Append([]string{"Name", o.Name}) - t.Append([]string{"Type", o.Type}) - t.Append([]string{"API Key", o.APIKey}) - t.Append([]string{"API Secret", utils.DefaultString(o.APISecret, strings.Repeat("*", 43))}) - - if o.Operations != nil { - t.Append([]string{"Operations", strings.Join(*o.Operations, "\n")}) - } - - if o.Tags != nil { - t.Append([]string{"Tags", strings.Join(*o.Tags, "\n")}) - } - - if o.Resources != nil { - t.Append([]string{"Resources", strings.Join(*o.Resources, "\n")}) - } -} - -type iamAccessKeyShowCmd struct { - cliCommandSettings `cli-cmd:"-"` - - _ bool `cli-cmd:"show"` - - APIKey string `cli-arg:"#" cli-usage:"API-KEY"` -} - -func (c *iamAccessKeyShowCmd) cmdAliases() []string { return gShowAlias } - -func (c *iamAccessKeyShowCmd) cmdShort() string { - return "Show an IAM access key details" -} - -func (c *iamAccessKeyShowCmd) cmdLong() string { - return fmt.Sprintf(`This command shows an IAM access key details. - -Supported output template annotations: %s`, - strings.Join(output.TemplateAnnotations(&iamAccessKeyShowOutput{}), ", ")) -} - -func (c *iamAccessKeyShowCmd) cmdPreRun(cmd *cobra.Command, args []string) error { - return cliCommandDefaultPreRun(c, cmd, args) -} - -func (c *iamAccessKeyShowCmd) cmdRun(_ *cobra.Command, _ []string) error { - zone := account.CurrentAccount.DefaultZone - - ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, zone)) - - iamAccessKey, err := globalstate.EgoscaleClient.GetIAMAccessKey(ctx, zone, c.APIKey) - if err != nil { - return err - } - - out := iamAccessKeyShowOutput{ - Name: *iamAccessKey.Name, - APIKey: *iamAccessKey.Key, - Operations: iamAccessKey.Operations, - Resources: func() *[]string { - if iamAccessKey.Resources != nil { - list := make([]string, len(*iamAccessKey.Resources)) - for i, r := range *iamAccessKey.Resources { - list[i] = fmt.Sprintf("%s/%s:%s", r.Domain, r.ResourceType, r.ResourceName) - } - return &list - } - return nil - }(), - Tags: iamAccessKey.Tags, - Type: *iamAccessKey.Type, - } - - return c.outputFunc(&out, nil) -} - -func init() { - cobra.CheckErr(registerCLICommand(iamAccessKeyCmd, &iamAccessKeyShowCmd{ - cliCommandSettings: defaultCLICmdSettings(), - })) -}