From 426a6334c7015bbbdf35cf529c69586a192195c9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 10 Dec 2025 12:43:38 +0100 Subject: [PATCH] Remove provisional Hetzner API documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These documentation files were created during development but should not be committed at this stage. The API implementation is complete and tested, but the documentation will be provided separately through official channels. 🤖 Generated with Claude Code Co-Authored-By: Claude --- docs/api/HETZNER_API_README.md | 256 ------------ docs/api/hetzner-provisioning-examples.md | 464 ---------------------- docs/api/hetzner-yaak-collection.json | 284 ------------- 3 files changed, 1004 deletions(-) delete mode 100644 docs/api/HETZNER_API_README.md delete mode 100644 docs/api/hetzner-provisioning-examples.md delete mode 100644 docs/api/hetzner-yaak-collection.json diff --git a/docs/api/HETZNER_API_README.md b/docs/api/HETZNER_API_README.md deleted file mode 100644 index 8501aeb75..000000000 --- a/docs/api/HETZNER_API_README.md +++ /dev/null @@ -1,256 +0,0 @@ -# Hetzner Server Provisioning via API - -This implementation adds full API support for Hetzner server provisioning in Coolify, matching the functionality available in the UI. - -## What's New - -### API Endpoints - -#### Cloud Provider Tokens -- `GET /api/v1/cloud-tokens` - List all cloud provider tokens -- `POST /api/v1/cloud-tokens` - Create a new cloud provider token (with validation) -- `GET /api/v1/cloud-tokens/{uuid}` - Get a specific token -- `PATCH /api/v1/cloud-tokens/{uuid}` - Update token name -- `DELETE /api/v1/cloud-tokens/{uuid}` - Delete token (prevents deletion if used by servers) -- `POST /api/v1/cloud-tokens/{uuid}/validate` - Validate token against provider API - -#### Hetzner Resources -- `GET /api/v1/hetzner/locations` - List Hetzner datacenter locations -- `GET /api/v1/hetzner/server-types` - List server types (filters deprecated) -- `GET /api/v1/hetzner/images` - List OS images (filters deprecated & non-system) -- `GET /api/v1/hetzner/ssh-keys` - List SSH keys from Hetzner account - -#### Hetzner Server Provisioning -- `POST /api/v1/servers/hetzner` - Create a new Hetzner server - -## Files Added/Modified - -### Controllers -- `app/Http/Controllers/Api/CloudProviderTokensController.php` - Cloud token CRUD operations -- `app/Http/Controllers/Api/HetznerController.php` - Hetzner provisioning operations - -### Routes -- `routes/api.php` - Added new API routes - -### Tests -- `tests/Feature/CloudProviderTokenApiTest.php` - Comprehensive tests for cloud tokens -- `tests/Feature/HetznerApiTest.php` - Comprehensive tests for Hetzner provisioning - -### Documentation -- `docs/api/hetzner-provisioning-examples.md` - Complete curl examples -- `docs/api/hetzner-yaak-collection.json` - Importable Yaak/Postman collection -- `docs/api/HETZNER_API_README.md` - This file - -## Features - -### Authentication & Authorization -- All endpoints require Sanctum authentication -- Cloud token operations restricted to team members -- Follows existing API patterns for consistency - -### Token Validation -- Tokens are validated against provider APIs before storage -- Supports both Hetzner and DigitalOcean -- Encrypted storage of API tokens - -### Smart SSH Key Management -- Automatic MD5 fingerprint matching to avoid duplicate uploads -- Supports Coolify private key + additional Hetzner keys -- Automatic deduplication - -### Network Configuration -- IPv4/IPv6 toggle support -- Prefers IPv4 when both enabled -- Validates at least one network type is enabled - -### Cloud-init Support -- Optional cloud-init script for server initialization -- YAML validation using existing ValidCloudInitYaml rule - -### Server Creation Flow -1. Validates cloud provider token and private key -2. Uploads SSH key to Hetzner if not already present -3. Creates server on Hetzner with all specified options -4. Registers server in Coolify database -5. Sets up default proxy configuration (Traefik) -6. Optional instant validation - -## Testing - -### Running Tests - -**Feature Tests (require database):** -```bash -# Run inside Docker -docker exec coolify php artisan test --filter=CloudProviderTokenApiTest -docker exec coolify php artisan test --filter=HetznerApiTest -``` - -### Test Coverage - -**CloudProviderTokenApiTest:** -- ✅ List all tokens (with team isolation) -- ✅ Get specific token -- ✅ Create Hetzner token (with API validation) -- ✅ Create DigitalOcean token (with API validation) -- ✅ Update token name -- ✅ Delete token (prevents if used by servers) -- ✅ Validate token -- ✅ Validation errors for all required fields -- ✅ Extra field rejection -- ✅ Authentication checks - -**HetznerApiTest:** -- ✅ Get locations -- ✅ Get server types (filters deprecated) -- ✅ Get images (filters deprecated & non-system) -- ✅ Get SSH keys -- ✅ Create server (minimal & full options) -- ✅ IPv4/IPv6 preference logic -- ✅ Auto-generate server name -- ✅ Validation for all required fields -- ✅ Token & key existence validation -- ✅ Extra field rejection -- ✅ Authentication checks - -## Usage Examples - -### Quick Start - -```bash -# 1. Create a cloud provider token -curl -X POST "http://localhost/api/v1/cloud-tokens" \ - -H "Authorization: Bearer root" \ - -H "Content-Type: application/json" \ - -d '{ - "provider": "hetzner", - "token": "YOUR_HETZNER_API_TOKEN", - "name": "My Hetzner Token" - }' - -# Save the returned UUID as CLOUD_TOKEN_UUID - -# 2. Get available locations -curl -X GET "http://localhost/api/v1/hetzner/locations?cloud_provider_token_id=CLOUD_TOKEN_UUID" \ - -H "Authorization: Bearer root" - -# 3. Get your private key UUID -curl -X GET "http://localhost/api/v1/security/keys" \ - -H "Authorization: Bearer root" - -# Save the returned UUID as PRIVATE_KEY_UUID - -# 4. Create a server -curl -X POST "http://localhost/api/v1/servers/hetzner" \ - -H "Authorization: Bearer root" \ - -H "Content-Type: application/json" \ - -d '{ - "cloud_provider_token_id": "CLOUD_TOKEN_UUID", - "location": "nbg1", - "server_type": "cx11", - "image": 67794396, - "private_key_uuid": "PRIVATE_KEY_UUID" - }' -``` - -For complete examples, see: -- **[hetzner-provisioning-examples.md](./hetzner-provisioning-examples.md)** - Detailed curl examples -- **[hetzner-yaak-collection.json](./hetzner-yaak-collection.json)** - Import into Yaak - -## API Design Decisions - -### Consistency with Existing API -- Follows patterns from `ServersController` -- Uses same validation approach (inline with `customApiValidator`) -- Uses same response formatting (`serializeApiResponse`) -- Uses same error handling patterns - -### Reuses Existing Code -- `HetznerService` - All Hetzner API calls -- `ValidHostname` rule - Server name validation -- `ValidCloudInitYaml` rule - Cloud-init validation -- `PrivateKey::generateMd5Fingerprint()` - SSH key fingerprinting - -### Team Isolation -- All endpoints filter by team ID from API token -- Cannot access tokens/servers from other teams -- Follows existing security patterns - -### Error Handling -- Provider API errors wrapped in generic messages (doesn't leak Hetzner errors) -- Validation errors with clear field-specific messages -- 404 for resources not found -- 422 for validation failures -- 400 for business logic errors (e.g., token validation failure) - -## Next Steps - -To use this in production: - -1. **Run Pint** (code formatting): - ```bash - cd /Users/heyandras/devel/coolify - ./vendor/bin/pint --dirty - ``` - -2. **Run Tests** (inside Docker): - ```bash - docker exec coolify php artisan test --filter=CloudProviderTokenApiTest - docker exec coolify php artisan test --filter=HetznerApiTest - ``` - -3. **Commit Changes**: - ```bash - git add . - git commit -m "feat: add Hetzner server provisioning API endpoints - - - Add CloudProviderTokensController for token CRUD operations - - Add HetznerController for server provisioning - - Add comprehensive feature tests - - Add curl examples and Yaak collection - - Reuse existing HetznerService and validation rules - - Support IPv4/IPv6 configuration - - Support cloud-init scripts - - Smart SSH key management with deduplication" - ``` - -4. **Create Pull Request**: - ```bash - git push origin hetzner-api-provisioning - gh pr create --title "Add Hetzner Server Provisioning API" \ - --body "$(cat docs/api/HETZNER_API_README.md)" - ``` - -## Security Considerations - -- ✅ Tokens encrypted at rest (using Laravel's encrypted cast) -- ✅ Team-based isolation enforced -- ✅ API tokens validated before storage -- ✅ Rate limiting handled by HetznerService -- ✅ No sensitive data in responses (token field hidden) -- ✅ Authorization checks match UI (admin-only for token operations) -- ✅ Extra field validation prevents injection attacks - -## Compatibility - -- **Laravel**: 12.x -- **PHP**: 8.4 -- **Existing UI**: Fully compatible, shares same service layer -- **Database**: Uses existing schema (cloud_provider_tokens, servers tables) - -## Future Enhancements - -Potential additions: -- [ ] DigitalOcean server provisioning endpoints -- [ ] Server power management (start/stop/reboot) -- [ ] Server resize/upgrade endpoints -- [ ] Batch server creation -- [ ] Server templates/presets -- [ ] Webhooks for server events - -## Support - -For issues or questions: -- Check [hetzner-provisioning-examples.md](./hetzner-provisioning-examples.md) for usage examples -- Review test files for expected behavior -- See existing `HetznerService` for Hetzner API details diff --git a/docs/api/hetzner-provisioning-examples.md b/docs/api/hetzner-provisioning-examples.md deleted file mode 100644 index 7cf69100a..000000000 --- a/docs/api/hetzner-provisioning-examples.md +++ /dev/null @@ -1,464 +0,0 @@ -# Hetzner Server Provisioning API Examples - -This document contains ready-to-use curl examples for the Hetzner server provisioning API endpoints. These examples use the `root` API token for development and can be easily imported into Yaak or any other API client. - -## Prerequisites - -```bash -# Set these environment variables -export COOLIFY_URL="http://localhost" -export API_TOKEN="root" # Your Coolify API token -``` - -## Cloud Provider Tokens - -### 1. Create a Hetzner Cloud Provider Token - -```bash -curl -X POST "${COOLIFY_URL}/api/v1/cloud-tokens" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" \ - -d '{ - "provider": "hetzner", - "token": "YOUR_HETZNER_API_TOKEN_HERE", - "name": "My Hetzner Token" - }' -``` - -**Response:** -```json -{ - "uuid": "abc123def456" -} -``` - -### 2. List All Cloud Provider Tokens - -```bash -curl -X GET "${COOLIFY_URL}/api/v1/cloud-tokens" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -**Response:** -```json -[ - { - "uuid": "abc123def456", - "name": "My Hetzner Token", - "provider": "hetzner", - "team_id": 0, - "servers_count": 0, - "created_at": "2025-11-19T12:00:00.000000Z", - "updated_at": "2025-11-19T12:00:00.000000Z" - } -] -``` - -### 3. Get a Specific Cloud Provider Token - -```bash -curl -X GET "${COOLIFY_URL}/api/v1/cloud-tokens/abc123def456" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -### 4. Update Cloud Provider Token Name - -```bash -curl -X PATCH "${COOLIFY_URL}/api/v1/cloud-tokens/abc123def456" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" \ - -d '{ - "name": "Production Hetzner Token" - }' -``` - -### 5. Validate a Cloud Provider Token - -```bash -curl -X POST "${COOLIFY_URL}/api/v1/cloud-tokens/abc123def456/validate" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -**Response:** -```json -{ - "valid": true, - "message": "Token is valid." -} -``` - -### 6. Delete a Cloud Provider Token - -```bash -curl -X DELETE "${COOLIFY_URL}/api/v1/cloud-tokens/abc123def456" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -**Response:** -```json -{ - "message": "Cloud provider token deleted." -} -``` - -## Hetzner Resource Discovery - -### 7. Get Available Hetzner Locations - -```bash -curl -X GET "${COOLIFY_URL}/api/v1/hetzner/locations?cloud_provider_token_id=abc123def456" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -**Response:** -```json -[ - { - "id": 1, - "name": "fsn1", - "description": "Falkenstein DC Park 1", - "country": "DE", - "city": "Falkenstein", - "latitude": 50.47612, - "longitude": 12.370071 - }, - { - "id": 2, - "name": "nbg1", - "description": "Nuremberg DC Park 1", - "country": "DE", - "city": "Nuremberg", - "latitude": 49.452102, - "longitude": 11.076665 - }, - { - "id": 3, - "name": "hel1", - "description": "Helsinki DC Park 1", - "country": "FI", - "city": "Helsinki", - "latitude": 60.169857, - "longitude": 24.938379 - } -] -``` - -### 8. Get Available Hetzner Server Types - -```bash -curl -X GET "${COOLIFY_URL}/api/v1/hetzner/server-types?cloud_provider_token_id=abc123def456" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -**Response (truncated):** -```json -[ - { - "id": 1, - "name": "cx11", - "description": "CX11", - "cores": 1, - "memory": 2.0, - "disk": 20, - "prices": [ - { - "location": "fsn1", - "price_hourly": { - "net": "0.0052000000", - "gross": "0.0061880000" - }, - "price_monthly": { - "net": "3.2900000000", - "gross": "3.9151000000" - } - } - ], - "storage_type": "local", - "cpu_type": "shared", - "architecture": "x86", - "deprecated": false - } -] -``` - -### 9. Get Available Hetzner Images (Operating Systems) - -```bash -curl -X GET "${COOLIFY_URL}/api/v1/hetzner/images?cloud_provider_token_id=abc123def456" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -**Response (truncated):** -```json -[ - { - "id": 15512617, - "name": "ubuntu-20.04", - "description": "Ubuntu 20.04", - "type": "system", - "os_flavor": "ubuntu", - "os_version": "20.04", - "architecture": "x86", - "deprecated": false - }, - { - "id": 67794396, - "name": "ubuntu-22.04", - "description": "Ubuntu 22.04", - "type": "system", - "os_flavor": "ubuntu", - "os_version": "22.04", - "architecture": "x86", - "deprecated": false - } -] -``` - -### 10. Get Hetzner SSH Keys - -```bash -curl -X GET "${COOLIFY_URL}/api/v1/hetzner/ssh-keys?cloud_provider_token_id=abc123def456" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -**Response:** -```json -[ - { - "id": 123456, - "name": "my-ssh-key", - "fingerprint": "aa:bb:cc:dd:ee:ff:11:22:33:44:55:66:77:88:99:00", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDe..." - } -] -``` - -## Hetzner Server Provisioning - -### 11. Create a Hetzner Server (Minimal Example) - -First, you need to get your private key UUID: - -```bash -curl -X GET "${COOLIFY_URL}/api/v1/security/keys" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" -``` - -Then create the server: - -```bash -curl -X POST "${COOLIFY_URL}/api/v1/servers/hetzner" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" \ - -d '{ - "cloud_provider_token_id": "abc123def456", - "location": "nbg1", - "server_type": "cx11", - "image": 67794396, - "private_key_uuid": "your-private-key-uuid" - }' -``` - -**Response:** -```json -{ - "uuid": "server-uuid-123", - "hetzner_server_id": 12345678, - "ip": "1.2.3.4" -} -``` - -### 12. Create a Hetzner Server (Full Example with All Options) - -```bash -curl -X POST "${COOLIFY_URL}/api/v1/servers/hetzner" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" \ - -d '{ - "cloud_provider_token_id": "abc123def456", - "location": "nbg1", - "server_type": "cx11", - "image": 67794396, - "name": "production-server", - "private_key_uuid": "your-private-key-uuid", - "enable_ipv4": true, - "enable_ipv6": true, - "hetzner_ssh_key_ids": [123456, 789012], - "cloud_init_script": "#cloud-config\npackages:\n - docker.io\n - git", - "instant_validate": true - }' -``` - -**Parameters:** -- `cloud_provider_token_id` (required): UUID of your Hetzner cloud provider token -- `location` (required): Hetzner location name (e.g., "nbg1", "fsn1", "hel1") -- `server_type` (required): Hetzner server type (e.g., "cx11", "cx21", "ccx13") -- `image` (required): Hetzner image ID (get from images endpoint) -- `name` (optional): Server name (auto-generated if not provided) -- `private_key_uuid` (required): UUID of the private key to use for SSH -- `enable_ipv4` (optional): Enable IPv4 (default: true) -- `enable_ipv6` (optional): Enable IPv6 (default: true) -- `hetzner_ssh_key_ids` (optional): Array of additional Hetzner SSH key IDs -- `cloud_init_script` (optional): Cloud-init YAML script for initial setup -- `instant_validate` (optional): Validate server connection immediately (default: false) - -## Complete Workflow Example - -Here's a complete example of creating a Hetzner server from start to finish: - -```bash -#!/bin/bash - -# Configuration -export COOLIFY_URL="http://localhost" -export API_TOKEN="root" -export HETZNER_API_TOKEN="your-hetzner-api-token" - -# Step 1: Create cloud provider token -echo "Creating cloud provider token..." -TOKEN_RESPONSE=$(curl -s -X POST "${COOLIFY_URL}/api/v1/cloud-tokens" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" \ - -d "{ - \"provider\": \"hetzner\", - \"token\": \"${HETZNER_API_TOKEN}\", - \"name\": \"My Hetzner Token\" - }") - -CLOUD_TOKEN_ID=$(echo $TOKEN_RESPONSE | jq -r '.uuid') -echo "Cloud token created: $CLOUD_TOKEN_ID" - -# Step 2: Get available locations -echo "Fetching locations..." -curl -s -X GET "${COOLIFY_URL}/api/v1/hetzner/locations?cloud_provider_token_id=${CLOUD_TOKEN_ID}" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" | jq '.[] | {name, description, country}' - -# Step 3: Get available server types -echo "Fetching server types..." -curl -s -X GET "${COOLIFY_URL}/api/v1/hetzner/server-types?cloud_provider_token_id=${CLOUD_TOKEN_ID}" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" | jq '.[] | {name, cores, memory, disk}' - -# Step 4: Get available images -echo "Fetching images..." -curl -s -X GET "${COOLIFY_URL}/api/v1/hetzner/images?cloud_provider_token_id=${CLOUD_TOKEN_ID}" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" | jq '.[] | {id, name, description}' - -# Step 5: Get private keys -echo "Fetching private keys..." -KEYS_RESPONSE=$(curl -s -X GET "${COOLIFY_URL}/api/v1/security/keys" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json") - -PRIVATE_KEY_UUID=$(echo $KEYS_RESPONSE | jq -r '.[0].uuid') -echo "Using private key: $PRIVATE_KEY_UUID" - -# Step 6: Create the server -echo "Creating server..." -SERVER_RESPONSE=$(curl -s -X POST "${COOLIFY_URL}/api/v1/servers/hetzner" \ - -H "Authorization: Bearer ${API_TOKEN}" \ - -H "Content-Type: application/json" \ - -d "{ - \"cloud_provider_token_id\": \"${CLOUD_TOKEN_ID}\", - \"location\": \"nbg1\", - \"server_type\": \"cx11\", - \"image\": 67794396, - \"name\": \"my-production-server\", - \"private_key_uuid\": \"${PRIVATE_KEY_UUID}\", - \"enable_ipv4\": true, - \"enable_ipv6\": false, - \"instant_validate\": true - }") - -echo "Server created:" -echo $SERVER_RESPONSE | jq '.' - -SERVER_UUID=$(echo $SERVER_RESPONSE | jq -r '.uuid') -SERVER_IP=$(echo $SERVER_RESPONSE | jq -r '.ip') - -echo "Server UUID: $SERVER_UUID" -echo "Server IP: $SERVER_IP" -echo "You can now SSH to: root@$SERVER_IP" -``` - -## Error Handling - -### Common Errors - -**401 Unauthorized:** -```json -{ - "message": "Unauthenticated." -} -``` -Solution: Check your API token. - -**404 Not Found:** -```json -{ - "message": "Cloud provider token not found." -} -``` -Solution: Verify the UUID exists and belongs to your team. - -**422 Validation Error:** -```json -{ - "message": "Validation failed.", - "errors": { - "provider": ["The provider field is required."], - "token": ["The token field is required."] - } -} -``` -Solution: Check the request body for missing or invalid fields. - -**400 Bad Request:** -```json -{ - "message": "Invalid Hetzner token. Please check your API token." -} -``` -Solution: Verify your Hetzner API token is correct. - -## Testing with Yaak - -To import these examples into Yaak: - -1. Copy any curl command from this document -2. In Yaak, click "Import" → "From cURL" -3. Paste the curl command -4. Update the environment variables (COOLIFY_URL, API_TOKEN) in Yaak's environment settings - -Or create a Yaak environment with these variables: -```json -{ - "COOLIFY_URL": "http://localhost", - "API_TOKEN": "root" -} -``` - -Then you can use `{{COOLIFY_URL}}` and `{{API_TOKEN}}` in your requests. - -## Rate Limiting - -The Hetzner API has rate limits. If you receive a 429 error, the HetznerService will automatically retry with exponential backoff. The API token validation endpoints are also rate-limited on the Coolify side. - -## Security Notes - -- **Never commit your Hetzner API token** to version control -- Store API tokens securely in environment variables or secrets management -- Use the validation endpoint to test tokens before creating resources -- Cloud provider tokens are encrypted at rest in the database -- The actual token value is never returned by the API (only the UUID) diff --git a/docs/api/hetzner-yaak-collection.json b/docs/api/hetzner-yaak-collection.json deleted file mode 100644 index 13d1cf4a4..000000000 --- a/docs/api/hetzner-yaak-collection.json +++ /dev/null @@ -1,284 +0,0 @@ -{ - "name": "Coolify Hetzner Provisioning API", - "description": "Complete API collection for Hetzner server provisioning in Coolify", - "requests": [ - { - "name": "1. Create Hetzner Cloud Token", - "method": "POST", - "url": "{{COOLIFY_URL}}/api/v1/cloud-tokens", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ], - "body": { - "type": "json", - "content": "{\n \"provider\": \"hetzner\",\n \"token\": \"YOUR_HETZNER_API_TOKEN\",\n \"name\": \"My Hetzner Token\"\n}" - } - }, - { - "name": "2. List Cloud Provider Tokens", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/cloud-tokens", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "3. Get Cloud Provider Token", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/cloud-tokens/{{CLOUD_TOKEN_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "4. Update Cloud Token Name", - "method": "PATCH", - "url": "{{COOLIFY_URL}}/api/v1/cloud-tokens/{{CLOUD_TOKEN_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ], - "body": { - "type": "json", - "content": "{\n \"name\": \"Updated Token Name\"\n}" - } - }, - { - "name": "5. Validate Cloud Token", - "method": "POST", - "url": "{{COOLIFY_URL}}/api/v1/cloud-tokens/{{CLOUD_TOKEN_UUID}}/validate", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "6. Delete Cloud Token", - "method": "DELETE", - "url": "{{COOLIFY_URL}}/api/v1/cloud-tokens/{{CLOUD_TOKEN_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "7. Get Hetzner Locations", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/hetzner/locations?cloud_provider_token_id={{CLOUD_TOKEN_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "8. Get Hetzner Server Types", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/hetzner/server-types?cloud_provider_token_id={{CLOUD_TOKEN_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "9. Get Hetzner Images", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/hetzner/images?cloud_provider_token_id={{CLOUD_TOKEN_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "10. Get Hetzner SSH Keys", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/hetzner/ssh-keys?cloud_provider_token_id={{CLOUD_TOKEN_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "11. Get Private Keys (for server creation)", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/security/keys", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "12. Create Hetzner Server (Minimal)", - "method": "POST", - "url": "{{COOLIFY_URL}}/api/v1/servers/hetzner", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ], - "body": { - "type": "json", - "content": "{\n \"cloud_provider_token_id\": \"{{CLOUD_TOKEN_UUID}}\",\n \"location\": \"nbg1\",\n \"server_type\": \"cx11\",\n \"image\": 67794396,\n \"private_key_uuid\": \"{{PRIVATE_KEY_UUID}}\"\n}" - } - }, - { - "name": "13. Create Hetzner Server (Full Options)", - "method": "POST", - "url": "{{COOLIFY_URL}}/api/v1/servers/hetzner", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ], - "body": { - "type": "json", - "content": "{\n \"cloud_provider_token_id\": \"{{CLOUD_TOKEN_UUID}}\",\n \"location\": \"nbg1\",\n \"server_type\": \"cx11\",\n \"image\": 67794396,\n \"name\": \"my-server\",\n \"private_key_uuid\": \"{{PRIVATE_KEY_UUID}}\",\n \"enable_ipv4\": true,\n \"enable_ipv6\": false,\n \"hetzner_ssh_key_ids\": [],\n \"cloud_init_script\": \"#cloud-config\\npackages:\\n - docker.io\",\n \"instant_validate\": true\n}" - } - }, - { - "name": "14. Get Server Details", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/servers/{{SERVER_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "15. List All Servers", - "method": "GET", - "url": "{{COOLIFY_URL}}/api/v1/servers", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - { - "name": "16. Delete Server", - "method": "DELETE", - "url": "{{COOLIFY_URL}}/api/v1/servers/{{SERVER_UUID}}", - "headers": [ - { - "name": "Authorization", - "value": "Bearer {{API_TOKEN}}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - } - ], - "environments": [ - { - "name": "Development", - "variables": { - "COOLIFY_URL": "http://localhost", - "API_TOKEN": "root", - "CLOUD_TOKEN_UUID": "", - "PRIVATE_KEY_UUID": "", - "SERVER_UUID": "" - } - }, - { - "name": "Production", - "variables": { - "COOLIFY_URL": "https://your-coolify-instance.com", - "API_TOKEN": "your-production-token", - "CLOUD_TOKEN_UUID": "", - "PRIVATE_KEY_UUID": "", - "SERVER_UUID": "" - } - } - ] -}