modified: README.md
This commit is contained in:
393
README.md
393
README.md
@@ -1,123 +1,300 @@
|
||||
You are helping implement an internal web application called **Support Provisioning Portal**.
|
||||
# Support Provisioning Portal
|
||||
|
||||
Your task is to bootstrap the project based on the local `README.md` in this repository and then implement the first vertical slice with strong engineering discipline.
|
||||
Internal WordPress plugin for support staff to provision standardized Proxmox VE VMs without direct Proxmox access.
|
||||
|
||||
## Product context
|
||||
The application runs as a WordPress plugin and exposes both:
|
||||
|
||||
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.
|
||||
- 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
|
||||
|
||||
## Technical direction
|
||||
|
||||
Use this stack unless the repository already contains an equivalent decision:
|
||||
- Monorepo with pnpm
|
||||
- Next.js + TypeScript for `apps/web`
|
||||
- Node.js + TypeScript for `apps/api`
|
||||
- Fastify preferred for the API
|
||||
- PostgreSQL + Prisma
|
||||
- Tailwind CSS for the web UI
|
||||
- Zod for request/response validation
|
||||
|
||||
## Constraints
|
||||
|
||||
- Do not overengineer.
|
||||
- Prefer a clean vertical slice over broad scaffolding.
|
||||
- Keep Proxmox integration behind a dedicated adapter/module.
|
||||
- Use clear domain names and explicit types.
|
||||
- Avoid magic strings.
|
||||
- Add TODOs only when truly necessary.
|
||||
- Document all non-obvious decisions in code comments or small docs.
|
||||
- Make the codebase easy to extend toward RBAC, SSO, and multi-cluster support later.
|
||||
|
||||
## Initial implementation goals
|
||||
|
||||
Implement a usable first slice with the following:
|
||||
|
||||
1. Monorepo structure
|
||||
- `apps/web`
|
||||
- `apps/api`
|
||||
- `packages/types`
|
||||
- `packages/proxmox-client`
|
||||
- `prisma`
|
||||
|
||||
2. Database schema with at least:
|
||||
- users
|
||||
- templates
|
||||
- deployments
|
||||
- audit_logs
|
||||
|
||||
3. Backend API endpoints
|
||||
- `GET /api/templates`
|
||||
- `GET /api/deployments`
|
||||
- `GET /api/deployments/:id`
|
||||
- `POST /api/deployments`
|
||||
- `POST /api/deployments/:id/start`
|
||||
- `POST /api/deployments/:id/stop`
|
||||
- `DELETE /api/deployments/:id`
|
||||
|
||||
4. Proxmox adapter
|
||||
- token auth support
|
||||
- stubbed or mockable implementation if no live environment is available
|
||||
- methods for clone/start/stop/delete/getStatus
|
||||
- clear interface separation between domain service and transport
|
||||
|
||||
5. Web UI
|
||||
- dashboard page listing deployments
|
||||
- templates page
|
||||
- create deployment form
|
||||
- deployment detail view
|
||||
- simple status badges and action buttons
|
||||
|
||||
6. Seed data
|
||||
- at least 3 sample templates
|
||||
|
||||
7. Audit logging
|
||||
- every mutating action must write an audit log row
|
||||
|
||||
8. Developer experience
|
||||
- `.env.example`
|
||||
- scripts for dev/build/lint
|
||||
- basic README sections updated if needed
|
||||
|
||||
## Working style
|
||||
|
||||
Proceed in small, reviewable steps:
|
||||
1. inspect repository
|
||||
2. propose concrete file plan
|
||||
3. implement foundation
|
||||
4. implement backend slice
|
||||
5. implement frontend slice
|
||||
6. verify types/build consistency
|
||||
7. summarize what was created and what remains
|
||||
|
||||
## Output requirements
|
||||
|
||||
- Start by reading the local `README.md` and align implementation with it.
|
||||
- Show the file/folder plan before making broad changes.
|
||||
- Then create the project incrementally.
|
||||
- When assumptions are required, state them briefly and choose the most pragmatic path.
|
||||
- Favor production-style code structure over tutorial-style code.
|
||||
- Where live Proxmox access is unavailable, create a mock adapter that can later be replaced without touching domain logic.
|
||||
|
||||
## Quality bar
|
||||
|
||||
- TypeScript strict mode
|
||||
- input validation at API boundaries
|
||||
- no secrets committed
|
||||
- minimal but coherent UI
|
||||
- compile-ready code where possible
|
||||
- no dead code
|
||||
- no fake features presented as complete
|
||||
|
||||
Begin by inspecting the repository and proposing the exact bootstrap structure to create.
|
||||
Reference in New Issue
Block a user