proxcli 0.8.1__tar.gz → 0.8.2__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 (52) hide show
  1. {proxcli-0.8.1 → proxcli-0.8.2}/.github/workflows/ci.yml +1 -1
  2. {proxcli-0.8.1 → proxcli-0.8.2}/CHANGELOG.md +13 -0
  3. {proxcli-0.8.1 → proxcli-0.8.2}/PKG-INFO +14 -2
  4. {proxcli-0.8.1 → proxcli-0.8.2}/README.md +13 -1
  5. {proxcli-0.8.1 → proxcli-0.8.2}/TODO.md +4 -3
  6. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/vm.py +31 -0
  7. {proxcli-0.8.1 → proxcli-0.8.2}/pyproject.toml +1 -1
  8. {proxcli-0.8.1 → proxcli-0.8.2}/uv.lock +2 -2
  9. {proxcli-0.8.1 → proxcli-0.8.2}/.env.example +0 -0
  10. {proxcli-0.8.1 → proxcli-0.8.2}/.gitignore +0 -0
  11. {proxcli-0.8.1 → proxcli-0.8.2}/.python-version +0 -0
  12. {proxcli-0.8.1 → proxcli-0.8.2}/AGENTS.md +0 -0
  13. {proxcli-0.8.1 → proxcli-0.8.2}/PLAN.md +0 -0
  14. {proxcli-0.8.1 → proxcli-0.8.2}/PROJECT.md +0 -0
  15. {proxcli-0.8.1 → proxcli-0.8.2}/PROMPT.md +0 -0
  16. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/__init__.py +0 -0
  17. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/__init__.py +0 -0
  18. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/auth.py +0 -0
  19. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/cluster.py +0 -0
  20. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/completion.py +0 -0
  21. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/container.py +0 -0
  22. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/firewall_helpers.py +0 -0
  23. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/main.py +0 -0
  24. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/node.py +0 -0
  25. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/pool.py +0 -0
  26. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/storage.py +0 -0
  27. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/cli/tasks.py +0 -0
  28. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/client/__init__.py +0 -0
  29. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/client/auth.py +0 -0
  30. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/client/client.py +0 -0
  31. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/client/exceptions.py +0 -0
  32. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/config/__init__.py +0 -0
  33. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/config/config.py +0 -0
  34. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/config/models.py +0 -0
  35. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/output/__init__.py +0 -0
  36. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/output/formatter.py +0 -0
  37. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/output/json_fmt.py +0 -0
  38. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/output/table_fmt.py +0 -0
  39. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/output/yaml_fmt.py +0 -0
  40. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/utils/__init__.py +0 -0
  41. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/utils/helpers.py +0 -0
  42. {proxcli-0.8.1 → proxcli-0.8.2}/proxmox/utils/logging.py +0 -0
  43. {proxcli-0.8.1 → proxcli-0.8.2}/tests/__init__.py +0 -0
  44. {proxcli-0.8.1 → proxcli-0.8.2}/tests/conftest.py +0 -0
  45. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_auth.py +0 -0
  46. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_cli/__init__.py +0 -0
  47. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_cli/test_main.py +0 -0
  48. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_client.py +0 -0
  49. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_config.py +0 -0
  50. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_integration/__init__.py +0 -0
  51. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_output/__init__.py +0 -0
  52. {proxcli-0.8.1 → proxcli-0.8.2}/tests/test_output/test_formatter.py +0 -0
@@ -70,4 +70,4 @@ jobs:
70
70
  name: dist
71
71
  path: dist/
72
72
 
73
- - run: uv publish --token "${{ secrets.PYPI_TOKEN }}"
73
+ - run: uv publish --token "${{ secrets.PYPI_TOKEN }}" --check-url https://pypi.org/simple
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.2] - 2026-06-20
11
+
12
+ ### Added
13
+ - **vm agent interfaces** — query QEMU guest agent for network interface
14
+ and IP information via ``proxmox vm agent interfaces <vmid>``.
15
+ Requires ``qemu-guest-agent`` in the VM.
16
+
17
+ ### Fixed
18
+ - CI publish job now uses ``uv publish --check-url https://pypi.org/simple``
19
+ to skip already-published versions instead of failing with "File already
20
+ exists".
21
+
10
22
  ## [0.8.1] - 2026-06-20
11
23
 
12
24
  ### Added
@@ -124,6 +136,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
124
136
  - CSRF ticket auto-refresh on 401.
125
137
  - AI-agent-friendly: default JSON output, strict exit codes, `--dry-run` mode.
126
138
 
