Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:00:27 +08:00
commit 0c6988a884
19 changed files with 5729 additions and 0 deletions

View File

@@ -0,0 +1,378 @@
# Proxmox API Reference
## Overview
The Proxmox API enables programmatic management of the cluster via REST. This reference focuses on common patterns for Python (proxmoxer) and Terraform/Ansible usage.
## Authentication Methods
### API Tokens (Recommended)
**Create API token via CLI:**
```bash
pveum user token add <user>@<realm> <token-id> --privsep 0
```
**Environment variables:**
```bash
export PROXMOX_VE_API_TOKEN="user@realm!token-id=secret"
export PROXMOX_VE_ENDPOINT="https://192.168.3.5:8006"
```
### Password Authentication
```bash
export PROXMOX_VE_USERNAME="root@pam"
export PROXMOX_VE_PASSWORD="password"
export PROXMOX_VE_ENDPOINT="https://192.168.3.5:8006"
```
## Python API Usage (proxmoxer)
### Installation
```bash
# Using uv inline script metadata
# /// script
# dependencies = ["proxmoxer", "requests"]
# ///
```
### Basic Connection
```python
#!/usr/bin/env python3
# /// script
# dependencies = ["proxmoxer", "requests"]
# ///
from proxmoxer import ProxmoxAPI
import os
# Connect using API token
proxmox = ProxmoxAPI(
os.getenv("PROXMOX_VE_ENDPOINT").replace("https://", "").replace(":8006", ""),
user=os.getenv("PROXMOX_VE_USERNAME"),
token_name=os.getenv("PROXMOX_VE_TOKEN_NAME"),
token_value=os.getenv("PROXMOX_VE_TOKEN_VALUE"),
verify_ssl=False
)
# OR using password
proxmox = ProxmoxAPI(
'192.168.3.5',
user='root@pam',
password=os.getenv("PROXMOX_VE_PASSWORD"),
verify_ssl=False
)
```
### Common Operations
**List VMs:**
```python
# Get all VMs across cluster
for node in proxmox.nodes.get():
node_name = node['node']
for vm in proxmox.nodes(node_name).qemu.get():
print(f"VM {vm['vmid']}: {vm['name']} on {node_name} - {vm['status']}")
```
**Get VM Configuration:**
```python
vmid = 101
node = "foxtrot"
vm_config = proxmox.nodes(node).qemu(vmid).config.get()
print(f"VM {vmid} config: {vm_config}")
```
**Clone Template:**
```python
template_id = 9000
new_vmid = 101
node = "foxtrot"
# Clone template
proxmox.nodes(node).qemu(template_id).clone.post(
newid=new_vmid,
name="docker-01-nexus",
full=1, # Full clone (not linked)
storage="local-lvm"
)
# Wait for clone to complete
import time
while True:
tasks = proxmox.nodes(node).tasks.get()
clone_task = next((t for t in tasks if t['type'] == 'qmclone' and str(t['id']) == str(new_vmid)), None)
if not clone_task or clone_task['status'] == 'stopped':
break
time.sleep(2)
```
**Update VM Configuration:**
```python
# Set cloud-init parameters
proxmox.nodes(node).qemu(vmid).config.put(
ipconfig0="ip=192.168.3.100/24,gw=192.168.3.1",
nameserver="192.168.3.1",
searchdomain="spaceships.work",
sshkeys="ssh-rsa AAAA..."
)
```
**Start/Stop VM:**
```python
# Start VM
proxmox.nodes(node).qemu(vmid).status.start.post()
# Stop VM (graceful)
proxmox.nodes(node).qemu(vmid).status.shutdown.post()
# Force stop
proxmox.nodes(node).qemu(vmid).status.stop.post()
```
**Delete VM:**
```python
proxmox.nodes(node).qemu(vmid).delete()
```
### Cluster Operations
**Get Cluster Status:**
```python
cluster_status = proxmox.cluster.status.get()
for node in cluster_status:
if node['type'] == 'node':
print(f"Node: {node['name']} - {node['online']}")
```
**Get Node Resources:**
```python
node_status = proxmox.nodes(node).status.get()
print(f"CPU: {node_status['cpu']*100:.1f}%")
print(f"Memory: {node_status['memory']['used']/1024**3:.1f}GB / {node_status['memory']['total']/1024**3:.1f}GB")
```
### Storage Operations
**List Storage:**
```python
for storage in proxmox.storage.get():
print(f"Storage: {storage['storage']} - Type: {storage['type']} - {storage['active']}")
```
**Get Storage Content:**
```python
storage = "local-lvm"
content = proxmox.storage(storage).content.get()
for item in content:
print(f"{item['volid']} - {item.get('vmid', 'N/A')} - {item['size']/1024**3:.1f}GB")
```
## Terraform Provider Patterns
### Basic Resource (VM from Clone)
```hcl
resource "proxmox_vm_qemu" "docker_host" {
name = "docker-01-nexus"
target_node = "foxtrot"
vmid = 101
clone = "ubuntu-template"
full_clone = true
cores = 4
memory = 8192
sockets = 1
network {
bridge = "vmbr0"
model = "virtio"
tag = 30 # VLAN 30
}
disk {
storage = "local-lvm"
type = "scsi"
size = "50G"
}
ipconfig0 = "ip=192.168.3.100/24,gw=192.168.3.1"
sshkeys = file("~/.ssh/id_rsa.pub")
}
```
### Data Sources
```hcl
# Get template information
data "proxmox_vm_qemu" "template" {
name = "ubuntu-template"
target_node = "foxtrot"
}
# Get storage information
data "proxmox_storage" "local_lvm" {
node = "foxtrot"
storage = "local-lvm"
}
```
## Ansible Module Patterns
### Create VM from Template
```yaml
- name: Clone template to create VM
community.proxmox.proxmox_kvm:
api_host: "{{ proxmox_api_host }}"
api_user: "{{ proxmox_api_user }}"
api_token_id: "{{ proxmox_token_id }}"
api_token_secret: "{{ proxmox_token_secret }}"
node: foxtrot
vmid: 101
name: docker-01-nexus
clone: ubuntu-template
full: true
storage: local-lvm
net:
net0: 'virtio,bridge=vmbr0,tag=30'
ipconfig:
ipconfig0: 'ip=192.168.3.100/24,gw=192.168.3.1'
cores: 4
memory: 8192
agent: 1
state: present
```
### Start VM
```yaml
- name: Start VM
community.proxmox.proxmox_kvm:
api_host: "{{ proxmox_api_host }}"
api_user: "{{ proxmox_api_user }}"
api_token_id: "{{ proxmox_token_id }}"
api_token_secret: "{{ proxmox_token_secret }}"
node: foxtrot
vmid: 101
state: started
```
## Matrix Cluster Specifics
### Node IP Addresses
```python
MATRIX_NODES = {
"foxtrot": "192.168.3.5",
"golf": "192.168.3.6",
"hotel": "192.168.3.7"
}
```
### Storage Pools
```python
STORAGE_POOLS = {
"local": "dir", # Local directory
"local-lvm": "lvmthin", # LVM thin on boot disk
"ceph-pool": "rbd" # CEPH RBD (when configured)
}
```
### Network Bridges
```python
BRIDGES = {
"vmbr0": "192.168.3.0/24", # Management + VLAN 9 (Corosync)
"vmbr1": "192.168.5.0/24", # CEPH Public (MTU 9000)
"vmbr2": "192.168.7.0/24" # CEPH Private (MTU 9000)
}
```
## Error Handling
### Python Example
```python
from proxmoxer import ProxmoxAPI, ResourceException
import sys
try:
proxmox = ProxmoxAPI('192.168.3.5', user='root@pam', password='pass', verify_ssl=False)
vm_config = proxmox.nodes('foxtrot').qemu(101).config.get()
except ResourceException as e:
print(f"API Error: {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Unexpected error: {e}", file=sys.stderr)
sys.exit(1)
```
### Ansible Example
```yaml
- name: Clone VM with error handling
community.proxmox.proxmox_kvm:
api_host: "{{ proxmox_api_host }}"
# ... config ...
register: clone_result
failed_when: false
- name: Check clone result
ansible.builtin.fail:
msg: "Failed to clone VM: {{ clone_result.msg }}"
when: clone_result.failed
```
## API Endpoints Reference
### Common Endpoints
```text
GET /api2/json/nodes # List nodes
GET /api2/json/nodes/{node}/qemu # List VMs on node
GET /api2/json/nodes/{node}/qemu/{vmid} # Get VM status
POST /api2/json/nodes/{node}/qemu/{vmid}/clone # Clone VM
PUT /api2/json/nodes/{node}/qemu/{vmid}/config # Update config
POST /api2/json/nodes/{node}/qemu/{vmid}/status/start # Start VM
POST /api2/json/nodes/{node}/qemu/{vmid}/status/shutdown # Stop VM
DELETE /api2/json/nodes/{node}/qemu/{vmid} # Delete VM
GET /api2/json/cluster/status # Cluster status
GET /api2/json/storage # List storage
```
## Best Practices
1. **Use API tokens** - More secure than password authentication
2. **Handle SSL properly** - Use `verify_ssl=True` with proper CA cert in production
3. **Check task completion** - Clone/migrate operations are async, poll for completion
4. **Error handling** - Always catch ResourceException and provide meaningful errors
5. **Rate limiting** - Don't hammer the API, add delays in loops
6. **Idempotency** - Check if resource exists before creating
7. **Use VMID ranges** - Reserve ranges for different purposes (templates: 9000-9999, VMs: 100-999)
## Further Reading
- [Proxmox VE API Documentation](https://pve.proxmox.com/pve-docs/api-viewer/)
- [proxmoxer GitHub](https://github.com/proxmoxer/proxmoxer)
- [community.proxmox Collection](https://docs.ansible.com/ansible/latest/collections/community/proxmox/)