proxcli 0.16.2__tar.gz → 0.17.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. {proxcli-0.16.2 → proxcli-0.17.0}/CHANGELOG.md +36 -0
  2. {proxcli-0.16.2 → proxcli-0.17.0}/PKG-INFO +49 -59
  3. {proxcli-0.16.2 → proxcli-0.17.0}/README.md +47 -57
  4. proxcli-0.17.0/docs/api-permissions.md +328 -0
  5. proxcli-0.17.0/proxmox/cli/auth.py +624 -0
  6. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/main.py +17 -4
  7. proxcli-0.17.0/proxmox/config/writer.py +85 -0
  8. proxcli-0.17.0/proxmox/ssh/__init__.py +6 -0
  9. proxcli-0.17.0/proxmox/ssh/runner.py +240 -0
  10. proxcli-0.17.0/proxmox/ssh/script.py +166 -0
  11. {proxcli-0.16.2 → proxcli-0.17.0}/pyproject.toml +1 -1
  12. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_main.py +33 -0
  13. proxcli-0.17.0/tests/test_config_writer.py +91 -0
  14. proxcli-0.17.0/tests/test_ssh_runner.py +216 -0
  15. proxcli-0.17.0/tests/test_ssh_script.py +106 -0
  16. {proxcli-0.16.2 → proxcli-0.17.0}/uv.lock +1 -1
  17. proxcli-0.16.2/docs/api-permissions.md +0 -221
  18. proxcli-0.16.2/proxmox/cli/auth.py +0 -296
  19. {proxcli-0.16.2 → proxcli-0.17.0}/.env.example +0 -0
  20. {proxcli-0.16.2 → proxcli-0.17.0}/.github/workflows/ci.yml +0 -0
  21. {proxcli-0.16.2 → proxcli-0.17.0}/.gitignore +0 -0
  22. {proxcli-0.16.2 → proxcli-0.17.0}/.python-version +0 -0
  23. {proxcli-0.16.2 → proxcli-0.17.0}/AGENTS.md +0 -0
  24. {proxcli-0.16.2 → proxcli-0.17.0}/PLAN.md +0 -0
  25. {proxcli-0.16.2 → proxcli-0.17.0}/PROJECT.md +0 -0
  26. {proxcli-0.16.2 → proxcli-0.17.0}/PROMPT.md +0 -0
  27. {proxcli-0.16.2 → proxcli-0.17.0}/TODO.md +0 -0
  28. {proxcli-0.16.2 → proxcli-0.17.0}/docs/DESIGN.md +0 -0
  29. {proxcli-0.16.2 → proxcli-0.17.0}/docs/api-coverage.md +0 -0
  30. {proxcli-0.16.2 → proxcli-0.17.0}/docs/assets/index-Bzx5-fXr.css +0 -0
  31. {proxcli-0.16.2 → proxcli-0.17.0}/docs/assets/index-CXpOjuxt.css +0 -0
  32. {proxcli-0.16.2 → proxcli-0.17.0}/docs/assets/index-DLDs0H6j.js +0 -0
  33. {proxcli-0.16.2 → proxcli-0.17.0}/docs/assets/index-DYQPMK8x.js +0 -0
  34. {proxcli-0.16.2 → proxcli-0.17.0}/docs/cloud-init.md +0 -0
  35. {proxcli-0.16.2 → proxcli-0.17.0}/docs/coding-agents.md +0 -0
  36. {proxcli-0.16.2 → proxcli-0.17.0}/docs/coverage.json +0 -0
  37. {proxcli-0.16.2 → proxcli-0.17.0}/docs/demos/cluster.gif +0 -0
  38. {proxcli-0.16.2 → proxcli-0.17.0}/docs/demos/node-list.gif +0 -0
  39. {proxcli-0.16.2 → proxcli-0.17.0}/docs/demos/vm-list.gif +0 -0
  40. {proxcli-0.16.2 → proxcli-0.17.0}/docs/demos/vm-show.gif +0 -0
  41. {proxcli-0.16.2 → proxcli-0.17.0}/docs/demos/yaml-spec.gif +0 -0
  42. {proxcli-0.16.2 → proxcli-0.17.0}/docs/favicon.svg +0 -0
  43. {proxcli-0.16.2 → proxcli-0.17.0}/docs/icons.svg +0 -0
  44. {proxcli-0.16.2 → proxcli-0.17.0}/docs/index.html +0 -0
  45. {proxcli-0.16.2 → proxcli-0.17.0}/docs/production-automation.md +0 -0
  46. {proxcli-0.16.2 → proxcli-0.17.0}/docs/quickstart.md +0 -0
  47. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/.gitignore +0 -0
  48. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/README.md +0 -0
  49. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/build-all.sh +0 -0
  50. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/eslint.config.js +0 -0
  51. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/index.html +0 -0
  52. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/package-lock.json +0 -0
  53. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/package.json +0 -0
  54. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/coverage.json +0 -0
  55. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/demos/cluster.gif +0 -0
  56. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/demos/node-list.gif +0 -0
  57. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/demos/vm-list.gif +0 -0
  58. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/demos/vm-show.gif +0 -0
  59. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/demos/yaml-spec.gif +0 -0
  60. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/favicon.svg +0 -0
  61. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/public/icons.svg +0 -0
  62. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/.gitignore +0 -0
  63. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/.prettierrc +0 -0
  64. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/README.md +0 -0
  65. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/eslint.config.mjs +0 -0
  66. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/package-lock.json +0 -0
  67. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/package.json +0 -0
  68. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/public/cluster-real.txt +0 -0
  69. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/public/node-list-real.txt +0 -0
  70. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/public/vm-list-real.txt +0 -0
  71. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/public/vm-show-real.txt +0 -0
  72. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/remotion.config.ts +0 -0
  73. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/src/Composition.tsx +0 -0
  74. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/src/Root.tsx +0 -0
  75. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/src/index.css +0 -0
  76. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/src/index.ts +0 -0
  77. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/remotion-demos/tsconfig.json +0 -0
  78. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/src/App.jsx +0 -0
  79. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/src/components/CoverageGrid.jsx +0 -0
  80. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/src/components/SplitFlapAgent.jsx +0 -0
  81. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/src/index.css +0 -0
  82. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/src/main.jsx +0 -0
  83. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/src/pages/Docs.jsx +0 -0
  84. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/src/pages/Landing.jsx +0 -0
  85. {proxcli-0.16.2 → proxcli-0.17.0}/docs/website/vite.config.js +0 -0
  86. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/__init__.py +0 -0
  87. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/__init__.py +0 -0
  88. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/acl.py +0 -0
  89. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/api.py +0 -0
  90. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/backup.py +0 -0
  91. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/ceph.py +0 -0
  92. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/cluster.py +0 -0
  93. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/completion.py +0 -0
  94. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/container.py +0 -0
  95. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/firewall_helpers.py +0 -0
  96. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/network.py +0 -0
  97. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/node.py +0 -0
  98. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/pool.py +0 -0
  99. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/role.py +0 -0
  100. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/storage.py +0 -0
  101. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/tasks.py +0 -0
  102. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/update.py +0 -0
  103. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/user.py +0 -0
  104. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/vm.py +0 -0
  105. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/cli/vm_spec.py +0 -0
  106. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/client/__init__.py +0 -0
  107. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/client/auth.py +0 -0
  108. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/client/client.py +0 -0
  109. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/client/exceptions.py +0 -0
  110. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/config/__init__.py +0 -0
  111. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/config/config.py +0 -0
  112. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/config/models.py +0 -0
  113. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/output/__init__.py +0 -0
  114. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/output/formatter.py +0 -0
  115. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/output/json_fmt.py +0 -0
  116. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/output/log_fmt.py +0 -0
  117. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/output/table_fmt.py +0 -0
  118. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/output/yaml_fmt.py +0 -0
  119. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/utils/__init__.py +0 -0
  120. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/utils/helpers.py +0 -0
  121. {proxcli-0.16.2 → proxcli-0.17.0}/proxmox/utils/logging.py +0 -0
  122. {proxcli-0.16.2 → proxcli-0.17.0}/tests/__init__.py +0 -0
  123. {proxcli-0.16.2 → proxcli-0.17.0}/tests/conftest.py +0 -0
  124. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_auth.py +0 -0
  125. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/__init__.py +0 -0
  126. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_api.py +0 -0
  127. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_backup.py +0 -0
  128. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_backup_restore.py +0 -0
  129. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_ceph.py +0 -0
  130. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_container_ip.py +0 -0
  131. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_network.py +0 -0
  132. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_node_system.py +0 -0
  133. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_role_acl.py +0 -0
  134. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_task_wait.py +0 -0
  135. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_user.py +0 -0
  136. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_agent.py +0 -0
  137. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_clone.py +0 -0
  138. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_disk.py +0 -0
  139. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_ip.py +0 -0
  140. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_iso.py +0 -0
  141. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_migrate.py +0 -0
  142. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_set.py +0 -0
  143. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_cli/test_vm_template.py +0 -0
  144. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_client.py +0 -0
  145. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_config.py +0 -0
  146. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_integration/__init__.py +0 -0
  147. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_output/__init__.py +0 -0
  148. {proxcli-0.16.2 → proxcli-0.17.0}/tests/test_output/test_formatter.py +0 -0
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ _No changes yet._
11
+
12
+ ## [0.17.0] - 2026-09-25
13
+
14
+ ### Added
15
+ - **`proxmox auth setup` rewritten as an SSH-based interactive configurator.**
16
+ `proxmox auth setup --host <node>` SSHes into a Proxmox node as `root@pam`
17
+ and, in one idempotent pass, creates the recommended `proxcli-*` roles, an
18
+ API token, and the ACLs that bind them — then writes the resulting token
19
+ secret to `credentials.json` (mode `0600`, with a `.bak` on overwrite). No
20
+ UI, no manual `pveum`, no hand-editing JSON. The generated bash script uses
21
+ `pveum` (roles/ACLs) and `pvesh ... --output-format json` (token
22
+ create/regenerate with secret capture) and is safe to re-run. Key-based SSH
23
+ auth is the default; password auth is supported when `sshpass` is installed.
24
+ New flags: `--via {ssh,api}`, `--host`, `--ssh-user`, `--port`,
25
+ `-i/--identity`, `--ssh-password`, `--ssh-password-stdin`, `--pve-user`,
26
+ `--token-name`, `--privsep/--no-privsep`, `--regenerate`, `--non-interactive`,
27
+ `--force`, `--no-write`, `--dry-run`, `--json`. `--dry-run` previews the
28
+ script without contacting the node; `--json` returns it structured for
29
+ agents. The token is created with **privilege separation ON** and roles
30
+ assigned directly via ACLs (least-privilege). The legacy REST path is kept
31
+ as `--via api` (roles + ACLs only; cannot capture the secret).
32
+ - **`proxcli-network` role**: new recommended role (`SDN.Audit,SDN.Use`)
33
+ granted at `/sdn`. Attaching a VM NIC to an **SDN-managed bridge** (e.g.
34
+ `vmbr0`) requires `SDN.Use` on top of `VM.Config.Network`; without it, VM
35
+ creation fails at the `net0` step with HTTP 403
36
+ `Permission check failed (/sdn, SDN.Use)`. `proxmox auth setup` now creates
37
+ the role + ACL automatically, `proxmox auth status` checks SDN read access,
38
+ and the stray-role allow-list includes it. `SDN.Allocate` (fabric
39
+ create/modify) is intentionally excluded — proxcli only consumes existing
40
+ SDN networks. See `docs/api-permissions.md`.
41
+
8
42
  ## [0.16.2] - 2026-06-30
