feat: more api endpoints

This commit is contained in:
Andras Bacsai 2024-06-21 16:46:13 +02:00
parent 72033279c2
commit cd85094113
7 changed files with 230 additions and 8 deletions

View File

@ -0,0 +1,136 @@
<?php
namespace App\Http\Controllers\Api;
use App\Actions\Application\StopApplication;
use App\Http\Controllers\Controller;
use App\Models\Application;
use App\Models\Project;
use Illuminate\Http\Request;
use Visus\Cuid2\Cuid2;
class Applications extends Controller
{
public function applications(Request $request)
{
$teamId = get_team_id_from_token();
if (is_null($teamId)) {
return invalid_token();
}
$projects = Project::where('team_id', $teamId)->get();
$applications = collect();
$applications->push($projects->pluck('applications')->flatten());
$applications = $applications->flatten();
return response()->json($applications);
}
public function application_by_uuid(Request $request)
{
$teamId = get_team_id_from_token();
if (is_null($teamId)) {
return invalid_token();
}
$uuid = $request->route('uuid');
if (! $uuid) {
return response()->json(['error' => 'UUID is required.'], 400);
}
$application = Application::where('uuid', $uuid)->first();
if (! $application) {
return response()->json(['error' => 'Application not found.'], 404);
}
return response()->json($application);
}
public function action_deploy(Request $request)
{
$teamId = get_team_id_from_token();
if (is_null($teamId)) {
return invalid_token();
}
$force = $request->query->get('force') ?? false;
$instant_deploy = $request->query->get('instant_deploy') ?? false;
$uuid = $request->route('uuid');
if (! $uuid) {
return response()->json(['error' => 'UUID is required.'], 400);
}
$application = Application::where('uuid', $uuid)->first();
if (! $application) {
return response()->json(['error' => 'Application not found.'], 404);
}
$deployment_uuid = new Cuid2(7);
queue_application_deployment(
application: $application,
deployment_uuid: $deployment_uuid,
force_rebuild: $force,
is_api: true,
no_questions_asked: $instant_deploy
);
return response()->json(
[
'message' => 'Deployment request queued.',
'deployment_uuid' => $deployment_uuid->toString(),
'deployment_api_url' => base_url().'/api/v1/deployment/'.$deployment_uuid->toString(),
],
200
);
}
public function action_stop(Request $request)
{
$teamId = get_team_id_from_token();
if (is_null($teamId)) {
return invalid_token();
}
$uuid = $request->route('uuid');
if (! $uuid) {
return response()->json(['error' => 'UUID is required.'], 400);
}
$application = Application::where('uuid', $uuid)->first();
if (! $application) {
return response()->json(['error' => 'Application not found.'], 404);
}
StopApplication::dispatch($application);
return response()->json(['message' => 'Stopping request queued.'], 200);
}
public function action_restart(Request $request)
{
$teamId = get_team_id_from_token();
if (is_null($teamId)) {
return invalid_token();
}
$uuid = $request->route('uuid');
if (! $uuid) {
return response()->json(['error' => 'UUID is required.'], 400);
}
$application = Application::where('uuid', $uuid)->first();
if (! $application) {
return response()->json(['error' => 'Application not found.'], 404);
}
$deployment_uuid = new Cuid2(7);
queue_application_deployment(
application: $application,
deployment_uuid: $deployment_uuid,
restart_only: true,
is_api: true,
);
return response()->json(
[
'message' => 'Restart request queued.',
'deployment_uuid' => $deployment_uuid->toString(),
'deployment_api_url' => base_url().'/api/v1/deployment/'.$deployment_uuid->toString(),
],
200
);
}
}

View File

@ -38,7 +38,25 @@ public function deployments(Request $request)
'status',
])->sortBy('id')->toArray();
return response()->json($deployments_per_server, 200);
return response()->json(serialize_api_response($deployments_per_server), 200);
}
public function deployment_by_uuid(Request $request)
{
$teamId = get_team_id_from_token();
if (is_null($teamId)) {
return invalid_token();
}
$uuid = $request->route('uuid');
if (! $uuid) {
return response()->json(['error' => 'UUID is required.'], 400);
}
$deployment = ApplicationDeploymentQueue::where('deployment_uuid', $uuid)->first()->makeHidden('logs');
if (! $deployment) {
return response()->json(['error' => 'Deployment not found.'], 404);
}
return response()->json(serialize_api_response($deployment), 200);
}
public function deploy(Request $request)

