Skip to content

Commit ea5afd2

Browse files
committed
feat: Add Rancher reset-admin-credentials command
Signed-off-by: Thomas Coudert <thomas.coudert@ovhcloud.com>
1 parent 747c474 commit ea5afd2

File tree

5 files changed

+69
-104
lines changed

5 files changed

+69
-104
lines changed

doc/ovhcloud.md

Lines changed: 18 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,27 @@
1-
# OVHcloud CLI (`ovhcloud`) Documentation
1+
## ovhcloud
22

3-
---
3+
CLI to manage your OVHcloud services
44

5-
## Overview
5+
### Options
66

7-
`ovhcloud` is a single, unified command‑line interface for managing the full range of OVHcloud products and account resources directly from your terminal. Whether you need to automate provisioning, perform quick look‑ups, or integrate OVHcloud operations into CI/CD pipelines, `ovhcloud` offers fine‑grained commands and consistent output formats (table, JSON, YAML, or custom gval expressions).
8-
9-
---
10-
11-
## Quick Start
12-
13-
```bash
14-
# Display the top‑level help
15-
ovhcloud --help
16-
17-
# Log in and create API credentials (interactive)
18-
ovhcloud login
19-
20-
# List your VPS instances as JSON
21-
ohvcloud vps list --json
22-
```
23-
24-
Check out the [authentication page](authentication.md) for further information about the authentication means.
25-
26-
### Generate Shell Completion
27-
28-
```bash
29-
# Bash
30-
eval "$(./ovhcloud completion bash)"
31-
# Zsh
32-
eval "$(./ovhcloud completion zsh)"
33-
# Fish
34-
./ovhcloud completion fish | source
35-
# PowerShell
36-
./ovhcloud completion powershell | Out-String | Invoke-Expression
377
```
38-
39-
Add the appropriate line to your shell’s startup file (`~/.bashrc`, `~/.zshrc`, etc.) to enable persistent autocompletion.
40-
41-
---
42-
43-
## Global Usage
44-
45-
```text
46-
ovhcloud [command] [flags]
8+
-d, --debug Activate debug mode (will log all HTTP requests details)
9+
-f, --format string Output value according to given format (expression using https://github.com/PaesslerAG/gval syntax)
10+
Examples:
11+
--format 'id' (to extract a single field)
12+
--format 'nested.field.subfield' (to extract a nested field)
13+
--format '[id, 'name']' (to extract multiple fields as an array)
14+
--format '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object)
15+
--format 'name+","+type' (to extract and concatenate fields in a string)
16+
--format '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields)
17+
-h, --help help for ovhcloud
18+
-e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution
19+
-i, --interactive Interactive output
20+
-j, --json Output in JSON
21+
-y, --yaml Output in YAML
4722
```
4823

49-
### Global Flags
50-
51-
| Flag | Description |
52-
| ----------------- | ---------------------------------------------------- |
53-
| `--debug` | Activate debug mode (logs all HTTP‑request details). |
54-
| `--ignore-errors` | Ignore errors of API calls made when listing items. |
55-
| `--format <expr>` | Format output with a [gval] expression. |
56-
| `--filter <expr>` | Filter lists output with a [gval] expression. |
57-
| `-h`, `--help` | Display help for `ovhcloud` or a specific command. |
58-
| `--interactive` | Produce interactive (prompt‑based) output. |
59-
| `--json` | Output data in JSON format. |
60-
| `--yaml` | Output data in YAML format. |
61-
62-
[gval]: https://github.com/PaesslerAG/gval
63-
64-
#### Filtering examples
65-
66-
- Strict string equality: `--filter 'name=="something"'`
67-
- String regexp comparison: `--filter 'name=~"something"'`
68-
- Number comparison: `--filter 'bootId > 1'`
69-
70-
#### Formatting example
71-
72-
- Extract only one field: `--format 'ip'`
73-
- Extract an object: `--format '{name: ip}'`
74-
75-
---
76-
77-
## Command Reference
78-
79-
Below is the full list of primary sub‑commands available at the time of writing. Each can be explored in depth with `ovhcloud <command> --help`.
24+
### SEE ALSO
8025

8126
* [ovhcloud account](ovhcloud_account.md) - Manage your account
8227
* [ovhcloud alldom](ovhcloud_alldom.md) - Retrieve information and manage your AllDom services
@@ -122,30 +67,3 @@ Below is the full list of primary sub‑commands available at the time of writin
12267
* [ovhcloud webhosting](ovhcloud_webhosting.md) - Retrieve information and manage your WebHosting services
12368
* [ovhcloud xdsl](ovhcloud_xdsl.md) - Retrieve information and manage your XDSL services
12469

