diff --git a/app/Enums/RedirectTypes.php b/app/Enums/RedirectTypes.php new file mode 100644 index 000000000..efe8bd9de --- /dev/null +++ b/app/Enums/RedirectTypes.php @@ -0,0 +1,10 @@ +push($projects->pluck('applications')->flatten()); $applications = $applications->flatten(); - return response()->json($applications); + return response()->json(serialize_api_response($applications)); } public function application_by_uuid(Request $request) @@ -36,12 +40,42 @@ public function application_by_uuid(Request $request) if (! $uuid) { return response()->json(['error' => 'UUID is required.'], 400); } - $application = Application::where('uuid', $uuid)->first(); + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); if (! $application) { return response()->json(['error' => 'Application not found.'], 404); } - return response()->json($application); + return response()->json(serialize_api_response($application)); + } + + public function delete_by_uuid(Request $request) + { + ray()->clearAll(); + $teamId = get_team_id_from_token(); + $cleanup = $request->query->get('cleanup') ?? false; + if (is_null($teamId)) { + return invalid_token(); + } + + if ($request->collect()->count() == 0) { + return response()->json([ + 'message' => 'Invalid request.', + ], 400); + } + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); + + if (! $application) { + return response()->json([ + 'success' => false, + 'message' => 'Application not found', + ], 404); + } + DeleteResourceJob::dispatch($application, $cleanup); + + return response()->json([ + 'success' => true, + 'message' => 'Application deletion request queued.', + ]); } public function update_by_uuid(Request $request) @@ -57,7 +91,7 @@ public function update_by_uuid(Request $request) 'message' => 'Invalid request.', ], 400); } - $application = Application::where('uuid', $request->uuid)->first(); + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); if (! $application) { return response()->json([ @@ -66,7 +100,7 @@ public function update_by_uuid(Request $request) ], 404); } $server = $application->destination->server; - $allowedFields = ['name', 'description', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose', 'docker_compose_raw', 'docker_compose_domains', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'redirect']; + $allowedFields = ['name', 'description', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'redirect']; $validator = Validator::make($request->all(), [ 'name' => 'string|max:255', 'description' => 'string|nullable', @@ -118,10 +152,10 @@ public function update_by_uuid(Request $request) 'docker_compose_location' => 'string', 'docker_compose' => 'string|nullable', 'docker_compose_raw' => 'string|nullable', - 'docker_compose_domains' => 'string|nullable', // must be like: "{\"api\":{\"domain\":\"http:\\/\\/b8sos8k.127.0.0.1.sslip.io\"}}" + // 'docker_compose_domains' => 'string|nullable', // must be like: "{\"api\":{\"domain\":\"http:\\/\\/b8sos8k.127.0.0.1.sslip.io\"}}" 'docker_compose_custom_start_command' => 'string|nullable', 'docker_compose_custom_build_command' => 'string|nullable', - 'redirect' => 'enum:both,www,non-www', + 'redirect' => Rule::enum(RedirectTypes::class), ]); // Validate ports_exposes @@ -130,7 +164,7 @@ public function update_by_uuid(Request $request) foreach ($ports as $port) { if (! is_numeric($port)) { return response()->json([ - 'message' => 'Validation failed', + 'message' => 'Validation failed.', 'errors' => [ 'ports_exposes' => 'The ports_exposes should be a comma separated list of numbers.', ], @@ -145,7 +179,7 @@ public function update_by_uuid(Request $request) $port = explode(':', $portMapping); if (in_array($port[0], $ports)) { return response()->json([ - 'message' => 'Validation failed', + 'message' => 'Validation failed.', 'errors' => [ 'ports_mappings' => 'The first number before : should be unique between mappings.', ], @@ -158,7 +192,7 @@ public function update_by_uuid(Request $request) if ($request->has('custom_labels')) { if (! isBase64Encoded($request->custom_labels)) { return response()->json([ - 'message' => 'Validation failed', + 'message' => 'Validation failed.', 'errors' => [ 'custom_labels' => 'The custom_labels should be base64 encoded.', ], @@ -167,7 +201,7 @@ public function update_by_uuid(Request $request) $customLabels = base64_decode($request->custom_labels); if (mb_detect_encoding($customLabels, 'ASCII', true) === false) { return response()->json([ - 'message' => 'Validation failed', + 'message' => 'Validation failed.', 'errors' => [ 'custom_labels' => 'The custom_labels should be base64 encoded.', ], @@ -185,7 +219,7 @@ public function update_by_uuid(Request $request) } return response()->json([ - 'message' => 'Validation failed', + 'message' => 'Validation failed.', 'errors' => $errors, ], 422); } @@ -203,7 +237,7 @@ public function update_by_uuid(Request $request) }); if (count($errors) > 0) { return response()->json([ - 'message' => 'Validation failed', + 'message' => 'Validation failed.', 'errors' => $errors, ], 422); } @@ -216,9 +250,272 @@ public function update_by_uuid(Request $request) $application->fill($request->all()); $application->save(); + return response()->json(serialize_api_response($application)); + } + + public function envs_by_uuid(Request $request) + { + ray()->clearAll(); + $teamId = get_team_id_from_token(); + if (is_null($teamId)) { + return invalid_token(); + } + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); + + if (! $application) { + return response()->json([ + 'success' => false, + 'message' => 'Application not found', + ], 404); + } + $envs = $application->environment_variables->sortBy('id')->merge($application->environment_variables_preview->sortBy('id')); + + return response()->json(serialize_api_response($envs)); + } + + public function update_env_by_uuid(Request $request) + { + ray()->clearAll(); + $allowedFields = ['key', 'value', 'is_preview', 'is_build_time', 'is_literal', 'both']; + $teamId = get_team_id_from_token(); + + if (is_null($teamId)) { + return invalid_token(); + } + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); + + if (! $application) { + return response()->json([ + 'success' => false, + 'message' => 'Application not found', + ], 404); + } + $validator = Validator::make($request->all(), [ + 'key' => 'string|required', + 'value' => 'string|nullable', + 'is_preview' => 'boolean', + 'is_build_time' => 'boolean', + 'is_literal' => 'boolean', + 'both' => 'boolean', + ]); + + $extraFields = array_diff(array_keys($request->all()), $allowedFields); + if ($validator->fails() || ! empty($extraFields)) { + $errors = $validator->errors(); + if (! empty($extraFields)) { + foreach ($extraFields as $field) { + $errors->add($field, 'This field is not allowed.'); + } + } + + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => $errors, + ], 422); + } + $is_preview = $request->is_preview ?? false; + $is_build_time = $request->is_build_time ?? false; + $is_literal = $request->is_literal ?? false; + $both = $request->both ?? false; + if ($both) { + $env = $application->environment_variables_preview->where('key', $request->key)->first(); + if ($env) { + $env->value = $request->value; + if ($env->is_build_time != $is_build_time) { + $env->is_build_time = $is_build_time; + } + if ($env->is_literal != $is_literal) { + $env->is_literal = $is_literal; + } + ray($env); + $env->save(); + } + + $env = $application->environment_variables->where('key', $request->key)->first(); + if ($env) { + $env->value = $request->value; + if ($env->is_build_time != $is_build_time) { + $env->is_build_time = $is_build_time; + } + if ($env->is_literal != $is_literal) { + $env->is_literal = $is_literal; + } + $env->save(); + } + + return response()->json([ + 'message' => 'Environment variables updated.', + ]); + } + if ($is_preview) { + $env = $application->environment_variables_preview->where('key', $request->key)->first(); + if ($env) { + $env->value = $request->value; + if ($env->is_build_time != $is_build_time) { + $env->is_build_time = $is_build_time; + } + if ($env->is_literal != $is_literal) { + $env->is_literal = $is_literal; + } + if ($env->is_preview != $is_preview) { + $env->is_preview = $is_preview; + } + $env->save(); + + return response()->json(serialize_api_response($env)); + } else { + return response()->json([ + 'message' => 'Environment variable not found.', + ], 404); + } + } else { + $env = $application->environment_variables->where('key', $request->key)->first(); + if ($env) { + $env->value = $request->value; + if ($env->is_build_time != $is_build_time) { + $env->is_build_time = $is_build_time; + } + if ($env->is_literal != $is_literal) { + $env->is_literal = $is_literal; + } + if ($env->is_preview != $is_preview) { + $env->is_preview = $is_preview; + } + $env->save(); + + return response()->json(serialize_api_response($env)); + } else { + + return response()->json([ + 'message' => 'Environment variable not found.', + ], 404); + + } + } + return response()->json([ - 'message' => 'Application updated successfully.', - 'application' => $application, + 'message' => 'Something went wrong.', + ], 500); + + } + + public function create_env(Request $request) + { + ray()->clearAll(); + $allowedFields = ['key', 'value', 'is_preview', 'is_build_time', 'is_literal']; + $teamId = get_team_id_from_token(); + + if (is_null($teamId)) { + return invalid_token(); + } + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); + + if (! $application) { + return response()->json([ + 'success' => false, + 'message' => 'Application not found', + ], 404); + } + $validator = Validator::make($request->all(), [ + 'key' => 'string|required', + 'value' => 'string|nullable', + 'is_preview' => 'boolean', + 'is_build_time' => 'boolean', + 'is_literal' => 'boolean', + ]); + + $extraFields = array_diff(array_keys($request->all()), $allowedFields); + if ($validator->fails() || ! empty($extraFields)) { + $errors = $validator->errors(); + if (! empty($extraFields)) { + foreach ($extraFields as $field) { + $errors->add($field, 'This field is not allowed.'); + } + } + + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => $errors, + ], 422); + } + $is_preview = $request->is_preview ?? false; + if ($is_preview) { + $env = $application->environment_variables_preview->where('key', $request->key)->first(); + if ($env) { + return response()->json([ + 'message' => 'Environment variable already exists. Use PATCH request to update it.', + ], 409); + } else { + $env = $application->environment_variables()->create([ + 'key' => $request->key, + 'value' => $request->value, + 'is_preview' => $request->is_preview ?? false, + 'is_build_time' => $request->is_build_time ?? false, + 'is_literal' => $request->is_literal ?? false, + ]); + + return response()->json(serialize_api_response($env))->setStatusCode(201); + } + } else { + $env = $application->environment_variables->where('key', $request->key)->first(); + if ($env) { + return response()->json([ + 'message' => 'Environment variable already exists. Use PATCH request to update it.', + ], 409); + } else { + $env = $application->environment_variables()->create([ + 'key' => $request->key, + 'value' => $request->value, + 'is_preview' => $request->is_preview ?? false, + 'is_build_time' => $request->is_build_time ?? false, + 'is_literal' => $request->is_literal ?? false, + ]); + + return response()->json(serialize_api_response($env))->setStatusCode(201); + + } + } + + return response()->json([ + 'message' => 'Something went wrong.', + ], 500); + + } + + public function delete_env_by_uuid(Request $request) + { + ray()->clearAll(); + $teamId = get_team_id_from_token(); + $both = $request->query->get('both') ?? false; + if (is_null($teamId)) { + return invalid_token(); + } + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); + + if (! $application) { + return response()->json([ + 'success' => false, + 'message' => 'Application not found.', + ], 404); + } + $found_env = EnvironmentVariable::where('uuid', $request->env_uuid)->where('application_id', $application->id)->first(); + if (! $found_env) { + return response()->json([ + 'success' => false, + 'message' => 'Environment variable not found.', + ], 404); + } + $found_env->delete(); + if ($both) { + $found_other_pair = EnvironmentVariable::where('application_id', $application->id)->where('key', $found_env->key)->first(); + if ($found_other_pair) { + $found_other_pair->delete(); + } + } + + return response()->json([ + 'success' => true, + 'message' => 'Environment variable deleted.', ]); } @@ -234,7 +531,7 @@ public function action_deploy(Request $request) if (! $uuid) { return response()->json(['error' => 'UUID is required.'], 400); } - $application = Application::where('uuid', $uuid)->first(); + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); if (! $application) { return response()->json(['error' => 'Application not found.'], 404); } @@ -270,7 +567,7 @@ public function action_stop(Request $request) if (! $uuid) { return response()->json(['error' => 'UUID is required.'], 400); } - $application = Application::where('uuid', $uuid)->first(); + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); if (! $application) { return response()->json(['error' => 'Application not found.'], 404); } @@ -295,7 +592,7 @@ public function action_restart(Request $request) if (! $uuid) { return response()->json(['error' => 'UUID is required.'], 400); } - $application = Application::where('uuid', $uuid)->first(); + $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); if (! $application) { return response()->json(['error' => 'Application not found.'], 404); } diff --git a/app/Http/Controllers/Api/Deploy.php b/app/Http/Controllers/Api/Deploy.php index f7a34facc..d510970dd 100644 --- a/app/Http/Controllers/Api/Deploy.php +++ b/app/Http/Controllers/Api/Deploy.php @@ -49,14 +49,14 @@ public function deployment_by_uuid(Request $request) } $uuid = $request->route('uuid'); if (! $uuid) { - return response()->json(['error' => 'UUID is required.'], 400); + return response()->json(['message' => 'UUID is required.'], 400); } - $deployment = ApplicationDeploymentQueue::where('deployment_uuid', $uuid)->first()->makeHidden('logs'); + $deployment = ApplicationDeploymentQueue::where('deployment_uuid', $uuid)->first(); if (! $deployment) { - return response()->json(['error' => 'Deployment not found.'], 404); + return response()->json(['message' => 'Deployment not found.'], 404); } - return response()->json(serialize_api_response($deployment), 200); + return response()->json(serialize_api_response($deployment->makeHidden('logs')), 200); } public function deploy(Request $request) @@ -67,7 +67,7 @@ public function deploy(Request $request) $force = $request->query->get('force') ?? false; if ($uuids && $tags) { - return response()->json(['error' => 'You can only use uuid or tag, not both.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); + return response()->json(['message' => 'You can only use uuid or tag, not both.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); } if (is_null($teamId)) { return invalid_token(); @@ -78,7 +78,7 @@ public function deploy(Request $request) return $this->by_uuids($uuids, $teamId, $force); } - return response()->json(['error' => 'You must provide uuid or tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); + return response()->json(['message' => 'You must provide uuid or tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); } private function by_uuids(string $uuid, int $teamId, bool $force = false) @@ -87,7 +87,7 @@ private function by_uuids(string $uuid, int $teamId, bool $force = false) $uuids = collect(array_filter($uuids)); if (count($uuids) === 0) { - return response()->json(['error' => 'No UUIDs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); + return response()->json(['message' => 'No UUIDs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); } $deployments = collect(); $payload = collect(); @@ -108,7 +108,7 @@ private function by_uuids(string $uuid, int $teamId, bool $force = false) return response()->json($payload->toArray(), 200); } - return response()->json(['error' => 'No resources found.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404); + return response()->json(['message' => 'No resources found.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404); } public function by_tags(string $tags, int $team_id, bool $force = false) @@ -117,7 +117,7 @@ public function by_tags(string $tags, int $team_id, bool $force = false) $tags = collect(array_filter($tags)); if (count($tags) === 0) { - return response()->json(['error' => 'No TAGs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); + return response()->json(['message' => 'No TAGs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400); } $message = collect([]); $deployments = collect(); @@ -147,7 +147,6 @@ public function by_tags(string $tags, int $team_id, bool $force = false) $message = $message->merge($return_message); } } - ray($message); if ($message->count() > 0) { $payload->put('message', $message->toArray()); if ($deployments->count() > 0) { @@ -157,7 +156,7 @@ public function by_tags(string $tags, int $team_id, bool $force = false) return response()->json($payload->toArray(), 200); } - return response()->json(['error' => 'No resources found with this tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404); + return response()->json(['message' => 'No resources found with this tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404); } public function deploy_resource($resource, bool $force = false): array diff --git a/app/Http/Controllers/Api/Domains.php b/app/Http/Controllers/Api/Domains.php deleted file mode 100644 index 6473b64de..000000000 --- a/app/Http/Controllers/Api/Domains.php +++ /dev/null @@ -1,54 +0,0 @@ -all(), [ - 'uuid' => 'required|string|exists:applications,uuid', - 'domains' => 'required|array', - 'domains.*' => 'required|string|distinct', - ]); - - if ($validator->fails()) { - return response()->json([ - 'success' => false, - 'message' => 'Validation failed', - 'errors' => $validator->errors(), - ], 422); - } - - $application = Application::where('uuid', $request->uuid)->first(); - - if (! $application) { - return response()->json([ - 'success' => false, - 'message' => 'Application not found', - ], 404); - } - - $existingDomains = explode(',', $application->fqdn); - $domainsToDelete = $request->domains; - $updatedDomains = array_diff($existingDomains, $domainsToDelete); - $application->fqdn = implode(',', $updatedDomains); - $application->custom_labels = base64_encode(implode("\n ", generateLabelsApplication($application))); - $application->save(); - - return response()->json([ - 'success' => true, - 'message' => 'Domains updated successfully', - 'application' => $application, - ]); - } -} diff --git a/app/Http/Controllers/Api/EnvironmentVariables.php b/app/Http/Controllers/Api/EnvironmentVariables.php new file mode 100644 index 000000000..d27d4f501 --- /dev/null +++ b/app/Http/Controllers/Api/EnvironmentVariables.php @@ -0,0 +1,46 @@ +clearAll(); + $teamId = get_team_id_from_token(); + $both = $request->query->get('both') ?? false; + if (is_null($teamId)) { + return invalid_token(); + } + $env = EnvironmentVariable::where('uuid', $request->env_uuid)->first(); + if (! $env) { + return response()->json([ + 'success' => false, + 'message' => 'Environment variable not found.', + ], 404); + } + $found_app = $env->resource()->whereRelation('environment.project.team', 'id', $teamId)->first(); + if (! $found_app) { + return response()->json([ + 'success' => false, + 'message' => 'Environment variable not found.', + ], 404); + } + $env->delete(); + if ($both) { + $found_other_pair = EnvironmentVariable::where('application_id', $found_app->id)->where('key', $env->key)->first(); + if ($found_other_pair) { + $found_other_pair->delete(); + } + } + + return response()->json([ + 'success' => true, + 'message' => 'Environment variable deleted.', + ]); + } +} diff --git a/app/Http/Controllers/Api/Server.php b/app/Http/Controllers/Api/Server.php index 7a6090bf8..1a58da7b0 100644 --- a/app/Http/Controllers/Api/Server.php +++ b/app/Http/Controllers/Api/Server.php @@ -36,7 +36,7 @@ public function server_by_uuid(Request $request) } $server = ModelsServer::whereTeamId($teamId)->whereUuid(request()->uuid)->first(); if (is_null($server)) { - return response()->json(['error' => 'Server not found.'], 404); + return response()->json(['message' => 'Server not found.'], 404); } if ($with_resources) { $server['resources'] = $server->definedResources()->map(function ($resource) { diff --git a/app/Models/Application.php b/app/Models/Application.php index 98b79549f..8b9ff8ee7 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -60,6 +60,11 @@ protected static function booted() }); } + public static function ownedByCurrentTeamAPI(int $teamId) + { + return Application::whereRelation('environment.project.team', 'id', $teamId)->orderBy('name'); + } + public function delete_configurations() { $server = data_get($this, 'destination.server'); diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index 8731eab2d..04a556274 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; use Symfony\Component\Yaml\Yaml; +use Visus\Cuid2\Cuid2; class EnvironmentVariable extends Model { @@ -25,6 +26,11 @@ class EnvironmentVariable extends Model protected static function booted() { + static::creating(function (Model $model) { + if (! $model->uuid) { + $model->uuid = (string) new Cuid2(); + } + }); static::created(function (EnvironmentVariable $environment_variable) { if ($environment_variable->application_id && ! $environment_variable->is_preview) { $found = ModelsEnvironmentVariable::where('key', $environment_variable->key)->where('application_id', $environment_variable->application_id)->where('is_preview', true)->first(); @@ -220,7 +226,7 @@ private function set_environment_variables(?string $environment_variable = null) protected function key(): Attribute { return Attribute::make( - set: fn (string $value) => str($value)->trim(), + set: fn (string $value) => str($value)->trim()->replace(' ', '_')->value, ); } } diff --git a/database/migrations/2024_06_25_184323_remove_docker_compose_pr.php b/database/migrations/2024_06_25_184323_update_db.php similarity index 58% rename from database/migrations/2024_06_25_184323_remove_docker_compose_pr.php rename to database/migrations/2024_06_25_184323_update_db.php index 819a3b3f5..ef6ee74f7 100644 --- a/database/migrations/2024_06_25_184323_remove_docker_compose_pr.php +++ b/database/migrations/2024_06_25_184323_update_db.php @@ -1,8 +1,10 @@ dropColumn('docker_compose_pr'); $table->dropColumn('docker_compose_pr_raw'); }); + Schema::table('environment_variables', function (Blueprint $table) { + $table->string('uuid')->nullable()->after('id'); + }); + + EnvironmentVariable::all()->each(function (EnvironmentVariable $environmentVariable) { + $environmentVariable->update([ + 'uuid' => (string) new Cuid2(), + ]); + }); + Schema::table('environment_variables', function (Blueprint $table) { + $table->string('uuid')->nullable(false)->change(); + }); } /** @@ -28,5 +42,9 @@ public function down(): void $table->longText('docker_compose_pr')->nullable()->after('docker_compose_location'); $table->longText('docker_compose_pr_raw')->nullable()->after('docker_compose'); }); + Schema::table('environment_variables', function (Blueprint $table) { + $table->dropColumn('uuid'); + }); + } }; diff --git a/routes/api.php b/routes/api.php index 858a2282f..41a369f3d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,7 +2,7 @@ use App\Http\Controllers\Api\Applications; use App\Http\Controllers\Api\Deploy; -use App\Http\Controllers\Api\Domains; +use App\Http\Controllers\Api\EnvironmentVariables; use App\Http\Controllers\Api\Resources; use App\Http\Controllers\Api\Server; use App\Http\Controllers\Api\Team; @@ -34,28 +34,36 @@ }); Route::match(['get', 'post'], '/deploy', [Deploy::class, 'deploy']); Route::get('/deployments', [Deploy::class, 'deployments']); - Route::get('/deployment/{uuid}', [Deploy::class, 'deployment_by_uuid']); + Route::get('/deployments/{uuid}', [Deploy::class, 'deployment_by_uuid']); Route::get('/servers', [Server::class, 'servers']); - Route::get('/server/{uuid}', [Server::class, 'server_by_uuid']); + Route::get('/servers/{uuid}', [Server::class, 'server_by_uuid']); Route::get('/servers/domains', [Server::class, 'get_domains_by_server']); Route::get('/resources', [Resources::class, 'resources']); Route::get('/applications', [Applications::class, 'applications']); - Route::get('/application/{uuid}', [Applications::class, 'application_by_uuid']); - Route::put('/application/{uuid}', [Applications::class, 'update_by_uuid']); - Route::match(['get', 'post'], '/application/{uuid}/action/deploy', [Applications::class, 'action_deploy']); - Route::match(['get', 'post'], '/application/{uuid}/action/restart', [Applications::class, 'action_restart']); - Route::match(['get', 'post'], '/application/{uuid}/action/stop', [Applications::class, 'action_stop']); - Route::delete('/domains', [Domains::class, 'deleteDomains']); + Route::get('/applications/{uuid}', [Applications::class, 'application_by_uuid']); + Route::patch('/applications/{uuid}', [Applications::class, 'update_by_uuid']); + Route::delete('/applications/{uuid}', [Applications::class, 'delete_by_uuid']); + + Route::get('/applications/{uuid}/envs', [Applications::class, 'envs_by_uuid']); + Route::post('/applications/{uuid}/envs', [Applications::class, 'create_env']); + Route::patch('/applications/{uuid}/envs', [Applications::class, 'update_env_by_uuid']); + Route::delete('/applications/{uuid}/envs/{env_uuid}', [Applications::class, 'delete_env_by_uuid']); + + Route::delete('/envs/{env_uuid}', [EnvironmentVariables::class, 'delete_env_by_uuid']); + + Route::match(['get', 'post'], '/applications/{uuid}/action/deploy', [Applications::class, 'action_deploy']); + Route::match(['get', 'post'], '/applications/{uuid}/action/restart', [Applications::class, 'action_restart']); + Route::match(['get', 'post'], '/applications/{uuid}/action/stop', [Applications::class, 'action_stop']); Route::get('/teams', [Team::class, 'teams']); - Route::get('/team/current', [Team::class, 'current_team']); - Route::get('/team/current/members', [Team::class, 'current_team_members']); - Route::get('/team/{id}', [Team::class, 'team_by_id']); - Route::get('/team/{id}/members', [Team::class, 'members_by_id']); + Route::get('/teams/current', [Team::class, 'current_team']); + Route::get('/teams/current/members', [Team::class, 'current_team_members']); + Route::get('/teams/{id}', [Team::class, 'team_by_id']); + Route::get('/teams/{id}/members', [Team::class, 'members_by_id']); // Route::get('/projects', [Project::class, 'projects']); //Route::get('/project/{uuid}', [Project::class, 'project_by_uuid']);