diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php index ef5b4869d..f5a00fe15 100644 --- a/database/seeders/ApplicationSeeder.php +++ b/database/seeders/ApplicationSeeder.php @@ -15,6 +15,7 @@ class ApplicationSeeder extends Seeder public function run(): void { Application::create([ + 'uuid' => 'docker-compose', 'name' => 'Docker Compose Example', 'repository_project_id' => 603035348, 'git_repository' => 'coollabsio/coolify-examples', @@ -30,6 +31,7 @@ public function run(): void 'source_type' => GithubApp::class, ]); Application::create([ + 'uuid' => 'nodejs', 'name' => 'NodeJS Fastify Example', 'fqdn' => 'http://nodejs.127.0.0.1.sslip.io', 'repository_project_id' => 603035348, @@ -45,6 +47,7 @@ public function run(): void 'source_type' => GithubApp::class, ]); Application::create([ + 'uuid' => 'dockerfile', 'name' => 'Dockerfile Example', 'fqdn' => 'http://dockerfile.127.0.0.1.sslip.io', 'repository_project_id' => 603035348, @@ -60,6 +63,7 @@ public function run(): void 'source_type' => GithubApp::class, ]); Application::create([ + 'uuid' => 'dockerfile-pure', 'name' => 'Pure Dockerfile Example', 'fqdn' => 'http://pure-dockerfile.127.0.0.1.sslip.io', 'git_repository' => 'coollabsio/coolify', @@ -78,6 +82,7 @@ public function run(): void ', ]); Application::create([ + 'uuid' => 'crashloop', 'name' => 'Crash Loop Example', 'git_repository' => 'coollabsio/coolify', 'git_branch' => 'v4.x', diff --git a/database/seeders/GithubAppSeeder.php b/database/seeders/GithubAppSeeder.php index b34c00473..10e23c36a 100644 --- a/database/seeders/GithubAppSeeder.php +++ b/database/seeders/GithubAppSeeder.php @@ -14,6 +14,7 @@ public function run(): void { GithubApp::create([ 'id' => 0, + 'uuid' => 'github-public', 'name' => 'Public GitHub', 'api_url' => 'https://api.github.com', 'html_url' => 'https://github.com', @@ -22,7 +23,7 @@ public function run(): void ]); GithubApp::create([ 'name' => 'coolify-laravel-dev-public', - 'uuid' => '69420', + 'uuid' => 'github-app', 'organization' => 'coollabsio', 'api_url' => 'https://api.github.com', 'html_url' => 'https://github.com', diff --git a/database/seeders/GitlabAppSeeder.php b/database/seeders/GitlabAppSeeder.php index ec2b7ec5e..5dfb59902 100644 --- a/database/seeders/GitlabAppSeeder.php +++ b/database/seeders/GitlabAppSeeder.php @@ -14,6 +14,7 @@ public function run(): void { GitlabApp::create([ 'id' => 1, + 'uuid' => 'gitlab-public', 'name' => 'Public GitLab', 'api_url' => 'https://gitlab.com/api/v4', 'html_url' => 'https://gitlab.com', diff --git a/database/seeders/PrivateKeySeeder.php b/database/seeders/PrivateKeySeeder.php index 6b44d0867..0aa4153b3 100644 --- a/database/seeders/PrivateKeySeeder.php +++ b/database/seeders/PrivateKeySeeder.php @@ -13,6 +13,7 @@ class PrivateKeySeeder extends Seeder public function run(): void { PrivateKey::create([ + 'uuid' => 'ssh', 'team_id' => 0, 'name' => 'Testing Host Key', 'description' => 'This is a test docker container', @@ -27,6 +28,7 @@ public function run(): void ]); PrivateKey::create([ + 'uuid' => 'github-key', 'team_id' => 0, 'name' => 'development-github-app', 'description' => 'This is the key for using the development GitHub app', diff --git a/database/seeders/ProjectSeeder.php b/database/seeders/ProjectSeeder.php index 33cd8cd06..ab8e54051 100644 --- a/database/seeders/ProjectSeeder.php +++ b/database/seeders/ProjectSeeder.php @@ -9,10 +9,14 @@ class ProjectSeeder extends Seeder { public function run(): void { - Project::create([ + $project = Project::create([ + 'uuid' => 'project', 'name' => 'My first project', 'description' => 'This is a test project in development', 'team_id' => 0, ]); + + // Update the auto-created environment with a deterministic UUID + $project->environments()->first()->update(['uuid' => 'production']); } } diff --git a/database/seeders/S3StorageSeeder.php b/database/seeders/S3StorageSeeder.php index 9fa531447..b38df6ad5 100644 --- a/database/seeders/S3StorageSeeder.php +++ b/database/seeders/S3StorageSeeder.php @@ -13,6 +13,7 @@ class S3StorageSeeder extends Seeder public function run(): void { S3Storage::create([ + 'uuid' => 'minio', 'name' => 'Local MinIO', 'description' => 'Local MinIO S3 Storage', 'key' => 'minioadmin', diff --git a/database/seeders/ServerSeeder.php b/database/seeders/ServerSeeder.php index d32843107..2d8746691 100644 --- a/database/seeders/ServerSeeder.php +++ b/database/seeders/ServerSeeder.php @@ -13,6 +13,7 @@ public function run(): void { Server::create([ 'id' => 0, + 'uuid' => 'localhost', 'name' => 'localhost', 'description' => 'This is a test docker container in development mode', 'ip' => 'coolify-testing-host', diff --git a/database/seeders/StandaloneDockerSeeder.php b/database/seeders/StandaloneDockerSeeder.php index a466de56b..e31c62d9f 100644 --- a/database/seeders/StandaloneDockerSeeder.php +++ b/database/seeders/StandaloneDockerSeeder.php @@ -15,6 +15,7 @@ public function run(): void if (StandaloneDocker::find(0) == null) { StandaloneDocker::create([ 'id' => 0, + 'uuid' => 'docker', 'name' => 'Standalone Docker 1', 'network' => 'coolify', 'server_id' => 0, diff --git a/database/seeders/StandalonePostgresqlSeeder.php b/database/seeders/StandalonePostgresqlSeeder.php index 1fc96a610..59ee6fd42 100644 --- a/database/seeders/StandalonePostgresqlSeeder.php +++ b/database/seeders/StandalonePostgresqlSeeder.php @@ -11,6 +11,7 @@ class StandalonePostgresqlSeeder extends Seeder public function run(): void { StandalonePostgresql::create([ + 'uuid' => 'postgresql', 'name' => 'Local PostgreSQL', 'description' => 'Local PostgreSQL for testing', 'postgres_password' => 'postgres', diff --git a/openapi.json b/openapi.json index 2d87ed51b..fdeb8853b 100644 --- a/openapi.json +++ b/openapi.json @@ -3295,6 +3295,387 @@ ] } }, + "\/cloud-tokens": { + "get": { + "tags": [ + "Cloud Tokens" + ], + "summary": "List Cloud Provider Tokens", + "description": "List all cloud provider tokens for the authenticated team.", + "operationId": "list-cloud-tokens", + "responses": { + "200": { + "description": "Get all cloud provider tokens.", + "content": { + "application\/json": { + "schema": { + "type": "array", + "items": { + "properties": { + "uuid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "type": "string", + "enum": [ + "hetzner", + "digitalocean" + ] + }, + "team_id": { + "type": "integer" + }, + "servers_count": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "type": "object" + } + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "400": { + "$ref": "#\/components\/responses\/400" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + }, + "post": { + "tags": [ + "Cloud Tokens" + ], + "summary": "Create Cloud Provider Token", + "description": "Create a new cloud provider token. The token will be validated before being stored.", + "operationId": "create-cloud-token", + "requestBody": { + "description": "Cloud provider token details", + "required": true, + "content": { + "application\/json": { + "schema": { + "required": [ + "provider", + "token", + "name" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "hetzner", + "digitalocean" + ], + "example": "hetzner", + "description": "The cloud provider." + }, + "token": { + "type": "string", + "example": "your-api-token-here", + "description": "The API token for the cloud provider." + }, + "name": { + "type": "string", + "example": "My Hetzner Token", + "description": "A friendly name for the token." + } + }, + "type": "object" + } + } + } + }, + "responses": { + "201": { + "description": "Cloud provider token created.", + "content": { + "application\/json": { + "schema": { + "properties": { + "uuid": { + "type": "string", + "example": "og888os", + "description": "The UUID of the token." + } + }, + "type": "object" + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "400": { + "$ref": "#\/components\/responses\/400" + }, + "422": { + "$ref": "#\/components\/responses\/422" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, + "\/cloud-tokens\/{uuid}": { + "get": { + "tags": [ + "Cloud Tokens" + ], + "summary": "Get Cloud Provider Token", + "description": "Get cloud provider token by UUID.", + "operationId": "get-cloud-token-by-uuid", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "Token UUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Get cloud provider token by UUID", + "content": { + "application\/json": { + "schema": { + "properties": { + "uuid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "team_id": { + "type": "integer" + }, + "servers_count": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "404": { + "$ref": "#\/components\/responses\/404" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + }, + "delete": { + "tags": [ + "Cloud Tokens" + ], + "summary": "Delete Cloud Provider Token", + "description": "Delete cloud provider token by UUID. Cannot delete if token is used by any servers.", + "operationId": "delete-cloud-token-by-uuid", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "UUID of the cloud provider token.", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Cloud provider token deleted.", + "content": { + "application\/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "Cloud provider token deleted." + } + }, + "type": "object" + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "400": { + "$ref": "#\/components\/responses\/400" + }, + "404": { + "$ref": "#\/components\/responses\/404" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + }, + "patch": { + "tags": [ + "Cloud Tokens" + ], + "summary": "Update Cloud Provider Token", + "description": "Update cloud provider token name.", + "operationId": "update-cloud-token-by-uuid", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "Token UUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Cloud provider token updated.", + "required": true, + "content": { + "application\/json": { + "schema": { + "properties": { + "name": { + "type": "string", + "description": "The friendly name for the token." + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Cloud provider token updated.", + "content": { + "application\/json": { + "schema": { + "properties": { + "uuid": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "404": { + "$ref": "#\/components\/responses\/404" + }, + "422": { + "$ref": "#\/components\/responses\/422" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, + "\/cloud-tokens\/{uuid}\/validate": { + "post": { + "tags": [ + "Cloud Tokens" + ], + "summary": "Validate Cloud Provider Token", + "description": "Validate a cloud provider token against the provider API.", + "operationId": "validate-cloud-token-by-uuid", + "parameters": [ + { + "name": "uuid", + "in": "path", + "description": "Token UUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Token validation result.", + "content": { + "application\/json": { + "schema": { + "properties": { + "valid": { + "type": "boolean", + "example": true + }, + "message": { + "type": "string", + "example": "Token is valid." + } + }, + "type": "object" + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "404": { + "$ref": "#\/components\/responses\/404" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, "\/databases": { "get": { "tags": [ @@ -6334,6 +6715,407 @@ ] } }, + "\/hetzner\/locations": { + "get": { + "tags": [ + "Hetzner" + ], + "summary": "Get Hetzner Locations", + "description": "Get all available Hetzner datacenter locations.", + "operationId": "get-hetzner-locations", + "parameters": [ + { + "name": "cloud_provider_token_id", + "in": "query", + "description": "Cloud provider token UUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of Hetzner locations.", + "content": { + "application\/json": { + "schema": { + "type": "array", + "items": { + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "country": { + "type": "string" + }, + "city": { + "type": "string" + }, + "latitude": { + "type": "number" + }, + "longitude": { + "type": "number" + } + }, + "type": "object" + } + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "404": { + "$ref": "#\/components\/responses\/404" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, + "\/hetzner\/server-types": { + "get": { + "tags": [ + "Hetzner" + ], + "summary": "Get Hetzner Server Types", + "description": "Get all available Hetzner server types (instance sizes).", + "operationId": "get-hetzner-server-types", + "parameters": [ + { + "name": "cloud_provider_token_id", + "in": "query", + "description": "Cloud provider token UUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of Hetzner server types.", + "content": { + "application\/json": { + "schema": { + "type": "array", + "items": { + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "cores": { + "type": "integer" + }, + "memory": { + "type": "number" + }, + "disk": { + "type": "integer" + }, + "prices": { + "type": "array" + } + }, + "type": "object" + } + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "404": { + "$ref": "#\/components\/responses\/404" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, + "\/hetzner\/images": { + "get": { + "tags": [ + "Hetzner" + ], + "summary": "Get Hetzner Images", + "description": "Get all available Hetzner system images (operating systems).", + "operationId": "get-hetzner-images", + "parameters": [ + { + "name": "cloud_provider_token_id", + "in": "query", + "description": "Cloud provider token UUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of Hetzner images.", + "content": { + "application\/json": { + "schema": { + "type": "array", + "items": { + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string" + }, + "os_flavor": { + "type": "string" + }, + "os_version": { + "type": "string" + }, + "architecture": { + "type": "string" + } + }, + "type": "object" + } + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "404": { + "$ref": "#\/components\/responses\/404" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, + "\/hetzner\/ssh-keys": { + "get": { + "tags": [ + "Hetzner" + ], + "summary": "Get Hetzner SSH Keys", + "description": "Get all SSH keys stored in the Hetzner account.", + "operationId": "get-hetzner-ssh-keys", + "parameters": [ + { + "name": "cloud_provider_token_id", + "in": "query", + "description": "Cloud provider token UUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of Hetzner SSH keys.", + "content": { + "application\/json": { + "schema": { + "type": "array", + "items": { + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "fingerprint": { + "type": "string" + }, + "public_key": { + "type": "string" + } + }, + "type": "object" + } + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "404": { + "$ref": "#\/components\/responses\/404" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, + "\/servers\/hetzner": { + "post": { + "tags": [ + "Hetzner" + ], + "summary": "Create Hetzner Server", + "description": "Create a new server on Hetzner and register it in Coolify.", + "operationId": "create-hetzner-server", + "requestBody": { + "description": "Hetzner server creation parameters", + "required": true, + "content": { + "application\/json": { + "schema": { + "required": [ + "cloud_provider_token_id", + "location", + "server_type", + "image", + "private_key_uuid" + ], + "properties": { + "cloud_provider_token_id": { + "type": "string", + "example": "abc123", + "description": "Cloud provider token UUID" + }, + "location": { + "type": "string", + "example": "nbg1", + "description": "Hetzner location name" + }, + "server_type": { + "type": "string", + "example": "cx11", + "description": "Hetzner server type name" + }, + "image": { + "type": "integer", + "example": 15512617, + "description": "Hetzner image ID" + }, + "name": { + "type": "string", + "example": "my-server", + "description": "Server name (auto-generated if not provided)" + }, + "private_key_uuid": { + "type": "string", + "example": "xyz789", + "description": "Private key UUID" + }, + "enable_ipv4": { + "type": "boolean", + "example": true, + "description": "Enable IPv4 (default: true)" + }, + "enable_ipv6": { + "type": "boolean", + "example": true, + "description": "Enable IPv6 (default: true)" + }, + "hetzner_ssh_key_ids": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Additional Hetzner SSH key IDs" + }, + "cloud_init_script": { + "type": "string", + "description": "Cloud-init YAML script (optional)" + }, + "instant_validate": { + "type": "boolean", + "example": false, + "description": "Validate server immediately after creation" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "201": { + "description": "Hetzner server created.", + "content": { + "application\/json": { + "schema": { + "properties": { + "uuid": { + "type": "string", + "example": "og888os", + "description": "The UUID of the server." + }, + "hetzner_server_id": { + "type": "integer", + "description": "The Hetzner server ID." + }, + "ip": { + "type": "string", + "description": "The server IP address." + } + }, + "type": "object" + } + } + } + }, + "401": { + "$ref": "#\/components\/responses\/401" + }, + "400": { + "$ref": "#\/components\/responses\/400" + }, + "404": { + "$ref": "#\/components\/responses\/404" + }, + "422": { + "$ref": "#\/components\/responses\/422" + } + }, + "security": [ + { + "bearerAuth": [] + } + ] + } + }, "\/version": { "get": { "summary": "Version", @@ -10209,6 +10991,10 @@ "name": "Applications", "description": "Applications" }, + { + "name": "Cloud Tokens", + "description": "Cloud Tokens" + }, { "name": "Databases", "description": "Databases" @@ -10221,6 +11007,10 @@ "name": "GitHub Apps", "description": "GitHub Apps" }, + { + "name": "Hetzner", + "description": "Hetzner" + }, { "name": "Projects", "description": "Projects" diff --git a/openapi.yaml b/openapi.yaml index b42d5ab75..854da07ec 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -2090,6 +2090,224 @@ paths: security: - bearerAuth: [] + /cloud-tokens: + get: + tags: + - 'Cloud Tokens' + summary: 'List Cloud Provider Tokens' + description: 'List all cloud provider tokens for the authenticated team.' + operationId: list-cloud-tokens + responses: + '200': + description: 'Get all cloud provider tokens.' + content: + application/json: + schema: + type: array + items: + properties: { uuid: { type: string }, name: { type: string }, provider: { type: string, enum: [hetzner, digitalocean] }, team_id: { type: integer }, servers_count: { type: integer }, created_at: { type: string }, updated_at: { type: string } } + type: object + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + security: + - + bearerAuth: [] + post: + tags: + - 'Cloud Tokens' + summary: 'Create Cloud Provider Token' + description: 'Create a new cloud provider token. The token will be validated before being stored.' + operationId: create-cloud-token + requestBody: + description: 'Cloud provider token details' + required: true + content: + application/json: + schema: + required: + - provider + - token + - name + properties: + provider: + type: string + enum: [hetzner, digitalocean] + example: hetzner + description: 'The cloud provider.' + token: + type: string + example: your-api-token-here + description: 'The API token for the cloud provider.' + name: + type: string + example: 'My Hetzner Token' + description: 'A friendly name for the token.' + type: object + responses: + '201': + description: 'Cloud provider token created.' + content: + application/json: + schema: + properties: + uuid: { type: string, example: og888os, description: 'The UUID of the token.' } + type: object + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + '422': + $ref: '#/components/responses/422' + security: + - + bearerAuth: [] + '/cloud-tokens/{uuid}': + get: + tags: + - 'Cloud Tokens' + summary: 'Get Cloud Provider Token' + description: 'Get cloud provider token by UUID.' + operationId: get-cloud-token-by-uuid + parameters: + - + name: uuid + in: path + description: 'Token UUID' + required: true + schema: + type: string + responses: + '200': + description: 'Get cloud provider token by UUID' + content: + application/json: + schema: + properties: + uuid: { type: string } + name: { type: string } + provider: { type: string } + team_id: { type: integer } + servers_count: { type: integer } + created_at: { type: string } + updated_at: { type: string } + type: object + '401': + $ref: '#/components/responses/401' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] + delete: + tags: + - 'Cloud Tokens' + summary: 'Delete Cloud Provider Token' + description: 'Delete cloud provider token by UUID. Cannot delete if token is used by any servers.' + operationId: delete-cloud-token-by-uuid + parameters: + - + name: uuid + in: path + description: 'UUID of the cloud provider token.' + required: true + schema: + type: string + format: uuid + responses: + '200': + description: 'Cloud provider token deleted.' + content: + application/json: + schema: + properties: + message: { type: string, example: 'Cloud provider token deleted.' } + type: object + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] + patch: + tags: + - 'Cloud Tokens' + summary: 'Update Cloud Provider Token' + description: 'Update cloud provider token name.' + operationId: update-cloud-token-by-uuid + parameters: + - + name: uuid + in: path + description: 'Token UUID' + required: true + schema: + type: string + requestBody: + description: 'Cloud provider token updated.' + required: true + content: + application/json: + schema: + properties: + name: + type: string + description: 'The friendly name for the token.' + type: object + responses: + '200': + description: 'Cloud provider token updated.' + content: + application/json: + schema: + properties: + uuid: { type: string } + type: object + '401': + $ref: '#/components/responses/401' + '404': + $ref: '#/components/responses/404' + '422': + $ref: '#/components/responses/422' + security: + - + bearerAuth: [] + '/cloud-tokens/{uuid}/validate': + post: + tags: + - 'Cloud Tokens' + summary: 'Validate Cloud Provider Token' + description: 'Validate a cloud provider token against the provider API.' + operationId: validate-cloud-token-by-uuid + parameters: + - + name: uuid + in: path + description: 'Token UUID' + required: true + schema: + type: string + responses: + '200': + description: 'Token validation result.' + content: + application/json: + schema: + properties: + valid: { type: boolean, example: true } + message: { type: string, example: 'Token is valid.' } + type: object + '401': + $ref: '#/components/responses/401' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] /databases: get: tags: @@ -4099,6 +4317,220 @@ paths: security: - bearerAuth: [] + /hetzner/locations: + get: + tags: + - Hetzner + summary: 'Get Hetzner Locations' + description: 'Get all available Hetzner datacenter locations.' + operationId: get-hetzner-locations + parameters: + - + name: cloud_provider_token_id + in: query + description: 'Cloud provider token UUID' + required: true + schema: + type: string + responses: + '200': + description: 'List of Hetzner locations.' + content: + application/json: + schema: + type: array + items: + properties: { id: { type: integer }, name: { type: string }, description: { type: string }, country: { type: string }, city: { type: string }, latitude: { type: number }, longitude: { type: number } } + type: object + '401': + $ref: '#/components/responses/401' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] + /hetzner/server-types: + get: + tags: + - Hetzner + summary: 'Get Hetzner Server Types' + description: 'Get all available Hetzner server types (instance sizes).' + operationId: get-hetzner-server-types + parameters: + - + name: cloud_provider_token_id + in: query + description: 'Cloud provider token UUID' + required: true + schema: + type: string + responses: + '200': + description: 'List of Hetzner server types.' + content: + application/json: + schema: + type: array + items: + properties: { id: { type: integer }, name: { type: string }, description: { type: string }, cores: { type: integer }, memory: { type: number }, disk: { type: integer }, prices: { type: array } } + type: object + '401': + $ref: '#/components/responses/401' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] + /hetzner/images: + get: + tags: + - Hetzner + summary: 'Get Hetzner Images' + description: 'Get all available Hetzner system images (operating systems).' + operationId: get-hetzner-images + parameters: + - + name: cloud_provider_token_id + in: query + description: 'Cloud provider token UUID' + required: true + schema: + type: string + responses: + '200': + description: 'List of Hetzner images.' + content: + application/json: + schema: + type: array + items: + properties: { id: { type: integer }, name: { type: string }, description: { type: string }, type: { type: string }, os_flavor: { type: string }, os_version: { type: string }, architecture: { type: string } } + type: object + '401': + $ref: '#/components/responses/401' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] + /hetzner/ssh-keys: + get: + tags: + - Hetzner + summary: 'Get Hetzner SSH Keys' + description: 'Get all SSH keys stored in the Hetzner account.' + operationId: get-hetzner-ssh-keys + parameters: + - + name: cloud_provider_token_id + in: query + description: 'Cloud provider token UUID' + required: true + schema: + type: string + responses: + '200': + description: 'List of Hetzner SSH keys.' + content: + application/json: + schema: + type: array + items: + properties: { id: { type: integer }, name: { type: string }, fingerprint: { type: string }, public_key: { type: string } } + type: object + '401': + $ref: '#/components/responses/401' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] + /servers/hetzner: + post: + tags: + - Hetzner + summary: 'Create Hetzner Server' + description: 'Create a new server on Hetzner and register it in Coolify.' + operationId: create-hetzner-server + requestBody: + description: 'Hetzner server creation parameters' + required: true + content: + application/json: + schema: + required: + - cloud_provider_token_id + - location + - server_type + - image + - private_key_uuid + properties: + cloud_provider_token_id: + type: string + example: abc123 + description: 'Cloud provider token UUID' + location: + type: string + example: nbg1 + description: 'Hetzner location name' + server_type: + type: string + example: cx11 + description: 'Hetzner server type name' + image: + type: integer + example: 15512617 + description: 'Hetzner image ID' + name: + type: string + example: my-server + description: 'Server name (auto-generated if not provided)' + private_key_uuid: + type: string + example: xyz789 + description: 'Private key UUID' + enable_ipv4: + type: boolean + example: true + description: 'Enable IPv4 (default: true)' + enable_ipv6: + type: boolean + example: true + description: 'Enable IPv6 (default: true)' + hetzner_ssh_key_ids: + type: array + items: { type: integer } + description: 'Additional Hetzner SSH key IDs' + cloud_init_script: + type: string + description: 'Cloud-init YAML script (optional)' + instant_validate: + type: boolean + example: false + description: 'Validate server immediately after creation' + type: object + responses: + '201': + description: 'Hetzner server created.' + content: + application/json: + schema: + properties: + uuid: { type: string, example: og888os, description: 'The UUID of the server.' } + hetzner_server_id: { type: integer, description: 'The Hetzner server ID.' } + ip: { type: string, description: 'The server IP address.' } + type: object + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + '404': + $ref: '#/components/responses/404' + '422': + $ref: '#/components/responses/422' + security: + - + bearerAuth: [] /version: get: summary: Version @@ -6580,6 +7012,9 @@ tags: - name: Applications description: Applications + - + name: 'Cloud Tokens' + description: 'Cloud Tokens' - name: Databases description: Databases @@ -6589,6 +7024,9 @@ tags: - name: 'GitHub Apps' description: 'GitHub Apps' + - + name: Hetzner + description: Hetzner - name: Projects description: Projects