feat: lots of api endpoints
This commit is contained in:
parent
dbc235d84a
commit
da6f2da3d0
15
app/Enums/NewDatabaseTypes.php
Normal file
15
app/Enums/NewDatabaseTypes.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum NewDatabaseTypes: string
|
||||
{
|
||||
case POSTGRESQL = 'postgresql';
|
||||
case MYSQL = 'mysql';
|
||||
case MONGODB = 'mongodb';
|
||||
case REDIS = 'redis';
|
||||
case MARIADB = 'mariadb';
|
||||
case KEYDB = 'keydb';
|
||||
case DRAGONFLY = 'dragonfly';
|
||||
case CLICKHOUSE = 'clickhouse';
|
||||
}
|
@ -20,7 +20,7 @@ public function __construct($userId = null)
|
||||
$userId = auth()->user()->id ?? null;
|
||||
}
|
||||
if (is_null($userId)) {
|
||||
throw new \Exception('User id is null');
|
||||
throw new \RuntimeException('User id is null');
|
||||
}
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
@ -13,47 +13,45 @@
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class Applications extends Controller
|
||||
class ApplicationsController extends Controller
|
||||
{
|
||||
public function applications(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$projects = Project::where('team_id', $teamId)->get();
|
||||
$applications = collect();
|
||||
$applications->push($projects->pluck('applications')->flatten());
|
||||
$applications = $applications->flatten();
|
||||
$applications = $applications->map(function ($application) {
|
||||
return serializeApiResponse($application);
|
||||
});
|
||||
|
||||
return response()->json(serialize_api_response($applications));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $applications,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create_application(Request $request)
|
||||
{
|
||||
|
||||
ray()->clearAll();
|
||||
$allowedFields = ['project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', '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', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile'];
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
if (! $request->isJson()) {
|
||||
return response()->json([
|
||||
'message' => 'Invalid request.',
|
||||
'error' => 'Content-Type must be application/json.',
|
||||
], 400);
|
||||
}
|
||||
// check if request is valid json
|
||||
if (! json_decode($request->getContent())) {
|
||||
return response()->json([
|
||||
'message' => 'Invalid request.',
|
||||
'error' => 'Invalid JSON.',
|
||||
], 400);
|
||||
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$validator = customApiValidator($request->all(), [
|
||||
'name' => 'string|max:255',
|
||||
@ -75,6 +73,7 @@ public function create_application(Request $request)
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
@ -88,22 +87,22 @@ public function create_application(Request $request)
|
||||
|
||||
$project = Project::whereTeamId($teamId)->whereUuid($request->project_uuid)->first();
|
||||
if (! $project) {
|
||||
return response()->json(['error' => 'Project not found.'], 404);
|
||||
return response()->json(['succes' => false, 'message' => 'Project not found.'], 404);
|
||||
}
|
||||
$environment = $project->environments()->where('name', $request->environment_name)->first();
|
||||
if (! $environment) {
|
||||
return response()->json(['error' => 'Environment not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Environment not found.'], 404);
|
||||
}
|
||||
$server = Server::whereTeamId($teamId)->whereUuid($serverUuid)->first();
|
||||
if (! $server) {
|
||||
return response()->json(['error' => 'Server not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Server not found.'], 404);
|
||||
}
|
||||
$destinations = $server->destinations();
|
||||
if ($destinations->count() == 0) {
|
||||
return response()->json(['error' => 'Server has no destinations.'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'Server has no destinations.'], 400);
|
||||
}
|
||||
if ($destinations->count() > 1 && ! $request->has('destination_uuid')) {
|
||||
return response()->json(['error' => 'Server has multiple destinations and you do not set destination_uuid.'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'Server has multiple destinations and you do not set destination_uuid.'], 400);
|
||||
}
|
||||
$destination = $destinations->first();
|
||||
if ($type === 'public') {
|
||||
@ -114,11 +113,12 @@ public function create_application(Request $request)
|
||||
sharedDataApplications(),
|
||||
'git_repository' => 'string|required',
|
||||
'git_branch' => 'string|required',
|
||||
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
||||
'build_pack' => [Rule::enum(BuildPackTypes::class)],
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $validator->errors(),
|
||||
], 422);
|
||||
@ -128,7 +128,7 @@ public function create_application(Request $request)
|
||||
return $return;
|
||||
}
|
||||
$application = new Application();
|
||||
$this->removeUnnecessaryFieldsFromRequest($request);
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
|
||||
$application->fill($request->all());
|
||||
|
||||
@ -149,7 +149,10 @@ public function create_application(Request $request)
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(serialize_api_response($application));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($application),
|
||||
]);
|
||||
} elseif ($type === 'private-gh-app') {
|
||||
if (! $request->has('name')) {
|
||||
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
||||
@ -164,6 +167,7 @@ public function create_application(Request $request)
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $validator->errors(),
|
||||
], 422);
|
||||
@ -174,14 +178,14 @@ public function create_application(Request $request)
|
||||
}
|
||||
$githubApp = GithubApp::whereTeamId($teamId)->where('uuid', $githubAppUuid)->first();
|
||||
if (! $githubApp) {
|
||||
return response()->json(['error' => 'Github App not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Github App not found.'], 404);
|
||||
}
|
||||
$gitRepository = $request->git_repository;
|
||||
if (str($gitRepository)->startsWith('http') || str($gitRepository)->contains('github.com')) {
|
||||
$gitRepository = str($gitRepository)->replace('https://', '')->replace('http://', '')->replace('github.com/', '');
|
||||
}
|
||||
$application = new Application();
|
||||
$this->removeUnnecessaryFieldsFromRequest($request);
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
|
||||
$application->fill($request->all());
|
||||
|
||||
@ -205,7 +209,10 @@ public function create_application(Request $request)
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(serialize_api_response($application));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($application),
|
||||
]);
|
||||
} elseif ($type === 'private-deploy-key') {
|
||||
if (! $request->has('name')) {
|
||||
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
||||
@ -230,11 +237,11 @@ public function create_application(Request $request)
|
||||
}
|
||||
$privateKey = PrivateKey::whereTeamId($teamId)->where('uuid', $request->private_key_uuid)->first();
|
||||
if (! $privateKey) {
|
||||
return response()->json(['error' => 'Private Key not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Private Key not found.'], 404);
|
||||
}
|
||||
|
||||
$application = new Application();
|
||||
$this->removeUnnecessaryFieldsFromRequest($request);
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
|
||||
$application->fill($request->all());
|
||||
$application->fqdn = $fqdn;
|
||||
@ -255,7 +262,10 @@ public function create_application(Request $request)
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(serialize_api_response($application));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($application),
|
||||
]);
|
||||
} elseif ($type === 'dockerfile') {
|
||||
if (! $request->has('name')) {
|
||||
$request->offsetSet('name', 'dockerfile-'.new Cuid2(7));
|
||||
@ -266,6 +276,7 @@ public function create_application(Request $request)
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $validator->errors(),
|
||||
], 422);
|
||||
@ -276,6 +287,7 @@ public function create_application(Request $request)
|
||||
}
|
||||
if (! isBase64Encoded($request->dockerfile)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'dockerfile' => 'The dockerfile should be base64 encoded.',
|
||||
@ -285,6 +297,7 @@ public function create_application(Request $request)
|
||||
$dockerFile = base64_decode($request->dockerfile);
|
||||
if (mb_detect_encoding($dockerFile, 'ASCII', true) === false) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'dockerfile' => 'The dockerfile should be base64 encoded.',
|
||||
@ -292,7 +305,7 @@ public function create_application(Request $request)
|
||||
], 422);
|
||||
}
|
||||
$dockerFile = base64_decode($request->dockerfile);
|
||||
$this->removeUnnecessaryFieldsFromRequest($request);
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
|
||||
$port = get_port_from_dockerfile($request->dockerfile);
|
||||
if (! $port) {
|
||||
@ -324,42 +337,179 @@ public function create_application(Request $request)
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(serialize_api_response($application));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($application),
|
||||
]);
|
||||
} elseif ($type === 'docker-image') {
|
||||
if (! $request->has('name')) {
|
||||
$request->offsetSet('name', 'docker-image-'.new Cuid2(7));
|
||||
}
|
||||
$validator = customApiValidator($request->all(), [
|
||||
sharedDataApplications(),
|
||||
'docker_registry_image_name' => 'string|required',
|
||||
'docker_registry_image_tag' => 'string',
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $validator->errors(),
|
||||
], 422);
|
||||
}
|
||||
$return = $this->validateDataApplications($request, $server);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
if (! $request->docker_registry_image_tag) {
|
||||
$request->offsetSet('docker_registry_image_tag', 'latest');
|
||||
}
|
||||
$application = new Application();
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
|
||||
$application->fill($request->all());
|
||||
$application->fqdn = $fqdn;
|
||||
$application->build_pack = 'dockerimage';
|
||||
$application->destination_id = $destination->id;
|
||||
$application->destination_type = $destination->getMorphClass();
|
||||
$application->environment_id = $environment->id;
|
||||
|
||||
$application->git_repository = 'coollabsio/coolify';
|
||||
$application->git_branch = 'main';
|
||||
$application->save();
|
||||
|
||||
if ($instantDeploy) {
|
||||
$deployment_uuid = new Cuid2(7);
|
||||
|
||||
queue_application_deployment(
|
||||
application: $application,
|
||||
deployment_uuid: $deployment_uuid,
|
||||
no_questions_asked: true,
|
||||
is_api: true,
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(['error' => 'Invalid type.'], 400);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($application),
|
||||
]);
|
||||
} elseif ($type === 'docker-compose-empty') {
|
||||
if (! $request->has('name')) {
|
||||
$request->offsetSet('name', 'service'.new Cuid2(7));
|
||||
}
|
||||
$validator = customApiValidator($request->all(), [
|
||||
sharedDataApplications(),
|
||||
'docker_compose' => 'string|required',
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $validator->errors(),
|
||||
], 422);
|
||||
}
|
||||
$return = $this->validateDataApplications($request, $server);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
if (! isBase64Encoded($request->docker_compose)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'docker_compose' => 'The docker_compose should be base64 encoded.',
|
||||
],
|
||||
], 422);
|
||||
}
|
||||
$dockerCompose = base64_decode($request->docker_compose);
|
||||
if (mb_detect_encoding($dockerCompose, 'ASCII', true) === false) {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'docker_compose' => 'The docker_compose should be base64 encoded.',
|
||||
],
|
||||
], 422);
|
||||
}
|
||||
$dockerCompose = base64_decode($request->docker_compose);
|
||||
$dockerComposeRaw = Yaml::dump(Yaml::parse($dockerCompose), 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
|
||||
|
||||
// $isValid = validateComposeFile($dockerComposeRaw, $server_id);
|
||||
// if ($isValid !== 'OK') {
|
||||
// return $this->dispatch('error', "Invalid docker-compose file.\n$isValid");
|
||||
// }
|
||||
|
||||
$service = new Service();
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$service->name = $request->name;
|
||||
$service->description = $request->description;
|
||||
$service->docker_compose_raw = $dockerComposeRaw;
|
||||
$service->environment_id = $environment->id;
|
||||
$service->server_id = $server->id;
|
||||
$service->destination_id = $destination->id;
|
||||
$service->destination_type = $destination->getMorphClass();
|
||||
$service->save();
|
||||
|
||||
$service->name = "service-$service->uuid";
|
||||
$service->parse(isNew: true);
|
||||
// if ($instantDeploy) {
|
||||
// $deployment_uuid = new Cuid2(7);
|
||||
|
||||
// queue_application_deployment(
|
||||
// application: $application,
|
||||
// deployment_uuid: $deployment_uuid,
|
||||
// no_questions_asked: true,
|
||||
// is_api: true,
|
||||
// );
|
||||
// }
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($service),
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Invalid type.'], 400);
|
||||
|
||||
}
|
||||
|
||||
public function application_by_uuid(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$uuid = $request->route('uuid');
|
||||
if (! $uuid) {
|
||||
return response()->json(['error' => 'UUID is required.'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 400);
|
||||
}
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
if (! $application) {
|
||||
return response()->json(['error' => 'Application not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
return response()->json(serialize_api_response($application));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($application),
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete_by_uuid(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
$cleanup = $request->query->get('cleanup') ?? false;
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
if ($request->collect()->count() == 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Invalid request.',
|
||||
], 400);
|
||||
}
|
||||
@ -381,17 +531,21 @@ public function delete_by_uuid(Request $request)
|
||||
|
||||
public function update_by_uuid(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
if ($request->collect()->count() == 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Invalid request.',
|
||||
], 400);
|
||||
}
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
|
||||
if (! $application) {
|
||||
@ -423,6 +577,7 @@ public function update_by_uuid(Request $request)
|
||||
foreach ($ports as $port) {
|
||||
if (! is_numeric($port)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'ports_exposes' => 'The ports_exposes should be a comma separated list of numbers.',
|
||||
@ -445,6 +600,7 @@ public function update_by_uuid(Request $request)
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
@ -467,15 +623,21 @@ public function update_by_uuid(Request $request)
|
||||
$application->fill($data);
|
||||
$application->save();
|
||||
|
||||
return response()->json(serialize_api_response($application));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($application),
|
||||
]);
|
||||
}
|
||||
|
||||
public function envs_by_uuid(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
|
||||
@ -487,17 +649,24 @@ public function envs_by_uuid(Request $request)
|
||||
}
|
||||
$envs = $application->environment_variables->sortBy('id')->merge($application->environment_variables_preview->sortBy('id'));
|
||||
|
||||
return response()->json(serialize_api_response($envs));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($envs),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update_env_by_uuid(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$allowedFields = ['key', 'value', 'is_preview', 'is_build_time', 'is_literal'];
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
|
||||
@ -525,6 +694,7 @@ public function update_env_by_uuid(Request $request)
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
@ -547,9 +717,10 @@ public function update_env_by_uuid(Request $request)
|
||||
}
|
||||
$env->save();
|
||||
|
||||
return response()->json(serialize_api_response($env));
|
||||
return response()->json(serializeApiResponse($env));
|
||||
} else {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Environment variable not found.',
|
||||
], 404);
|
||||
}
|
||||
@ -568,10 +739,14 @@ public function update_env_by_uuid(Request $request)
|
||||
}
|
||||
$env->save();
|
||||
|
||||
return response()->json(serialize_api_response($env));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($env),
|
||||
]);
|
||||
} else {
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Environment variable not found.',
|
||||
], 404);
|
||||
|
||||
@ -579,6 +754,7 @@ public function update_env_by_uuid(Request $request)
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Something went wrong.',
|
||||
], 500);
|
||||
|
||||
@ -586,11 +762,15 @@ public function update_env_by_uuid(Request $request)
|
||||
|
||||
public function create_bulk_envs(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
|
||||
@ -604,6 +784,7 @@ public function create_bulk_envs(Request $request)
|
||||
$bulk_data = $request->get('data');
|
||||
if (! $bulk_data) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Bulk data is required.',
|
||||
], 400);
|
||||
}
|
||||
@ -620,6 +801,7 @@ public function create_bulk_envs(Request $request)
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $validator->errors(),
|
||||
], 422);
|
||||
@ -671,18 +853,18 @@ public function create_bulk_envs(Request $request)
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Environments updated.',
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($env),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create_env(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$allowedFields = ['key', 'value', 'is_preview', 'is_build_time', 'is_literal'];
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
|
||||
@ -710,6 +892,7 @@ public function create_env(Request $request)
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
@ -719,6 +902,7 @@ public function create_env(Request $request)
|
||||
$env = $application->environment_variables_preview->where('key', $request->key)->first();
|
||||
if ($env) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Environment variable already exists. Use PATCH request to update it.',
|
||||
], 409);
|
||||
} else {
|
||||
@ -730,7 +914,10 @@ public function create_env(Request $request)
|
||||
'is_literal' => $request->is_literal ?? false,
|
||||
]);
|
||||
|
||||
return response()->json(serialize_api_response($env))->setStatusCode(201);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($env),
|
||||
])->setStatusCode(201);
|
||||
}
|
||||
} else {
|
||||
$env = $application->environment_variables->where('key', $request->key)->first();
|
||||
@ -747,12 +934,16 @@ public function create_env(Request $request)
|
||||
'is_literal' => $request->is_literal ?? false,
|
||||
]);
|
||||
|
||||
return response()->json(serialize_api_response($env))->setStatusCode(201);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($env),
|
||||
])->setStatusCode(201);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Something went wrong.',
|
||||
], 500);
|
||||
|
||||
@ -760,10 +951,9 @@ public function create_env(Request $request)
|
||||
|
||||
public function delete_env_by_uuid(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
|
||||
@ -790,19 +980,19 @@ public function delete_env_by_uuid(Request $request)
|
||||
|
||||
public function action_deploy(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$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);
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 400);
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
if (! $application) {
|
||||
return response()->json(['error' => 'Application not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
$deployment_uuid = new Cuid2(7);
|
||||
@ -817,53 +1007,66 @@ public function action_deploy(Request $request)
|
||||
|
||||
return response()->json(
|
||||
[
|
||||
'success' => true,
|
||||
'message' => 'Deployment request queued.',
|
||||
'data' => [
|
||||
'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();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$uuid = $request->route('uuid');
|
||||
$sync = $request->query->get('sync') ?? false;
|
||||
if (! $uuid) {
|
||||
return response()->json(['error' => 'UUID is required.'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 400);
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
if (! $application) {
|
||||
return response()->json(['error' => 'Application not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Application not found.'], 404);
|
||||
}
|
||||
if ($sync) {
|
||||
StopApplication::run($application);
|
||||
|
||||
return response()->json(['message' => 'Stopped the application.'], 200);
|
||||
return response()->json(
|
||||
[
|
||||
'success' => true,
|
||||
'message' => 'Stopped the application.',
|
||||
],
|
||||
);
|
||||
} else {
|
||||
StopApplication::dispatch($application);
|
||||
|
||||
return response()->json(['message' => 'Stopping request queued.'], 200);
|
||||
return response()->json(
|
||||
[
|
||||
'success' => true,
|
||||
'message' => 'Stopping request queued.',
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function action_restart(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$uuid = $request->route('uuid');
|
||||
if (! $uuid) {
|
||||
return response()->json(['error' => 'UUID is required.'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 400);
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
if (! $application) {
|
||||
return response()->json(['error' => 'Application not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
$deployment_uuid = new Cuid2(7);
|
||||
@ -877,31 +1080,25 @@ public function action_restart(Request $request)
|
||||
|
||||
return response()->json(
|
||||
[
|
||||
'success' => true,
|
||||
'message' => 'Restart request queued.',
|
||||
'data' => [
|
||||
'deployment_uuid' => $deployment_uuid->toString(),
|
||||
'deployment_api_url' => base_url().'/api/v1/deployment/'.$deployment_uuid->toString(),
|
||||
],
|
||||
200
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private function removeUnnecessaryFieldsFromRequest(Request $request)
|
||||
{
|
||||
$request->offsetUnset('project_uuid');
|
||||
$request->offsetUnset('environment_name');
|
||||
$request->offsetUnset('destination_uuid');
|
||||
$request->offsetUnset('server_uuid');
|
||||
$request->offsetUnset('type');
|
||||
$request->offsetUnset('domains');
|
||||
$request->offsetUnset('instant_deploy');
|
||||
$request->offsetUnset('github_app_uuid');
|
||||
$request->offsetUnset('private_key_uuid');
|
||||
}
|
||||
|
||||
private function validateDataApplications(Request $request, Server $server)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
|
||||
// Default build pack is nixpacks
|
||||
if (! $request->has('build_pack')) {
|
||||
$request->offsetSet('build_pack', 'nixpacks');
|
||||
}
|
||||
|
||||
// Validate ports_mappings
|
||||
if ($request->has('ports_mappings')) {
|
||||
@ -910,6 +1107,7 @@ private function validateDataApplications(Request $request, Server $server)
|
||||
$port = explode(':', $portMapping);
|
||||
if (in_array($port[0], $ports)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'ports_mappings' => 'The first number before : should be unique between mappings.',
|
||||
@ -923,6 +1121,7 @@ private function validateDataApplications(Request $request, Server $server)
|
||||
if ($request->has('custom_labels')) {
|
||||
if (! isBase64Encoded($request->custom_labels)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'custom_labels' => 'The custom_labels should be base64 encoded.',
|
||||
@ -932,6 +1131,7 @@ private function validateDataApplications(Request $request, Server $server)
|
||||
$customLabels = base64_decode($request->custom_labels);
|
||||
if (mb_detect_encoding($customLabels, 'ASCII', true) === false) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'custom_labels' => 'The custom_labels should be base64 encoded.',
|
||||
@ -954,12 +1154,14 @@ private function validateDataApplications(Request $request, Server $server)
|
||||
});
|
||||
if (count($errors) > 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
}
|
||||
if (checkIfDomainIsAlreadyUsed($fqdn, $teamId)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'domains' => 'One of the domain is already used.',
|
259
app/Http/Controllers/Api/DatabasesController.php
Normal file
259
app/Http/Controllers/Api/DatabasesController.php
Normal file
@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Actions\Database\StartClickhouse;
|
||||
use App\Actions\Database\StartDragonfly;
|
||||
use App\Actions\Database\StartKeydb;
|
||||
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\Database\StopDatabase;
|
||||
use App\Enums\NewDatabaseTypes;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class DatabasesController extends Controller
|
||||
{
|
||||
public function databases(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$projects = Project::where('team_id', $teamId)->get();
|
||||
$databases = collect();
|
||||
foreach ($projects as $project) {
|
||||
$databases = $databases->merge($project->databases());
|
||||
}
|
||||
$databases = $databases->map(function ($database) {
|
||||
return serializeApiResponse($database);
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $databases,
|
||||
]);
|
||||
}
|
||||
|
||||
public function database_by_uuid(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
if (! $request->uuid) {
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 404);
|
||||
}
|
||||
$database = queryDatabaseByUuidWithinTeam($request->uuid, $teamId);
|
||||
if (! $database) {
|
||||
return response()->json(['success' => false, 'message' => 'Database not found.'], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create_database(Request $request)
|
||||
{
|
||||
$allowedFields = ['type', 'name', 'description', 'image', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'postgres_user', 'postgres_password', 'postgres_db', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares'];
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$validator = customApiValidator($request->all(), [
|
||||
'type' => ['required', Rule::enum(NewDatabaseTypes::class)],
|
||||
'name' => 'string|max:255',
|
||||
'description' => 'string|nullable',
|
||||
'image' => 'string',
|
||||
'project_uuid' => 'string|required',
|
||||
'environment_name' => 'string|required',
|
||||
'server_uuid' => 'string|required',
|
||||
'destination_uuid' => 'string',
|
||||
'postgres_user' => 'string',
|
||||
'postgres_password' => 'string',
|
||||
'postgres_db' => 'string',
|
||||
'limits_memory' => 'string',
|
||||
'limits_memory_swap' => 'string',
|
||||
'limits_memory_swappiness' => 'numeric',
|
||||
'limits_memory_reservation' => 'string',
|
||||
'limits_cpus' => 'string',
|
||||
'limits_cpuset' => 'string|nullable',
|
||||
'limits_cpu_shares' => 'numeric',
|
||||
'instant_deploy' => '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([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
}
|
||||
$serverUuid = $request->server_uuid;
|
||||
$instantDeploy = $request->instant_deploy ?? false;
|
||||
|
||||
$project = Project::whereTeamId($teamId)->whereUuid($request->project_uuid)->first();
|
||||
if (! $project) {
|
||||
return response()->json(['succes' => false, 'message' => 'Project not found.'], 404);
|
||||
}
|
||||
$environment = $project->environments()->where('name', $request->environment_name)->first();
|
||||
if (! $environment) {
|
||||
return response()->json(['success' => false, 'message' => 'Environment not found.'], 404);
|
||||
}
|
||||
$server = Server::whereTeamId($teamId)->whereUuid($serverUuid)->first();
|
||||
if (! $server) {
|
||||
return response()->json(['success' => false, 'message' => 'Server not found.'], 404);
|
||||
}
|
||||
$destinations = $server->destinations();
|
||||
if ($destinations->count() == 0) {
|
||||
return response()->json(['success' => false, 'message' => 'Server has no destinations.'], 400);
|
||||
}
|
||||
if ($destinations->count() > 1 && ! $request->has('destination_uuid')) {
|
||||
return response()->json(['success' => false, 'message' => 'Server has multiple destinations and you do not set destination_uuid.'], 400);
|
||||
}
|
||||
$destination = $destinations->first();
|
||||
|
||||
if ($request->type === NewDatabaseTypes::POSTGRESQL->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_postgresql($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartPostgresql::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
} elseif ($request->type === NewDatabaseTypes::MARIADB->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_mariadb($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartMariadb::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
} elseif ($request->type === NewDatabaseTypes::MYSQL->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_mysql($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartMysql::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
} elseif ($request->type === NewDatabaseTypes::REDIS->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_redis($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartRedis::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
} elseif ($request->type === NewDatabaseTypes::DRAGONFLY->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_dragonfly($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartDragonfly::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
} elseif ($request->type === NewDatabaseTypes::KEYDB->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_keydb($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartKeydb::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
} elseif ($request->type === NewDatabaseTypes::CLICKHOUSE->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_clickhouse($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartClickhouse::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
} elseif ($request->type === NewDatabaseTypes::MONGODB->value) {
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
$database = create_standalone_mongodb($environment->id, $destination->uuid, $request->all());
|
||||
if ($instantDeploy) {
|
||||
StartMongodb::dispatch($database);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database starting queued.',
|
||||
'data' => serializeApiResponse($database),
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Invalid database type requested.'], 400);
|
||||
}
|
||||
|
||||
public function delete_by_uuid(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
if (! $request->uuid) {
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 404);
|
||||
}
|
||||
$database = queryDatabaseByUuidWithinTeam($request->uuid, $teamId);
|
||||
if (! $database) {
|
||||
return response()->json(['success' => false, 'message' => 'Database not found.'], 404);
|
||||
}
|
||||
StopDatabase::dispatch($database);
|
||||
$database->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Database deletion request queued.',
|
||||
]);
|
||||
}
|
||||
}
|
@ -18,13 +18,13 @@
|
||||
use Illuminate\Http\Request;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class Deploy extends Controller
|
||||
class DeployController extends Controller
|
||||
{
|
||||
public function deployments(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$servers = Server::whereTeamId($teamId)->get();
|
||||
$deployments_per_server = ApplicationDeploymentQueue::whereIn('status', ['in_progress', 'queued'])->whereIn('server_id', $servers->pluck('id'))->get([
|
||||
@ -38,39 +38,45 @@ public function deployments(Request $request)
|
||||
'status',
|
||||
])->sortBy('id')->toArray();
|
||||
|
||||
return response()->json(serialize_api_response($deployments_per_server), 200);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($deployments_per_server),
|
||||
]);
|
||||
}
|
||||
|
||||
public function deployment_by_uuid(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$uuid = $request->route('uuid');
|
||||
if (! $uuid) {
|
||||
return response()->json(['message' => 'UUID is required.'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 400);
|
||||
}
|
||||
$deployment = ApplicationDeploymentQueue::where('deployment_uuid', $uuid)->first();
|
||||
if (! $deployment) {
|
||||
return response()->json(['message' => 'Deployment not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Deployment not found.'], 404);
|
||||
}
|
||||
|
||||
return response()->json(serialize_api_response($deployment->makeHidden('logs')), 200);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($deployment->makeHidden('logs')),
|
||||
]);
|
||||
}
|
||||
|
||||
public function deploy(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
$uuids = $request->query->get('uuid');
|
||||
$tags = $request->query->get('tag');
|
||||
$force = $request->query->get('force') ?? false;
|
||||
|
||||
if ($uuids && $tags) {
|
||||
return response()->json(['message' => 'You can only use uuid or tag, not both.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
|
||||
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);
|
||||
}
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
if ($tags) {
|
||||
return $this->by_tags($tags, $teamId, $force);
|
||||
@ -78,7 +84,7 @@ public function deploy(Request $request)
|
||||
return $this->by_uuids($uuids, $teamId, $force);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'You must provide uuid or tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
|
||||
return response()->json(['success' => false, '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 +93,7 @@ private function by_uuids(string $uuid, int $teamId, bool $force = false)
|
||||
$uuids = collect(array_filter($uuids));
|
||||
|
||||
if (count($uuids) === 0) {
|
||||
return response()->json(['message' => 'No UUIDs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'No UUIDs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
|
||||
}
|
||||
$deployments = collect();
|
||||
$payload = collect();
|
||||
@ -96,19 +102,22 @@ private function by_uuids(string $uuid, int $teamId, bool $force = false)
|
||||
if ($resource) {
|
||||
['message' => $return_message, 'deployment_uuid' => $deployment_uuid] = $this->deploy_resource($resource, $force);
|
||||
if ($deployment_uuid) {
|
||||
$deployments->push(['message' => $return_message, 'resource_uuid' => $uuid, 'deployment_uuid' => $deployment_uuid->toString()]);
|
||||
$deployments->push(['success' => true, 'message' => $return_message, 'resource_uuid' => $uuid, 'deployment_uuid' => $deployment_uuid->toString()]);
|
||||
} else {
|
||||
$deployments->push(['message' => $return_message, 'resource_uuid' => $uuid]);
|
||||
$deployments->push(['success' => true, 'message' => $return_message, 'resource_uuid' => $uuid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($deployments->count() > 0) {
|
||||
$payload->put('deployments', $deployments->toArray());
|
||||
|
||||
return response()->json($payload->toArray(), 200);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($payload->toArray()),
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'No resources found.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404);
|
||||
return response()->json(['success' => false, '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 +126,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(['message' => 'No TAGs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'No TAGs provided.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 400);
|
||||
}
|
||||
$message = collect([]);
|
||||
$deployments = collect();
|
||||
@ -153,10 +162,13 @@ public function by_tags(string $tags, int $team_id, bool $force = false)
|
||||
$payload->put('details', $deployments->toArray());
|
||||
}
|
||||
|
||||
return response()->json($payload->toArray(), 200);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($payload->toArray()),
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'No resources found with this tag.', 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook'], 404);
|
||||
return response()->json(['success' => false, '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
|
||||
@ -164,7 +176,7 @@ public function deploy_resource($resource, bool $force = false): array
|
||||
$message = null;
|
||||
$deployment_uuid = null;
|
||||
if (gettype($resource) !== 'object') {
|
||||
return ['message' => "Resource ($resource) not found.", 'deployment_uuid' => $deployment_uuid];
|
||||
return ['success' => false, 'message' => "Resource ($resource) not found.", 'deployment_uuid' => $deployment_uuid];
|
||||
}
|
||||
$type = $resource?->getMorphClass();
|
||||
if ($type === 'App\Models\Application') {
|
||||
@ -228,6 +240,6 @@ public function deploy_resource($resource, bool $force = false): array
|
||||
$message = "Service {$resource->name} started. It could take a while, be patient.";
|
||||
}
|
||||
|
||||
return ['message' => $message, 'deployment_uuid' => $deployment_uuid];
|
||||
return ['success' => true, 'message' => $message, 'deployment_uuid' => $deployment_uuid];
|
||||
}
|
||||
}
|
@ -6,14 +6,13 @@
|
||||
use App\Models\EnvironmentVariable;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EnvironmentVariables extends Controller
|
||||
class EnvironmentVariablesController extends Controller
|
||||
{
|
||||
public function delete_env_by_uuid(Request $request)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$env = EnvironmentVariable::where('uuid', $request->env_uuid)->first();
|
||||
if (! $env) {
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Project as ModelsProject;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Project extends Controller
|
||||
{
|
||||
public function projects(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
}
|
||||
$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 invalid_token();
|
||||
}
|
||||
$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 invalid_token();
|
||||
}
|
||||
$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);
|
||||
}
|
||||
}
|
60
app/Http/Controllers/Api/ProjectController.php
Normal file
60
app/Http/Controllers/Api/ProjectController.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Project;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ProjectController extends Controller
|
||||
{
|
||||
public function projects(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$projects = Project::whereTeamId($teamId)->select('id', 'name', 'uuid')->get();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($projects),
|
||||
]);
|
||||
}
|
||||
|
||||
public function project_by_uuid(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$project = Project::whereTeamId($teamId)->whereUuid(request()->uuid)->first()->load(['environments']);
|
||||
if (! $project) {
|
||||
return response()->json(['success' => false, 'message' => 'Project not found.'], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($project),
|
||||
]);
|
||||
}
|
||||
|
||||
public function environment_details(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$project = Project::whereTeamId($teamId)->whereUuid(request()->uuid)->first();
|
||||
$environment = $project->environments()->whereName(request()->environment_name)->first();
|
||||
if (! $environment) {
|
||||
return response()->json(['success' => false, 'message' => 'Environment not found.'], 404);
|
||||
}
|
||||
$environment = $environment->load(['applications', 'postgresqls', 'redis', 'mongodbs', 'mysqls', 'mariadbs', 'services']);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($environment),
|
||||
]);
|
||||
}
|
||||
}
|
@ -6,13 +6,13 @@
|
||||
use App\Models\Project;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Resources extends Controller
|
||||
class ResourcesController extends Controller
|
||||
{
|
||||
public function resources(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$projects = Project::where('team_id', $teamId)->get();
|
||||
$resources = collect();
|
||||
@ -34,6 +34,9 @@ public function resources(Request $request)
|
||||
return $payload;
|
||||
});
|
||||
|
||||
return response()->json($resources);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($resources),
|
||||
]);
|
||||
}
|
||||
}
|
160
app/Http/Controllers/Api/SecurityController.php
Normal file
160
app/Http/Controllers/Api/SecurityController.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\PrivateKey;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SecurityController extends Controller
|
||||
{
|
||||
public function keys(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$keys = PrivateKey::where('team_id', $teamId)->get();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($keys),
|
||||
]);
|
||||
}
|
||||
|
||||
public function key_by_uuid(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$key = PrivateKey::where('team_id', $teamId)->where('uuid', $request->uuid)->first();
|
||||
|
||||
if (is_null($key)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Key not found.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($key),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create_key(Request $request)
|
||||
{
|
||||
$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|max:255',
|
||||
'private_key' => 'required|string',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$errors = $validator->errors();
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
}
|
||||
if (! $request->name) {
|
||||
$request->offsetSet('name', generate_random_name());
|
||||
}
|
||||
if (! $request->description) {
|
||||
$request->offsetSet('description', 'Created by Coolify via API');
|
||||
}
|
||||
$key = PrivateKey::create([
|
||||
'team_id' => $teamId,
|
||||
'name' => $request->name,
|
||||
'description' => $request->description,
|
||||
'private_key' => $request->private_key,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($key),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update_key(Request $request)
|
||||
{
|
||||
$allowedFields = ['name', 'description', 'private_key'];
|
||||
$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|max:255',
|
||||
'private_key' => 'required|string',
|
||||
]);
|
||||
|
||||
$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([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
}
|
||||
$foundKey = PrivateKey::where('team_id', $teamId)->where('uuid', $request->uuid)->first();
|
||||
if (is_null($foundKey)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Key not found.',
|
||||
], 404);
|
||||
}
|
||||
$foundKey->update($request->all());
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($foundKey),
|
||||
])->setStatusCode(201);
|
||||
}
|
||||
|
||||
public function delete_key(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
if (! $request->uuid) {
|
||||
return response()->json(['success' => false, 'message' => 'UUID is required.'], 422);
|
||||
}
|
||||
|
||||
$key = PrivateKey::where('team_id', $teamId)->where('uuid', $request->uuid)->first();
|
||||
if (is_null($key)) {
|
||||
return response()->json(['success' => false, 'message' => 'Key not found.'], 404);
|
||||
}
|
||||
$key->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Key deleted.',
|
||||
]);
|
||||
}
|
||||
}
|
@ -8,14 +8,15 @@
|
||||
use App\Models\Project;
|
||||
use App\Models\Server as ModelsServer;
|
||||
use Illuminate\Http\Request;
|
||||
use Stringable;
|
||||
|
||||
class Servers extends Controller
|
||||
class ServersController extends Controller
|
||||
{
|
||||
public function servers(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$servers = ModelsServer::whereTeamId($teamId)->select('id', 'name', 'uuid', 'ip', 'user', 'port')->get()->load(['settings'])->map(function ($server) {
|
||||
$server['is_reachable'] = $server->settings->is_reachable;
|
||||
@ -23,16 +24,22 @@ public function servers(Request $request)
|
||||
|
||||
return $server;
|
||||
});
|
||||
$servers = $servers->map(function ($server) {
|
||||
return serializeApiResponse($server);
|
||||
});
|
||||
|
||||
return response()->json($servers);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $servers,
|
||||
]);
|
||||
}
|
||||
|
||||
public function server_by_uuid(Request $request)
|
||||
{
|
||||
$with_resources = $request->query('resources');
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$server = ModelsServer::whereTeamId($teamId)->whereUuid(request()->uuid)->first();
|
||||
if (is_null($server)) {
|
||||
@ -60,22 +67,25 @@ public function server_by_uuid(Request $request)
|
||||
$server->load(['settings']);
|
||||
}
|
||||
|
||||
return response()->json($server);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($server),
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_domains_by_server(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$uuid = $request->query->get('uuid');
|
||||
$uuid = $request->get('uuid');
|
||||
if ($uuid) {
|
||||
$domains = Application::getDomainsByUuid($uuid);
|
||||
|
||||
return response()->json([
|
||||
'uuid' => $uuid,
|
||||
'domains' => $domains,
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($domains),
|
||||
]);
|
||||
}
|
||||
$projects = Project::where('team_id', $teamId)->get();
|
||||
@ -86,8 +96,13 @@ public function get_domains_by_server(Request $request)
|
||||
foreach ($applications as $application) {
|
||||
$ip = $application->destination->server->ip;
|
||||
$fqdn = str($application->fqdn)->explode(',')->map(function ($fqdn) {
|
||||
return str($fqdn)->replace('http://', '')->replace('https://', '')->replace('/', '');
|
||||
$f = str($fqdn)->replace('http://', '')->replace('https://', '')->explode('/');
|
||||
|
||||
return str(str($f[0])->explode(':')[0]);
|
||||
})->filter(function (Stringable $fqdn) {
|
||||
return $fqdn->isNotEmpty();
|
||||
});
|
||||
|
||||
if ($ip === 'host.docker.internal') {
|
||||
if ($settings->public_ipv4) {
|
||||
$domains->push([
|
||||
@ -122,7 +137,11 @@ public function get_domains_by_server(Request $request)
|
||||
if ($service_applications->count() > 0) {
|
||||
foreach ($service_applications as $application) {
|
||||
$fqdn = str($application->fqdn)->explode(',')->map(function ($fqdn) {
|
||||
return str($fqdn)->replace('http://', '')->replace('https://', '')->replace('/', '');
|
||||
$f = str($fqdn)->replace('http://', '')->replace('https://', '')->explode('/');
|
||||
|
||||
return str(str($f[0])->explode(':')[0]);
|
||||
})->filter(function (Stringable $fqdn) {
|
||||
return $fqdn->isNotEmpty();
|
||||
});
|
||||
if ($ip === 'host.docker.internal') {
|
||||
if ($settings->public_ipv4) {
|
||||
@ -162,6 +181,9 @@ public function get_domains_by_server(Request $request)
|
||||
];
|
||||
})->values();
|
||||
|
||||
return response()->json($domains);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($domains),
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Team extends Controller
|
||||
{
|
||||
public function teams(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
}
|
||||
$teams = auth()->user()->teams;
|
||||
|
||||
return response()->json($teams);
|
||||
}
|
||||
|
||||
public function team_by_id(Request $request)
|
||||
{
|
||||
$id = $request->id;
|
||||
$teamId = get_team_id_from_token();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
}
|
||||
$teams = auth()->user()->teams;
|
||||
$team = $teams->where('id', $id)->first();
|
||||
if (is_null($team)) {
|
||||
return response()->json(['error' => 'Team not found.', 'docs' => 'https://coolify.io/docs/api-reference/get-team-by-teamid'], 404);
|
||||
}
|
||||
|
||||
return response()->json($team);
|
||||
}
|
||||
|
||||
public function members_by_id(Request $request)
|
||||
{
|
||||
$id = $request->id;
|
||||
$teamId = get_team_id_from_token();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
}
|
||||
$teams = auth()->user()->teams;
|
||||
$team = $teams->where('id', $id)->first();
|
||||
if (is_null($team)) {
|
||||
return response()->json(['error' => 'Team not found.', 'docs' => 'https://coolify.io/docs/api-reference/get-team-by-teamid-members'], 404);
|
||||
}
|
||||
|
||||
return response()->json($team->members);
|
||||
}
|
||||
|
||||
public function current_team(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
}
|
||||
$team = auth()->user()->currentTeam();
|
||||
|
||||
return response()->json($team);
|
||||
}
|
||||
|
||||
public function current_team_members(Request $request)
|
||||
{
|
||||
$teamId = get_team_id_from_token();
|
||||
if (is_null($teamId)) {
|
||||
return invalid_token();
|
||||
}
|
||||
$team = auth()->user()->currentTeam();
|
||||
|
||||
return response()->json($team->members);
|
||||
}
|
||||
}
|
89
app/Http/Controllers/Api/TeamController.php
Normal file
89
app/Http/Controllers/Api/TeamController.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TeamController extends Controller
|
||||
{
|
||||
public function teams(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$teams = auth()->user()->teams;
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($teams),
|
||||
]);
|
||||
}
|
||||
|
||||
public function team_by_id(Request $request)
|
||||
{
|
||||
$id = $request->id;
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$teams = auth()->user()->teams;
|
||||
$team = $teams->where('id', $id)->first();
|
||||
if (is_null($team)) {
|
||||
return response()->json(['success' => false, 'message' => 'Team not found.', 'docs' => 'https://coolify.io/docs/api-reference/get-team-by-teamid'], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($team),
|
||||
]);
|
||||
}
|
||||
|
||||
public function members_by_id(Request $request)
|
||||
{
|
||||
$id = $request->id;
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$teams = auth()->user()->teams;
|
||||
$team = $teams->where('id', $id)->first();
|
||||
if (is_null($team)) {
|
||||
return response()->json(['success' => false, 'message' => 'Team not found.', 'docs' => 'https://coolify.io/docs/api-reference/get-team-by-teamid-members'], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($team->members),
|
||||
]);
|
||||
}
|
||||
|
||||
public function current_team(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$team = auth()->user()->currentTeam();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($team),
|
||||
]);
|
||||
}
|
||||
|
||||
public function current_team_members(Request $request)
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
$team = auth()->user()->currentTeam();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => serializeApiResponse($team->members),
|
||||
]);
|
||||
}
|
||||
}
|
34
app/Http/Middleware/ApiAllowed.php
Normal file
34
app/Http/Middleware/ApiAllowed.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\InstanceSettings;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ApiAllowed
|
||||
{
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
ray()->clearAll();
|
||||
if (isCloud()) {
|
||||
return $next($request);
|
||||
}
|
||||
$settings = InstanceSettings::get();
|
||||
if ($settings->is_api_enabled === false) {
|
||||
return response()->json(['success' => true, 'message' => 'API is disabled.'], 403);
|
||||
}
|
||||
|
||||
if (! isDev()) {
|
||||
if ($settings->allowed_ips) {
|
||||
$allowedIps = explode(',', $settings->allowed_ips);
|
||||
if (! in_array($request->ip(), $allowedIps)) {
|
||||
return response()->json(['success' => true, 'message' => 'You are not allowed to access the API.'], 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -18,7 +18,8 @@ class Configuration extends Component
|
||||
|
||||
public bool $is_dns_validation_enabled;
|
||||
|
||||
// public bool $next_channel;
|
||||
public bool $is_api_enabled;
|
||||
|
||||
protected string $dynamic_config_path = '/data/coolify/proxy/dynamic';
|
||||
|
||||
protected Server $server;
|
||||
@ -30,6 +31,7 @@ class Configuration extends Component
|
||||
'settings.public_port_max' => 'required',
|
||||
'settings.custom_dns_servers' => 'nullable',
|
||||
'settings.instance_name' => 'nullable',
|
||||
'settings.allowed_ips' => 'nullable',
|
||||
];
|
||||
|
||||
protected $validationAttributes = [
|
||||
@ -38,6 +40,7 @@ class Configuration extends Component
|
||||
'settings.public_port_min' => 'Public port min',
|
||||
'settings.public_port_max' => 'Public port max',
|
||||
'settings.custom_dns_servers' => 'Custom DNS servers',
|
||||
'settings.allowed_ips' => 'Allowed IPs',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
@ -45,8 +48,8 @@ public function mount()
|
||||
$this->do_not_track = $this->settings->do_not_track;
|
||||
$this->is_auto_update_enabled = $this->settings->is_auto_update_enabled;
|
||||
$this->is_registration_enabled = $this->settings->is_registration_enabled;
|
||||
// $this->next_channel = $this->settings->next_channel;
|
||||
$this->is_dns_validation_enabled = $this->settings->is_dns_validation_enabled;
|
||||
$this->is_api_enabled = $this->settings->is_api_enabled;
|
||||
}
|
||||
|
||||
public function instantSave()
|
||||
@ -55,12 +58,7 @@ public function instantSave()
|
||||
$this->settings->is_auto_update_enabled = $this->is_auto_update_enabled;
|
||||
$this->settings->is_registration_enabled = $this->is_registration_enabled;
|
||||
$this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled;
|
||||
// if ($this->next_channel) {
|
||||
// $this->settings->next_channel = false;
|
||||
// $this->next_channel = false;
|
||||
// } else {
|
||||
// $this->settings->next_channel = $this->next_channel;
|
||||
// }
|
||||
$this->settings->is_api_enabled = $this->is_api_enabled;
|
||||
$this->settings->save();
|
||||
$this->dispatch('success', 'Settings updated!');
|
||||
}
|
||||
@ -94,6 +92,13 @@ public function submit()
|
||||
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->unique();
|
||||
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->implode(',');
|
||||
|
||||
$this->settings->allowed_ips = str($this->settings->allowed_ips)->replaceEnd(',', '')->trim();
|
||||
$this->settings->allowed_ips = str($this->settings->allowed_ips)->trim()->explode(',')->map(function ($ip) {
|
||||
return str($ip)->trim();
|
||||
});
|
||||
$this->settings->allowed_ips = $this->settings->allowed_ips->unique();
|
||||
$this->settings->allowed_ips = $this->settings->allowed_ips->implode(',');
|
||||
|
||||
$this->settings->save();
|
||||
$this->server->setupDynamicProxyConfiguration();
|
||||
if (! $error_show) {
|
||||
|
@ -17,6 +17,7 @@ class InstanceSettings extends Model implements SendsEmail
|
||||
protected $casts = [
|
||||
'resale_license' => 'encrypted',
|
||||
'smtp_password' => 'encrypted',
|
||||
'allowed_ip_ranges' => 'array',
|
||||
];
|
||||
|
||||
public function fqdn(): Attribute
|
||||
|
@ -13,6 +13,8 @@ class StandaloneClickhouse extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type'];
|
||||
|
||||
protected $casts = [
|
||||
'clickhouse_password' => 'encrypted',
|
||||
];
|
||||
@ -178,17 +180,44 @@ public function team()
|
||||
return data_get($this, 'environment.project.team');
|
||||
}
|
||||
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return 'standalone-clickhouse';
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false): string
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "clickhouse://{$this->clickhouse_user}:{$this->clickhouse_password}@{$this->uuid}:9000/{$this->clickhouse_db}",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "clickhouse://{$this->clickhouse_user}:{$this->clickhouse_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->clickhouse_db}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "clickhouse://{$this->clickhouse_user}:{$this->clickhouse_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->clickhouse_db}";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "clickhouse://{$this->clickhouse_user}:{$this->clickhouse_password}@{$this->uuid}:9000/{$this->clickhouse_db}";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ class StandaloneDragonfly extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type'];
|
||||
|
||||
protected $casts = [
|
||||
'dragonfly_password' => 'encrypted',
|
||||
];
|
||||
@ -178,17 +180,44 @@ public function portsMappingsArray(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return 'standalone-dragonfly';
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false): string
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "redis://:{$this->dragonfly_password}@{$this->uuid}:6379/0",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "redis://:{$this->dragonfly_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "redis://:{$this->dragonfly_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "redis://:{$this->dragonfly_password}@{$this->uuid}:6379/0";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ class StandaloneKeydb extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url'];
|
||||
|
||||
protected $casts = [
|
||||
'keydb_password' => 'encrypted',
|
||||
];
|
||||
@ -178,17 +180,44 @@ public function portsMappingsArray(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return 'standalone-keydb';
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false): string
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "redis://{$this->keydb_password}@{$this->uuid}:6379/0",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "redis://{$this->keydb_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "redis://{$this->keydb_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "redis://{$this->keydb_password}@{$this->uuid}:6379/0";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ class StandaloneMariadb extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type'];
|
||||
|
||||
protected $casts = [
|
||||
'mariadb_password' => 'encrypted',
|
||||
];
|
||||
@ -161,6 +163,13 @@ public function isLogDrainEnabled()
|
||||
return data_get($this, 'is_log_drain_enabled', false);
|
||||
}
|
||||
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return 'standalone-mariadb';
|
||||
@ -183,12 +192,32 @@ public function portsMappingsArray(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false): string
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "mysql://{$this->mariadb_user}:{$this->mariadb_password}@{$this->uuid}:3306/{$this->mariadb_database}",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "mysql://{$this->mariadb_user}:{$this->mariadb_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mariadb_database}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "mysql://{$this->mariadb_user}:{$this->mariadb_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mariadb_database}";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "mysql://{$this->mariadb_user}:{$this->mariadb_password}@{$this->uuid}:3306/{$this->mariadb_database}";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ class StandaloneMongodb extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type'];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($database) {
|
||||
@ -198,17 +200,44 @@ public function portsMappingsArray(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return 'standalone-mongodb';
|
||||
}
|
||||
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "mongodb://{$this->mongo_initdb_root_username}:{$this->mongo_initdb_root_password}@{$this->uuid}:27017/?directConnection=true",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "mongodb://{$this->mongo_initdb_root_username}:{$this->mongo_initdb_root_password}@{$this->destination->server->getIp}:{$this->public_port}/?directConnection=true";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "mongodb://{$this->mongo_initdb_root_username}:{$this->mongo_initdb_root_password}@{$this->destination->server->getIp}:{$this->public_port}/?directConnection=true";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "mongodb://{$this->mongo_initdb_root_username}:{$this->mongo_initdb_root_password}@{$this->uuid}:27017/?directConnection=true";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ class StandaloneMysql extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type'];
|
||||
|
||||
protected $casts = [
|
||||
'mysql_password' => 'encrypted',
|
||||
'mysql_root_password' => 'encrypted',
|
||||
@ -157,6 +159,13 @@ public function link()
|
||||
return null;
|
||||
}
|
||||
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return 'standalone-mysql';
|
||||
@ -184,12 +193,32 @@ public function portsMappingsArray(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false): string
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "mysql://{$this->mysql_user}:{$this->mysql_password}@{$this->uuid}:3306/{$this->mysql_database}",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "mysql://{$this->mysql_user}:{$this->mysql_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mysql_database}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "mysql://{$this->mysql_user}:{$this->mysql_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mysql_database}";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "mysql://{$this->mysql_user}:{$this->mysql_password}@{$this->uuid}:3306/{$this->mysql_database}";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ class StandalonePostgresql extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type'];
|
||||
|
||||
protected $casts = [
|
||||
'init_scripts' => 'array',
|
||||
'postgres_password' => 'encrypted',
|
||||
@ -179,17 +181,44 @@ public function team()
|
||||
return data_get($this, 'environment.project.team');
|
||||
}
|
||||
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return 'standalone-postgresql';
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false): string
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "postgres://{$this->postgres_user}:{$this->postgres_password}@{$this->uuid}:5432/{$this->postgres_db}",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "postgres://{$this->postgres_user}:{$this->postgres_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->postgres_db}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "postgres://{$this->postgres_user}:{$this->postgres_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->postgres_db}";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "postgres://{$this->postgres_user}:{$this->postgres_password}@{$this->uuid}:5432/{$this->postgres_db}";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ class StandaloneRedis extends BaseModel
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type'];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($database) {
|
||||
@ -179,12 +181,39 @@ public function type(): string
|
||||
return 'standalone-redis';
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false): string
|
||||
public function databaseType(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => $this->type(),
|
||||
);
|
||||
}
|
||||
|
||||
protected function internalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn () => "redis://:{$this->redis_password}@{$this->uuid}:6379/0",
|
||||
);
|
||||
}
|
||||
|
||||
protected function externalDbUrl(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
return "redis://:{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function get_db_url(bool $useInternal = false)
|
||||
{
|
||||
if ($this->is_public && ! $useInternal) {
|
||||
return "redis://:{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
||||
return $this->externalDbUrl;
|
||||
} else {
|
||||
return "redis://:{$this->redis_password}@{$this->uuid}:6379/0";
|
||||
return $this->internalDbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,25 +3,27 @@
|
||||
use App\Enums\BuildPackTypes;
|
||||
use App\Enums\RedirectTypes;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
function get_team_id_from_token()
|
||||
function getTeamIdFromToken()
|
||||
{
|
||||
$token = auth()->user()->currentAccessToken();
|
||||
|
||||
return data_get($token, 'team_id');
|
||||
}
|
||||
function invalid_token()
|
||||
function invalidTokenResponse()
|
||||
{
|
||||
return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api-reference/authorization'], 400);
|
||||
return response()->json(['success' => false, 'message' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api-reference/authorization'], 400);
|
||||
}
|
||||
|
||||
function serialize_api_response($data)
|
||||
function serializeApiResponse($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) {
|
||||
@ -33,6 +35,16 @@ function serialize_api_response($data)
|
||||
unset($data['updated_at']);
|
||||
$data['updated_at'] = $updated_at;
|
||||
}
|
||||
if (data_get($data, 'name')) {
|
||||
$data = $data->prepend($data['name'], 'name');
|
||||
}
|
||||
if (data_get($data, 'description')) {
|
||||
$data = $data->prepend($data['description'], 'description');
|
||||
}
|
||||
if (data_get($data, 'uuid')) {
|
||||
$data = $data->prepend($data['uuid'], 'uuid');
|
||||
}
|
||||
|
||||
if (data_get($data, 'id')) {
|
||||
$data = $data->prepend($data['id'], 'id');
|
||||
}
|
||||
@ -90,3 +102,36 @@ function sharedDataApplications()
|
||||
'manual_webhook_secret_gitea' => 'string|nullable',
|
||||
];
|
||||
}
|
||||
|
||||
function validateIncomingRequest(Request $request)
|
||||
{
|
||||
// check if request is json
|
||||
if (! $request->isJson()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Invalid request.',
|
||||
'error' => 'Content-Type must be application/json.',
|
||||
], 400);
|
||||
}
|
||||
// check if request is valid json
|
||||
if (! json_decode($request->getContent())) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Invalid request.',
|
||||
'error' => 'Invalid JSON.',
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
function removeUnnecessaryFieldsFromRequest(Request $request)
|
||||
{
|
||||
$request->offsetUnset('project_uuid');
|
||||
$request->offsetUnset('environment_name');
|
||||
$request->offsetUnset('destination_uuid');
|
||||
$request->offsetUnset('server_uuid');
|
||||
$request->offsetUnset('type');
|
||||
$request->offsetUnset('domains');
|
||||
$request->offsetUnset('instant_deploy');
|
||||
$request->offsetUnset('github_app_uuid');
|
||||
$request->offsetUnset('private_key_uuid');
|
||||
}
|
||||
|
@ -19,131 +19,163 @@ function generate_database_name(string $type): string
|
||||
return $type.'-database-'.$cuid;
|
||||
}
|
||||
|
||||
function create_standalone_postgresql($environment_id, $destination_uuid): StandalonePostgresql
|
||||
function create_standalone_postgresql($environmentId, $destinationUuid, ?array $otherData = null): StandalonePostgresql
|
||||
{
|
||||
// TODO: If another type of destination is added, this will need to be updated.
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
$destination = StandaloneDocker::where('uuid', $destinationUuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandalonePostgresql();
|
||||
$database->name = generate_database_name('postgresql');
|
||||
$database->postgres_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environmentId;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return StandalonePostgresql::create([
|
||||
'name' => generate_database_name('postgresql'),
|
||||
'postgres_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
return $database;
|
||||
}
|
||||
|
||||
function create_standalone_redis($environment_id, $destination_uuid): StandaloneRedis
|
||||
function create_standalone_redis($environment_id, $destination_uuid, ?array $otherData = null): StandaloneRedis
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandaloneRedis();
|
||||
$database->name = generate_database_name('redis');
|
||||
$database->redis_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return StandaloneRedis::create([
|
||||
'name' => generate_database_name('redis'),
|
||||
'redis_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
return $database;
|
||||
}
|
||||
|
||||
function create_standalone_mongodb($environment_id, $destination_uuid): StandaloneMongodb
|
||||
function create_standalone_mongodb($environment_id, $destination_uuid, ?array $otherData = null): StandaloneMongodb
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandaloneMongodb();
|
||||
$database->name = generate_database_name('mongodb');
|
||||
$database->mongo_initdb_root_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return StandaloneMongodb::create([
|
||||
'name' => generate_database_name('mongodb'),
|
||||
'mongo_initdb_root_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
return $database;
|
||||
}
|
||||
function create_standalone_mysql($environment_id, $destination_uuid): StandaloneMysql
|
||||
function create_standalone_mysql($environment_id, $destination_uuid, ?array $otherData = null): StandaloneMysql
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandaloneMysql();
|
||||
$database->name = generate_database_name('mysql');
|
||||
$database->mysql_root_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->mysql_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return StandaloneMysql::create([
|
||||
'name' => generate_database_name('mysql'),
|
||||
'mysql_root_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'mysql_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
return $database;
|
||||
}
|
||||
function create_standalone_mariadb($environment_id, $destination_uuid): StandaloneMariadb
|
||||
function create_standalone_mariadb($environment_id, $destination_uuid, ?array $otherData = null): StandaloneMariadb
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandaloneMariadb();
|
||||
$database->name = generate_database_name('mariadb');
|
||||
$database->mariadb_root_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->mariadb_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
|
||||
return StandaloneMariadb::create([
|
||||
'name' => generate_database_name('mariadb'),
|
||||
'mariadb_root_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'mariadb_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return $database;
|
||||
}
|
||||
function create_standalone_keydb($environment_id, $destination_uuid): StandaloneKeydb
|
||||
function create_standalone_keydb($environment_id, $destination_uuid, ?array $otherData = null): StandaloneKeydb
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandaloneKeydb();
|
||||
$database->name = generate_database_name('keydb');
|
||||
$database->keydb_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return StandaloneKeydb::create([
|
||||
'name' => generate_database_name('keydb'),
|
||||
'keydb_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
return $database;
|
||||
}
|
||||
|
||||
function create_standalone_dragonfly($environment_id, $destination_uuid): StandaloneDragonfly
|
||||
function create_standalone_dragonfly($environment_id, $destination_uuid, ?array $otherData = null): StandaloneDragonfly
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandaloneDragonfly();
|
||||
$database->name = generate_database_name('dragonfly');
|
||||
$database->dragonfly_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return StandaloneDragonfly::create([
|
||||
'name' => generate_database_name('dragonfly'),
|
||||
'dragonfly_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
return $database;
|
||||
}
|
||||
function create_standalone_clickhouse($environment_id, $destination_uuid): StandaloneClickhouse
|
||||
function create_standalone_clickhouse($environment_id, $destination_uuid, ?array $otherData = null): StandaloneClickhouse
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
$database = new StandaloneClickhouse();
|
||||
$database->name = generate_database_name('clickhouse');
|
||||
$database->clickhouse_admin_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
if ($otherData) {
|
||||
$database->fill($otherData);
|
||||
}
|
||||
$database->save();
|
||||
|
||||
return StandaloneClickhouse::create([
|
||||
'name' => generate_database_name('clickhouse'),
|
||||
'clickhouse_admin_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
'environment_id' => $environment_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
return $database;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -538,6 +538,43 @@ function getResourceByUuid(string $uuid, ?int $teamId = null)
|
||||
|
||||
return null;
|
||||
}
|
||||
function queryDatabaseByUuidWithinTeam(string $uuid, string $teamId)
|
||||
{
|
||||
$postgresql = StandalonePostgresql::whereUuid($uuid)->first();
|
||||
if ($postgresql && $postgresql->team()->id == $teamId) {
|
||||
return $postgresql->unsetRelation('environment')->unsetRelation('destination');
|
||||
}
|
||||
$redis = StandaloneRedis::whereUuid($uuid)->first();
|
||||
if ($redis && $redis->team()->id == $teamId) {
|
||||
return $redis->unsetRelation('environment');
|
||||
}
|
||||
$mongodb = StandaloneMongodb::whereUuid($uuid)->first();
|
||||
if ($mongodb && $mongodb->team()->id == $teamId) {
|
||||
return $mongodb->unsetRelation('environment');
|
||||
}
|
||||
$mysql = StandaloneMysql::whereUuid($uuid)->first();
|
||||
if ($mysql && $mysql->team()->id == $teamId) {
|
||||
return $mysql->unsetRelation('environment');
|
||||
}
|
||||
$mariadb = StandaloneMariadb::whereUuid($uuid)->first();
|
||||
if ($mariadb && $mariadb->team()->id == $teamId) {
|
||||
return $mariadb->unsetRelation('environment');
|
||||
}
|
||||
$keydb = StandaloneKeydb::whereUuid($uuid)->first();
|
||||
if ($keydb && $keydb->team()->id == $teamId) {
|
||||
return $keydb->unsetRelation('environment');
|
||||
}
|
||||
$dragonfly = StandaloneDragonfly::whereUuid($uuid)->first();
|
||||
if ($dragonfly && $dragonfly->team()->id == $teamId) {
|
||||
return $dragonfly->unsetRelation('environment');
|
||||
}
|
||||
$clickhouse = StandaloneClickhouse::whereUuid($uuid)->first();
|
||||
if ($clickhouse && $clickhouse->team()->id == $teamId) {
|
||||
return $clickhouse->unsetRelation('environment');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
function queryResourcesByUuid(string $uuid)
|
||||
{
|
||||
$resource = null;
|
||||
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->boolean('is_api_enabled')->default(true);
|
||||
$table->text('allowed_ips')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->dropColumn('is_api_enabled');
|
||||
$table->dropColumn('allowed_ips');
|
||||
});
|
||||
}
|
||||
};
|
@ -25,7 +25,16 @@
|
||||
<x-forms.input type="number" id="settings.public_port_max" label="Public Port Max" />
|
||||
</div> --}}
|
||||
</div>
|
||||
<h2 class="pt-6">API</h2>
|
||||
|
||||
<div class="md:w-96">
|
||||
<x-forms.checkbox instantSave id="is_api_enabled" label="Enabled" />
|
||||
</div>
|
||||
<x-forms.input id="settings.allowed_ips" label="Allowed IPs"
|
||||
helper="Allowed IP lists for the API. A comma separated list of IPs. Empty means you allow from everywhere."
|
||||
placeholder="1.1.1.1,8.8.8.8" />
|
||||
</form>
|
||||
|
||||
<h2 class="pt-6">Advanced</h2>
|
||||
<div class="text-right md:w-96">
|
||||
@if (!is_null(env('AUTOUPDATE', null)))
|
||||
@ -36,13 +45,5 @@
|
||||
@endif
|
||||
<x-forms.checkbox instantSave id="is_registration_enabled" label="Registration Allowed" />
|
||||
<x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" />
|
||||
{{-- @if ($next_channel)
|
||||
<x-forms.checkbox instantSave helper="Not recommended. Only if you like to live on the edge."
|
||||
id="next_channel" label="Enable pre-release (early) updates" />
|
||||
@else
|
||||
<x-forms.checkbox disabled instantSave
|
||||
helper="Currently disabled. Not recommended. Only if you like to live on the edge." id="next_channel"
|
||||
label="Enable pre-release (early) updates" />
|
||||
@endif --}}
|
||||
</div>
|
||||
</div>
|
||||
|
128
routes/api.php
128
routes/api.php
@ -1,11 +1,16 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Api\Applications;
|
||||
use App\Http\Controllers\Api\Deploy;
|
||||
use App\Http\Controllers\Api\EnvironmentVariables;
|
||||
use App\Http\Controllers\Api\Resources;
|
||||
use App\Http\Controllers\Api\Servers;
|
||||
use App\Http\Controllers\Api\Team;
|
||||
use App\Http\Controllers\Api\ApplicationsController;
|
||||
use App\Http\Controllers\Api\DatabasesController;
|
||||
use App\Http\Controllers\Api\DeployController;
|
||||
use App\Http\Controllers\Api\EnvironmentVariablesController;
|
||||
use App\Http\Controllers\Api\ProjectController;
|
||||
use App\Http\Controllers\Api\ResourcesController;
|
||||
use App\Http\Controllers\Api\SecurityController;
|
||||
use App\Http\Controllers\Api\ServersController;
|
||||
use App\Http\Controllers\Api\TeamController;
|
||||
use App\Http\Middleware\ApiAllowed;
|
||||
use App\Models\InstanceSettings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
@ -22,59 +27,106 @@
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Feedback sent.'], 200);
|
||||
return response()->json(['success' => true, 'message' => 'Feedback sent.'], 200);
|
||||
});
|
||||
|
||||
Route::group([
|
||||
'middleware' => ['auth:sanctum'],
|
||||
'prefix' => 'v1',
|
||||
], function () {
|
||||
Route::get('/enable', function () {
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
if ($teamId !== '0') {
|
||||
return response()->json(['success' => false, 'message' => 'You are not allowed to enable the API.'], 403);
|
||||
}
|
||||
$settings = InstanceSettings::get();
|
||||
$settings->update(['is_api_enabled' => true]);
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'API enabled.'], 200);
|
||||
});
|
||||
Route::get('/disable', function () {
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
if ($teamId !== '0') {
|
||||
return response()->json(['success' => false, 'message' => 'You are not allowed to disable the API.'], 403);
|
||||
}
|
||||
$settings = InstanceSettings::get();
|
||||
$settings->update(['is_api_enabled' => false]);
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'API disabled.'], 200);
|
||||
});
|
||||
|
||||
});
|
||||
Route::group([
|
||||
'middleware' => ['auth:sanctum', ApiAllowed::class],
|
||||
'prefix' => 'v1',
|
||||
], function () {
|
||||
Route::get('/version', function () {
|
||||
return response(config('version'));
|
||||
});
|
||||
Route::match(['get', 'post'], '/deploy', [Deploy::class, 'deploy']);
|
||||
Route::get('/deployments', [Deploy::class, 'deployments']);
|
||||
Route::get('/deployments/{uuid}', [Deploy::class, 'deployment_by_uuid']);
|
||||
|
||||
// Add environments endpoints
|
||||
Route::get('/servers', [Servers::class, 'servers']);
|
||||
Route::get('/servers/{uuid}', [Servers::class, 'server_by_uuid']);
|
||||
Route::get('/servers/domains', [Servers::class, 'get_domains_by_server']);
|
||||
Route::get('/teams', [TeamController::class, 'teams']);
|
||||
Route::get('/teams/current', [TeamController::class, 'current_team']);
|
||||
Route::get('/teams/current/members', [TeamController::class, 'current_team_members']);
|
||||
Route::get('/teams/{id}', [TeamController::class, 'team_by_id']);
|
||||
Route::get('/teams/{id}/members', [TeamController::class, 'members_by_id']);
|
||||
|
||||
Route::get('/resources', [Resources::class, 'resources']);
|
||||
Route::get('/projects', [ProjectController::class, 'projects']);
|
||||
Route::get('/projects/{uuid}', [ProjectController::class, 'project_by_uuid']);
|
||||
Route::get('/projects/{uuid}/{environment_name}', [ProjectController::class, 'environment_details']);
|
||||
|
||||
Route::get('/applications', [Applications::class, 'applications']);
|
||||
Route::post('/applications', [Applications::class, 'create_application']);
|
||||
Route::get('/security/keys', [SecurityController::class, 'keys']);
|
||||
Route::post('/security/keys', [SecurityController::class, 'create_key']);
|
||||
|
||||
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('/security/keys/{uuid}', [SecurityController::class, 'key_by_uuid']);
|
||||
Route::patch('/security/keys/{uuid}', [SecurityController::class, 'update_key']);
|
||||
Route::delete('/security/keys/{uuid}', [SecurityController::class, 'delete_key']);
|
||||
|
||||
Route::get('/applications/{uuid}/envs', [Applications::class, 'envs_by_uuid']);
|
||||
Route::post('/applications/{uuid}/envs', [Applications::class, 'create_env']);
|
||||
Route::post('/applications/{uuid}/envs/bulk', [Applications::class, 'create_bulk_envs']);
|
||||
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::match(['get', 'post'], '/deploy', [DeployController::class, 'deploy']);
|
||||
|
||||
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('/deployments', [DeployController::class, 'deployments']);
|
||||
Route::get('/deployments/{uuid}', [DeployController::class, 'deployment_by_uuid']);
|
||||
|
||||
Route::delete('/envs/{env_uuid}', [EnvironmentVariables::class, 'delete_env_by_uuid']);
|
||||
Route::get('/servers', [ServersController::class, 'servers']);
|
||||
Route::get('/servers/{uuid}', [ServersController::class, 'server_by_uuid']);
|
||||
Route::get('/servers/{uuid}/domains', [ServersController::class, 'get_domains_by_server']);
|
||||
|
||||
Route::get('/teams', [Team::class, 'teams']);
|
||||
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('/resources', [ResourcesController::class, 'resources']);
|
||||
|
||||
Route::get('/applications', [ApplicationsController::class, 'applications']);
|
||||
Route::post('/applications', [ApplicationsController::class, 'create_application']);
|
||||
|
||||
Route::get('/applications/{uuid}', [ApplicationsController::class, 'application_by_uuid']);
|
||||
Route::patch('/applications/{uuid}', [ApplicationsController::class, 'update_by_uuid']);
|
||||
Route::delete('/applications/{uuid}', [ApplicationsController::class, 'delete_by_uuid']);
|
||||
|
||||
Route::get('/applications/{uuid}/envs', [ApplicationsController::class, 'envs_by_uuid']);
|
||||
Route::post('/applications/{uuid}/envs', [ApplicationsController::class, 'create_env']);
|
||||
Route::post('/applications/{uuid}/envs/bulk', [ApplicationsController::class, 'create_bulk_envs']);
|
||||
Route::patch('/applications/{uuid}/envs', [ApplicationsController::class, 'update_env_by_uuid']);
|
||||
Route::delete('/applications/{uuid}/envs/{env_uuid}', [ApplicationsController::class, 'delete_env_by_uuid']);
|
||||
|
||||
Route::match(['get', 'post'], '/applications/{uuid}/action/deploy', [ApplicationsController::class, 'action_deploy']);
|
||||
Route::match(['get', 'post'], '/applications/{uuid}/action/restart', [ApplicationsController::class, 'action_restart']);
|
||||
Route::match(['get', 'post'], '/applications/{uuid}/action/stop', [ApplicationsController::class, 'action_stop']);
|
||||
|
||||
Route::get('/databases', [DatabasesController::class, 'databases']);
|
||||
Route::post('/databases', [DatabasesController::class, 'create_database']);
|
||||
Route::get('/databases/{uuid}', [DatabasesController::class, 'database_by_uuid']);
|
||||
// Route::patch('/databases/{uuid}', [DatabasesController::class, 'update_by_uuid']);
|
||||
Route::delete('/databases/{uuid}', [DatabasesController::class, 'delete_by_uuid']);
|
||||
|
||||
Route::delete('/envs/{env_uuid}', [EnvironmentVariablesController::class, 'delete_env_by_uuid']);
|
||||
|
||||
// Route::get('/projects', [Project::class, 'projects']);
|
||||
//Route::get('/project/{uuid}', [Project::class, 'project_by_uuid']);
|
||||
//Route::get('/project/{uuid}/{environment_name}', [Project::class, 'environment_details']);
|
||||
});
|
||||
|
||||
Route::any('/{any}', function () {
|
||||
return response()->json(['error' => 'Not found.'], 404);
|
||||
return response()->json(['success' => false, 'message' => 'Not found.', 'docs' => 'https://coolify.io/docs'], 404);
|
||||
})->where('any', '.*');
|
||||
|
||||
// Route::middleware(['throttle:5'])->group(function () {
|
||||
|
Loading…
Reference in New Issue
Block a user