proxcli 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.
- proxcli-0.1.0/.github/workflows/ci.yml +54 -0
- proxcli-0.1.0/.gitignore +23 -0
- proxcli-0.1.0/.python-version +1 -0
- proxcli-0.1.0/CHANGELOG.md +29 -0
- proxcli-0.1.0/PKG-INFO +262 -0
- proxcli-0.1.0/PLAN.md +769 -0
- proxcli-0.1.0/PROJECT.md +168 -0
- proxcli-0.1.0/PROMPT.md +100 -0
- proxcli-0.1.0/README.md +239 -0
- proxcli-0.1.0/proxmox/__init__.py +0 -0
- proxcli-0.1.0/proxmox/cli/__init__.py +0 -0
- proxcli-0.1.0/proxmox/cli/auth.py +130 -0
- proxcli-0.1.0/proxmox/cli/cluster.py +21 -0
- proxcli-0.1.0/proxmox/cli/container.py +157 -0
- proxcli-0.1.0/proxmox/cli/main.py +231 -0
- proxcli-0.1.0/proxmox/cli/node.py +55 -0
- proxcli-0.1.0/proxmox/cli/storage.py +63 -0
- proxcli-0.1.0/proxmox/cli/tasks.py +65 -0
- proxcli-0.1.0/proxmox/cli/vm.py +211 -0
- proxcli-0.1.0/proxmox/client/__init__.py +0 -0
- proxcli-0.1.0/proxmox/client/auth.py +113 -0
- proxcli-0.1.0/proxmox/client/client.py +217 -0
- proxcli-0.1.0/proxmox/client/exceptions.py +43 -0
- proxcli-0.1.0/proxmox/config/__init__.py +0 -0
- proxcli-0.1.0/proxmox/config/config.py +98 -0
- proxcli-0.1.0/proxmox/config/models.py +51 -0
- proxcli-0.1.0/proxmox/output/__init__.py +0 -0
- proxcli-0.1.0/proxmox/output/formatter.py +26 -0
- proxcli-0.1.0/proxmox/output/json_fmt.py +11 -0
- proxcli-0.1.0/proxmox/output/table_fmt.py +64 -0
- proxcli-0.1.0/proxmox/output/yaml_fmt.py +12 -0
- proxcli-0.1.0/proxmox/utils/__init__.py +0 -0
- proxcli-0.1.0/proxmox/utils/helpers.py +14 -0
- proxcli-0.1.0/proxmox/utils/logging.py +15 -0
- proxcli-0.1.0/pyproject.toml +58 -0
- proxcli-0.1.0/tests/__init__.py +0 -0
- proxcli-0.1.0/tests/conftest.py +50 -0
- proxcli-0.1.0/tests/test_auth.py +84 -0
- proxcli-0.1.0/tests/test_cli/__init__.py +0 -0
- proxcli-0.1.0/tests/test_cli/test_main.py +67 -0
- proxcli-0.1.0/tests/test_client.py +121 -0
- proxcli-0.1.0/tests/test_config.py +125 -0
- proxcli-0.1.0/tests/test_integration/__init__.py +0 -0
- proxcli-0.1.0/tests/test_output/__init__.py +0 -0
- proxcli-0.1.0/tests/test_output/test_formatter.py +49 -0
- proxcli-0.1.0/uv.lock +650 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-24.04
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
14
|
+
|
|
15
|
+
- uses: astral-sh/setup-uv@d4a5f06b29e0840685266df17132b0834efba237 # v5.2.2
|
|
16
|
+
with:
|
|
17
|
+
enable-cache: true
|
|
18
|
+
|
|
19
|
+
- run: uv sync
|
|
20
|
+
- run: uv run ruff check .
|
|
21
|
+
|
|
22
|
+
test:
|
|
23
|
+
runs-on: ubuntu-24.04
|
|
24
|
+
strategy:
|
|
25
|
+
matrix:
|
|
26
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
29
|
+
|
|
30
|
+
- uses: astral-sh/setup-uv@d4a5f06b29e0840685266df17132b0834efba237 # v5.2.2
|
|
31
|
+
with:
|
|
32
|
+
enable-cache: true
|
|
33
|
+
|
|
34
|
+
- run: uv python install ${{ matrix.python-version }}
|
|
35
|
+
- run: uv sync --python ${{ matrix.python-version }}
|
|
36
|
+
- run: uv run pytest --cov=proxmox.client --cov=proxmox.config --cov=proxmox.output --cov-report=xml
|
|
37
|
+
|
|
38
|
+
build:
|
|
39
|
+
runs-on: ubuntu-24.04
|
|
40
|
+
needs: [lint, test]
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
43
|
+
|
|
44
|
+
- uses: astral-sh/setup-uv@d4a5f06b29e0840685266df17132b0834efba237 # v5.2.2
|
|
45
|
+
with:
|
|
46
|
+
enable-cache: true
|
|
47
|
+
|
|
48
|
+
- run: uv sync
|
|
49
|
+
- run: uv build
|
|
50
|
+
|
|
51
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.0
|
|
52
|
+
with:
|
|
53
|
+
name: dist
|
|
54
|
+
path: dist/
|
proxcli-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# IDE / Editor
|
|
13
|
+
*.swp
|
|
14
|
+
*.swo
|
|
15
|
+
*~
|
|
16
|
+
|
|
17
|
+
# Coverage
|
|
18
|
+
.coverage
|
|
19
|
+
htmlcov/
|
|
20
|
+
coverage.xml
|
|
21
|
+
|
|
22
|
+
# Rust cache
|
|
23
|
+
.ruff_cache/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-06-20
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Initial release.
|
|
14
|
+
- `proxmox auth login|status|clear` — credential management (password + API token).
|
|
15
|
+
- `proxmox vm` subcommand: `list`, `show`, `create`, `start`, `stop`, `reboot`, `suspend`, `resume`, `delete`.
|
|
16
|
+
- `proxmox container` subcommand: `list`, `show`, `create`, `start`, `stop`, `delete`.
|
|
17
|
+
- `proxmox node` subcommand: `list`, `show`, `status`.
|
|
18
|
+
- `proxmox storage` subcommand: `list`, `show`, `content`.
|
|
19
|
+
- `proxmox cluster` subcommand: `status`.
|
|
20
|
+
- `proxmox task` subcommand: `list`, `show`.
|
|
21
|
+
- Output formats: `json` (default), `table` (rich), `yaml`.
|
|
22
|
+
- Global flags: `--dry-run`, `--insecure`, `--timeout`, `--verbose`, `--output`, `--password-stdin`.
|
|
23
|
+
- `PROXMOX_PASSWORD` environment variable support.
|
|
24
|
+
- Credential persistence in XDG config (`~/.config/proxmox-cli/credentials.json`, `0600`).
|
|
25
|
+
- Retry with exponential backoff on 5xx responses.
|
|
26
|
+
- CSRF ticket auto-refresh on 401.
|
|
27
|
+
- AI-agent-friendly: default JSON output, strict exit codes, `--dry-run` mode.
|
|
28
|
+
|
|
29
|
+
[0.1.0]: https://github.com/xezpeleta/proxmox-cli/releases/tag/v0.1.0
|
proxcli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proxcli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A CLI tool to interact with Proxmox VE nodes and clusters via the REST API
|
|
5
|
+
Author-email: Xabi Ezpeleta <xezpeleta@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Intended Audience :: System Administrators
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: System :: Systems Administration
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: httpx>=0.27
|
|
19
|
+
Requires-Dist: pydantic>=2
|
|
20
|
+
Requires-Dist: pyyaml>=6
|
|
21
|
+
Requires-Dist: rich>=13
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# proxmox
|
|
25
|
+
|
|
26
|
+
A CLI tool to interact with [Proxmox VE](https://www.proxmox.com/) nodes and clusters via the REST API.
|
|
27
|
+
|
|
28
|
+
Designed to be easy for humans (table output, ergonomic flags) and AI agents (structured JSON, strict exit codes, `--dry-run`). Provides a higher-level abstraction over the raw Proxmox API.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
Requires Python 3.10+ and [uv](https://docs.astral.sh/uv/).
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# From PyPI
|
|
36
|
+
uv tool install proxmox
|
|
37
|
+
|
|
38
|
+
# From Git
|
|
39
|
+
uv tool install git+https://github.com/xezpeleta/proxmox-cli.git
|
|
40
|
+
|
|
41
|
+
# From local checkout
|
|
42
|
+
uv tool install .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quickstart
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Authenticate (password-based)
|
|
49
|
+
proxmox auth login --url https://192.168.1.10:8006 --username root@pam --password your_password
|
|
50
|
+
|
|
51
|
+
# Or with an API token
|
|
52
|
+
proxmox auth login --url https://192.168.1.10:8006 --username root@pam --api-token 'root@pam!my-token=deadbeef...'
|
|
53
|
+
|
|
54
|
+
# Check auth status
|
|
55
|
+
proxmox auth status
|
|
56
|
+
|
|
57
|
+
# List VMs
|
|
58
|
+
proxmox vm list
|
|
59
|
+
|
|
60
|
+
# Show a specific VM
|
|
61
|
+
proxmox vm show 100
|
|
62
|
+
|
|
63
|
+
# Create a VM
|
|
64
|
+
proxmox vm create --node pve01 --vmid 110 --memory 2048 --cores 2 --name webserver
|
|
65
|
+
|
|
66
|
+
# Start / stop / reboot
|
|
67
|
+
proxmox vm start 110
|
|
68
|
+
proxmox vm stop 110
|
|
69
|
+
proxmox vm reboot 110
|
|
70
|
+
|
|
71
|
+
# Delete (with purge)
|
|
72
|
+
proxmox vm delete 110 --purge
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Authentication
|
|
76
|
+
|
|
77
|
+
Credentials are stored in `~/.config/proxmox-cli/credentials.json` with restrictive permissions (`0600`).
|
|
78
|
+
|
|
79
|
+
### Auth methods
|
|
80
|
+
|
|
81
|
+
| Method | Command |
|
|
82
|
+
|---|---|
|
|
83
|
+
| Password | `proxmox auth login --url ... --username ... --password ...` |
|
|
84
|
+
| Password (stdin) | `echo "$PASS" \| proxmox auth login --url ... --username ... --password-stdin` |
|
|
85
|
+
| API token | `proxmox auth login --url ... --username ... --api-token 'user!tokenid=secret'` |
|
|
86
|
+
|
|
87
|
+
### Override credentials per command
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
proxmox --url https://other-pve:8006 --username admin@pam --password pass123 vm list
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Environment variable
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
export PROXMOX_PASSWORD=mysecret
|
|
97
|
+
proxmox vm list --username root@pam --url https://pve:8006
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Self-signed certificates
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
proxmox --insecure vm list
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Command Reference
|
|
107
|
+
|
|
108
|
+
### Global flags
|
|
109
|
+
|
|
110
|
+
| Flag | Default | Description |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `--url` | (config file) | Proxmox API URL |
|
|
113
|
+
| `--username` | (config file) | Username |
|
|
114
|
+
| `--password` | — | Password |
|
|
115
|
+
| `--password-stdin` | — | Read password from stdin |
|
|
116
|
+
| `--api-token` | — | API token (`user!tokenid=secret`) |
|
|
117
|
+
| `--output` | `json` | Output format: `json`, `table`, `yaml` |
|
|
118
|
+
| `--dry-run` | off | Print the API request without executing |
|
|
119
|
+
| `--insecure` | off | Skip TLS verification |
|
|
120
|
+
| `--timeout` | `30` | Request timeout in seconds |
|
|
121
|
+
| `--verbose` | off | Debug output to stderr |
|
|
122
|
+
| `--version` | — | Show version |
|
|
123
|
+
|
|
124
|
+
### Auth
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
proxmox auth login # Save credentials
|
|
128
|
+
proxmox auth status # Show current auth context
|
|
129
|
+
proxmox auth clear # Remove saved credentials
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### VM (QEMU)
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
proxmox vm list [--node <node>]
|
|
136
|
+
proxmox vm show <vmid> [--node <node>]
|
|
137
|
+
proxmox vm create --node <node> --vmid <id> --memory <mb> [--cores <n>] [--name <name>] [--storage <name>] [--net <config>]
|
|
138
|
+
proxmox vm start <vmid> [--node <node>]
|
|
139
|
+
proxmox vm stop <vmid> [--node <node>]
|
|
140
|
+
proxmox vm reboot <vmid> [--node <node>]
|
|
141
|
+
proxmox vm suspend <vmid> [--node <node>]
|
|
142
|
+
proxmox vm resume <vmid> [--node <node>]
|
|
143
|
+
proxmox vm delete <vmid> [--node <node>] [--force] [--purge]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Container (LXC)
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
proxmox container list [--node <node>]
|
|
150
|
+
proxmox container show <vmid> [--node <node>]
|
|
151
|
+
proxmox container create --node <node> --vmid <id> --ostemplate <tmpl> [--memory <mb>] [--cores <n>] [--storage <name>]
|
|
152
|
+
proxmox container start <vmid> [--node <node>]
|
|
153
|
+
proxmox container stop <vmid> [--node <node>]
|
|
154
|
+
proxmox container delete <vmid> [--node <node>] [--force] [--purge]
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Node
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
proxmox node list
|
|
161
|
+
proxmox node show <node>
|
|
162
|
+
proxmox node status [<node>]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Storage
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
proxmox storage list [--node <node>]
|
|
169
|
+
proxmox storage show <storage>
|
|
170
|
+
proxmox storage content <storage> [--node <node>]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Cluster
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
proxmox cluster status
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Task
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
proxmox task list [--node <node>]
|
|
183
|
+
proxmox task show <upid>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Output Formats
|
|
187
|
+
|
|
188
|
+
### JSON (default)
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
[
|
|
192
|
+
{
|
|
193
|
+
"vmid": 100,
|
|
194
|
+
"name": "webserver",
|
|
195
|
+
"status": "running",
|
|
196
|
+
"cpu": 0.05,
|
|
197
|
+
"mem": 2048
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Table
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
┌──────┬───────────┬─────────┬───────┬──────┐
|
|
206
|
+
│ vmid │ name │ status │ cpu │ mem │
|
|
207
|
+
├──────┼───────────┼─────────┼───────┼──────┤
|
|
208
|
+
│ 100 │ webserver │ running │ 0.05 │ 2048 │
|
|
209
|
+
└──────┴───────────┴─────────┴───────┴──────┘
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### YAML
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
- vmid: 100
|
|
216
|
+
name: webserver
|
|
217
|
+
status: running
|
|
218
|
+
cpu: 0.05
|
|
219
|
+
mem: 2048
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## AI Agent Usage
|
|
223
|
+
|
|
224
|
+
Every command emits valid JSON by default (stdout) and diagnostic messages on stderr. Exit codes follow Unix conventions.
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Dry-run to preview the API call
|
|
228
|
+
proxmox --dry-run vm create --node pve01 --vmid 110 --memory 1024
|
|
229
|
+
|
|
230
|
+
# Machine-parseable JSON output
|
|
231
|
+
proxmox --output json vm list | jq '.[] | {vmid, status}'
|
|
232
|
+
|
|
233
|
+
# Check exit code
|
|
234
|
+
proxmox vm show 999 || echo "VM not found"
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Development
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# Clone
|
|
241
|
+
git clone https://github.com/xezpeleta/proxmox-cli.git
|
|
242
|
+
cd proxmox-cli
|
|
243
|
+
|
|
244
|
+
# Install dev dependencies
|
|
245
|
+
uv sync
|
|
246
|
+
|
|
247
|
+
# Run tests
|
|
248
|
+
uv run pytest
|
|
249
|
+
|
|
250
|
+
# Run with coverage
|
|
251
|
+
uv run pytest --cov=proxmox --cov-report=term-missing
|
|
252
|
+
|
|
253
|
+
# Lint
|
|
254
|
+
uv run ruff check .
|
|
255
|
+
|
|
256
|
+
# Build
|
|
257
|
+
uv build
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
MIT
|