pmox 0.1.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.
pmox-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Luke Ward
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
pmox-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,228 @@
1
+ Metadata-Version: 2.4
2
+ Name: pmox
3
+ Version: 0.1.0
4
+ Summary: A friendly, AI-friendly CLI to explore and manage a Proxmox VE cluster.
5
+ Author: Luke Ward
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/lukebward/pmox
8
+ Project-URL: Repository, https://github.com/lukebward/pmox
9
+ Project-URL: Issues, https://github.com/lukebward/pmox/issues
10
+ Project-URL: Changelog, https://github.com/lukebward/pmox/blob/main/CHANGELOG.md
11
+ Keywords: proxmox,pve,virtualization,homelab,infrastructure,cli
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: System :: Systems Administration
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: proxmoxer>=2.0
24
+ Requires-Dist: requests>=2.28
25
+ Requires-Dist: typer>=0.12
26
+ Requires-Dist: rich>=13.0
27
+ Requires-Dist: python-dotenv>=1.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # pmox
34
+
35
+ A friendly, **AI-friendly** command-line tool to explore and manage a [Proxmox VE](https://www.proxmox.com/) cluster.
36
+
37
+ `pmox` wraps the Proxmox API with clean commands, pretty tables for humans, and a
38
+ `--json` mode for machines. It is **read-only by default** so you (or an AI) can
39
+ explore safely, with two layers of protection before anything can change.
40
+
41
+ ```
42
+ pmox nodes list
43
+ pmox vm list
44
+ pmox vm status 100
45
+ pmox --dangerous vm start 100
46
+ pmox --dangerous vm delete 100 --yes
47
+ ```
48
+
49
+ ## Safety model
50
+
51
+ Two independent gates protect your cluster:
52
+
53
+ | Gate | Flag | Applies to | Default |
54
+ |------|------|-----------|---------|
55
+ | **Dangerous mode** | `--dangerous` (or `PMOX_DANGEROUS=1`) | *any* state change (power, create, delete, clone, migrate, snapshot) | **off — read-only** |
56
+ | **Confirmation** | `--yes` | *destructive* ops: `delete`, `stop`, `reset`, `migrate`, `rollback` | required when non-interactive |
57
+
58
+ So:
59
+
60
+ - **Explore** with no flags — nothing can be modified.
61
+ - **Change** something benign (e.g. `start`) — add `--dangerous`.
62
+ - **Destroy** something (e.g. `delete`) — add `--dangerous` **and** `--yes`.
63
+
64
+ When running non-interactively (e.g. an AI calling the CLI), a destructive op
65
+ *without* `--yes` is refused rather than silently prompted. Exit codes:
66
+ `0` ok · `1` error · `2` config · `3` confirmation required · `4` read-only.
67
+
68
+ ## Install
69
+
70
+ From [PyPI](https://pypi.org/project/pmox/):
71
+
72
+ ```bash
73
+ pip install pmox
74
+ ```
75
+
76
+ Or install from source (editable), e.g. for development:
77
+
78
+ **macOS / Linux**
79
+
80
+ ```bash
81
+ git clone https://github.com/lukebward/pmox.git
82
+ cd pmox
83
+ python3 -m venv .venv
84
+ source .venv/bin/activate
85
+ pip install -e .
86
+ ```
87
+
88
+ **Windows (PowerShell)**
89
+
90
+ ```powershell
91
+ git clone https://github.com/lukebward/pmox.git
92
+ cd pmox
93
+ python -m venv .venv
94
+ .venv\Scripts\Activate.ps1
95
+ pip install -e .
96
+ ```
97
+
98
+ This puts a `pmox` command on your PATH. You can also run it without installing
99
+ via `python -m pmox`.
100
+
101
+ ## Configure
102
+
103
+ Create an **API token** in Proxmox: *Datacenter → Permissions → API Tokens*.
104
+ For full management, give the token the privileges it needs (or, for a homelab,
105
+ uncheck "Privilege Separation" so it inherits the user's permissions).
106
+
107
+ Provide configuration via environment variables, a `.env` file, a TOML config
108
+ file, or CLI flags (highest priority last):
109
+
110
+ **`.env`** (copy from `.env.example`):
111
+
112
+ ```ini
113
+ PROXMOX_HOST=192.168.1.10
114
+ PROXMOX_TOKEN_ID=root@pam!pmox
115
+ PROXMOX_TOKEN_SECRET=00000000-0000-0000-0000-000000000000
116
+ PROXMOX_VERIFY_SSL=false
117
+ ```
118
+
119
+ **TOML** at `~/.config/pmox/config.toml` (or point `--config` / `PMOX_CONFIG` at one):
120
+
121
+ ```toml
122
+ host = "192.168.1.10"
123
+ token_id = "root@pam!pmox"
124
+ token_secret = "..."
125
+ verify_ssl = false
126
+ ```
127
+
128
+ > TLS verification defaults to **off** because homelab Proxmox uses self-signed
129
+ > certificates. Set `PROXMOX_VERIFY_SSL=true` (or `--verify-ssl`) if your node
130
+ > has a CA-signed cert.
131
+
132
+ ## Commands
133
+
134
+ ```
135
+ pmox version Proxmox version of the connected node
136
+ pmox nodes list nodes + CPU/mem/uptime
137
+ pmox nodes status <node> detailed node status
138
+ pmox cluster status cluster membership/quorum
139
+ pmox cluster resources [--type] everything the cluster sees (vm|node|storage|...)
140
+
141
+ pmox vm list [--node N] QEMU VMs (cluster-wide)
142
+ pmox vm status <vmid> live status (node auto-resolved)
143
+ pmox vm config <vmid> configuration
144
+ pmox vm start|shutdown|reboot|suspend|resume <vmid> (needs --dangerous)
145
+ pmox vm stop|reset <vmid> (needs --dangerous --yes)
146
+ pmox vm create <vmid> --node N [--name X] [-o key=value ...]
147
+ pmox vm clone <vmid> --newid <id> [--name X] [--full] [--target N]
148
+ pmox vm migrate <vmid> --target N [--online] (needs --dangerous --yes)
149
+ pmox vm delete <vmid> [--purge] (needs --dangerous --yes)
150
+ pmox vm snapshot list|create|delete|rollback <vmid> ...
151
+
152
+ pmox ct ... same as `vm`, for LXC containers
153
+ pmox storage list [--node N] storage usage
154
+ pmox storage content <id> --node N
155
+ pmox task list --node N recent tasks
156
+ pmox task status|log <upid> --node N
157
+ ```
158
+
159
+ `--node` is optional for guest commands — `pmox` finds which node a VMID lives on
160
+ via the cluster resources endpoint.
161
+
162
+ ## Using with an AI (e.g. Claude)
163
+
164
+ Point the AI at the CLI and let it run commands via the shell. Because your shell
165
+ captures pmox's output, it **emits JSON automatically** — the model gets
166
+ structured output to parse with no flag, while you still see tables at your own
167
+ terminal. (Force it either way with `--json` / `--no-json`, or globally with
168
+ `PMOX_JSON=1` / `PMOX_JSON=0`.)
169
+
170
+ - Leave dangerous mode **off** for exploration. The AI literally cannot change
171
+ anything without you adding `--dangerous` (and `--yes` for destructive ops),
172
+ so accidental damage is impossible during read-only investigation.
173
+
174
+ ```bash
175
+ pmox cluster resources # AI explores freely, read-only (JSON auto)
176
+ pmox vm status 100
177
+ ```
178
+
179
+ When you *want* the AI to act, tell it to include the flags explicitly:
180
+
181
+ ```bash
182
+ pmox --dangerous vm start 100
183
+ pmox --dangerous vm snapshot create 100 before-upgrade
184
+ ```
185
+
186
+ ## Claude Code plugin
187
+
188
+ This repo is also a Claude Code plugin (in [`plugin/`](plugin/)), so Claude can
189
+ drive `pmox` for you with the safety gates intact:
190
+
191
+ ```
192
+ /plugin marketplace add lukebward/pmox
193
+ /plugin install pmox@pmox-marketplace
194
+ ```
195
+
196
+ It adds a `proxmox` skill (auto-activates when you ask about your cluster) plus
197
+ `/pmox:cluster-status`, `/pmox:list-guests`, and `/pmox:run`. Install the CLI
198
+ first (`pipx install pmox`). See [`plugin/README.md`](plugin/README.md).
199
+
200
+ ## Development & tests
201
+
202
+ The test-suite mocks the Proxmox API, so **no live cluster is required**.
203
+
204
+ ```bash
205
+ pip install -e ".[dev]"
206
+ pytest
207
+ ```
208
+
209
+ Tests cover config precedence, the safety gates, output formatting, the API
210
+ client's endpoint mapping, and the CLI end-to-end with an injected fake client.
211
+
212
+ ## Architecture
213
+
214
+ ```
215
+ pmox/
216
+ config.py Settings + precedence merge (file < env < flags)
217
+ client.py thin, injectable wrapper over proxmoxer (the only API surface)
218
+ output.py Rich tables + plain JSON; byte/uptime/percent formatters
219
+ safety.py the two gates: require_dangerous() and confirm()
220
+ cli.py Typer app wiring config + client + output + safety together
221
+ ```
222
+
223
+ Each module has one job and a clear interface, which is what makes the whole
224
+ thing straightforward to test with mocks.
225
+
226
+ ## License
227
+
228
+ [MIT](LICENSE) © 2026 Luke Ward
pmox-0.1.0/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # pmox
2
+
3
+ A friendly, **AI-friendly** command-line tool to explore and manage a [Proxmox VE](https://www.proxmox.com/) cluster.
4
+
5
+ `pmox` wraps the Proxmox API with clean commands, pretty tables for humans, and a
6
+ `--json` mode for machines. It is **read-only by default** so you (or an AI) can
7
+ explore safely, with two layers of protection before anything can change.
8
+
9
+ ```
10
+ pmox nodes list
11
+ pmox vm list
12
+ pmox vm status 100
13
+ pmox --dangerous vm start 100
14
+ pmox --dangerous vm delete 100 --yes
15
+ ```
16
+
17
+ ## Safety model
18
+
19
+ Two independent gates protect your cluster:
20
+
21
+ | Gate | Flag | Applies to | Default |
22
+ |------|------|-----------|---------|
23
+ | **Dangerous mode** | `--dangerous` (or `PMOX_DANGEROUS=1`) | *any* state change (power, create, delete, clone, migrate, snapshot) | **off — read-only** |
24
+ | **Confirmation** | `--yes` | *destructive* ops: `delete`, `stop`, `reset`, `migrate`, `rollback` | required when non-interactive |
25
+
26
+ So:
27
+
28
+ - **Explore** with no flags — nothing can be modified.
29
+ - **Change** something benign (e.g. `start`) — add `--dangerous`.
30
+ - **Destroy** something (e.g. `delete`) — add `--dangerous` **and** `--yes`.
31
+
32
+ When running non-interactively (e.g. an AI calling the CLI), a destructive op
33
+ *without* `--yes` is refused rather than silently prompted. Exit codes:
34
+ `0` ok · `1` error · `2` config · `3` confirmation required · `4` read-only.
35
+
36
+ ## Install
37
+
38
+ From [PyPI](https://pypi.org/project/pmox/):
39
+
40
+ ```bash
41
+ pip install pmox
42
+ ```
43
+
44
+ Or install from source (editable), e.g. for development:
45
+
46
+ **macOS / Linux**
47
+
48
+ ```bash
49
+ git clone https://github.com/lukebward/pmox.git
50
+ cd pmox
51
+ python3 -m venv .venv
52
+ source .venv/bin/activate
53
+ pip install -e .
54
+ ```
55
+
56
+ **Windows (PowerShell)**
57
+
58
+ ```powershell
59
+ git clone https://github.com/lukebward/pmox.git
60
+ cd pmox
61
+ python -m venv .venv
62
+ .venv\Scripts\Activate.ps1
63
+ pip install -e .
64
+ ```
65
+
66
+ This puts a `pmox` command on your PATH. You can also run it without installing
67
+ via `python -m pmox`.
68
+
69
+ ## Configure
70
+
71
+ Create an **API token** in Proxmox: *Datacenter → Permissions → API Tokens*.
72
+ For full management, give the token the privileges it needs (or, for a homelab,
73
+ uncheck "Privilege Separation" so it inherits the user's permissions).
74
+
75
+ Provide configuration via environment variables, a `.env` file, a TOML config
76
+ file, or CLI flags (highest priority last):
77
+
78
+ **`.env`** (copy from `.env.example`):
79
+
80
+ ```ini
81
+ PROXMOX_HOST=192.168.1.10
82
+ PROXMOX_TOKEN_ID=root@pam!pmox
83
+ PROXMOX_TOKEN_SECRET=00000000-0000-0000-0000-000000000000
84
+ PROXMOX_VERIFY_SSL=false
85
+ ```
86
+
87
+ **TOML** at `~/.config/pmox/config.toml` (or point `--config` / `PMOX_CONFIG` at one):
88
+
89
+ ```toml
90
+ host = "192.168.1.10"
91
+ token_id = "root@pam!pmox"
92
+ token_secret = "..."
93
+ verify_ssl = false
94
+ ```
95
+
96
+ > TLS verification defaults to **off** because homelab Proxmox uses self-signed
97
+ > certificates. Set `PROXMOX_VERIFY_SSL=true` (or `--verify-ssl`) if your node
98
+ > has a CA-signed cert.
99
+
100
+ ## Commands
101
+
102
+ ```
103
+ pmox version Proxmox version of the connected node
104
+ pmox nodes list nodes + CPU/mem/uptime
105
+ pmox nodes status <node> detailed node status
106
+ pmox cluster status cluster membership/quorum
107
+ pmox cluster resources [--type] everything the cluster sees (vm|node|storage|...)
108
+
109
+ pmox vm list [--node N] QEMU VMs (cluster-wide)
110
+ pmox vm status <vmid> live status (node auto-resolved)
111
+ pmox vm config <vmid> configuration
112
+ pmox vm start|shutdown|reboot|suspend|resume <vmid> (needs --dangerous)
113
+ pmox vm stop|reset <vmid> (needs --dangerous --yes)
114
+ pmox vm create <vmid> --node N [--name X] [-o key=value ...]
115
+ pmox vm clone <vmid> --newid <id> [--name X] [--full] [--target N]
116
+ pmox vm migrate <vmid> --target N [--online] (needs --dangerous --yes)
117
+ pmox vm delete <vmid> [--purge] (needs --dangerous --yes)
118
+ pmox vm snapshot list|create|delete|rollback <vmid> ...
119
+
120
+ pmox ct ... same as `vm`, for LXC containers
121
+ pmox storage list [--node N] storage usage
122
+ pmox storage content <id> --node N
123
+ pmox task list --node N recent tasks
124
+ pmox task status|log <upid> --node N
125
+ ```
126
+
127
+ `--node` is optional for guest commands — `pmox` finds which node a VMID lives on
128
+ via the cluster resources endpoint.
129
+
130
+ ## Using with an AI (e.g. Claude)
131
+
132
+ Point the AI at the CLI and let it run commands via the shell. Because your shell
133
+ captures pmox's output, it **emits JSON automatically** — the model gets
134
+ structured output to parse with no flag, while you still see tables at your own
135
+ terminal. (Force it either way with `--json` / `--no-json`, or globally with
136
+ `PMOX_JSON=1` / `PMOX_JSON=0`.)
137
+
138
+ - Leave dangerous mode **off** for exploration. The AI literally cannot change
139
+ anything without you adding `--dangerous` (and `--yes` for destructive ops),
140
+ so accidental damage is impossible during read-only investigation.
141
+
142
+ ```bash
143
+ pmox cluster resources # AI explores freely, read-only (JSON auto)
144
+ pmox vm status 100
145
+ ```
146
+
147
+ When you *want* the AI to act, tell it to include the flags explicitly:
148
+
149
+ ```bash
150
+ pmox --dangerous vm start 100
151
+ pmox --dangerous vm snapshot create 100 before-upgrade
152
+ ```
153
+
154
+ ## Claude Code plugin
155
+
156
+ This repo is also a Claude Code plugin (in [`plugin/`](plugin/)), so Claude can
157
+ drive `pmox` for you with the safety gates intact:
158
+
159
+ ```
160
+ /plugin marketplace add lukebward/pmox
161
+ /plugin install pmox@pmox-marketplace
162
+ ```
163
+
164
+ It adds a `proxmox` skill (auto-activates when you ask about your cluster) plus
165
+ `/pmox:cluster-status`, `/pmox:list-guests`, and `/pmox:run`. Install the CLI
166
+ first (`pipx install pmox`). See [`plugin/README.md`](plugin/README.md).
167
+
168
+ ## Development & tests
169
+
170
+ The test-suite mocks the Proxmox API, so **no live cluster is required**.
171
+
172
+ ```bash
173
+ pip install -e ".[dev]"
174
+ pytest
175
+ ```
176
+
177
+ Tests cover config precedence, the safety gates, output formatting, the API
178
+ client's endpoint mapping, and the CLI end-to-end with an injected fake client.
179
+
180
+ ## Architecture
181
+
182
+ ```
183
+ pmox/
184
+ config.py Settings + precedence merge (file < env < flags)
185
+ client.py thin, injectable wrapper over proxmoxer (the only API surface)
186
+ output.py Rich tables + plain JSON; byte/uptime/percent formatters
187
+ safety.py the two gates: require_dangerous() and confirm()
188
+ cli.py Typer app wiring config + client + output + safety together
189
+ ```
190
+
191
+ Each module has one job and a clear interface, which is what makes the whole
192
+ thing straightforward to test with mocks.
193
+
194
+ ## License
195
+
196
+ [MIT](LICENSE) © 2026 Luke Ward
@@ -0,0 +1,3 @@
1
+ """pmox - a friendly, AI-friendly CLI for exploring and managing a Proxmox VE cluster."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__": # pragma: no cover
4
+ main()