proxcli 0.8.0__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.
- {proxcli-0.8.0 → proxcli-0.8.2}/.github/workflows/ci.yml +1 -1
- {proxcli-0.8.0 → proxcli-0.8.2}/CHANGELOG.md +20 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/PKG-INFO +14 -2
- {proxcli-0.8.0 → proxcli-0.8.2}/README.md +13 -1
- {proxcli-0.8.0 → proxcli-0.8.2}/TODO.md +4 -3
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/vm.py +141 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/pyproject.toml +1 -1
- {proxcli-0.8.0 → proxcli-0.8.2}/uv.lock +1 -1
- {proxcli-0.8.0 → proxcli-0.8.2}/.env.example +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/.gitignore +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/.python-version +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/AGENTS.md +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/PLAN.md +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/PROJECT.md +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/PROMPT.md +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/auth.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/cluster.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/completion.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/container.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/firewall_helpers.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/main.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/node.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/pool.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/storage.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/cli/tasks.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/client/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/client/auth.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/client/client.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/client/exceptions.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/config/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/config/config.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/config/models.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/output/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/output/formatter.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/output/json_fmt.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/output/table_fmt.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/output/yaml_fmt.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/utils/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/utils/helpers.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/proxmox/utils/logging.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/conftest.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_auth.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_cli/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_cli/test_main.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_client.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_config.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_integration/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_output/__init__.py +0 -0
- {proxcli-0.8.0 → proxcli-0.8.2}/tests/test_output/test_formatter.py +0 -0
|
@@ -7,6 +7,24 @@ 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
|
+
|
|
22
|
+
## [0.8.1] - 2026-06-20
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- **vm snapshot** management: ``list``, ``create``, ``show``, ``rollback``,
|
|
26
|
+
``delete``. Wraps ``/nodes/{node}/qemu/{vmid}/snapshot`` endpoints.
|
|
27
|
+
|
|
10
28
|
## [0.8.0] - 2026-06-20
|
|
11
29
|
|
|
12
30
|
### Fixed
|
|
@@ -118,6 +136,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
118
136
|
- CSRF ticket auto-refresh on 401.
|
|
119
137
|
- AI-agent-friendly: default JSON output, strict exit codes, `--dry-run` mode.
|
|
120
138
|
|
|
139
|
+
[0.8.2]: https://github.com/xezpeleta/proxcli/releases/tag/v0.8.2
|
|
140
|
+
[0.8.1]: https://github.com/xezpeleta/proxcli/releases/tag/v0.8.1
|
|
121
141
|
[0.8.0]: https://github.com/xezpeleta/proxcli/releases/tag/v0.8.0
|
|
122
142
|
[0.7.2]: https://github.com/xezpeleta/proxcli/releases/tag/v0.7.2
|
|
123
143
|
[0.7.1]: https://github.com/xezpeleta/proxcli/releases/tag/v0.7.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proxcli
|
|
3
|
-
Version: 0.8.
|
|
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> --
|
|
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> --
|
|
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
|
|
|
@@ -84,6 +84,55 @@ def register_vm_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
84
84
|
vm_delete.add_argument("--purge", action="store_true", help="Purge VM from all configurations")
|
|
85
85
|
vm_delete.set_defaults(func=_vm_delete)
|
|
86
86
|
|
|
87
|
+
# --- snapshot ---
|
|
88
|
+
snap = vm_sub.add_parser("snapshot", help="Manage VM snapshots")
|
|
89
|
+
snap_sub = snap.add_subparsers(dest="snap_action", title="snapshot actions", required=True)
|
|
90
|
+
|
|
91
|
+
snap_list = snap_sub.add_parser("list", help="List snapshots")
|
|
92
|
+
snap_list.add_argument("vmid", type=vmid_type, help="VM ID")
|
|
93
|
+
snap_list.add_argument("--node", help="Node name (auto-detected if omitted)")
|
|
94
|
+
snap_list.set_defaults(func=_vm_snapshot_list)
|
|
95
|
+
|
|
96
|
+
snap_create = snap_sub.add_parser("create", help="Create a snapshot")
|
|
97
|
+
snap_create.add_argument("vmid", type=vmid_type, help="VM ID")
|
|
98
|
+
snap_create.add_argument("snapname", help="Snapshot name")
|
|
99
|
+
snap_create.add_argument("--node", help="Node name (auto-detected if omitted)")
|
|
100
|
+
snap_create.add_argument("--description", default=None, help="Snapshot description")
|
|
101
|
+
snap_create.add_argument("--vmstate", type=int, choices=[0, 1], default=0,
|
|
102
|
+
help="Include RAM state (1=yes, 0=no, default: 0)")
|
|
103
|
+
snap_create.set_defaults(func=_vm_snapshot_create)
|
|
104
|
+
|
|
105
|
+
snap_show = snap_sub.add_parser("show", help="Show snapshot details")
|
|
106
|
+
snap_show.add_argument("vmid", type=vmid_type, help="VM ID")
|
|
107
|
+
snap_show.add_argument("snapname", help="Snapshot name")
|
|
108
|
+
snap_show.add_argument("--node", help="Node name (auto-detected if omitted)")
|
|
109
|
+
snap_show.set_defaults(func=_vm_snapshot_show)
|
|
110
|
+
|
|
111
|
+
snap_rollback = snap_sub.add_parser("rollback", help="Rollback to a snapshot")
|
|
112
|
+
snap_rollback.add_argument("vmid", type=vmid_type, help="VM ID")
|
|
113
|
+
snap_rollback.add_argument("snapname", help="Snapshot name")
|
|
114
|
+
snap_rollback.add_argument("--node", help="Node name (auto-detected if omitted)")
|
|
115
|
+
snap_rollback.add_argument("--start", type=int, choices=[0, 1], default=0,
|
|
116
|
+
help="Start VM after rollback (1=yes, 0=no, default: 0)")
|
|
117
|
+
snap_rollback.set_defaults(func=_vm_snapshot_rollback)
|
|
118
|
+
|
|
119
|
+
snap_delete = snap_sub.add_parser("delete", help="Delete a snapshot")
|
|
120
|
+
snap_delete.add_argument("vmid", type=vmid_type, help="VM ID")
|
|
121
|
+
snap_delete.add_argument("snapname", help="Snapshot name")
|
|
122
|
+
snap_delete.add_argument("--node", help="Node name (auto-detected if omitted)")
|
|
123
|
+
snap_delete.add_argument("--force", type=int, choices=[0, 1], default=0,
|
|
124
|
+
help="Force removal (1=yes, 0=no, default: 0)")
|
|
125
|
+
snap_delete.set_defaults(func=_vm_snapshot_delete)
|
|
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
|
+
|
|
87
136
|
# --- firewall ---
|
|
88
137
|
fw = vm_sub.add_parser("firewall", help="Manage VM firewall")
|
|
89
138
|
fw_sub = fw.add_subparsers(dest="fw_resource", title="resources", required=True)
|
|
@@ -325,6 +374,98 @@ def _vm_delete(args: argparse.Namespace, client: ProxmoxClient) -> dict:
|
|
|
325
374
|
return result if isinstance(result, dict) else {"data": result}
|
|
326
375
|
|
|
327
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
|
+
|
|
399
|
+
# ---------------------------------------------------------------------------
|
|
400
|
+
# VM snapshot handlers
|
|
401
|
+
# ---------------------------------------------------------------------------
|
|
402
|
+
|
|
403
|
+
def _vm_snapshot_list(args: argparse.Namespace, client: ProxmoxClient) -> dict | list:
|
|
404
|
+
node = _resolve_node(client, args.node, args.vmid)
|
|
405
|
+
if not node:
|
|
406
|
+
return {"error": f"VM {args.vmid} not found"}
|
|
407
|
+
result = client.get(f"/nodes/{node}/qemu/{args.vmid}/snapshot")
|
|
408
|
+
# Add _node for consistency
|
|
409
|
+
if isinstance(result, list):
|
|
410
|
+
for snap in result:
|
|
411
|
+
if isinstance(snap, dict):
|
|
412
|
+
snap["_node"] = node
|
|
413
|
+
snap["_vmid"] = args.vmid
|
|
414
|
+
return result
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def _vm_snapshot_create(args: argparse.Namespace, client: ProxmoxClient) -> dict:
|
|
418
|
+
node = _resolve_node(client, args.node, args.vmid)
|
|
419
|
+
if not node:
|
|
420
|
+
return {"error": f"VM {args.vmid} not found"}
|
|
421
|
+
data: dict = {"snapname": args.snapname}
|
|
422
|
+
if args.description:
|
|
423
|
+
data["description"] = args.description
|
|
424
|
+
if args.vmstate:
|
|
425
|
+
data["vmstate"] = args.vmstate
|
|
426
|
+
result = client.post(f"/nodes/{node}/qemu/{args.vmid}/snapshot", data=data)
|
|
427
|
+
return result if isinstance(result, dict) else {"data": result}
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def _vm_snapshot_show(args: argparse.Namespace, client: ProxmoxClient) -> dict:
|
|
431
|
+
node = _resolve_node(client, args.node, args.vmid)
|
|
432
|
+
if not node:
|
|
433
|
+
return {"error": f"VM {args.vmid} not found"}
|
|
434
|
+
result = client.get(f"/nodes/{node}/qemu/{args.vmid}/snapshot/{args.snapname}")
|
|
435
|
+
if isinstance(result, dict):
|
|
436
|
+
result["_node"] = node
|
|
437
|
+
result["_vmid"] = args.vmid
|
|
438
|
+
return result
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def _vm_snapshot_rollback(args: argparse.Namespace, client: ProxmoxClient) -> dict:
|
|
442
|
+
node = _resolve_node(client, args.node, args.vmid)
|
|
443
|
+
if not node:
|
|
444
|
+
return {"error": f"VM {args.vmid} not found"}
|
|
445
|
+
data: dict = {}
|
|
446
|
+
if args.start:
|
|
447
|
+
data["start"] = args.start
|
|
448
|
+
result = client.post(
|
|
449
|
+
f"/nodes/{node}/qemu/{args.vmid}/snapshot/{args.snapname}/rollback",
|
|
450
|
+
data=data or None,
|
|
451
|
+
)
|
|
452
|
+
return result if isinstance(result, dict) else {"data": result}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def _vm_snapshot_delete(args: argparse.Namespace, client: ProxmoxClient) -> dict:
|
|
456
|
+
node = _resolve_node(client, args.node, args.vmid)
|
|
457
|
+
if not node:
|
|
458
|
+
return {"error": f"VM {args.vmid} not found"}
|
|
459
|
+
params: dict = {}
|
|
460
|
+
if args.force:
|
|
461
|
+
params["force"] = args.force
|
|
462
|
+
result = client.delete(
|
|
463
|
+
f"/nodes/{node}/qemu/{args.vmid}/snapshot/{args.snapname}",
|
|
464
|
+
params=params or None,
|
|
465
|
+
)
|
|
466
|
+
return result if isinstance(result, dict) else {"data": result}
|
|
467
|
+
|
|
468
|
+
|
|
328
469
|
# ---------------------------------------------------------------------------
|
|
329
470
|
# VM firewall handlers
|
|
330
471
|
# ---------------------------------------------------------------------------
|
|
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
|
|
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
|