Merge pull request #86 from ovh/dev/aamstutz/add-iam-user-cmds
Some checks failed
Build and test / build (1.24.x) (push) Has been cancelled
Build and test / build (1.25.x) (push) Has been cancelled

feat(iam): Add commands to manage local users
This commit is contained in:
Arthur Amstutz 2025-11-10 08:29:02 +01:00 committed by GitHub
commit 44bc4f7d48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 549 additions and 0 deletions

View file

@ -33,4 +33,5 @@ Manage IAM resources, permissions and policies
* [ovhcloud iam policy](ovhcloud_iam_policy.md) - Manage IAM policies
* [ovhcloud iam resource](ovhcloud_iam_resource.md) - Manage IAM resources
* [ovhcloud iam resource-group](ovhcloud_iam_resource-group.md) - Manage IAM resource groups
* [ovhcloud iam user](ovhcloud_iam_user.md) - Manage IAM users

37
doc/ovhcloud_iam_user.md Normal file
View file

@ -0,0 +1,37 @@
## ovhcloud iam user
Manage IAM users
### Options
```
-h, --help help for user
```
### Options inherited from parent commands
```
-d, --debug Activate debug mode (will log all HTTP requests details)
-f, --format string Output value according to given format (expression using https://github.com/PaesslerAG/gval syntax)
Examples:
--format 'id' (to extract a single field)
--format 'nested.field.subfield' (to extract a nested field)
--format '[id, 'name']' (to extract multiple fields as an array)
--format '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object)
--format 'name+","+type' (to extract and concatenate fields in a string)
--format '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields)
-e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution
-i, --interactive Interactive output
-j, --json Output in JSON
-y, --yaml Output in YAML
```
### SEE ALSO
* [ovhcloud iam](ovhcloud_iam.md) - Manage IAM resources, permissions and policies
* [ovhcloud iam user create](ovhcloud_iam_user_create.md) - Create a new user
* [ovhcloud iam user delete](ovhcloud_iam_user_delete.md) - Delete a specific IAM user
* [ovhcloud iam user edit](ovhcloud_iam_user_edit.md) - Edit an existing user
* [ovhcloud iam user get](ovhcloud_iam_user_get.md) - Get a specific IAM user
* [ovhcloud iam user list](ovhcloud_iam_user_list.md) - List IAM users

View file

@ -0,0 +1,86 @@
## ovhcloud iam user create
Create a new user
### Synopsis
Use this command to create a new IAM user.
There are three ways to define the creation parameters:
1. Using only CLI flags:
ovhcloud iam user create --login my_user --password 'MyStrongPassword123!' --email fake.email@ovhcloud.com
2. Using a configuration file:
First you can generate an example of parameters file using the following command:
ovhcloud iam user create --init-file ./params.json
You will be able to choose from several examples of parameters. Once an example has been selected, the content is written in the given file.
After editing the file to set the correct creation parameters, run:
ovhcloud iam user create --from-file ./params.json
Note that you can also pipe the content of the parameters file, like the following:
cat ./params.json | ovhcloud iam user create
In both cases, you can override the parameters in the given file using command line flags, for example:
ovhcloud iam user create --from-file ./params.json --login nameoverriden
3. Using your default text editor:
ovhcloud iam user create --editor
You will be able to choose from several examples of parameters. Once an example has been selected, the CLI will open your
default text editor to update the parameters. When saving the file, the creation will start.
Note that it is also possible to override values in the presented examples using command line flags like the following:
ovhcloud iam user create --editor --login nameoverriden
```
ovhcloud iam user create [flags]
```
### Options
```
--description string Description of the user
--editor Use a text editor to define parameters
--email string Email of the user
--from-file string File containing parameters
--group string Group of the user
-h, --help help for create
--init-file string Create a file with example parameters
--login string Login of the user
--password string Password of the user
--replace Replace parameters file if it already exists
--type string Type of the user (ROOT, SERVICE, USER)
```
### Options inherited from parent commands
```
-d, --debug Activate debug mode (will log all HTTP requests details)
-f, --format string Output value according to given format (expression using https://github.com/PaesslerAG/gval syntax)
Examples:
--format 'id' (to extract a single field)
--format 'nested.field.subfield' (to extract a nested field)
--format '[id, 'name']' (to extract multiple fields as an array)
--format '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object)
--format 'name+","+type' (to extract and concatenate fields in a string)
--format '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields)
-e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution
-i, --interactive Interactive output
-j, --json Output in JSON
-y, --yaml Output in YAML
```
### SEE ALSO
* [ovhcloud iam user](ovhcloud_iam_user.md) - Manage IAM users

View file

