lasthourcloud/app/Http/Controllers/Api/DeployController.php

260 lines
10 KiB
PHP
Raw Normal View History

2024-02-02 10:50:28 +00:00
<?php
namespace App\Http\Controllers\Api;
2024-04-10 13:00:46 +00:00
use App\Actions\Database\StartClickhouse;
use App\Actions\Database\StartDragonfly;
use App\Actions\Database\StartKeydb;
2024-02-02 10:50:28 +00:00
use App\Actions\Database\StartMariadb;
use App\Actions\Database\StartMongodb;
use App\Actions\Database\StartMysql;
use App\Actions\Database\StartPostgresql;
use App\Actions\Database\StartRedis;
use App\Actions\Service\StartService;
use App\Http\Controllers\Controller;
2024-03-07 11:27:23 +00:00
use App\Models\ApplicationDeploymentQueue;
use App\Models\Server;
2024-02-02 10:50:28 +00:00
use App\Models\Tag;
use Illuminate\Http\Request;
use Visus\Cuid2\Cuid2;
2024-07-01 14:26:50 +00:00
class DeployController extends Controller
2024-02-02 10:50:28 +00:00
{
private function removeSensitiveData($deployment)
{
$token = auth()->user()->currentAccessToken();
if ($token->can('view:sensitive')) {
return serializeApiResponse($deployment);
}
$deployment->makeHidden([
'logs',
]);
return serializeApiResponse($deployment);
}
2024-03-11 08:42:02 +00:00
public function deployments(Request $request)
{
2024-07-01 14:26:50 +00:00
$teamId = getTeamIdFromToken();
2024-03-07 11:27:23 +00:00
if (is_null($teamId)) {
2024-07-01 14:26:50 +00:00
return invalidTokenResponse();
2024-03-07 11:27:23 +00:00
}
$servers = Server::whereTeamId($teamId)->get();
2024-06-10 20:43:34 +00:00
$deployments_per_server = ApplicationDeploymentQueue::whereIn('status', ['in_progress', 'queued'])->whereIn('server_id', $servers->pluck('id'))->get([
'id',
'application_id',
'application_name',
'deployment_url',
'pull_request_id',
'server_name',
'server_id',
'status',
2024-03-07 11:27:23 +00:00
])->sortBy('id')->toArray();
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response()->json([
'success' => true,
'data' => serializeApiResponse($deployments_per_server),
]);
2024-06-21 14:46:13 +00:00
}
public function deployment_by_uuid(Request $request)
{
2024-07-01 14:26:50 +00:00
$teamId = getTeamIdFromToken();
2024-06-21 14:46:13 +00:00
if (is_null($teamId)) {
2024-07-01 14:26:50 +00:00
return invalidTokenResponse();
2024-06-21 14:46:13 +00:00
}
$uuid = $request->route('uuid');
if (! $uuid) {
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'UUID is required.'], 400);
2024-06-21 14:46:13 +00:00
}
2024-06-26 11:00:36 +00:00
$deployment = ApplicationDeploymentQueue::where('deployment_uuid', $uuid)->first();
2024-06-21 14:46:13 +00:00
if (! $deployment) {
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'Deployment not found.'], 404);
2024-06-21 14:46:13 +00:00
}
2024-07-01 14:26:50 +00:00
return response()->json([
'success' => true,
'data' => $this->removeSensitiveData($deployment),
2024-07-01 14:26:50 +00:00
]);
2024-03-07 11:27:23 +00:00
}
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
public function deploy(Request $request)
{
2024-07-01 14:26:50 +00:00
$teamId = getTeamIdFromToken();
2024-02-02 10:50:28 +00:00
$uuids = $request->query->get('uuid');
$tags = $request->query->get('tag');
$force = $request->query->get('force') ?? false;
if ($uuids && $tags) {
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'You can only use uuid or tag, not both.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
2024-02-02 10:50:28 +00:00
}
if (is_null($teamId)) {
2024-07-01 14:26:50 +00:00
return invalidTokenResponse();
2024-02-02 10:50:28 +00:00
}
if ($tags) {
return $this->by_tags($tags, $teamId, $force);
2024-06-10 20:43:34 +00:00
} elseif ($uuids) {
2024-02-02 10:50:28 +00:00
return $this->by_uuids($uuids, $teamId, $force);
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'You must provide uuid or tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
private function by_uuids(string $uuid, int $teamId, bool $force = false)
{
$uuids = explode(',', $uuid);
$uuids = collect(array_filter($uuids));
if (count($uuids) === 0) {
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'No UUIDs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
2024-02-02 10:50:28 +00:00
}
$deployments = collect();
$payload = collect();
2024-02-02 10:50:28 +00:00
foreach ($uuids as $uuid) {
$resource = getResourceByUuid($uuid, $teamId);
if ($resource) {
['message' => $return_message, 'deployment_uuid' => $deployment_uuid] = $this->deploy_resource($resource, $force);
if ($deployment_uuid) {
2024-07-01 14:26:50 +00:00
$deployments->push(['success' => true, 'message' => $return_message, 'resource_uuid' => $uuid, 'deployment_uuid' => $deployment_uuid->toString()]);
2024-03-11 08:42:02 +00:00
} else {
2024-07-01 14:26:50 +00:00
$deployments->push(['success' => true, 'message' => $return_message, 'resource_uuid' => $uuid]);
}
2024-02-02 10:50:28 +00:00
}
}
2024-03-11 08:42:02 +00:00
if ($deployments->count() > 0) {
$payload->put('deployments', $deployments->toArray());
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response()->json([
'success' => true,
'data' => serializeApiResponse($payload->toArray()),
]);
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'No resources found.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404);
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
public function by_tags(string $tags, int $team_id, bool $force = false)
{
$tags = explode(',', $tags);
$tags = collect(array_filter($tags));
if (count($tags) === 0) {
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'No TAGs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
2024-02-02 10:50:28 +00:00
}
$message = collect([]);
$deployments = collect();
$payload = collect();
2024-02-02 10:50:28 +00:00
foreach ($tags as $tag) {
$found_tag = Tag::where(['name' => $tag, 'team_id' => $team_id])->first();
2024-06-10 20:43:34 +00:00
if (! $found_tag) {
// $message->push("Tag {$tag} not found.");
2024-02-02 10:50:28 +00:00
continue;
}
$applications = $found_tag->applications()->get();
$services = $found_tag->services()->get();
2024-02-03 11:39:07 +00:00
if ($applications->count() === 0 && $services->count() === 0) {
2024-02-02 10:50:28 +00:00
$message->push("No resources found for tag {$tag}.");
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
continue;
}
2024-02-03 11:39:07 +00:00
foreach ($applications as $resource) {
['message' => $return_message, 'deployment_uuid' => $deployment_uuid] = $this->deploy_resource($resource, $force);
if ($deployment_uuid) {
$deployments->push(['resource_uuid' => $resource->uuid, 'deployment_uuid' => $deployment_uuid->toString()]);
}
2024-02-03 11:39:07 +00:00
$message = $message->merge($return_message);
}
foreach ($services as $resource) {
['message' => $return_message] = $this->deploy_resource($resource, $force);
2024-02-02 10:50:28 +00:00
$message = $message->merge($return_message);
}
}
if ($message->count() > 0) {
$payload->put('message', $message->toArray());
if ($deployments->count() > 0) {
$payload->put('details', $deployments->toArray());
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response()->json([
'success' => true,
'data' => serializeApiResponse($payload->toArray()),
]);
2024-02-02 10:50:28 +00:00
}
2024-07-01 14:26:50 +00:00
return response()->json(['success' => false, 'message' => 'No resources found with this tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404);
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
public function deploy_resource($resource, bool $force = false): array
2024-02-02 10:50:28 +00:00
{
2024-03-11 08:42:02 +00:00
$message = null;
$deployment_uuid = null;
if (gettype($resource) !== 'object') {
2024-07-01 14:26:50 +00:00
return ['success' => false, 'message' => "Resource ($resource) not found.", 'deployment_uuid' => $deployment_uuid];
}
$type = $resource?->getMorphClass();
2024-02-02 10:50:28 +00:00
if ($type === 'App\Models\Application') {
$deployment_uuid = new Cuid2(7);
2024-02-02 10:50:28 +00:00
queue_application_deployment(
application: $resource,
deployment_uuid: $deployment_uuid,
2024-02-02 10:50:28 +00:00
force_rebuild: $force,
);
2024-03-11 08:42:02 +00:00
$message = "Application {$resource->name} deployment queued.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandalonePostgresql') {
2024-02-02 10:50:28 +00:00
StartPostgresql::run($resource);
$resource->update([
'started_at' => now(),
]);
2024-03-11 08:42:02 +00:00
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandaloneRedis') {
2024-02-02 10:50:28 +00:00
StartRedis::run($resource);
$resource->update([
'started_at' => now(),
]);
2024-03-11 08:42:02 +00:00
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandaloneKeydb') {
2024-04-10 13:00:46 +00:00
StartKeydb::run($resource);
$resource->update([
'started_at' => now(),
]);
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandaloneDragonfly') {
2024-04-10 13:00:46 +00:00
StartDragonfly::run($resource);
$resource->update([
'started_at' => now(),
]);
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandaloneClickhouse') {
2024-04-10 13:00:46 +00:00
StartClickhouse::run($resource);
$resource->update([
'started_at' => now(),
]);
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandaloneMongodb') {
2024-02-02 10:50:28 +00:00
StartMongodb::run($resource);
$resource->update([
'started_at' => now(),
]);
2024-03-11 08:42:02 +00:00
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandaloneMysql') {
2024-02-02 10:50:28 +00:00
StartMysql::run($resource);
$resource->update([
'started_at' => now(),
]);
2024-03-11 08:42:02 +00:00
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\StandaloneMariadb') {
2024-02-02 10:50:28 +00:00
StartMariadb::run($resource);
$resource->update([
'started_at' => now(),
]);
2024-03-11 08:42:02 +00:00
$message = "Database {$resource->name} started.";
2024-06-10 20:43:34 +00:00
} elseif ($type === 'App\Models\Service') {
2024-02-02 10:50:28 +00:00
StartService::run($resource);
2024-03-11 08:42:02 +00:00
$message = "Service {$resource->name} started. It could take a while, be patient.";
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return ['success' => true, 'message' => $message, 'deployment_uuid' => $deployment_uuid];
2024-02-02 10:50:28 +00:00
}
}