9
43
 
10
44
  ### Added
@@ -363,6 +397,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
363
397
  - CSRF ticket auto-refresh on 401.
364
398
  - AI-agent-friendly: default JSON output, strict exit codes, `--dry-run` mode.
365
399
 
400
+ [Unreleased]: https://github.com/xezpeleta/proxcli/compare/v0.17.0...HEAD
401
+ [0.17.0]: https://github.com/xezpeleta/proxcli/releases/tag/v0.17.0
366
402
  [0.16.2]: https://github.com/xezpeleta/proxcli/releases/tag/v0.16.2
367
403
  [0.16.1]: https://github.com/xezpeleta/proxcli/releases/tag/v0.16.1
368
404
  [0.16.0]: https://github.com/xezpeleta/proxcli/releases/tag/v0.16.0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: proxcli
3
- Version: 0.16.2
3
+ Version: 0.17.0
4
4
  Summary: A CLI tool to interact with Proxmox VE nodes and clusters via the REST API
5
5
  Author-email: Xabi Ezpeleta <xezpeleta@gmail.com>
6
6
  License: MIT
@@ -45,38 +45,15 @@ uv tool install .
45
45
  ## Quickstart
46
46
 
47
47
  ```bash
48
- # Create credentials file manually
49
- mkdir -p ~/.config/proxmox-cli
50
- chmod 700 ~/.config/proxmox-cli
51
-
52
- # For API token auth:
53
- cat > ~/.config/proxmox-cli/credentials.json <<'EOF'
54
- {
55
- "url": "https://192.168.1.10:8006",
56
- "username": "root@pam",
57
- "auth_method": "api_token",
58
- "api_token_id": "my-token",
59
- "api_token_secret": "deadbeef-..."
60
- }
61
- EOF
62
- chmod 600 ~/.config/proxmox-cli/credentials.json
63
-
64
- # For password auth:
65
- cat > ~/.config/proxmox-cli/credentials.json <<'EOF'
66
- {
67
- "url": "https://192.168.1.10:8006",
68
- "username": "root@pam",
69
- "auth_method": "password",
70
- "password": "your_password",
71
- "verify_tls": false
72
- }
73
- EOF
74
- chmod 600 ~/.config/proxmox-cli/credentials.json
75
-
76
- # Enable shell completions
77
- source <(proxmox completion bash) # bash
78
- source <(proxmox completion zsh) # zsh
79
- proxmox completion fish | source # fish (or save to ~/.config/fish/completions/proxmox.fish)
48
+ # Bootstrap credentials + permissions on a node in one step.
49
+ # Requires SSH access to a Proxmox node as root@pam (key auth by default).
50
+ proxmox auth setup --host pve01.lan
51
+ # → creates the recommended proxcli roles, an API token, and ACLs on the node
52
+ # → writes the token to ~/.config/proxmox-cli/credentials.json (mode 0600)
53
+ # Preview the script without changing anything:
54
+ # proxmox auth setup --host pve01.lan --dry-run
55
+ # Password auth (needs sshpass installed):
56
+ # proxmox auth setup --host pve01.lan --ssh-password-stdin
80
57
 
81
58
  # Check auth status
82
59
  proxmox auth status
@@ -86,6 +63,15 @@ proxmox vm list
86
63
 
87
64
  # Show a specific VM
88
65
  proxmox vm show 100
66
+ ```
67
+
68
+ Prefer to write the config file by hand? See [Manual config file](#manual-config-file) below.
69
+
70
+ ```bash
71
+ # Enable shell completions
72
+ source <(proxmox completion bash) # bash
73
+ source <(proxmox completion zsh) # zsh
74
+ proxmox completion fish | source # fish (or save to ~/.config/fish/completions/proxmox.fish)
89
75
 
90
76
  # Create a VM (CLI flags)
91
77
  proxmox vm create --node pve01 --vmid 110 --memory 2048 --cores 2 --name webserver
@@ -107,11 +93,33 @@ proxmox vm delete 110 --purge
107
93
 
108
94
  ## Authentication
109
95
 
110
- Credentials are stored in `~/.config/proxmox-cli/credentials.json` with restrictive permissions (`0600`).
96
+ Credentials are stored in `~/.config/proxmox-cli/credentials.json` with restrictive permissions (`0600`). A system-wide config at `/etc/proxmox-cli/credentials.json` is also supported (checked after the user-level path).
97
+
98
+ ### Recommended: `auth setup`
99
+
100
+ `proxmox auth setup --host <node>` SSHes into a Proxmox node as `root@pam` and, in one idempotent pass, creates the recommended `proxcli-*` roles, an API token, and the ACLs that bind them — then writes the resulting token secret to `credentials.json` for you.
101
+
102
+ ```bash
103
+ # Key-based SSH auth (default):
104
+ proxmox auth setup --host pve01.lan
105
+
106
+ # Password auth (requires sshpass):
107
+ proxmox auth setup --host pve01.lan --ssh-password-stdin
108
+
109
+ # Preview the generated script without touching the node:
110
+ proxmox auth setup --host pve01.lan --dry-run
111
+
112
+ # JSON output for agents/automation:
113
+ proxmox auth setup --host pve01.lan --dry-run --json
114
+ ```
115
+
116
+ Options: `--ssh-user`, `--port`, `-i/--identity`, `--pve-user` (default `root@pam`), `--token-name` (default `proxcli`), `--privsep/--no-privsep` (default on — privilege separation), `--regenerate` (rotate the token secret), `--force` (overwrite an existing `credentials.json`), `--no-write` (run on the node but don't save locally).
111
117
 
112
- **proxcli never creates, modifies, or deletes this file.** You must create it manually.
118
+ The legacy `--via api` path uses an existing Administrator token over the REST API to create roles + ACLs only (it cannot capture or write the token secret). Prefer `--via ssh`.
113
119
 
114
- ### Config file format
120
+ ### Manual config file
121
+
122
+ If you prefer to hand-edit credentials, create `~/.config/proxmox-cli/credentials.json` (chmod 600):
115
123
 
116
124
  ```json
117
125
  {
@@ -119,14 +127,12 @@ Credentials are stored in `~/.config/proxmox-cli/credentials.json` with restrict
119
127
  "username": "root@pam",
120
128
  "auth_method": "api_token",
121
129
  "api_token_id": "my-token",
122
- "api_token_secret": "deadbeef-...",
130
+ "api_token_secret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
123
131
  "verify_tls": false
124
132
  }
125
133
  ```
126
134
 
127
- For password auth, use `"auth_method": "password"` with `"password"` instead of `"api_token_id"`/`"api_token_secret"`.
128
-
129
- A system-wide config at `/etc/proxmox-cli/credentials.json` is also supported (checked after the user-level path).
135
+ For password auth, use `"auth_method": "password"` with a `"password"` field instead of `api_token_id` / `api_token_secret`.
130
136
 
131
137
  ### Override credentials per command
132
138
 
@@ -147,23 +153,6 @@ proxmox vm list --username root@pam --url https://pve:8006
147
153
  proxmox --insecure vm list
148
154
  ```
149
155
 
150
- ### Manual config file
151
-
152
- If you prefer to hand-edit credentials, create `~/.config/proxmox-cli/credentials.json` (chmod 600):
153
-
154
- ```json
155
- {
156
- "url": "https://192.168.1.10:8006",
157
- "username": "root@pam",
158
- "auth_method": "api_token",
159
- "api_token_id": "my-token",
160
- "api_token_secret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
161
- "verify_tls": false
162
- }
163
- ```
164
-
165
- For password auth, use `"auth_method": "password"` with a `"password"` field instead of `api_token_id` / `api_token_secret`.
166
-
167
156
  ## Command Reference
168
157
 
169
158
  ### Global flags
@@ -188,7 +177,8 @@ For password auth, use `"auth_method": "password"` with a `"password"` field ins
188
177
  ```bash
189
178
  proxmox auth status # Show current auth context
190
179
  proxmox auth status --permissions # + effective permissions from API
191
- proxmox auth setup # Create recommended roles + ACLs (needs Administrator)
180
+ proxmox auth setup # Bootstrap roles + token + ACLs (SSH as root@pam, writes credentials.json)
181
+ proxmox auth setup --dry-run # Preview the generated script without changing anything
192
182
  proxmox auth check # Live permission test table (39 checks)
193
183
  ```
194
184
 
@@ -22,38 +22,15 @@ uv tool install .
22
22
  ## Quickstart
23
23
 
24
24
  ```bash
25
- # Create credentials file manually
26
- mkdir -p ~/.config/proxmox-cli
27
- chmod 700 ~/.config/proxmox-cli
28
-
29
- # For API token auth:
30
- cat > ~/.config/proxmox-cli/credentials.json <<'EOF'
31
- {
32
- "url": "https://192.168.1.10:8006",
33
- "username": "root@pam",
34
- "auth_method": "api_token",
35
- "api_token_id": "my-token",
36
- "api_token_secret": "deadbeef-..."
37
- }
38
- EOF
39
- chmod 600 ~/.config/proxmox-cli/credentials.json
40
-
41
- # For password auth:
42
- cat > ~/.config/proxmox-cli/credentials.json <<'EOF'
43
- {
44
- "url": "https://192.168.1.10:8006",
45
- "username": "root@pam",
46
- "auth_method": "password",
47
- "password": "your_password",
48
- "verify_tls": false
49
- }
50
- EOF
51
- chmod 600 ~/.config/proxmox-cli/credentials.json
52
-
53
- # Enable shell completions
54
- source <(proxmox completion bash) # bash
55
- source <(proxmox completion zsh) # zsh
56
- proxmox completion fish | source # fish (or save to ~/.config/fish/completions/proxmox.fish)
25
+ # Bootstrap credentials + permissions on a node in one step.
26
+ # Requires SSH access to a Proxmox node as root@pam (key auth by default).
27
+ proxmox auth setup --host pve01.lan
28
+ # → creates the recommended proxcli roles, an API token, and ACLs on the node
29
+ # → writes the token to ~/.config/proxmox-cli/credentials.json (mode 0600)
30
+ # Preview the script without changing anything:
31
+ # proxmox auth setup --host pve01.lan --dry-run
32
+ # Password auth (needs sshpass installed):
33
+ # proxmox auth setup --host pve01.lan --ssh-password-stdin
57
34
 
58
35
  # Check auth status
59
36
  proxmox auth status
@@ -63,6 +40,15 @@ proxmox vm list
63
40
 
64
41
  # Show a specific VM
65
42
  proxmox vm show 100
43
+ ```
44
+
45
+ Prefer to write the config file by hand? See [Manual config file](#manual-config-file) below.
46
+
47
+ ```bash
48
+ # Enable shell completions
49
+ source <(proxmox completion bash) # bash
50
+ source <(proxmox completion zsh) # zsh
51
+ proxmox completion fish | source # fish (or save to ~/.config/fish/completions/proxmox.fish)
66
52
 
67
53
  # Create a VM (CLI flags)
68
54
  proxmox vm create --node pve01 --vmid 110 --memory 2048 --cores 2 --name webserver
@@ -84,11 +70,33 @@ proxmox vm delete 110 --purge
84
70
 
85
71
  ## Authentication
86
72
 
87
- Credentials are stored in `~/.config/proxmox-cli/credentials.json` with restrictive permissions (`0600`).
73
+ Credentials are stored in `~/.config/proxmox-cli/credentials.json` with restrictive permissions (`0600`). A system-wide config at `/etc/proxmox-cli/credentials.json` is also supported (checked after the user-level path).
74
+
75
+ ### Recommended: `auth setup`
76
+
77
+ `proxmox auth setup --host <node>` SSHes into a Proxmox node as `root@pam` and, in one idempotent pass, creates the recommended `proxcli-*` roles, an API token, and the ACLs that bind them — then writes the resulting token secret to `credentials.json` for you.
78
+
79
+ ```bash
80
+ # Key-based SSH auth (default):
81
+ proxmox auth setup --host pve01.lan
82
+
83
+ # Password auth (requires sshpass):
84
+ proxmox auth setup --host pve01.lan --ssh-password-stdin
85
+
86
+ # Preview the generated script without touching the node:
87
+ proxmox auth setup --host pve01.lan --dry-run
88
+
89
+ # JSON output for agents/automation:
90
+ proxmox auth setup --host pve01.lan --dry-run --json
91
+ ```
92
+
93
+ Options: `--ssh-user`, `--port`, `-i/--identity`, `--pve-user` (default `root@pam`), `--token-name` (default `proxcli`), `--privsep/--no-privsep` (default on — privilege separation), `--regenerate` (rotate the token secret), `--force` (overwrite an existing `credentials.json`), `--no-write` (run on the node but don't save locally).
88
94
 
89
- **proxcli never creates, modifies, or deletes this file.** You must create it manually.
95
+ The legacy `--via api` path uses an existing Administrator token over the REST API to create roles + ACLs only (it cannot capture or write the token secret). Prefer `--via ssh`.
90
96
 
91
- ### Config file format
97
+ ### Manual config file
98
+
99
+ If you prefer to hand-edit credentials, create `~/.config/proxmox-cli/credentials.json` (chmod 600):
92
100
 
93
101
  ```json
94
102
  {
@@ -96,14 +104,12 @@ Credentials are stored in `~/.config/proxmox-cli/credentials.json` with restrict
96
104
  "username": "root@pam",
97
105
  "auth_method": "api_token",
98
106
  "api_token_id": "my-token",
99
- "api_token_secret": "deadbeef-...",
107
+ "api_token_secret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
100
108
  "verify_tls": false
101
109
  }
102
110
  ```
103
111
 
104
- For password auth, use `"auth_method": "password"` with `"password"` instead of `"api_token_id"`/`"api_token_secret"`.
105
-
106
- A system-wide config at `/etc/proxmox-cli/credentials.json` is also supported (checked after the user-level path).
112
+ For password auth, use `"auth_method": "password"` with a `"password"` field instead of `api_token_id` / `api_token_secret`.
107
113
 
108
114
  ### Override credentials per command
109
115
 
@@ -124,23 +130,6 @@ proxmox vm list --username root@pam --url https://pve:8006
124
130
  proxmox --insecure vm list
125
131
  ```
126
132
 
127
- ### Manual config file
128
-
129
- If you prefer to hand-edit credentials, create `~/.config/proxmox-cli/credentials.json` (chmod 600):
130
-
131
- ```json
132
- {
133
- "url": "https://192.168.1.10:8006",
134
- "username": "root@pam",
135
- "auth_method": "api_token",
136
- "api_token_id": "my-token",
137
- "api_token_secret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
138
- "verify_tls": false
139
- }
140
- ```
141
-
142
- For password auth, use `"auth_method": "password"` with a `"password"` field instead of `api_token_id` / `api_token_secret`.
143
-
144
133
  ## Command Reference
145
134
 
146
135
  ### Global flags
@@ -165,7 +154,8 @@ For password auth, use `"auth_method": "password"` with a `"password"` field ins
165
154
  ```bash
166
155
  proxmox auth status # Show current auth context
167
156
  proxmox auth status --permissions # + effective permissions from API
168
- proxmox auth setup # Create recommended roles + ACLs (needs Administrator)
157
+ proxmox auth setup # Bootstrap roles + token + ACLs (SSH as root@pam, writes credentials.json)
158
+ proxmox auth setup --dry-run # Preview the generated script without changing anything
169
159
  proxmox auth check # Live permission test table (39 checks)
170
160
  ```
171
161