Metadata-Version: 2.4
Name: hiveframe
Version: 0.1.7
Summary: Proxmox automation toolkit — define infrastructure as YAML, provision with one command
Project-URL: Homepage, https://codeberg.org/itzdrixxyy/hiveframe
Project-URL: Repository, https://codeberg.org/itzdrixxyy/hiveframe
Author: itzdrixxyy
License: MIT
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: click>=8.0
Requires-Dist: fastapi>=0.100
Requires-Dist: httpx>=0.24
Requires-Dist: jinja2>=3.1
Requires-Dist: proxmoxer>=2.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.31.0
Requires-Dist: rich>=13.0
Requires-Dist: uvicorn>=0.23
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.12.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
Description-Content-Type: text/markdown

# HiveFrame

**Proxmox automation toolkit — define infrastructure as YAML, provision with one command**

![PyPI](https://img.shields.io/pypi/v/hiveframe)
![Python](https://img.shields.io/badge/python-3.11%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)
[![Codeberg](https://img.shields.io/badge/codeberg-itzdrixxyy%2Fhiveframe-blue)](https://codeberg.org/itzdrixxyy/hiveframe)

---

## Installation

```bash
pip install hiveframe
```

---

## What it does

HiveFrame lets you define Proxmox infrastructure as YAML and provision it with one command. VLANs, VMs, firewall rules, and cloud-init config — all declarative, all version-controllable. Built for VMware refugees and MSPs who want GitOps-style workflows without enterprise tooling.

**Why not Terraform?** The Proxmox provider works but pulls in significant overhead for straightforward use cases. HiveFrame is the lightweight middle ground — a YAML file, a CLI, and no external state backends.

---

## Quick start

```bash
pip install hiveframe
hiveframe config init   # set up your Proxmox connection interactively
hiveframe init          # scaffold a stack.yaml with commented fields
hiveframe validate      # check it against the schema
hiveframe plan          # preview what will be created
hiveframe apply         # provision VLANs, VMs, and firewall rules
```

That's the full workflow. Everything else (`status`, `destroy`, `status --watch`) is documented below.

---

## Commands

| Command                          | Description                                               |
|----------------------------------|-----------------------------------------------------------|
| `hiveframe config init`          | Interactive wizard to create `~/.hiveframe/config.yaml`   |
| `hiveframe init`                 | Scaffold a new `stack.yaml` with commented fields         |
| `hiveframe validate`             | Validate `stack.yaml` against the schema                  |
| `hiveframe plan`                 | Dry-run — show what would be created or skipped           |
| `hiveframe apply`                | Provision VLANs, VMs, and firewall rules                  |
| `hiveframe status`               | Show live drift between Proxmox and the stack definition  |
| `hiveframe status --watch`       | Poll continuously; fires webhook alerts on transitions    |
| `hiveframe destroy`              | Tear down all resources defined in the stack              |
| `hiveframe web`                  | Start the web dashboard at `http://127.0.0.1:8080`        |
| `hiveframe webhook test -n <name>` | Send a test drift payload to a configured webhook       |
| `hiveframe template list`          | List all bundled stack templates                        |
| `hiveframe template show <name>`   | Show template details and README                        |
| `hiveframe template use <name>`    | Write a template to `stack.yaml` in the current directory |

All commands accept `-f / --file` to point at a non-default stack file.  
The root group accepts `--debug` to print the resolved config path and diagnostics.

---

## Templates

HiveFrame ships pre-built stack templates for common lab environments. One command gets you from zero to a ready-to-use `stack.yaml`.

```bash
hiveframe template list                    # browse available templates
hiveframe template show ccna-lab           # view details and README
hiveframe template use ccna-lab            # write stack.yaml to current directory
hiveframe template use web-stack -o lab.yaml  # write to a custom path
```

### Available templates

| Name           | Description                                              | VLANs | VMs |
|----------------|----------------------------------------------------------|-------|-----|
| `ccna-lab`     | Two-VLAN network with routed segments for CCNA practice  | 2     | 2   |
| `security-lab` | Basic attack/defense lab with isolated network segments  | 2     | 2   |
| `web-stack`    | Two-tier web application lab                             | 2     | 2   |
| `bare-linux`   | Minimal single VM on a flat VLAN for general-purpose use | 1     | 1   |

After writing a template, update the `template_id` fields to match the template VM ID on your Proxmox host, then run `hiveframe validate`.

---

## Stack reference

### Top-level

| Field         | Type   | Default | Description                            |
|---------------|--------|---------|----------------------------------------|
| `name`        | `str`  | —       | Unique stack identifier                |
| `description` | `str`  | `""`    | Optional free-text description         |
| `node`        | `str`  | `pve`   | Default Proxmox node for all resources |
| `vlans`       | `list` | `[]`    | List of VLAN definitions               |
| `vms`         | `list` | `[]`    | List of VM definitions                 |

### VlanConfig

| Field         | Type   | Default | Description                                     |
|---------------|--------|---------|-------------------------------------------------|
| `name`        | `str`  | `""`    | Friendly identifier, referenced by VMs          |
| `vlan_id`     | `int`  | —       | 802.1Q VLAN ID (1–4094)                         |
| `cidr`        | `str`  | —       | Subnet in CIDR notation, e.g. `192.168.10.0/24` |
| `gateway`     | `str`  | `null`  | Gateway IP — assigned to the bridge             |
| `description` | `str`  | `""`    | Written as a comment on the Proxmox bridge      |
| `node`        | `str`  | `null`  | Override stack-level node for this VLAN         |

HiveFrame creates a dedicated Linux bridge per VLAN: `vmbr<vlan_id>`.

### VmConfig

| Field             | Type     | Default     | Description                                    |
|-------------------|----------|-------------|------------------------------------------------|
| `name`            | `str`    | —           | VM hostname and Proxmox name (RFC hostname)    |
| `template_id`     | `int`    | —           | VMID of the template to clone                  |
| `vlan`            | `str`    | —           | `name` of the VLAN to attach `net0` to         |
| `cores`           | `int`    | `2`         | vCPU count                                     |
| `memory_mb`       | `int`    | `2048`      | RAM in megabytes                               |
| `disk_gb`         | `int`    | `20`        | Total disk size in GB — resizes above template |
| `storage`         | `str`    | `local-lvm` | Proxmox storage pool for disk and cloud-init   |
| `start_on_create` | `bool`   | `true`      | Start VM immediately after provisioning        |
| `tags`            | `list`   | `[]`        | Proxmox tags to apply                          |
| `cloud_init`      | `object` | see below   | Cloud-init configuration block                 |
| `firewall`        | `list`   | `[]`        | Per-VM firewall rules (see FirewallRule)        |
| `node`            | `str`    | `null`      | Override stack-level node for this VM          |

### CloudInitConfig

| Field           | Type        | Default  | Description                                                      |
|-----------------|-------------|----------|------------------------------------------------------------------|
| `user`          | `str`       | `ubuntu` | Default user created by cloud-init                               |
| `password`      | `str`       | `null`   | Plain-text password — prefer `ssh_keys` in production            |
| `ssh_keys`      | `list[str]` | `[]`     | Authorized public keys                                           |
| `ip_config`     | `str`       | `null`   | `dhcp`, or Proxmox format: `ip=192.168.1.5/24,gw=192.168.1.1`  |
| `nameservers`   | `list[str]` | `[]`     | DNS servers                                                      |
| `search_domain` | `str`       | `null`   | DNS search domain                                                |

### FirewallRule

Per-VM firewall rules under the `firewall:` list. Rules are applied to the Proxmox VM firewall and take effect immediately on `hiveframe apply`.

| Field       | Type                           | Default   | Description                                      |
|-------------|--------------------------------|-----------|--------------------------------------------------|
| `direction` | `in` \| `out`                  | `in`      | Traffic direction                                |
| `action`    | `ACCEPT` \| `DROP` \| `REJECT` | `ACCEPT`  | Rule action                                      |
| `protocol`  | `tcp` \| `udp` \| `icmp`      | `null`    | Required when `dport` or `sport` is set          |
| `source`    | `str`                          | `null`    | Source IP or CIDR                                |
| `dest`      | `str`                          | `null`    | Destination IP or CIDR                           |
| `dport`     | `str`                          | `null`    | Destination port or range, e.g. `22` or `80:443` |
| `sport`     | `str`                          | `null`    | Source port or range                             |
| `comment`   | `str`                          | `null`    | Free-text label shown in Proxmox UI              |
| `enabled`   | `bool`                         | `true`    | Whether the rule is active                       |

```yaml
firewall:
  - direction: in
    action: ACCEPT
    protocol: tcp
    dport: "22"
    comment: allow SSH
  - direction: in
    action: DROP
    comment: drop all inbound
```

### State file

After `apply`, HiveFrame writes `.hiveframe-state.json` next to your `stack.yaml`. This file tracks VMIDs, VLAN bridges, and firewall rule counts — it is required for `status` and `destroy`. Add it to `.gitignore` if your stack contains sensitive values.

---

## Configuration

`~/.hiveframe/config.yaml` is loaded automatically. Configs written before 0.1.4 using the flat `proxmox_host:` format are auto-migrated on first read.

### Single node

```yaml
nodes:
  - name: pve
    host: 10.0.20.1
    user: root@pam
    token_id: hiveframe
    token_secret: your-token-secret
    verify_ssl: false
```

### Multiple nodes

Add more entries under `nodes:`. Each VLAN and VM can target a specific node with a `node:` override; the stack-level `node:` is the default.

```yaml
nodes:
  - name: pve
    host: 10.0.20.1
    token_id: hiveframe
    token_secret: your-secret-1
  - name: pve2
    host: 10.0.20.2
    token_id: hiveframe
    token_secret: your-secret-2
```

Then in `stack.yaml`:

```yaml
name: my-stack
node: pve          # default

vlans:
  - name: mgmt
    vlan_id: 10
    cidr: 192.168.10.0/24
  - name: dmz
    vlan_id: 50
    cidr: 10.50.0.0/24
    node: pve2     # this VLAN is provisioned on pve2

vms:
  - name: controller
    template_id: 9000
    vlan: mgmt     # goes on pve (stack default)
  - name: worker
    template_id: 9000
    vlan: dmz
    node: pve2     # this VM is provisioned on pve2
```

### Webhook alerts

Webhooks fire on state transitions detected during `status --watch` — once when drift is first detected, once when it clears. They are never fired on every poll.

```yaml
nodes:
  - name: pve
    host: 10.0.20.1
    token_id: hiveframe
    token_secret: your-secret

webhooks:
  - name: slack-homelab
    url: https://hooks.slack.com/services/xxx/yyy/zzz
    provider: slack
    on: [drift, recovery]
  - name: discord-alerts
    url: https://discord.com/api/webhooks/xxx/yyy
    provider: discord
    on: [drift]
  - name: my-system
    url: https://my-system.internal/hooks/hiveframe
    provider: generic
    on: [drift, recovery]
```

Supported providers: `slack`, `discord`, `generic`.  
Supported events: `drift` (healthy → drifted), `recovery` (drifted → healthy).

Failed webhooks are retried once after 5 seconds. A warning is printed to the terminal if both attempts fail; the watch loop continues regardless.

Test a webhook without waiting for real drift:

```bash
hiveframe webhook test --name slack-homelab
```

### Environment variables (single-node fallback)

When no config file exists, HiveFrame reads these environment variables:

| Variable                         | Description               |
|----------------------------------|---------------------------|
| `HIVEFRAME_PROXMOX_HOST`         | IP or hostname, no scheme |
| `HIVEFRAME_PROXMOX_USER`         | Default: `root@pam`       |
| `HIVEFRAME_PROXMOX_TOKEN_ID`     | API token name            |
| `HIVEFRAME_PROXMOX_TOKEN_SECRET` | API token secret          |
| `HIVEFRAME_PROXMOX_VERIFY_SSL`   | Default: `false`          |

---

## Web dashboard

```bash
hiveframe web               # http://127.0.0.1:8080
hiveframe web --port 9090   # custom port
hiveframe web --host 0.0.0.0  # bind all interfaces
```

The dashboard shows live VLAN and VM status for the first configured node.

---

## Requirements

- Python 3.11+
- Proxmox VE 7.x, 8.x, or 9.x
- API token with sufficient Proxmox permissions (PVEVMAdmin or equivalent)
- Template VM with cloud-init drive (`ide2`) for VM provisioning

---

## Development

```bash
git clone https://codeberg.org/itzdrixxyy/hiveframe.git
cd hiveframe
pip install -e ".[dev]"
pytest
```

Copy `stack.yaml.example` to `stack.yaml` and fill in your values before running `apply`.

---

## Roadmap

Built:
- VLAN and VM provisioning with idempotent apply/destroy
- Firewall rule provisioning (per-VM)
- Drift detection with `status --watch`
- Webhook alerts (Slack, Discord, generic) on drift/recovery transitions
- Multi-node support — per-resource `node:` override, lazy client connections
- State file tracking for idempotent operations
- Web dashboard (FastAPI + HTMX)

Next:
- Tag-based filtering for plan/apply/destroy
- Scheduled drift checks (cron mode)
- Proxmox privilege separation (non-root API tokens)

---

## License

MIT — [itzdrixxyy](https://codeberg.org/itzdrixxyy)