139
+ [0.8.2]: https://github.com/xezpeleta/proxcli/releases/tag/v0.8.2
127
140
  [0.8.1]: https://github.com/xezpeleta/proxcli/releases/tag/v0.8.1
128
141
  [0.8.0]: https://github.com/xezpeleta/proxcli/releases/tag/v0.8.0
129
142
  [0.7.2]: https://github.com/xezpeleta/proxcli/releases/tag/v0.7.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxcli
3
- Version: 0.8.1
3
+ Version: 0.8.2
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
@@ -177,7 +177,9 @@ proxmox completion fish > ~/.config/fish/completions/proxmox.fish
177
177
  ```bash
178
178
  proxmox vm list [--node <node>]
179
179
  proxmox vm show <vmid> [--node <node>]
180
- proxmox vm create --node <node> --vmid <id> --memory <mb> [--cores <n>] [--name <name>] [--storage <name>] [--net <config>]
180
+ proxmox vm create --node <node> --memory <mb> [--vmid <id>] [--cores <n>] \
181
+ [--name <name>] [--cdrom <iso>] [--net <config>] [--disk <size>] \
182
+ [--scsihw <type>] [--bios seabios|ovmf] [--machine <type>] [--boot <order>]
181
183
  proxmox vm start <vmid> [--node <node>]
182
184
  proxmox vm stop <vmid> [--node <node>]
183
185
  proxmox vm reboot <vmid> [--node <node>]
@@ -185,6 +187,16 @@ proxmox vm suspend <vmid> [--node <node>]
185
187
  proxmox vm resume <vmid> [--node <node>]
186
188
  proxmox vm delete <vmid> [--node <node>] [--force] [--purge]
187
189
 
190
+ # VM snapshots
191
+ proxmox vm snapshot list <vmid> [--node <node>]
192
+ proxmox vm snapshot create <vmid> <snapname> [--description <text>] [--vmstate 1]
193
+ proxmox vm snapshot show <vmid> <snapname> [--node <node>]
194
+ proxmox vm snapshot rollback <vmid> <snapname> [--start 1]
195
+ proxmox vm snapshot delete <vmid> <snapname> [--force 1]
196
+
197
+ # VM guest agent
198
+ proxmox vm agent interfaces <vmid> [--node <node>]
199
+
188
200
  # VM firewall
189
201
  proxmox vm firewall options <vmid> [--node <node>]
190
202
  proxmox vm firewall enable <vmid> [--node <node>]
@@ -154,7 +154,9 @@ proxmox completion fish > ~/.config/fish/completions/proxmox.fish
154
154
  ```bash
155
155
  proxmox vm list [--node <node>]
156
156
  proxmox vm show <vmid> [--node <node>]
157
- proxmox vm create --node <node> --vmid <id> --memory <mb> [--cores <n>] [--name <name>] [--storage <name>] [--net <config>]
157
+ proxmox vm create --node <node> --memory <mb> [--vmid <id>] [--cores <n>] \
158
+ [--name <name>] [--cdrom <iso>] [--net <config>] [--disk <size>] \
159
+ [--scsihw <type>] [--bios seabios|ovmf] [--machine <type>] [--boot <order>]
158
160
  proxmox vm start <vmid> [--node <node>]
159
161
  proxmox vm stop <vmid> [--node <node>]
160
162
  proxmox vm reboot <vmid> [--node <node>]
@@ -162,6 +164,16 @@ proxmox vm suspend <vmid> [--node <node>]
162
164
  proxmox vm resume <vmid> [--node <node>]
163
165
  proxmox vm delete <vmid> [--node <node>] [--force] [--purge]
164
166
 
167
+ # VM snapshots
168
+ proxmox vm snapshot list <vmid> [--node <node>]
169
+ proxmox vm snapshot create <vmid> <snapname> [--description <text>] [--vmstate 1]
170
+ proxmox vm snapshot show <vmid> <snapname> [--node <node>]
171
+ proxmox vm snapshot rollback <vmid> <snapname> [--start 1]
172
+ proxmox vm snapshot delete <vmid> <snapname> [--force 1]
173
+
174
+ # VM guest agent
175
+ proxmox vm agent interfaces <vmid> [--node <node>]
176
+
165
177
  # VM firewall
166
178
  proxmox vm firewall options <vmid> [--node <node>]
167
179
  proxmox vm firewall enable <vmid> [--node <node>]
@@ -11,12 +11,13 @@ Completed items are marked with a check. Implementation notes are preserved for
11
11
  - [x] **Firewall management** — cluster, node, VM, and container. Options, enable/disable, policy, rules (CRUD), aliases (cluster), ipsets with CIDR mgmt (cluster), refs.
