All pages now use native Vuetify components directly. Flash messages are handled by the ToastStack component via Pinia store. Notifications use NotificationPanel. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
103 lines
3.8 KiB
Markdown
103 lines
3.8 KiB
Markdown
# Provisioning & Service Termination Fix - 2026-02-10
|
|
|
|
## Issues Fixed
|
|
|
|
### Issue #1: VPS Not Being Provisioned
|
|
**Root Cause:** All provisioning services (VirtFusion, Pterodactyl, SynergyCP, Enhance) were reading credentials from `config('services.*')` which pulls from `.env`, but the actual credentials are stored in the **database** via the `settings` table (configured in Admin → Settings → API).
|
|
|
|
**What Happened:**
|
|
- User configured VirtFusion API URL/token via admin panel settings (stored in DB)
|
|
- VirtFusionService was reading from `.env` (empty values)
|
|
- HTTP client tried to connect to relative hostnames like `sanctum`, `users`, `servers`
|
|
- cURL errors: "Could not resolve host: users"
|
|
|
|
**Files Updated:**
|
|
- `app/Services/Provisioning/VirtFusionService.php`
|
|
- `app/Services/Provisioning/PterodactylService.php`
|
|
- `app/Services/Provisioning/SynergyCPService.php`
|
|
- `app/Services/Provisioning/EnhanceService.php`
|
|
|
|
**Change:** All services now use `\App\Models\Setting::get('provider_api_url')` instead of `config('services.provider.url')`
|
|
|
|
### Issue #2: Services Not Terminated on Subscription Cancellation
|
|
**Root Cause:** `HandleSubscriptionCancelled` listener only sent a notification - it didn't call the provisioning service's `terminate()` method.
|
|
|
|
**What Happened:**
|
|
- User canceled subscription with "immediate" setting
|
|
- Subscription canceled in Stripe
|
|
- Service remained active on VirtFusion panel
|
|
- No cleanup of provisioned resources
|
|
|
|
**Files Updated:**
|
|
- `app/Listeners/HandleSubscriptionCancelled.php`
|
|
|
|
**Changes:**
|
|
- Made listener implement `ShouldQueue` (background job with retries)
|
|
- Added logic to find all active/suspended services for the subscription
|
|
- Call `terminate()` on each service via ProvisioningFactory
|
|
- Proper error handling and logging
|
|
- Service status updated to "terminated" in database
|
|
|
|
## Current State
|
|
|
|
### VirtFusion Configuration (Database)
|
|
```
|
|
virtfusion_api_url: https://cp.vps.ezscale.tech/api/v1
|
|
virtfusion_api_token: (encrypted in DB)
|
|
```
|
|
|
|
### How It Works Now
|
|
|
|
**Subscription Created:**
|
|
1. HandleSubscriptionCreated listener queued
|
|
2. Reads plan from database
|
|
3. Gets provisioning service (VirtFusionService for VPS)
|
|
4. **VirtFusionService reads URL/token from settings table**
|
|
5. Ensures user exists on VirtFusion panel
|
|
6. Creates server (package ID 43)
|
|
7. Changes package to match plan specs
|
|
8. Updates service record with IP, hostname, etc.
|
|
9. Sends credentials email to customer
|
|
|
|
**Subscription Canceled:**
|
|
1. HandleSubscriptionCancelled listener queued
|
|
2. Finds all active/suspended services for subscription
|
|
3. Gets provisioning service for each
|
|
4. Calls `terminate()` on VirtFusion (DELETE /servers/{id})
|
|
5. Updates service status to "terminated"
|
|
6. Sends cancellation email to customer
|
|
|
|
## Testing Needed
|
|
|
|
1. ✅ Horizon restarted to reload code changes
|
|
2. ⏳ Create a new VPS subscription and verify:
|
|
- Service is provisioned on VirtFusion
|
|
- Credentials email is sent
|
|
- Service appears in customer dashboard
|
|
3. ⏳ Cancel the subscription and verify:
|
|
- Service is terminated on VirtFusion
|
|
- Service status updates to "terminated"
|
|
- Cancellation email is sent
|
|
|
|
## Environment Variables (No Longer Used)
|
|
|
|
The following `.env` variables are **no longer used** for provisioning (database settings take precedence):
|
|
- ~~VIRTFUSION_API_URL~~
|
|
- ~~VIRTFUSION_API_TOKEN~~
|
|
- ~~PTERODACTYL_PANEL_URL~~
|
|
- ~~PTERODACTYL_API_KEY~~
|
|
- ~~SYNERGYCP_API_URL~~
|
|
- ~~SYNERGYCP_API_TOKEN~~
|
|
- ~~ENHANCE_API_URL~~
|
|
- ~~ENHANCE_API_TOKEN~~
|
|
|
|
**Configure all provisioning credentials in:** Admin Panel → Settings → API Integrations
|
|
|
|
## Migration Notes
|
|
|
|
If you have provisioning credentials in `.env`, migrate them to the database:
|
|
1. Go to Admin → Settings → API
|
|
2. Enter the URL and token for each provider
|
|
3. Click "Save" to encrypt and store in database
|
|
4. Remove from `.env` (optional, but recommended to avoid confusion)
|