@ -0,0 +1,36 @@
## ovhcloud iam user delete
Delete a specific IAM user
```
ovhcloud iam user delete <user_login> [flags]
```
### Options
```
-h, --help help for delete
```
### Options inherited from parent commands
```
-d, --debug Activate debug mode (will log all HTTP requests details)
-f, --format string Output value according to given format (expression using https://github.com/PaesslerAG/gval syntax)
Examples:
--format 'id' (to extract a single field)
--format 'nested.field.subfield' (to extract a nested field)
--format '[id, 'name']' (to extract multiple fields as an array)
--format '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object)
--format 'name+","+type' (to extract and concatenate fields in a string)
--format '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields)
-e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution
-i, --interactive Interactive output
-j, --json Output in JSON
-y, --yaml Output in YAML
```
### SEE ALSO
* [ovhcloud iam user](ovhcloud_iam_user.md) - Manage IAM users

View file

@ -0,0 +1,83 @@
## ovhcloud iam user edit
Edit an existing user
### Synopsis
Use this command to edit an existing IAM user.
There are three ways to define the editing parameters:
1. Using only CLI flags:
ovhcloud iam user edit <user_login> --email fake.email+replaced@ovhcloud.com
2. Using a configuration file:
First you can generate an example of parameters file using the following command:
ovhcloud iam user edit --init-file ./params.json
You will be able to choose from several examples of parameters. Once an example has been selected, the content is written in the given file.
After editing the file to set the correct parameters, run:
ovhcloud iam user edit <user_login> --from-file ./params.json
Note that you can also pipe the content of the parameters file, like the following:
cat ./params.json | ovhcloud iam user edit <user_login>
In both cases, you can override the parameters in the given file using command line flags, for example:
ovhcloud iam user edit <user_login> --from-file ./params.json --email fake.email+overriden@ovhcloud.com
3. Using your default text editor:
ovhcloud iam user edit <user_login> --editor
You will be able to choose from several examples of parameters. Once an example has been selected, the CLI will open your
default text editor to update the parameters. When saving the file, the creation will start.
Note that it is also possible to override values in the presented examples using command line flags like the following:
ovhcloud iam user edit <user_login> --editor --description "New description"
```
ovhcloud iam user edit <user_login> [flags]
```
### Options
```
--description string Description of the user
--editor Use a text editor to define parameters
--email string Email of the user
--from-file string File containing parameters
--group string Group of the user
-h, --help help for edit
--init-file string Create a file with example parameters
--replace Replace parameters file if it already exists
```
### Options inherited from parent commands
```
-d, --debug Activate debug mode (will log all HTTP requests details)
-f, --format string Output value according to given format (expression using https://github.com/PaesslerAG/gval syntax)
Examples:
--format 'id' (to extract a single field)
--format 'nested.field.subfield' (to extract a nested field)
--format '[id, 'name']' (to extract multiple fields as an array)
--format '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object)
--format 'name+","+type' (to extract and concatenate fields in a string)
--format '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields)
-e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution
-i, --interactive Interactive output
-j, --json Output in JSON
-y, --yaml Output in YAML
```
### SEE ALSO
* [ovhcloud iam user](ovhcloud_iam_user.md) - Manage IAM users

View file

@ -0,0 +1,36 @@
## ovhcloud iam user get
Get a specific IAM user
```
ovhcloud iam user get <user_login> [flags]
```
### Options
```
-h, --help help for get
```
### Options inherited from parent commands
```
-d, --debug Activate debug mode (will log all HTTP requests details)
-f, --format string Output value according to given format (expression using https://github.com/PaesslerAG/gval syntax)
Examples:
--format 'id' (to extract a single field)
--format 'nested.field.subfield' (to extract a nested field)
--format '[id, 'name']' (to extract multiple fields as an array)
--format '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object)
--format 'name+","+type' (to extract and concatenate fields in a string)
--format '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields)
-e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution
-i, --interactive Interactive output
-j, --json Output in JSON
-y, --yaml Output in YAML
```
### SEE ALSO
* [ovhcloud iam user](ovhcloud_iam_user.md) - Manage IAM users

View file

@ -0,0 +1,43 @@
## ovhcloud iam user list
List IAM users
```
ovhcloud iam user list [flags]
```
### Options
```
--filter stringArray Filter results by any property using https://github.com/PaesslerAG/gval syntax
Examples:
--filter 'state="running"'
--filter 'name=~"^my.*"'
--filter 'nested.property.subproperty>10'
--filter 'startDate>="2023-12-01"'
--filter 'name=~"something" && nbField>10'
-h, --help help for list
```
### Options inherited from parent commands
```
-d, --debug Activate debug mode (will log all HTTP requests details)
-f, --format string Output value according to given format (expression using https://github.com/PaesslerAG/gval syntax)
Examples:
--format 'id' (to extract a single field)
--format 'nested.field.subfield' (to extract a nested field)
--format '[id, 'name']' (to extract multiple fields as an array)
--format '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object)
--format 'name+","+type' (to extract and concatenate fields in a string)
--format '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields)
-e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution
-i, --interactive Interactive output
-j, --json Output in JSON
-y, --yaml Output in YAML
```
### SEE ALSO
* [ovhcloud iam user](ovhcloud_iam_user.md) - Manage IAM users