12
12
  - [x] **Pool management** — `proxmox pool`: list, show, create, update, delete. Wraps `/pools`.
13
13
  - [x] **Shell completions** — `proxmox completion bash|zsh|fish`. Dynamic, introspects the parser tree.
14
+ - [x] **VM snapshot management** — `proxmox vm snapshot`: list, create, show, rollback, delete. Wraps `/nodes/{node}/qemu/{vmid}/snapshot`.
15
+ - [x] **QEMU guest agent interfaces** — `proxmox vm agent interfaces <vmid>`. Wraps `/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces`.
16
+ - [x] **Streaming task logs** — `proxmox task log <upid> [--follow]`. Polls `/nodes/{node}/tasks/{upid}/log`.
17
+ - [x] **Global flag hint** — If user places `--output` / `--dry-run` / etc. after the resource, a hint suggests the correct order.
14
18
 
15
19
  ## v1.1 — Polish & Usability
16
20
 
17
- - [ ] **Streaming task logs (`--follow`)**
18
- - `proxmox task log <upid> --follow` that streams task output in real time (like `tail -f`). Requires httpx streaming.
19
-
20
21
  - [ ] **Startup time optimization**
21
22
  - Current `proxmox --help` takes ~350ms. Lazy-load subcommand modules so only the requested resource's code is imported. Move `import rich`, `import yaml` inside formatter functions. Target: <200ms.
22
23
 
@@ -124,6 +124,15 @@ def register_vm_parser(subparsers: argparse._SubParsersAction) -> None:
124
124
  help="Force removal (1=yes, 0=no, default: 0)")
125
125
  snap_delete.set_defaults(func=_vm_snapshot_delete)
126
126
 
127
+ # --- agent ---
128
+ agent = vm_sub.add_parser("agent", help="Query QEMU guest agent")
129
+ agent_sub = agent.add_subparsers(dest="agent_action", title="agent actions", required=True)
130
+
131
+ agent_ifaces = agent_sub.add_parser("interfaces", help="List network interfaces via guest agent")
132
+ agent_ifaces.add_argument("vmid", type=vmid_type, help="VM ID")
133
+ agent_ifaces.add_argument("--node", help="Node name (auto-detected if omitted)")
134
+ agent_ifaces.set_defaults(func=_vm_agent_interfaces)
135
+
127
136
  # --- firewall ---
128
137
  fw = vm_sub.add_parser("firewall", help="Manage VM firewall")
129
138
  fw_sub = fw.add_subparsers(dest="fw_resource", title="resources", required=True)
@@ -365,6 +374,28 @@ def _vm_delete(args: argparse.Namespace, client: ProxmoxClient) -> dict:
365
374
  return result if isinstance(result, dict) else {"data": result}
366
375
 
367
376
 
377
+ # ---------------------------------------------------------------------------
378
+ # VM guest agent handlers
379
+ # ---------------------------------------------------------------------------
380
+
381
+ def _vm_agent_interfaces(args: argparse.Namespace, client: ProxmoxClient) -> dict | list:
382
+ """Retrieve network interfaces via QEMU guest agent.
383
+
384
+ Requires qemu-guest-agent installed in the VM and agent enabled in VM options.
385
+ """
386
+ node = _resolve_node(client, args.node, args.vmid)
387
+ if not node:
388
+ return {"error": f"VM {args.vmid} not found"}
389
+ result = client.get(f"/nodes/{node}/qemu/{args.vmid}/agent/network-get-interfaces")
390
+ # The result is a list of interfaces, each with 'name', 'ip-addresses', etc.
391
+ if isinstance(result, list):
392
+ for iface in result:
393
+ if isinstance(iface, dict):
394
+ iface["_node"] = node
395
+ iface["_vmid"] = args.vmid
396
+ return result
397
+
398
+
368
399
  # ---------------------------------------------------------------------------
369
400
  # VM snapshot handlers
370
401
  # ---------------------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "proxcli"
3
- version = "0.8.1"
3
+ version = "0.8.2"
4
4
  description = "A CLI tool to interact with Proxmox VE nodes and clusters via the REST API"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,5 +1,5 @@
1
1
  version = 1
2
- revision = 3
2
+ revision = 2
3
3
  requires-python = ">=3.10"
4
4
 
5
5
  [[package]]
@@ -254,7 +254,7 @@ wheels = [
254
254
 
255
255
  [[package]]
256
256
  name = "proxcli"
257
- version = "0.8.1"
257
+ version = "0.8.2"
258
258
  source = { editable = "." }
259
259
  dependencies = [
260
260
  { name = "httpx" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes