feat: add server api endpoints
This commit is contained in:
parent
e96e8f6fec
commit
189a8347ed
@ -21,7 +21,6 @@ public function handle(Server $server, bool $reset = false)
|
|||||||
"cat $proxy_path/docker-compose.yml",
|
"cat $proxy_path/docker-compose.yml",
|
||||||
];
|
];
|
||||||
$proxy_configuration = instant_remote_process($payload, $server, false);
|
$proxy_configuration = instant_remote_process($payload, $server, false);
|
||||||
|
|
||||||
if ($reset || ! $proxy_configuration || is_null($proxy_configuration)) {
|
if ($reset || ! $proxy_configuration || is_null($proxy_configuration)) {
|
||||||
$proxy_configuration = str(generate_default_proxy_configuration($server))->trim()->value;
|
$proxy_configuration = str(generate_default_proxy_configuration($server))->trim()->value;
|
||||||
}
|
}
|
||||||
|
67
app/Actions/Server/ValidateServer.php
Normal file
67
app/Actions/Server/ValidateServer.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Server;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
|
||||||
|
class ValidateServer
|
||||||
|
{
|
||||||
|
use AsAction;
|
||||||
|
|
||||||
|
public ?string $uptime = null;
|
||||||
|
|
||||||
|
public ?string $error = null;
|
||||||
|
|
||||||
|
public ?string $supported_os_type = null;
|
||||||
|
|
||||||
|
public ?string $docker_installed = null;
|
||||||
|
|
||||||
|
public ?string $docker_compose_installed = null;
|
||||||
|
|
||||||
|
public ?string $docker_version = null;
|
||||||
|
|
||||||
|
public function handle(Server $server)
|
||||||
|
{
|
||||||
|
$server->update([
|
||||||
|
'validation_logs' => null,
|
||||||
|
]);
|
||||||
|
['uptime' => $this->uptime, 'error' => $error] = $server->validateConnection();
|
||||||
|
if (! $this->uptime) {
|
||||||
|
$this->error = 'Server is not reachable. Please validate your configuration and connection.<br>Check this <a target="_blank" class="text-black underline dark:text-white" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br><div class="text-error">Error: '.$error.'</div>';
|
||||||
|
$server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
throw new \Exception($this->error);
|
||||||
|
}
|
||||||
|
$this->supported_os_type = $server->validateOS();
|
||||||
|
if (! $this->supported_os_type) {
|
||||||
|
$this->error = 'Server OS type is not supported. Please install Docker manually before continuing: <a target="_blank" class="text-black underline dark:text-white" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
$server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
throw new \Exception($this->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->docker_installed = $server->validateDockerEngine();
|
||||||
|
$this->docker_compose_installed = $server->validateDockerCompose();
|
||||||
|
if (! $this->docker_installed || ! $this->docker_compose_installed) {
|
||||||
|
$this->error = 'Docker Engine is not installed. Please install Docker manually before continuing: <a target="_blank" class="text-black underline dark:text-white" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
$server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
throw new \Exception($this->error);
|
||||||
|
}
|
||||||
|
$this->docker_version = $server->validateDockerEngineVersion();
|
||||||
|
|
||||||
|
if ($this->docker_version) {
|
||||||
|
return 'OK';
|
||||||
|
} else {
|
||||||
|
$this->error = 'Docker Engine is not installed. Please install Docker manually before continuing: <a target="_blank" class="text-black underline dark:text-white" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
$server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
throw new \Exception($this->error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -167,7 +167,7 @@ public function environment_details(Request $request)
|
|||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: [
|
properties: [
|
||||||
'name' => ['type' => 'string', 'description' => 'The name of the project.'],
|
'uuid' => ['type' => 'string', 'description' => 'The name of the project.'],
|
||||||
'description' => ['type' => 'string', 'description' => 'The description of the project.'],
|
'description' => ['type' => 'string', 'description' => 'The description of the project.'],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -183,9 +183,7 @@ public function environment_details(Request $request)
|
|||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: [
|
properties: [
|
||||||
'uuid' => ['type' => 'string', 'example' => 'og888os'],
|
'uuid' => ['type' => 'string', 'example' => 'og888os', 'description' => 'The UUID of the project.'],
|
||||||
'name' => ['type' => 'string', 'example' => 'Project Name'],
|
|
||||||
'description' => ['type' => 'string', 'example' => 'Project Description'],
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -218,7 +216,7 @@ public function create_project(Request $request)
|
|||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'name' => 'string|max:255',
|
'name' => 'string|max:255|required',
|
||||||
'description' => 'string|nullable',
|
'description' => 'string|nullable',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -245,8 +243,6 @@ public function create_project(Request $request)
|
|||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'uuid' => $project->uuid,
|
'uuid' => $project->uuid,
|
||||||
'name' => $project->name,
|
|
||||||
'description' => $project->description,
|
|
||||||
])->setStatusCode(201);
|
])->setStatusCode(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Actions\Server\ValidateServer;
|
||||||
|
use App\Enums\ProxyStatus;
|
||||||
|
use App\Enums\ProxyTypes;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
|
use App\Models\PrivateKey;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Server as ModelsServer;
|
use App\Models\Server as ModelsServer;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@ -75,7 +79,7 @@ public function servers(Request $request)
|
|||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
return invalidTokenResponse();
|
return invalidTokenResponse();
|
||||||
}
|
}
|
||||||
$servers = ModelsServer::whereTeamId($teamId)->select('id', 'name', 'uuid', 'ip', 'user', 'port')->get()->load(['settings'])->map(function ($server) {
|
$servers = ModelsServer::whereTeamId($teamId)->select('id', 'name', 'uuid', 'ip', 'user', 'port', 'description')->get()->load(['settings'])->map(function ($server) {
|
||||||
$server['is_reachable'] = $server->settings->is_reachable;
|
$server['is_reachable'] = $server->settings->is_reachable;
|
||||||
$server['is_usable'] = $server->settings->is_usable;
|
$server['is_usable'] = $server->settings->is_usable;
|
||||||
|
|
||||||
@ -392,4 +396,390 @@ public function domains_by_server(Request $request)
|
|||||||
|
|
||||||
return response()->json(serializeApiResponse($domains));
|
return response()->json(serializeApiResponse($domains));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[OA\Post(
|
||||||
|
summary: 'Create Server',
|
||||||
|
description: 'Create Server.',
|
||||||
|
path: '/servers',
|
||||||
|
security: [
|
||||||
|
['bearerAuth' => []],
|
||||||
|
],
|
||||||
|
tags: ['Servers'],
|
||||||
|
requestBody: new OA\RequestBody(
|
||||||
|
required: true,
|
||||||
|
description: 'Server created.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'name' => ['type' => 'string', 'example' => 'My Server', 'description' => 'The name of the server.'],
|
||||||
|
'description' => ['type' => 'string', 'example' => 'My Server Description', 'description' => 'The description of the server.'],
|
||||||
|
'ip' => ['type' => 'string', 'example' => '127.0.0.1', 'description' => 'The IP of the server.'],
|
||||||
|
'port' => ['type' => 'integer', 'example' => 22, 'description' => 'The port of the server.'],
|
||||||
|
'user' => ['type' => 'string', 'example' => 'root', 'description' => 'The user of the server.'],
|
||||||
|
'private_key_uuid' => ['type' => 'string', 'example' => 'og888os', 'description' => 'The UUID of the private key.'],
|
||||||
|
'is_build_server' => ['type' => 'boolean', 'example' => false, 'description' => 'Is build server.'],
|
||||||
|
'instant_validate' => ['type' => 'boolean', 'example' => false, 'description' => 'Instant validate.'],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
responses: [
|
||||||
|
new OA\Response(
|
||||||
|
response: 201,
|
||||||
|
description: 'Server created.',
|
||||||
|
content: [
|
||||||
|
new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'uuid' => ['type' => 'string', 'example' => 'og888os', 'description' => 'The UUID of the server.'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
new OA\Response(
|
||||||
|
response: 401,
|
||||||
|
ref: '#/components/responses/401',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 400,
|
||||||
|
ref: '#/components/responses/400',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 404,
|
||||||
|
ref: '#/components/responses/404',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)]
|
||||||
|
public function create_server(Request $request)
|
||||||
|
{
|
||||||
|
$allowedFields = ['name', 'description', 'ip', 'port', 'user', 'private_key_uuid', 'is_build_server', 'instant_validate'];
|
||||||
|
|
||||||
|
$teamId = getTeamIdFromToken();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return invalidTokenResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = validateIncomingRequest($request);
|
||||||
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
$validator = customApiValidator($request->all(), [
|
||||||
|
'name' => 'string|max:255',
|
||||||
|
'description' => 'string|nullable',
|
||||||
|
'ip' => 'string|required',
|
||||||
|
'port' => 'integer|nullable',
|
||||||
|
'private_key_uuid' => 'string|required',
|
||||||
|
'user' => 'string|nullable',
|
||||||
|
'is_build_server' => 'boolean|nullable',
|
||||||
|
'instant_validate' => 'boolean|nullable',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
if (! $request->name) {
|
||||||
|
$request->offsetSet('name', generate_random_name());
|
||||||
|
}
|
||||||
|
if (! $request->user) {
|
||||||
|
$request->offsetSet('user', 'root');
|
||||||
|
}
|
||||||
|
if (is_null($request->port)) {
|
||||||
|
$request->offsetSet('port', 22);
|
||||||
|
}
|
||||||
|
if (is_null($request->is_build_server)) {
|
||||||
|
$request->offsetSet('is_build_server', false);
|
||||||
|
}
|
||||||
|
if (is_null($request->instant_validate)) {
|
||||||
|
$request->offsetSet('instant_validate', false);
|
||||||
|
}
|
||||||
|
$privateKey = PrivateKey::whereTeamId($teamId)->whereUuid($request->private_key_uuid)->first();
|
||||||
|
if (! $privateKey) {
|
||||||
|
return response()->json(['message' => 'Private key not found.'], 404);
|
||||||
|
}
|
||||||
|
$allServers = ModelsServer::whereIp($request->ip)->get();
|
||||||
|
if ($allServers->count() > 0) {
|
||||||
|
return response()->json(['message' => 'Server with this IP already exists.'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$server = ModelsServer::create([
|
||||||
|
'name' => $request->name,
|
||||||
|
'description' => $request->description,
|
||||||
|
'ip' => $request->ip,
|
||||||
|
'port' => $request->port,
|
||||||
|
'user' => $request->user,
|
||||||
|
'private_key_id' => $privateKey->id,
|
||||||
|
'team_id' => $teamId,
|
||||||
|
'proxy' => [
|
||||||
|
'type' => ProxyTypes::TRAEFIK_V2->value,
|
||||||
|
'status' => ProxyStatus::EXITED->value,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$server->settings()->update([
|
||||||
|
'is_build_server' => $request->is_build_server,
|
||||||
|
]);
|
||||||
|
if ($request->instant_validate) {
|
||||||
|
ValidateServer::dispatch($server);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'uuid' => $server->uuid,
|
||||||
|
])->setStatusCode(201);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[OA\Patch(
|
||||||
|
summary: 'Update Server',
|
||||||
|
description: 'Update Server.',
|
||||||
|
path: '/servers/{uuid}',
|
||||||
|
security: [
|
||||||
|
['bearerAuth' => []],
|
||||||
|
],
|
||||||
|
tags: ['Servers'],
|
||||||
|
requestBody: new OA\RequestBody(
|
||||||
|
required: true,
|
||||||
|
description: 'Server updated.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'name' => ['type' => 'string', 'description' => 'The name of the server.'],
|
||||||
|
'description' => ['type' => 'string', 'description' => 'The description of the server.'],
|
||||||
|
'ip' => ['type' => 'string', 'description' => 'The IP of the server.'],
|
||||||
|
'port' => ['type' => 'integer', 'description' => 'The port of the server.'],
|
||||||
|
'user' => ['type' => 'string', 'description' => 'The user of the server.'],
|
||||||
|
'private_key_uuid' => ['type' => 'string', 'description' => 'The UUID of the private key.'],
|
||||||
|
'is_build_server' => ['type' => 'boolean', 'description' => 'Is build server.'],
|
||||||
|
'instant_validate' => ['type' => 'boolean', 'description' => 'Instant validate.'],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
responses: [
|
||||||
|
new OA\Response(
|
||||||
|
response: 201,
|
||||||
|
description: 'Server updated.',
|
||||||
|
content: [
|
||||||
|
new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'array',
|
||||||
|
items: new OA\Items(ref: '#/components/schemas/Server')
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
new OA\Response(
|
||||||
|
response: 401,
|
||||||
|
ref: '#/components/responses/401',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 400,
|
||||||
|
ref: '#/components/responses/400',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 404,
|
||||||
|
ref: '#/components/responses/404',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)]
|
||||||
|
public function update_server(Request $request)
|
||||||
|
{
|
||||||
|
$allowedFields = ['name', 'description', 'ip', 'port', 'user', 'private_key_uuid', 'is_build_server', 'instant_validate'];
|
||||||
|
|
||||||
|
$teamId = getTeamIdFromToken();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return invalidTokenResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = validateIncomingRequest($request);
|
||||||
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
$validator = customApiValidator($request->all(), [
|
||||||
|
'name' => 'string|max:255|nullable',
|
||||||
|
'description' => 'string|nullable',
|
||||||
|
'ip' => 'string|nullable',
|
||||||
|
'port' => 'integer|nullable',
|
||||||
|
'private_key_uuid' => 'string|nullable',
|
||||||
|
'user' => 'string|nullable',
|
||||||
|
'is_build_server' => 'boolean|nullable',
|
||||||
|
'instant_validate' => 'boolean|nullable',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
$server = ModelsServer::whereTeamId($teamId)->whereUuid($request->uuid)->first();
|
||||||
|
if (! $server) {
|
||||||
|
return response()->json(['message' => 'Server not found.'], 404);
|
||||||
|
}
|
||||||
|
$server->update($request->only(['name', 'description', 'ip', 'port', 'user']));
|
||||||
|
if ($request->is_build_server) {
|
||||||
|
$server->settings()->update([
|
||||||
|
'is_build_server' => $request->is_build_server,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if ($request->instant_validate) {
|
||||||
|
ValidateServer::dispatch($server);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(serializeApiResponse($server))->setStatusCode(201);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[OA\Delete(
|
||||||
|
summary: 'Delete',
|
||||||
|
description: 'Delete server by UUID.',
|
||||||
|
path: '/servers/{uuid}',
|
||||||
|
security: [
|
||||||
|
['bearerAuth' => []],
|
||||||
|
],
|
||||||
|
tags: ['Servers'],
|
||||||
|
parameters: [
|
||||||
|
new OA\Parameter(
|
||||||
|
name: 'uuid',
|
||||||
|
in: 'path',
|
||||||
|
description: 'UUID of the server.',
|
||||||
|
required: true,
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
responses: [
|
||||||
|
new OA\Response(
|
||||||
|
response: 200,
|
||||||
|
description: 'Server deleted.',
|
||||||
|
content: [
|
||||||
|
new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'message' => ['type' => 'string', 'example' => 'Server deleted.'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
new OA\Response(
|
||||||
|
response: 401,
|
||||||
|
ref: '#/components/responses/401',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 400,
|
||||||
|
ref: '#/components/responses/400',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 404,
|
||||||
|
ref: '#/components/responses/404',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)]
|
||||||
|
public function delete_server(Request $request)
|
||||||
|
{
|
||||||
|
$teamId = getTeamIdFromToken();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return invalidTokenResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $request->uuid) {
|
||||||
|
return response()->json(['message' => 'Uuid is required.'], 422);
|
||||||
|
}
|
||||||
|
$server = ModelsServer::whereTeamId($teamId)->whereUuid($request->uuid)->first();
|
||||||
|
|
||||||
|
if (! $server) {
|
||||||
|
return response()->json(['message' => 'Server not found.'], 404);
|
||||||
|
}
|
||||||
|
if ($server->definedResources()->count() > 0) {
|
||||||
|
return response()->json(['message' => 'Server has resources, so you need to delete them before.'], 400);
|
||||||
|
}
|
||||||
|
$server->delete();
|
||||||
|
|
||||||
|
return response()->json(['message' => 'Server deleted.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[OA\Get(
|
||||||
|
summary: 'Validate',
|
||||||
|
description: 'Validate server by UUID.',
|
||||||
|
path: '/servers/{uuid}/validate',
|
||||||
|
security: [
|
||||||
|
['bearerAuth' => []],
|
||||||
|
],
|
||||||
|
tags: ['Servers'],
|
||||||
|
parameters: [
|
||||||
|
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server UUID', schema: new OA\Schema(type: 'integer')),
|
||||||
|
],
|
||||||
|
responses: [
|
||||||
|
new OA\Response(
|
||||||
|
response: 201,
|
||||||
|
description: 'Server validation started.',
|
||||||
|
content: [
|
||||||
|
new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'message' => ['type' => 'string', 'example' => 'Validation started.'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
new OA\Response(
|
||||||
|
response: 401,
|
||||||
|
ref: '#/components/responses/401',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 400,
|
||||||
|
ref: '#/components/responses/400',
|
||||||
|
),
|
||||||
|
new OA\Response(
|
||||||
|
response: 404,
|
||||||
|
ref: '#/components/responses/404',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)]
|
||||||
|
public function validate_server(Request $request)
|
||||||
|
{
|
||||||
|
$teamId = getTeamIdFromToken();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return invalidTokenResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $request->uuid) {
|
||||||
|
return response()->json(['message' => 'Uuid is required.'], 422);
|
||||||
|
}
|
||||||
|
$server = ModelsServer::whereTeamId($teamId)->whereUuid($request->uuid)->first();
|
||||||
|
|
||||||
|
if (! $server) {
|
||||||
|
return response()->json(['message' => 'Server not found.'], 404);
|
||||||
|
}
|
||||||
|
ValidateServer::dispatch($server);
|
||||||
|
|
||||||
|
return response()->json(['message' => 'Validation started.']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,6 @@ public function saveServer()
|
|||||||
$this->createdServer->settings->is_swarm_manager = $this->isSwarmManager;
|
$this->createdServer->settings->is_swarm_manager = $this->isSwarmManager;
|
||||||
$this->createdServer->settings->is_cloudflare_tunnel = $this->isCloudflareTunnel;
|
$this->createdServer->settings->is_cloudflare_tunnel = $this->isCloudflareTunnel;
|
||||||
$this->createdServer->settings->save();
|
$this->createdServer->settings->save();
|
||||||
$this->createdServer->addInitialNetwork();
|
|
||||||
$this->selectedExistingServer = $this->createdServer->id;
|
$this->selectedExistingServer = $this->createdServer->id;
|
||||||
$this->currentState = 'validate-server';
|
$this->currentState = 'validate-server';
|
||||||
}
|
}
|
||||||
|
@ -164,6 +164,9 @@ public function checkLocalhostConnection()
|
|||||||
|
|
||||||
public function validateServer($install = true)
|
public function validateServer($install = true)
|
||||||
{
|
{
|
||||||
|
$this->server->update([
|
||||||
|
'validation_logs' => null,
|
||||||
|
]);
|
||||||
$this->dispatch('init', $install);
|
$this->dispatch('init', $install);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,6 @@ public function submit()
|
|||||||
}
|
}
|
||||||
$server->settings->is_build_server = $this->is_build_server;
|
$server->settings->is_build_server = $this->is_build_server;
|
||||||
$server->settings->save();
|
$server->settings->save();
|
||||||
$server->addInitialNetwork();
|
|
||||||
|
|
||||||
return redirect()->route('server.show', $server->uuid);
|
return redirect()->route('server.show', $server->uuid);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@ -87,7 +87,10 @@ public function validateConnection()
|
|||||||
{
|
{
|
||||||
['uptime' => $this->uptime, 'error' => $error] = $this->server->validateConnection();
|
['uptime' => $this->uptime, 'error' => $error] = $this->server->validateConnection();
|
||||||
if (! $this->uptime) {
|
if (! $this->uptime) {
|
||||||
$this->error = 'Server is not reachable. Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br>Error: '.$error;
|
$this->error = 'Server is not reachable. Please validate your configuration and connection.<br>Check this <a target="_blank" class="text-black underline dark:text-white" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br><div class="text-error">Error: '.$error.'</div>';
|
||||||
|
$this->server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -99,6 +102,9 @@ public function validateOS()
|
|||||||
$this->supported_os_type = $this->server->validateOS();
|
$this->supported_os_type = $this->server->validateOS();
|
||||||
if (! $this->supported_os_type) {
|
if (! $this->supported_os_type) {
|
||||||
$this->error = 'Server OS type is not supported. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
$this->error = 'Server OS type is not supported. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
$this->server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -113,6 +119,9 @@ public function validateDockerEngine()
|
|||||||
if ($this->install) {
|
if ($this->install) {
|
||||||
if ($this->number_of_tries == $this->max_tries) {
|
if ($this->number_of_tries == $this->max_tries) {
|
||||||
$this->error = 'Docker Engine could not be installed. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
$this->error = 'Docker Engine could not be installed. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
$this->server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -126,6 +135,9 @@ public function validateDockerEngine()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->error = 'Docker Engine is not installed. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
$this->error = 'Docker Engine is not installed. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
$this->server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -148,6 +160,9 @@ public function validateDockerVersion()
|
|||||||
$this->dispatch('success', 'Server validated.');
|
$this->dispatch('success', 'Server validated.');
|
||||||
} else {
|
} else {
|
||||||
$this->error = 'Docker Engine version is not 22+. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
$this->error = 'Docker Engine version is not 22+. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
$this->server->update([
|
||||||
|
'validation_logs' => $this->error,
|
||||||
|
]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -19,85 +19,23 @@
|
|||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
#[OA\Schema(
|
#[OA\Schema(
|
||||||
description: 'Application model',
|
description: 'Server model',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: [
|
properties: [
|
||||||
'id' => ['type' => 'integer'],
|
'id' => ['type' => 'integer'],
|
||||||
'repository_project_id' => ['type' => 'integer', 'nullable' => true],
|
|
||||||
'uuid' => ['type' => 'string'],
|
'uuid' => ['type' => 'string'],
|
||||||
'name' => ['type' => 'string'],
|
'name' => ['type' => 'string'],
|
||||||
'fqdn' => ['type' => 'string'],
|
'description' => ['type' => 'string'],
|
||||||
'config_hash' => ['type' => 'string'],
|
'ip' => ['type' => 'string'],
|
||||||
'git_repository' => ['type' => 'string'],
|
'user' => ['type' => 'string'],
|
||||||
'git_branch' => ['type' => 'string'],
|
'port' => ['type' => 'integer'],
|
||||||
'git_commit_sha' => ['type' => 'string'],
|
'proxy' => ['type' => 'object'],
|
||||||
'git_full_url' => ['type' => 'string', 'nullable' => true],
|
'high_disk_usage_notification_sent' => ['type' => 'boolean'],
|
||||||
'docker_registry_image_name' => ['type' => 'string', 'nullable' => true],
|
'unreachable_notification_sent' => ['type' => 'boolean'],
|
||||||
'docker_registry_image_tag' => ['type' => 'string', 'nullable' => true],
|
'unreachable_count' => ['type' => 'integer'],
|
||||||
'build_pack' => ['type' => 'string'],
|
'validation_logs' => ['type' => 'string'],
|
||||||
'static_image' => ['type' => 'string'],
|
'log_drain_notification_sent' => ['type' => 'boolean'],
|
||||||
'install_command' => ['type' => 'string'],
|
'swarm_cluster' => ['type' => 'string'],
|
||||||
'build_command' => ['type' => 'string'],
|
|
||||||
'start_command' => ['type' => 'string'],
|
|
||||||
'ports_exposes' => ['type' => 'string'],
|
|
||||||
'ports_mappings' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'base_directory' => ['type' => 'string'],
|
|
||||||
'publish_directory' => ['type' => 'string'],
|
|
||||||
'health_check_path' => ['type' => 'string'],
|
|
||||||
'health_check_port' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'health_check_host' => ['type' => 'string'],
|
|
||||||
'health_check_method' => ['type' => 'string'],
|
|
||||||
'health_check_return_code' => ['type' => 'integer'],
|
|
||||||
'health_check_scheme' => ['type' => 'string'],
|
|
||||||
'health_check_response_text' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'health_check_interval' => ['type' => 'integer'],
|
|
||||||
'health_check_timeout' => ['type' => 'integer'],
|
|
||||||
'health_check_retries' => ['type' => 'integer'],
|
|
||||||
'health_check_start_period' => ['type' => 'integer'],
|
|
||||||
'limits_memory' => ['type' => 'string'],
|
|
||||||
'limits_memory_swap' => ['type' => 'string'],
|
|
||||||
'limits_memory_swappiness' => ['type' => 'integer'],
|
|
||||||
'limits_memory_reservation' => ['type' => 'string'],
|
|
||||||
'limits_cpus' => ['type' => 'string'],
|
|
||||||
'limits_cpuset' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'limits_cpu_shares' => ['type' => 'integer'],
|
|
||||||
'status' => ['type' => 'string'],
|
|
||||||
'preview_url_template' => ['type' => 'string'],
|
|
||||||
'destination_type' => ['type' => 'string'],
|
|
||||||
'destination_id' => ['type' => 'integer'],
|
|
||||||
'source_type' => ['type' => 'string'],
|
|
||||||
'source_id' => ['type' => 'integer'],
|
|
||||||
'private_key_id' => ['type' => 'integer', 'nullable' => true],
|
|
||||||
'environment_id' => ['type' => 'integer'],
|
|
||||||
'created_at' => ['type' => 'string', 'format' => 'date-time'],
|
|
||||||
'updated_at' => ['type' => 'string', 'format' => 'date-time'],
|
|
||||||
'description' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'dockerfile' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'health_check_enabled' => ['type' => 'boolean'],
|
|
||||||
'dockerfile_location' => ['type' => 'string'],
|
|
||||||
'custom_labels' => ['type' => 'string'],
|
|
||||||
'dockerfile_target_build' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'manual_webhook_secret_github' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'manual_webhook_secret_gitlab' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'docker_compose_location' => ['type' => 'string'],
|
|
||||||
'docker_compose' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'docker_compose_raw' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'docker_compose_domains' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'deleted_at' => ['type' => 'string', 'format' => 'date-time', 'nullable' => true],
|
|
||||||
'docker_compose_custom_start_command' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'docker_compose_custom_build_command' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'swarm_replicas' => ['type' => 'integer'],
|
|
||||||
'swarm_placement_constraints' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'manual_webhook_secret_bitbucket' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'custom_docker_run_options' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'post_deployment_command' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'post_deployment_command_container' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'pre_deployment_command' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'pre_deployment_command_container' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'watch_paths' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'custom_healthcheck_found' => ['type' => 'boolean'],
|
|
||||||
'manual_webhook_secret_gitea' => ['type' => 'string', 'nullable' => true],
|
|
||||||
'redirect' => ['type' => 'string'],
|
|
||||||
]
|
]
|
||||||
)]
|
)]
|
||||||
|
|
||||||
@ -123,6 +61,37 @@ protected static function booted()
|
|||||||
ServerSetting::create([
|
ServerSetting::create([
|
||||||
'server_id' => $server->id,
|
'server_id' => $server->id,
|
||||||
]);
|
]);
|
||||||
|
if ($server->id === 0) {
|
||||||
|
if ($server->isSwarm()) {
|
||||||
|
SwarmDocker::create([
|
||||||
|
'id' => 0,
|
||||||
|
'name' => 'coolify',
|
||||||
|
'network' => 'coolify-overlay',
|
||||||
|
'server_id' => $server->id,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
StandaloneDocker::create([
|
||||||
|
'id' => 0,
|
||||||
|
'name' => 'coolify',
|
||||||
|
'network' => 'coolify',
|
||||||
|
'server_id' => $server->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($server->isSwarm()) {
|
||||||
|
SwarmDocker::create([
|
||||||
|
'name' => 'coolify-overlay',
|
||||||
|
'network' => 'coolify-overlay',
|
||||||
|
'server_id' => $server->id,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
StandaloneDocker::create([
|
||||||
|
'name' => 'coolify',
|
||||||
|
'network' => 'coolify',
|
||||||
|
'server_id' => $server->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
static::deleting(function ($server) {
|
static::deleting(function ($server) {
|
||||||
$server->destinations()->each(function ($destination) {
|
$server->destinations()->each(function ($destination) {
|
||||||
@ -176,41 +145,6 @@ public function settings()
|
|||||||
return $this->hasOne(ServerSetting::class);
|
return $this->hasOne(ServerSetting::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addInitialNetwork()
|
|
||||||
{
|
|
||||||
if ($this->id === 0) {
|
|
||||||
if ($this->isSwarm()) {
|
|
||||||
SwarmDocker::create([
|
|
||||||
'id' => 0,
|
|
||||||
'name' => 'coolify',
|
|
||||||
'network' => 'coolify-overlay',
|
|
||||||
'server_id' => $this->id,
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
StandaloneDocker::create([
|
|
||||||
'id' => 0,
|
|
||||||
'name' => 'coolify',
|
|
||||||
'network' => 'coolify',
|
|
||||||
'server_id' => $this->id,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($this->isSwarm()) {
|
|
||||||
SwarmDocker::create([
|
|
||||||
'name' => 'coolify-overlay',
|
|
||||||
'network' => 'coolify-overlay',
|
|
||||||
'server_id' => $this->id,
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
StandaloneDocker::create([
|
|
||||||
'name' => 'coolify',
|
|
||||||
'network' => 'coolify',
|
|
||||||
'server_id' => $this->id,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setupDefault404Redirect()
|
public function setupDefault404Redirect()
|
||||||
{
|
{
|
||||||
$dynamic_conf_path = $this->proxyPath().'/dynamic';
|
$dynamic_conf_path = $this->proxyPath().'/dynamic';
|
||||||
|
@ -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('servers', function (Blueprint $table) {
|
||||||
|
$table->text('validation_logs')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('validation_logs');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
378
openapi.yaml
378
openapi.yaml
@ -3023,7 +3023,7 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
properties:
|
properties:
|
||||||
name:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
description: 'The name of the project.'
|
description: 'The name of the project.'
|
||||||
description:
|
description:
|
||||||
@ -3037,9 +3037,7 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
properties:
|
properties:
|
||||||
uuid: { type: string, example: og888os }
|
uuid: { type: string, example: og888os, description: 'The UUID of the project.' }
|
||||||
name: { type: string, example: 'Project Name' }
|
|
||||||
description: { type: string, example: 'Project Description' }
|
|
||||||
type: object
|
type: object
|
||||||
'401':
|
'401':
|
||||||
$ref: '#/components/responses/401'
|
$ref: '#/components/responses/401'
|
||||||
@ -3401,6 +3399,70 @@ paths:
|
|||||||
security:
|
security:
|
||||||
-
|
-
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Servers
|
||||||
|
summary: 'Create Server'
|
||||||
|
description: 'Create Server.'
|
||||||
|
operationId: fa44b42490379e428ba5b8747716a8d9
|
||||||
|
requestBody:
|
||||||
|
description: 'Server created.'
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: 'My Server'
|
||||||
|
description: 'The name of the server.'
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
example: 'My Server Description'
|
||||||
|
description: 'The description of the server.'
|
||||||
|
ip:
|
||||||
|
type: string
|
||||||
|
example: 127.0.0.1
|
||||||
|
description: 'The IP of the server.'
|
||||||
|
port:
|
||||||
|
type: integer
|
||||||
|
example: 22
|
||||||
|
description: 'The port of the server.'
|
||||||
|
user:
|
||||||
|
type: string
|
||||||
|
example: root
|
||||||
|
description: 'The user of the server.'
|
||||||
|
private_key_uuid:
|
||||||
|
type: string
|
||||||
|
example: og888os
|
||||||
|
description: 'The UUID of the private key.'
|
||||||
|
is_build_server:
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
|
description: 'Is build server.'
|
||||||
|
instant_validate:
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
|
description: 'Instant validate.'
|
||||||
|
type: object
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: 'Server created.'
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
uuid: { type: string, example: og888os, description: 'The UUID of the server.' }
|
||||||
|
type: object
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/404'
|
||||||
|
security:
|
||||||
|
-
|
||||||
|
bearerAuth: []
|
||||||
'/servers/{uuid}':
|
'/servers/{uuid}':
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -3432,6 +3494,95 @@ paths:
|
|||||||
security:
|
security:
|
||||||
-
|
-
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- Servers
|
||||||
|
summary: Delete
|
||||||
|
description: 'Delete server by UUID.'
|
||||||
|
operationId: 0231fe0134f0306b21f006ce51b0a3dc
|
||||||
|
parameters:
|
||||||
|
-
|
||||||
|
name: uuid
|
||||||
|
in: path
|
||||||
|
description: 'UUID of the server.'
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: 'Server deleted.'
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
message: { type: string, example: 'Server deleted.' }
|
||||||
|
type: object
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/404'
|
||||||
|
security:
|
||||||
|
-
|
||||||
|
bearerAuth: []
|
||||||
|
patch:
|
||||||
|
tags:
|
||||||
|
- Servers
|
||||||
|
summary: 'Update Server'
|
||||||
|
description: 'Update Server.'
|
||||||
|
operationId: 41bbdaf79eb1938592494fc5494442a0
|
||||||
|
requestBody:
|
||||||
|
description: 'Server updated.'
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: 'The name of the server.'
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
description: 'The description of the server.'
|
||||||
|
ip:
|
||||||
|
type: string
|
||||||
|
description: 'The IP of the server.'
|
||||||
|
port:
|
||||||
|
type: integer
|
||||||
|
description: 'The port of the server.'
|
||||||
|
user:
|
||||||
|
type: string
|
||||||
|
description: 'The user of the server.'
|
||||||
|
private_key_uuid:
|
||||||
|
type: string
|
||||||
|
description: 'The UUID of the private key.'
|
||||||
|
is_build_server:
|
||||||
|
type: boolean
|
||||||
|
description: 'Is build server.'
|
||||||
|
instant_validate:
|
||||||
|
type: boolean
|
||||||
|
description: 'Instant validate.'
|
||||||
|
type: object
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: 'Server updated.'
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Server'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/404'
|
||||||
|
security:
|
||||||
|
-
|
||||||
|
bearerAuth: []
|
||||||
'/servers/{uuid}/resources':
|
'/servers/{uuid}/resources':
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -3496,6 +3647,39 @@ paths:
|
|||||||
security:
|
security:
|
||||||
-
|
-
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
|
'/servers/{uuid}/validate':
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Servers
|
||||||
|
summary: Validate
|
||||||
|
description: 'Validate server by UUID.'
|
||||||
|
operationId: a543a12ef2cbc7a3dd22c3dbe6cbee89
|
||||||
|
parameters:
|
||||||
|
-
|
||||||
|
name: uuid
|
||||||
|
in: path
|
||||||
|
description: 'Server UUID'
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: 'Server validation started.'
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
message: { type: string, example: 'Validation started.' }
|
||||||
|
type: object
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/404'
|
||||||
|
security:
|
||||||
|
-
|
||||||
|
bearerAuth: []
|
||||||
/services:
|
/services:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -4302,191 +4486,35 @@ components:
|
|||||||
$ref: '#/components/schemas/Environment'
|
$ref: '#/components/schemas/Environment'
|
||||||
type: object
|
type: object
|
||||||
Server:
|
Server:
|
||||||
description: 'Application model'
|
description: 'Server model'
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
type: integer
|
type: integer
|
||||||
repository_project_id:
|
|
||||||
type: integer
|
|
||||||
nullable: true
|
|
||||||
uuid:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
fqdn:
|
|
||||||
type: string
|
|
||||||
config_hash:
|
|
||||||
type: string
|
|
||||||
git_repository:
|
|
||||||
type: string
|
|
||||||
git_branch:
|
|
||||||
type: string
|
|
||||||
git_commit_sha:
|
|
||||||
type: string
|
|
||||||
git_full_url:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
docker_registry_image_name:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
docker_registry_image_tag:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
build_pack:
|
|
||||||
type: string
|
|
||||||
static_image:
|
|
||||||
type: string
|
|
||||||
install_command:
|
|
||||||
type: string
|
|
||||||
build_command:
|
|
||||||
type: string
|
|
||||||
start_command:
|
|
||||||
type: string
|
|
||||||
ports_exposes:
|
|
||||||
type: string
|
|
||||||
ports_mappings:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
base_directory:
|
|
||||||
type: string
|
|
||||||
publish_directory:
|
|
||||||
type: string
|
|
||||||
health_check_path:
|
|
||||||
type: string
|
|
||||||
health_check_port:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
health_check_host:
|
|
||||||
type: string
|
|
||||||
health_check_method:
|
|
||||||
type: string
|
|
||||||
health_check_return_code:
|
|
||||||
type: integer
|
|
||||||
health_check_scheme:
|
|
||||||
type: string
|
|
||||||
health_check_response_text:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
health_check_interval:
|
|
||||||
type: integer
|
|
||||||
health_check_timeout:
|
|
||||||
type: integer
|
|
||||||
health_check_retries:
|
|
||||||
type: integer
|
|
||||||
health_check_start_period:
|
|
||||||
type: integer
|
|
||||||
limits_memory:
|
|
||||||
type: string
|
|
||||||
limits_memory_swap:
|
|
||||||
type: string
|
|
||||||
limits_memory_swappiness:
|
|
||||||
type: integer
|
|
||||||
limits_memory_reservation:
|
|
||||||
type: string
|
|
||||||
limits_cpus:
|
|
||||||
type: string
|
|
||||||
limits_cpuset:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
limits_cpu_shares:
|
|
||||||
type: integer
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
preview_url_template:
|
|
||||||
type: string
|
|
||||||
destination_type:
|
|
||||||
type: string
|
|
||||||
destination_id:
|
|
||||||
type: integer
|
|
||||||
source_type:
|
|
||||||
type: string
|
|
||||||
source_id:
|
|
||||||
type: integer
|
|
||||||
private_key_id:
|
|
||||||
type: integer
|
|
||||||
nullable: true
|
|
||||||
environment_id:
|
|
||||||
type: integer
|
|
||||||
created_at:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
updated_at:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
description:
|
description:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
ip:
|
||||||
dockerfile:
|
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
user:
|
||||||
health_check_enabled:
|
|
||||||
type: boolean
|
|
||||||
dockerfile_location:
|
|
||||||
type: string
|
type: string
|
||||||
custom_labels:
|
port:
|
||||||
type: string
|
|
||||||
dockerfile_target_build:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
manual_webhook_secret_github:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
manual_webhook_secret_gitlab:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
docker_compose_location:
|
|
||||||
type: string
|
|
||||||
docker_compose:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
docker_compose_raw:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
docker_compose_domains:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
deleted_at:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
nullable: true
|
|
||||||
docker_compose_custom_start_command:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
docker_compose_custom_build_command:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
swarm_replicas:
|
|
||||||
type: integer
|
type: integer
|
||||||
swarm_placement_constraints:
|
proxy:
|
||||||
type: string
|
type: object
|
||||||
nullable: true
|
high_disk_usage_notification_sent:
|
||||||
manual_webhook_secret_bitbucket:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
custom_docker_run_options:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
post_deployment_command:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
post_deployment_command_container:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
pre_deployment_command:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
pre_deployment_command_container:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
watch_paths:
|
|
||||||
type: string
|
|
||||||
nullable: true
|
|
||||||
custom_healthcheck_found:
|
|
||||||
type: boolean
|
type: boolean
|
||||||
manual_webhook_secret_gitea:
|
unreachable_notification_sent:
|
||||||
|
type: boolean
|
||||||
|
unreachable_count:
|
||||||
|
type: integer
|
||||||
|
validation_logs:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
log_drain_notification_sent:
|
||||||
redirect:
|
type: boolean
|
||||||
|
swarm_cluster:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
ServerSetting:
|
ServerSetting:
|
||||||
|
@ -40,6 +40,12 @@ class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-1
|
|||||||
Validate Server & Install Docker Engine
|
Validate Server & Install Docker Engine
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
</x-slide-over>
|
</x-slide-over>
|
||||||
|
@if ($server->validation_logs)
|
||||||
|
<h4>Previous Validation Logs</h4>
|
||||||
|
<div class="pb-8">
|
||||||
|
{!! $server->validation_logs !!}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id === 0)
|
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id === 0)
|
||||||
<x-forms.button class="mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
<x-forms.button class="mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
||||||
|
@ -61,6 +61,12 @@
|
|||||||
Route::get('/servers/{uuid}/domains', [ServersController::class, 'domains_by_server']);
|
Route::get('/servers/{uuid}/domains', [ServersController::class, 'domains_by_server']);
|
||||||
Route::get('/servers/{uuid}/resources', [ServersController::class, 'resources_by_server']);
|
Route::get('/servers/{uuid}/resources', [ServersController::class, 'resources_by_server']);
|
||||||
|
|
||||||
|
Route::get('/servers/{uuid}/validate', [ServersController::class, 'validate_server']);
|
||||||
|
|
||||||
|
Route::post('/servers', [ServersController::class, 'create_server']);
|
||||||
|
Route::patch('/servers/{uuid}', [ServersController::class, 'update_server']);
|
||||||
|
Route::delete('/servers/{uuid}', [ServersController::class, 'delete_server']);
|
||||||
|
|
||||||
Route::get('/resources', [ResourcesController::class, 'resources']);
|
Route::get('/resources', [ResourcesController::class, 'resources']);
|
||||||
|
|
||||||
Route::get('/applications', [ApplicationsController::class, 'applications']);
|
Route::get('/applications', [ApplicationsController::class, 'applications']);
|
||||||
|
Loading…
Reference in New Issue
Block a user