View file

@ -5,6 +5,7 @@
package cmd
import (
"github.com/ovh/ovhcloud-cli/internal/assets"
"github.com/ovh/ovhcloud-cli/internal/services/iam"
"github.com/spf13/cobra"
)
@ -149,5 +150,155 @@ func init() {
addInteractiveEditorFlag(iamResourceGroupEditCmd)
iamResourceGroupCmd.AddCommand(iamResourceGroupEditCmd)
// Users
iamUserCmd := &cobra.Command{
Use: "user",
Short: "Manage IAM users",
}
iamCmd.AddCommand(iamUserCmd)
iamUserCmd.AddCommand(withFilterFlag(&cobra.Command{
Use: "list",
Aliases: []string{"ls"},
Short: "List IAM users",
Run: iam.ListUsers,
}))
iamUserCmd.AddCommand(&cobra.Command{
Use: "get <user_login>",
Short: "Get a specific IAM user",
Run: iam.GetUser,
Args: cobra.ExactArgs(1),
})
iamUserCmd.AddCommand(getUserCreateCmd())
iamUserCmd.AddCommand(getUserEditCmd())
iamUserCmd.AddCommand(&cobra.Command{
Use: "delete <user_login>",
Short: "Delete a specific IAM user",
Run: iam.DeleteUser,
Args: cobra.ExactArgs(1),
})
rootCmd.AddCommand(iamCmd)
}
func getUserCreateCmd() *cobra.Command {
userCreateCmd := &cobra.Command{
Use: "create",
Short: "Create a new user",
Long: `Use this command to create a new IAM user.
There are three ways to define the creation parameters:
1. Using only CLI flags:
ovhcloud iam user create --login my_user --password 'MyStrongPassword123!' --email fake.email@ovhcloud.com
2. Using a configuration file:
First you can generate an example of parameters file using the following command:
ovhcloud iam user create --init-file ./params.json
You will be able to choose from several examples of parameters. Once an example has been selected, the content is written in the given file.
After editing the file to set the correct creation parameters, run:
ovhcloud iam user create --from-file ./params.json
Note that you can also pipe the content of the parameters file, like the following:
cat ./params.json | ovhcloud iam user create
In both cases, you can override the parameters in the given file using command line flags, for example:
ovhcloud iam user create --from-file ./params.json --login nameoverriden
3. Using your default text editor:
ovhcloud iam user create --editor
You will be able to choose from several examples of parameters. Once an example has been selected, the CLI will open your
default text editor to update the parameters. When saving the file, the creation will start.
Note that it is also possible to override values in the presented examples using command line flags like the following:
ovhcloud iam user create --editor --login nameoverriden
`,
Run: iam.CreateUser,
Args: cobra.NoArgs,
}
userCreateCmd.Flags().StringVar(&iam.UserSpec.Login, "login", "", "Login of the user")
userCreateCmd.Flags().StringVar(&iam.UserSpec.Email, "email", "", "Email of the user")
userCreateCmd.Flags().StringVar(&iam.UserSpec.Description, "description", "", "Description of the user")
userCreateCmd.Flags().StringVar(&iam.UserSpec.Group, "group", "", "Group of the user")
userCreateCmd.Flags().StringVar(&iam.UserSpec.Password, "password", "", "Password of the user")
userCreateCmd.Flags().StringVar(&iam.UserSpec.Type, "type", "", "Type of the user (ROOT, SERVICE, USER)")
// Common flags for other means to define parameters
addInitParameterFileFlag(userCreateCmd, assets.MeOpenapiSchema, "/me/identity/user", "post", iam.UserCreateExample, nil)
addInteractiveEditorFlag(userCreateCmd)
addFromFileFlag(userCreateCmd)
userCreateCmd.MarkFlagsMutuallyExclusive("from-file", "editor")
return userCreateCmd
}
func getUserEditCmd() *cobra.Command {
userEditCmd := &cobra.Command{
Use: "edit <user_login>",
Short: "Edit an existing user",
Long: `Use this command to edit an existing IAM user.
There are three ways to define the editing parameters:
1. Using only CLI flags:
ovhcloud iam user edit <user_login> --email fake.email+replaced@ovhcloud.com
2. Using a configuration file:
First you can generate an example of parameters file using the following command:
ovhcloud iam user edit --init-file ./params.json
You will be able to choose from several examples of parameters. Once an example has been selected, the content is written in the given file.
After editing the file to set the correct parameters, run:
ovhcloud iam user edit <user_login> --from-file ./params.json
Note that you can also pipe the content of the parameters file, like the following:
cat ./params.json | ovhcloud iam user edit <user_login>
In both cases, you can override the parameters in the given file using command line flags, for example:
ovhcloud iam user edit <user_login> --from-file ./params.json --email fake.email+overriden@ovhcloud.com
3. Using your default text editor:
ovhcloud iam user edit <user_login> --editor
You will be able to choose from several examples of parameters. Once an example has been selected, the CLI will open your
default text editor to update the parameters. When saving the file, the creation will start.
Note that it is also possible to override values in the presented examples using command line flags like the following:
ovhcloud iam user edit <user_login> --editor --description "New description"
`,
Run: iam.EditUser,
Args: cobra.ExactArgs(1),
}
userEditCmd.Flags().StringVar(&iam.UserSpec.Email, "email", "", "Email of the user")
userEditCmd.Flags().StringVar(&iam.UserSpec.Description, "description", "", "Description of the user")
userEditCmd.Flags().StringVar(&iam.UserSpec.Group, "group", "", "Group of the user")
// Common flags for other means to define parameters
addInitParameterFileFlag(userEditCmd, assets.MeOpenapiSchema, "/me/identity/user", "post", iam.UserEditExample, nil)
addInteractiveEditorFlag(userEditCmd)
addFromFileFlag(userEditCmd)
userEditCmd.MarkFlagsMutuallyExclusive("from-file", "editor")
return userEditCmd
}

