From b8708f086e9b09a4bda2441453853787729b735b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 16 Feb 2024 21:56:38 +0100 Subject: [PATCH] feat: initial api endpoints feat: server resources are now looks better --- app/Http/Controllers/Api/Deploy.php | 3 +- app/Http/Controllers/Api/Project.php | 39 ++++++++ app/Http/Controllers/Api/Server.php | 54 +++++++++++ app/Livewire/Project/Resource/Index.php | 2 +- app/Livewire/Server/Resources.php | 30 ++++++ app/Models/Environment.php | 1 - app/Models/ProjectSetting.php | 9 +- app/Models/Server.php | 2 + app/Models/Service.php | 42 +++++++++ app/Models/StandaloneMariadb.php | 3 + app/Models/StandaloneMongodb.php | 3 + app/Models/StandaloneMysql.php | 3 + app/Models/StandalonePostgresql.php | 4 + app/Models/StandaloneRedis.php | 4 + app/View/Components/Status/Services.php | 2 +- bootstrap/helpers/api.php | 7 ++ bootstrap/helpers/services.php | 43 --------- .../views/components/server/navbar.blade.php | 6 ++ .../components/services/navbar.blade.php | 6 +- .../views/components/status/index.blade.php | 10 +- .../views/livewire/server/delete.blade.php | 42 ++++----- .../views/livewire/server/resources.blade.php | 46 +++++++++ routes/api.php | 94 +++++++------------ routes/web.php | 5 +- 24 files changed, 318 insertions(+), 142 deletions(-) create mode 100644 app/Http/Controllers/Api/Project.php create mode 100644 app/Http/Controllers/Api/Server.php create mode 100644 app/Livewire/Server/Resources.php create mode 100644 bootstrap/helpers/api.php create mode 100644 resources/views/livewire/server/resources.blade.php diff --git a/app/Http/Controllers/Api/Deploy.php b/app/Http/Controllers/Api/Deploy.php index f071f3b5b..21da51d66 100644 --- a/app/Http/Controllers/Api/Deploy.php +++ b/app/Http/Controllers/Api/Deploy.php @@ -18,8 +18,7 @@ class Deploy extends Controller { public function deploy(Request $request) { - $token = auth()->user()->currentAccessToken(); - $teamId = data_get($token, 'team_id'); + $teamId = get_team_id_from_token(); $uuids = $request->query->get('uuid'); $tags = $request->query->get('tag'); $force = $request->query->get('force') ?? false; diff --git a/app/Http/Controllers/Api/Project.php b/app/Http/Controllers/Api/Project.php new file mode 100644 index 000000000..fa2ba34bb --- /dev/null +++ b/app/Http/Controllers/Api/Project.php @@ -0,0 +1,39 @@ +json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $projects = ModelsProject::whereTeamId($teamId)->select('id', 'name', 'uuid')->get(); + return response()->json($projects); + } + public function project_by_uuid(Request $request) + { + $teamId = get_team_id_from_token(); + if (is_null($teamId)) { + return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $project = ModelsProject::whereTeamId($teamId)->whereUuid(request()->uuid)->first()->load(['environments']); + return response()->json($project); + } + public function environment_details(Request $request) + { + $teamId = get_team_id_from_token(); + if (is_null($teamId)) { + return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $project = ModelsProject::whereTeamId($teamId)->whereUuid(request()->uuid)->first(); + $environment = $project->environments()->whereName(request()->environment_name)->first()->load(['applications', 'postgresqls', 'redis', 'mongodbs', 'mysqls', 'mariadbs', 'services']); + return response()->json($environment); + } +} diff --git a/app/Http/Controllers/Api/Server.php b/app/Http/Controllers/Api/Server.php new file mode 100644 index 000000000..e7b071a43 --- /dev/null +++ b/app/Http/Controllers/Api/Server.php @@ -0,0 +1,54 @@ +json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $servers = ModelsServer::whereTeamId($teamId)->select('id', 'name', 'uuid', 'ip', 'user', 'port')->get()->load(['settings'])->map(function ($server) { + $server['is_reachable'] = $server->settings->is_reachable; + $server['is_usable'] = $server->settings->is_usable; + return $server; + }); + ray($servers); + return response()->json($servers); + } + public function server_by_uuid(Request $request) + { + $teamId = get_team_id_from_token(); + if (is_null($teamId)) { + return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400); + } + $server = ModelsServer::whereTeamId($teamId)->whereUuid(request()->uuid)->first(); + if (is_null($server)) { + return response()->json(['error' => 'Server not found.'], 404); + } + $server->load(['settings']); + $server['resources'] = $server->definedResources()->map(function ($resource) { + $payload = [ + 'id' => $resource->id, + 'uuid' => $resource->uuid, + 'name' => $resource->name, + 'type' => $resource->type(), + 'created_at' => $resource->created_at, + 'updated_at' => $resource->updated_at, + ]; + if ($resource->type() === 'service') { + $payload['status'] = $resource->status(); + } else { + $payload['status'] = $resource->status; + } + return $payload; + }); + return response()->json($server); + } +} diff --git a/app/Livewire/Project/Resource/Index.php b/app/Livewire/Project/Resource/Index.php index 9e0a5e9db..9524392dc 100644 --- a/app/Livewire/Project/Resource/Index.php +++ b/app/Livewire/Project/Resource/Index.php @@ -104,7 +104,7 @@ public function mount() 'environment_name' => data_get($service, 'environment.name'), 'service_uuid' => data_get($service, 'uuid') ]); - $service->status = serviceStatus($service); + $service->status = $service->status(); } return $service; }); diff --git a/app/Livewire/Server/Resources.php b/app/Livewire/Server/Resources.php new file mode 100644 index 000000000..f9f3af37c --- /dev/null +++ b/app/Livewire/Server/Resources.php @@ -0,0 +1,30 @@ +parameters = get_route_parameters(); + try { + $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first(); + if (is_null($this->server)) { + return redirect()->route('server.index'); + } + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function render() + { + return view('livewire.server.resources'); + } +} diff --git a/app/Models/Environment.php b/app/Models/Environment.php index b9451ac3f..efbfc70d9 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -26,7 +26,6 @@ public function applications() { return $this->hasMany(Application::class); } - public function postgresqls() { return $this->hasMany(StandalonePostgresql::class); diff --git a/app/Models/ProjectSetting.php b/app/Models/ProjectSetting.php index 50192099e..d93bea05b 100644 --- a/app/Models/ProjectSetting.php +++ b/app/Models/ProjectSetting.php @@ -6,7 +6,10 @@ class ProjectSetting extends Model { - protected $fillable = [ - 'project_id' - ]; + protected $guarded = []; + + public function project() + { + return $this->belongsTo(Project::class); + } } diff --git a/app/Models/Server.php b/app/Models/Server.php index f19943d05..ce34486ed 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -245,6 +245,8 @@ public function databases() $mysqls = data_get($standaloneDocker, 'mysqls', collect([])); $mariadbs = data_get($standaloneDocker, 'mariadbs', collect([])); return $postgresqls->concat($redis)->concat($mongodbs)->concat($mysqls)->concat($mariadbs); + })->filter(function ($item) { + return data_get($item,'name') === 'coolify-db'; })->flatten(); } public function applications() diff --git a/app/Models/Service.php b/app/Models/Service.php index 244964db1..246e812c2 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -28,6 +28,48 @@ public function tags() { return $this->morphToMany(Tag::class, 'taggable'); } + public function status() { + $foundRunning = false; + $isDegraded = false; + $foundRestaring = false; + $applications = $this->applications; + $databases = $this->databases; + foreach ($applications as $application) { + if ($application->exclude_from_status) { + continue; + } + if (Str::of($application->status)->startsWith('running')) { + $foundRunning = true; + } else if (Str::of($application->status)->startsWith('restarting')) { + $foundRestaring = true; + } else { + $isDegraded = true; + } + } + foreach ($databases as $database) { + if ($database->exclude_from_status) { + continue; + } + if (Str::of($database->status)->startsWith('running')) { + $foundRunning = true; + } else if (Str::of($database->status)->startsWith('restarting')) { + $foundRestaring = true; + } else { + $isDegraded = true; + } + } + if ($foundRestaring) { + return 'degraded'; + } + if ($foundRunning && !$isDegraded) { + return 'running'; + } else if ($foundRunning && $isDegraded) { + return 'degraded'; + } else if (!$foundRunning && !$isDegraded) { + return 'exited'; + } + return 'exited'; + } public function extraFields() { $fields = collect([]); diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index 1143b018e..174397baa 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -82,6 +82,9 @@ public function tags() { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 610323f74..d6efaaa1e 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -85,6 +85,9 @@ public function tags() { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index fa6bbe28f..f317196aa 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -82,6 +82,9 @@ public function tags() { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index bcc43843b..3d2317159 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -82,6 +82,10 @@ public function tags() { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() + { + return data_get($this, 'environment.project'); + } public function link() { if (data_get($this, 'environment.project.uuid')) { diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 59c53f882..6b6b6c415 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -77,6 +77,10 @@ public function tags() { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() + { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/View/Components/Status/Services.php b/app/View/Components/Status/Services.php index 3fc302acf..f81ca9703 100644 --- a/app/View/Components/Status/Services.php +++ b/app/View/Components/Status/Services.php @@ -16,7 +16,7 @@ public function __construct( public Service $service, public string $complexStatus = 'exited', ) { - $this->complexStatus = serviceStatus($service); + $this->complexStatus = $service->status(); } /** diff --git a/bootstrap/helpers/api.php b/bootstrap/helpers/api.php new file mode 100644 index 000000000..94e9242cb --- /dev/null +++ b/bootstrap/helpers/api.php @@ -0,0 +1,7 @@ +user()->currentAccessToken(); + return data_get($token, 'team_id'); +} diff --git a/bootstrap/helpers/services.php b/bootstrap/helpers/services.php index 43a15444c..aa7d6fd54 100644 --- a/bootstrap/helpers/services.php +++ b/bootstrap/helpers/services.php @@ -21,49 +21,6 @@ function replaceVariables($variable) return $variable->replaceFirst('$', '')->replaceFirst('{', '')->replaceLast('}', ''); } -function serviceStatus(Service $service) -{ - $foundRunning = false; - $isDegraded = false; - $foundRestaring = false; - $applications = $service->applications; - $databases = $service->databases; - foreach ($applications as $application) { - if ($application->exclude_from_status) { - continue; - } - if (Str::of($application->status)->startsWith('running')) { - $foundRunning = true; - } else if (Str::of($application->status)->startsWith('restarting')) { - $foundRestaring = true; - } else { - $isDegraded = true; - } - } - foreach ($databases as $database) { - if ($database->exclude_from_status) { - continue; - } - if (Str::of($database->status)->startsWith('running')) { - $foundRunning = true; - } else if (Str::of($database->status)->startsWith('restarting')) { - $foundRestaring = true; - } else { - $isDegraded = true; - } - } - if ($foundRestaring) { - return 'degraded'; - } - if ($foundRunning && !$isDegraded) { - return 'running'; - } else if ($foundRunning && $isDegraded) { - return 'degraded'; - } else if (!$foundRunning && !$isDegraded) { - return 'exited'; - } - return 'exited'; -} function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase $oneService, bool $isInit = false) { // TODO: make this async diff --git a/resources/views/components/server/navbar.blade.php b/resources/views/components/server/navbar.blade.php index a6a2dd74a..08a8019a8 100644 --- a/resources/views/components/server/navbar.blade.php +++ b/resources/views/components/server/navbar.blade.php @@ -18,6 +18,12 @@ ]) }}"> + + + - @if (serviceStatus($service) === 'degraded') + @if ($service->status() === 'degraded') @endif - @if (serviceStatus($service) === 'running') + @if ($service->status() === 'running')