View File

@ -1,5 +1,7 @@
<?php
use Illuminate\Database\Eloquent\Collection;
function get_team_id_from_token()
{
$token = auth()->user()->currentAccessToken();
@ -10,3 +12,27 @@ function invalid_token()
{
return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api-reference/authorization'], 400);
}
function serialize_api_response($data)
{
if (! $data instanceof Collection) {
$data = collect($data);
}
$data = $data->sortKeys();
$created_at = data_get($data, 'created_at');
$updated_at = data_get($data, 'updated_at');
if ($created_at) {
unset($data['created_at']);
$data['created_at'] = $created_at;
}
if ($updated_at) {
unset($data['updated_at']);
$data['updated_at'] = $updated_at;
}
if (data_get($data, 'id')) {
$data = $data->prepend($data['id'], 'id');
}
return $data;
}

View File

@ -8,7 +8,7 @@
use App\Models\StandaloneDocker;
use Spatie\Url\Url;
function queue_application_deployment(Application $application, string $deployment_uuid, ?int $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, ?Server $server = null, ?StandaloneDocker $destination = null, bool $only_this_server = false, bool $rollback = false)
function queue_application_deployment(Application $application, string $deployment_uuid, ?int $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $is_api = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, ?Server $server = null, ?StandaloneDocker $destination = null, bool $only_this_server = false, bool $rollback = false)
{
$application_id = $application->id;
$deployment_link = Url::fromString($application->link()."/deployment/{$deployment_uuid}");
@ -35,6 +35,7 @@ function queue_application_deployment(Application $application, string $deployme
'pull_request_id' => $pull_request_id,
'force_rebuild' => $force_rebuild,
'is_webhook' => $is_webhook,
'is_api' => $is_api,
'restart_only' => $restart_only,
'commit' => $commit,
'rollback' => $rollback,

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('application_deployment_queues', function (Blueprint $table) {
$table->boolean('is_api')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('application_deployment_queues', function (Blueprint $table) {
$table->dropColumn('is_api');
});
}
};

View File

@ -74,9 +74,13 @@ class="w-6 h-6" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<div class="flex items-center gap-1">
@if (data_get($deployment, 'rollback') === true)
Rollback
@else
@if (data_get($deployment, 'is_api'))
API
@else
Manual
@endif
@endif
@if (data_get($deployment, 'commit'))
<div class="dark:hover:text-white"
x-on:click.stop="goto('{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}')">

View File

@ -1,5 +1,6 @@
<?php
use App\Http\Controllers\Api\Applications;
use App\Http\Controllers\Api\Deploy;
use App\Http\Controllers\Api\Domains;
use App\Http\Controllers\Api\Resources;
@ -31,17 +32,25 @@
Route::get('/version', function () {
return response(config('version'));
});
Route::get('/deploy', [Deploy::class, 'deploy']);
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('/servers', [Server::class, 'servers']);
Route::get('/server/{uuid}', [Server::class, 'server_by_uuid']);
Route::get('/resources', [Resources::class, 'resources']);
Route::get('/applications', [Applications::class, 'applications']);
Route::get('/application/{uuid}', [Applications::class, 'application_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::get('/domains', [Domains::class, 'domains']);
Route::put('/domains', [Domains::class, 'updateDomains']);
Route::delete('/domains', [Domains::class, 'deleteDomains']);
// Route::put('/domains', [Domains::class, 'updateDomains']);
// Route::delete('/domains', [Domains::class, 'deleteDomains']);
Route::get('/teams', [Team::class, 'teams']);
Route::get('/team/current', [Team::class, 'current_team']);
@ -54,7 +63,7 @@
//Route::get('/project/{uuid}/{environment_name}', [Project::class, 'environment_details']);
});
Route::get('/{any}', function () {
Route::any('/{any}', function () {
return response()->json(['error' => 'Not found.'], 404);
})->where('any', '.*');