View file

@ -35,6 +35,12 @@ var (
//go:embed templates/iam_resource_group.tmpl
iamResourceGroupTemplate string
//go:embed parameter-samples/user-create.json
UserCreateExample string
//go:embed parameter-samples/user-edit.json
UserEditExample string
IAMPolicySpec struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
@ -59,6 +65,15 @@ var (
IAMResourceSpec struct {
Tags map[string]string `json:"tags,omitempty"`
}
UserSpec struct {
Description string `json:"description,omitempty"`
Email string `json:"email,omitempty"`
Group string `json:"group,omitempty"`
Login string `json:"login,omitempty"`
Password string `json:"password,omitempty"`
Type string `json:"type,omitempty"`
}
)
type iamPermission struct {
@ -190,3 +205,51 @@ func prepareIAMPermissionsFromCLI() {
IAMPolicySpec.Resources = append(IAMPolicySpec.Resources, iamResourceURN{URN: urn})
}
}
func ListUsers(_ *cobra.Command, _ []string) {
common.ManageListRequest("/me/identity/user", "", []string{"login", "group", "description"}, flags.GenericFilters)
}
func GetUser(_ *cobra.Command, args []string) {
common.ManageObjectRequest("/me/identity/user", args[0], "")
}
func CreateUser(cmd *cobra.Command, _ []string) {
_, err := common.CreateResource(
cmd,
"/me/identity/user",
"/me/identity/user",
UserCreateExample,
UserSpec,
assets.MeOpenapiSchema,
[]string{"login", "password", "email"})
if err != nil {
display.OutputError(&flags.OutputFormatConfig, "failed to create user: %s", err)
return
}
display.OutputInfo(&flags.OutputFormatConfig, nil, "✅ User %s created successfully", UserSpec.Login)
}
func EditUser(cmd *cobra.Command, args []string) {
if err := common.EditResource(
cmd,
"/me/identity/user/{user}",
fmt.Sprintf("/me/identity/user/%s", url.PathEscape(args[0])),
UserSpec,
assets.MeOpenapiSchema,
); err != nil {
display.OutputError(&flags.OutputFormatConfig, "%s", err)
return
}
}
func DeleteUser(_ *cobra.Command, args []string) {
endpoint := fmt.Sprintf("/me/identity/user/%s", url.PathEscape(args[0]))
if err := httpLib.Client.Delete(endpoint, nil); err != nil {
display.OutputError(&flags.OutputFormatConfig, "failed to delete user %s: %s", args[0], err)
return
}
display.OutputInfo(&flags.OutputFormatConfig, nil, "✅ User %s deleted successfully", args[0])
}

View file

@ -0,0 +1,8 @@
{
"description": "User example",
"email": "fake.email@ovhcloud.com",
"group": "DEFAULT",
"login": "my_user",
"password": "ThisIsAStrongPassword123!",
"type": "USER"
}

View file

@ -0,0 +1,5 @@
{
"description": "New description",
"email": "fake.email@ovhcloud.com",
"group": "DEFAULT"
}