125-
> **Tip**  Use `--json`, `--yaml`, or `--format` with a gval expression to integrate `ovhcloud` into scripts and automation pipelines.
126-
127-
---
128-
129-
## Examples
130-
131-
| Task | Command |
132-
| ------------------------------------- | ---------------------------------------------- |
133-
| Log in and save credentials | `ovhcloud login` |
134-
| List VPS instances (tabular) | `ovhcloud vps list` |
135-
| Fetch details of a single VPS in JSON | `ovhcloud vps get <service_id> --json` |
136-
| Reinstall a baremetal interactively | `ovhcloud baremetal reinstall <id> --editor` |
137-
138-
---
139-
140-
## Troubleshooting
141-
142-
* **Verbose output** — Use `--debug` to inspect raw API calls and responses.
143-
* **Authentication issues** — Run `ovhcloud login` again to regenerate valid API keys.
144-
* **Rate limits** — OVHcloud APIs impose rate limits; plan retries or exponential backoff in scripts.
145-
146-
---
147-
148-
## Further Reading
149-
150-
* OVHcloud API reference: [https://eu.api.ovh.com/console](https://eu.api.ovh.com/console)
151-
* OVHcloud community guides and tutorials.

doc/ovhcloud_cloud_rancher.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ Manage Rancher services in the given cloud project
3535
* [ovhcloud cloud rancher edit](ovhcloud_cloud_rancher_edit.md) - Edit the given Rancher service
3636
* [ovhcloud cloud rancher get](ovhcloud_cloud_rancher_get.md) - Get a specific Rancher service
3737
* [ovhcloud cloud rancher list](ovhcloud_cloud_rancher_list.md) - List Rancher services
38+
* [ovhcloud cloud rancher reset-admin-credentials](ovhcloud_cloud_rancher_reset-admin-credentials.md) - Reset admin user credentials
3839

internal/cmd/cloud_rancher.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ func initCloudRancherCommand(cloudCmd *cobra.Command) {
4747

4848
rancherCmd.AddCommand(getRancherCreateCmd())
4949

50+
rancherCmd.AddCommand(&cobra.Command{
51+
Use: "reset-admin-credentials <rancher_id>",
52+
Short: "Reset admin user credentials",
53+
Run: cloud.ResetAdminCredentials,
54+
Args: cobra.ExactArgs(1),
55+
})
56+
5057
rancherCmd.AddCommand(&cobra.Command{
5158
Use: "delete <rancher_id>",
5259
Short: "Delete a specific Rancher service",

internal/cmd/cloud_rancher_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,18 @@ func (ms *MockSuite) TestCloudRancherCreateCmdCustomFormat(assert, require *td.T
9696
require.CmpNoError(err)
9797
assert.String(out, `["rancher-12345"]`)
9898
}
99+
func (ms *MockSuite) TestCloudRancherResetAdminCredentialsCmd(assert, require *td.T) {
100+
// Mock the POST request that resets the admin credentials
101+
httpmock.RegisterMatcherResponder(http.MethodPost,
102+
"https://eu.api.ovh.com/v2/publicCloud/project/fakeProjectID/rancher/fakeRancherID/adminCredentials",
103+
httpmock.Matcher{},
104+
httpmock.NewStringResponder(200, `{"username":"admin","password":"new-secret"}`),
105+
)
106+
107+
// Execute the command
108+
out, err := cmd.Execute("cloud", "rancher", "reset-admin-credentials", "--cloud-project", "fakeProjectID", "fakeRancherID")
109+
require.CmpNoError(err)
110+
111+
// Verify the output the new credentials
112+
assert.String(out, `✅ New Rancher service password for user admin: new-secret`)
113+
}

internal/services/cloud/cloud_rancher.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,17 @@ var (
3939
}
4040
)
4141

42-
type rancherIPRestriction struct {
43-
CIDRBlock string `json:"cidrBlock"`
44-
Description string `json:"description"`
45-
}
42+
type (
43+
rancherIPRestriction struct {
44+
CIDRBlock string `json:"cidrBlock"`
45+
Description string `json:"description"`
46+
}
47+
48+
rancherUser struct {
49+
Username string `json:"username"`
50+
Password string `json:"password"`
51+
}
52+
)
4653

4754
func ListCloudRanchers(_ *cobra.Command, _ []string) {
4855
projectID, err := getConfiguredCloudProject()
@@ -119,6 +126,23 @@ func CreateRancher(cmd *cobra.Command, args []string) {
119126
display.OutputInfo(&flags.OutputFormatConfig, rancher, "✅ Rancher %s created successfully (id: %s)", RancherSpec.TargetSpec.Name, rancher["id"])
120127
}
121128

129+
func ResetAdminCredentials(_ *cobra.Command, args []string) {
130+
projectID, err := getConfiguredCloudProject()
131+
if err != nil {
132+
display.OutputError(&flags.OutputFormatConfig, "%s", err)
133+
return
134+
}
135+
136+
var user rancherUser
137+
endpoint := fmt.Sprintf("/v2/publicCloud/project/%s/rancher/%s/adminCredentials", projectID, url.PathEscape(args[0]))
138+
if err := httpLib.Client.Post(endpoint, nil, &user); err != nil {
139+
display.OutputError(&flags.OutputFormatConfig, "failed to reset admin credentials for Rancher service: %s", err)
140+
return
141+
}
142+
143+
display.OutputInfo(&flags.OutputFormatConfig, nil, "✅ New Rancher service password for user %s: %s", user.Username, user.Password)
144+
}
145+
122146
func DeleteRancher(_ *cobra.Command, args []string) {
123147
projectID, err := getConfiguredCloudProject()
124148
if err != nil {

0 commit comments

Comments
 (0)