# Support Provisioning Portal Internal WordPress plugin for support staff to provision standardized Proxmox VE VMs without direct Proxmox access. The application runs as a WordPress plugin and exposes both: - an admin page at **Support Provisioning** - a frontend shortcode: `[support_provisioning_portal]` ## Implemented First Slice - WordPress plugin bootstrap with activation hook - Custom database tables: - `wp_spp_templates` - `wp_spp_deployments` - `wp_spp_audit_logs` - Seed data for 3 approved templates - WordPress REST API endpoints: - `GET /wp-json/support-provisioning/v1/templates` - `GET /wp-json/support-provisioning/v1/quota` - `GET /wp-json/support-provisioning/v1/deployments` - `GET /wp-json/support-provisioning/v1/deployments/:id` - `POST /wp-json/support-provisioning/v1/deployments` - `POST /wp-json/support-provisioning/v1/deployments/:id/start` - `POST /wp-json/support-provisioning/v1/deployments/:id/stop` - `POST /wp-json/support-provisioning/v1/deployments/:id/prolong` - `POST /wp-json/support-provisioning/v1/deployments/:id/refresh-ips` - `DELETE /wp-json/support-provisioning/v1/deployments/:id` - Mock Proxmox adapter for local/no-cluster use - HTTP token-auth Proxmox adapter behind the same interface - Audit log rows for every mutating action - Optional `Never expire` deployments - Per-user and global RAM contingents - IP address display for deployments when available from the mock adapter or Proxmox guest agent - Manual IP refresh action for deployments - Non-destructive expiration: expired VMs are stopped and locked, not deleted - Minimal admin/frontend UI for: - deployment dashboard - templates - create deployment form - deployment detail view - start/stop/delete actions - TTL prolongation for expired or active deployments - theme-inherited form controls and colors for shortcode rendering ## Install 1. Copy the `support-provisioning-portal` folder into: ```text wp-content/plugins/support-provisioning-portal ``` 2. Activate **Support Provisioning Portal** in WordPress admin. 3. Open **Support Provisioning** in the WordPress admin menu. 4. Optional: add this shortcode to an internal page: ```text [support_provisioning_portal] ``` ## Permissions - Logged-in users with `read` can view templates and deployments. - Logged-in users with `edit_posts` can create, start, stop, and delete deployments. - WordPress REST nonces are required for UI mutations. ## Expiration And Contingents Deployment creation supports either a TTL in hours or **Never expire**. When a deployment reaches its TTL: - WordPress cron and REST requests detect the expiration. - The plugin attempts to stop the VM. - The deployment status becomes `EXPIRED`. - The VM cannot be started again until the user prolongs its TTL. - The user can either prolong the TTL or delete the deployment. - Deleted deployments are hidden from the active deployment list, but audit rows remain. RAM contingents are configured from **Support Provisioning > Proxmox Settings**: - Default per-user RAM limit (MB) - Global RAM limit (MB) Set either value to `0` for unlimited. Active allocations include deployments in `PROVISIONING`, `STOPPED`, `RUNNING`, and `DELETING` states. Per-user overrides are available on each WordPress user profile under **Support Provisioning Contingent**. Leave the override empty to use the default per-user limit. ## IP Addresses Deployments include an `ipAddresses` field in REST responses and show those addresses in the UI. In mock mode, deterministic documentation-range IPs are assigned. In HTTP mode, the plugin reads IPs from the Proxmox guest-agent `network-get-interfaces` endpoint when available. If the guest agent reports IPs only after boot, use **Refresh IPs** in the deployment detail view. ## Proxmox Settings The plugin defaults to mock mode. Configure live Proxmox access from the **Support Provisioning** admin page: - Mode: `Mock` or `HTTP token auth` - Base URL, for example `https://proxmox.example.internal:8006` - Token ID, for example `user@realm!token-name` - Token Secret - Node, for example `pve-01` No Proxmox secrets are committed to the repository. ## Configure A Live Proxmox Link Use this section when moving from mock mode to a real Proxmox VE node. ### 1. Prepare Proxmox Templates The plugin only provisions from approved templates. For a first real test, either create Proxmox VM templates with the seeded IDs or update the plugin database rows to match your real template IDs. Seeded template IDs: | Plugin template | Proxmox template VMID | | --- | ---: | | Turnkey PBX Test Appliance | `9001` | | Windows Support Client | `9002` | | Linux Utility VM | `9003` | The fastest first test is to create one real Proxmox template with VMID `9003`, then use the **Linux Utility VM** option in the plugin. Template requirements: - The VM must be converted to a Proxmox template. - The template must exist on the Proxmox node configured in the plugin. - The plugin currently performs a full clone (`full=1`), so the target storage must have enough free capacity. - CPU and memory are set by the plugin after clone based on the template policy row. - For IP address display, install and enable `qemu-guest-agent` inside the guest and enable the guest agent option on the VM/template. If you do not want to use VMIDs `9001`, `9002`, or `9003`, update the template rows after activation: ```sql UPDATE wp_spp_templates SET proxmox_template_id = 1234 WHERE template_key = 'linux-utility-vm'; ``` Replace `wp_` with your WordPress table prefix. ### 2. Create A Dedicated Proxmox API User In Proxmox, create a dedicated user instead of using `root@pam` for the plugin. Example via Proxmox shell: ```bash pveum user add wp-support@pve --comment "WordPress Support Provisioning Portal" ``` You can also create the user in the Proxmox UI under **Datacenter > Permissions > Users**. ### 3. Create An API Token In the Proxmox UI: 1. Go to **Datacenter > Permissions > API Tokens**. 2. Click **Add**. 3. User: `wp-support@pve` 4. Token ID: `support-portal` 5. Enable **Privilege Separation**. 6. Save the token secret immediately. Proxmox only shows it once. The plugin stores these fields separately: - **Token ID**: `wp-support@pve!support-portal` - **Token Secret**: the secret value shown by Proxmox Do not include the `=` between token ID and secret in the WordPress settings. The plugin builds the required `PVEAPIToken=tokenid=secret` header internally. ### 4. Grant Proxmox Permissions Proxmox permissions are path based. For a first controlled test, grant the token access only to the node/storage/template area you intend to use. The plugin needs permissions for: - getting the next VMID - cloning a template VM - changing CPU and memory after clone - starting and stopping VMs - deleting VMs - reading VM status - reading guest-agent network interfaces for IP display Practical first-test option: ```bash pveum aclmod / -user wp-support@pve -role PVEVMAdmin ``` If the clone fails because storage permissions are missing, also grant datastore access on the storage path used by your templates/clones: ```bash pveum aclmod /storage/local-lvm -user wp-support@pve -role PVEDatastoreAdmin ``` For a tighter production setup, create a custom role with only the required privileges and assign it to the API token or user: ```bash pveum role add SupportProvisioner -privs "VM.Allocate VM.Audit VM.Clone VM.Config.CPU VM.Config.Memory VM.PowerMgmt Datastore.AllocateSpace Datastore.Audit Sys.Audit" pveum aclmod / -user wp-support@pve -role SupportProvisioner ``` Depending on your Proxmox version and storage layout, you may need to scope storage permissions separately, for example: ```bash pveum aclmod /storage/local-lvm -user wp-support@pve -role SupportProvisioner ``` ### 5. Check Proxmox TLS The plugin uses WordPress HTTP requests to call Proxmox. That means PHP/WordPress must trust the Proxmox HTTPS certificate. Recommended: - Use a DNS name for Proxmox, not a raw IP address. - Install a valid certificate on Proxmox, or install your internal CA certificate so the WordPress/PHP host trusts it. If Proxmox still uses its default self-signed certificate, WordPress may reject the request with an SSL/cURL certificate error. Fix the trust chain before debugging plugin credentials. ### 6. Configure WordPress Plugin Settings In WordPress admin, open **Support Provisioning > Proxmox Settings**: | Setting | Value | | --- | --- | | Mode | `HTTP token auth` | | Base URL | `https://proxmox.example.internal:8006` | | Token ID | `wp-support@pve!support-portal` | | Token Secret | token secret from Proxmox | | Node | Proxmox node name, for example `pve-01` | The **Node** value must match the Proxmox node name exactly as shown in the Proxmox UI under **Datacenter**. ### 7. First Live Test Checklist Before creating a deployment: - Confirm WordPress can reach Proxmox on TCP `8006`. - Confirm the Proxmox base URL opens from the WordPress server. - Confirm the configured node name is exact. - Confirm the selected plugin template points to a real Proxmox template VMID. - Confirm the token has clone, VM config, power, delete, audit, and datastore permissions. - Confirm target storage has enough capacity for a full clone. - Confirm RAM contingents in WordPress are not blocking the selected template. Then test in this order: 1. Switch plugin mode to `HTTP token auth`. 2. Create a deployment from **Linux Utility VM** or whichever template VMID you mapped. 3. Open the deployment detail view. 4. Click **Start**. 5. Wait for the guest to boot. 6. Click **Refresh IPs**. 7. Confirm IP addresses appear. 8. Click **Stop**. 9. Click **Delete** when done. ### 8. Common Failure Points | Symptom | Likely cause | | --- | --- | | `Missing Proxmox HTTP configuration` | One of Base URL, Token ID, Token Secret, or Node is empty. | | `Proxmox request failed with HTTP 401` | Token ID/secret is wrong, token was deleted, or the secret was copied incorrectly. | | `Proxmox request failed with HTTP 403` | Token exists but lacks permissions for clone/config/power/delete/storage. | | `Proxmox request failed with HTTP 404` | Node name or template VMID is wrong, or the template is on a different node. | | SSL/cURL certificate error | WordPress/PHP does not trust the Proxmox certificate. | | Deployment created but no IPs | Guest agent is missing, disabled, not running, or the VM has not finished booting. | | Start is blocked | Deployment is `EXPIRED`; prolong the TTL first. | ## Design Notes - Templates are the only provisioning path. - Resource limits come from approved templates, not user input. - Deployment lifecycle operations are routed through a dedicated Proxmox client interface. - Live Proxmox access can be replaced or expanded without changing REST or UI code. - WordPress users are used as actors for audit logging. This keeps the first slice simple and leaves room for later RBAC/SSO mapping. ## Original Bootstrap Brief The application is an internal self-service portal for support staff. It provisions standardized VMs on **Proxmox VE** through a backend service. Users must never interact with Proxmox directly. The application MUST run as a WordPress plugin. Typical resources: - turnkey PBX/test appliances - Windows support clients - Linux utility VMs The system must enforce: - template-based provisioning only - policy-controlled resource limits - audit logging - lifecycle actions - TTL / expiration support