Merge branch 'next' into dep-bump
This commit is contained in:
@@ -1,16 +1,12 @@
|
|||||||
# Coolify Configuration
|
|
||||||
APP_ID=
|
APP_ID=
|
||||||
APP_NAME=Coolify
|
APP_NAME=Coolify
|
||||||
APP_KEY=
|
APP_KEY=
|
||||||
|
|
||||||
# PostgreSQL Database Configuration
|
|
||||||
DB_USERNAME=coolify
|
DB_USERNAME=coolify
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=
|
||||||
|
|
||||||
# Redis Configuration
|
|
||||||
REDIS_PASSWORD=
|
REDIS_PASSWORD=
|
||||||
|
|
||||||
# Pusher Configuration
|
|
||||||
PUSHER_APP_ID=
|
PUSHER_APP_ID=
|
||||||
PUSHER_APP_KEY=
|
PUSHER_APP_KEY=
|
||||||
PUSHER_APP_SECRET=
|
PUSHER_APP_SECRET=
|
||||||
|
@@ -49,11 +49,7 @@ class StartClickhouse
|
|||||||
'hard' => 262144,
|
'hard' => 262144,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => "clickhouse-client --password {$this->database->clickhouse_admin_password} --query 'SELECT 1'",
|
'test' => "clickhouse-client --password {$this->database->clickhouse_admin_password} --query 'SELECT 1'",
|
||||||
'interval' => '5s',
|
'interval' => '5s',
|
||||||
|
@@ -46,11 +46,7 @@ class StartDragonfly
|
|||||||
'networks' => [
|
'networks' => [
|
||||||
$this->database->destination->network,
|
$this->database->destination->network,
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => "redis-cli -a {$this->database->dragonfly_password} ping",
|
'test' => "redis-cli -a {$this->database->dragonfly_password} ping",
|
||||||
'interval' => '5s',
|
'interval' => '5s',
|
||||||
|
@@ -48,11 +48,7 @@ class StartKeydb
|
|||||||
'networks' => [
|
'networks' => [
|
||||||
$this->database->destination->network,
|
$this->database->destination->network,
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => "keydb-cli --pass {$this->database->keydb_password} ping",
|
'test' => "keydb-cli --pass {$this->database->keydb_password} ping",
|
||||||
'interval' => '5s',
|
'interval' => '5s',
|
||||||
|
@@ -43,11 +43,7 @@ class StartMariadb
|
|||||||
'networks' => [
|
'networks' => [
|
||||||
$this->database->destination->network,
|
$this->database->destination->network,
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => ['CMD', 'healthcheck.sh', '--connect', '--innodb_initialized'],
|
'test' => ['CMD', 'healthcheck.sh', '--connect', '--innodb_initialized'],
|
||||||
'interval' => '5s',
|
'interval' => '5s',
|
||||||
|
@@ -51,11 +51,7 @@ class StartMongodb
|
|||||||
'networks' => [
|
'networks' => [
|
||||||
$this->database->destination->network,
|
$this->database->destination->network,
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => [
|
'test' => [
|
||||||
'CMD',
|
'CMD',
|
||||||
|
@@ -43,11 +43,7 @@ class StartMysql
|
|||||||
'networks' => [
|
'networks' => [
|
||||||
$this->database->destination->network,
|
$this->database->destination->network,
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => ['CMD', 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', "-p{$this->database->mysql_root_password}"],
|
'test' => ['CMD', 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', "-p{$this->database->mysql_root_password}"],
|
||||||
'interval' => '5s',
|
'interval' => '5s',
|
||||||
|
@@ -23,6 +23,9 @@ class StartPostgresql
|
|||||||
$this->database = $database;
|
$this->database = $database;
|
||||||
$container_name = $this->database->uuid;
|
$container_name = $this->database->uuid;
|
||||||
$this->configuration_dir = database_configuration_dir().'/'.$container_name;
|
$this->configuration_dir = database_configuration_dir().'/'.$container_name;
|
||||||
|
if (isDev()) {
|
||||||
|
$this->configuration_dir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/databases/'.$container_name;
|
||||||
|
}
|
||||||
|
|
||||||
$this->commands = [
|
$this->commands = [
|
||||||
"echo 'Starting database.'",
|
"echo 'Starting database.'",
|
||||||
@@ -47,11 +50,7 @@ class StartPostgresql
|
|||||||
'networks' => [
|
'networks' => [
|
||||||
$this->database->destination->network,
|
$this->database->destination->network,
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => [
|
'test' => [
|
||||||
'CMD-SHELL',
|
'CMD-SHELL',
|
||||||
@@ -78,7 +77,7 @@ class StartPostgresql
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
if (! is_null($this->database->limits_cpuset)) {
|
if (filled($this->database->limits_cpuset)) {
|
||||||
data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset);
|
data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset);
|
||||||
}
|
}
|
||||||
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
|
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
|
||||||
@@ -108,7 +107,7 @@ class StartPostgresql
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! is_null($this->database->postgres_conf) && ! empty($this->database->postgres_conf)) {
|
if (filled($this->database->postgres_conf)) {
|
||||||
$docker_compose['services'][$container_name]['volumes'][] = [
|
$docker_compose['services'][$container_name]['volumes'][] = [
|
||||||
'type' => 'bind',
|
'type' => 'bind',
|
||||||
'source' => $this->configuration_dir.'/custom-postgres.conf',
|
'source' => $this->configuration_dir.'/custom-postgres.conf',
|
||||||
@@ -199,9 +198,12 @@ class StartPostgresql
|
|||||||
|
|
||||||
private function generate_init_scripts()
|
private function generate_init_scripts()
|
||||||
{
|
{
|
||||||
if (is_null($this->database->init_scripts) || count($this->database->init_scripts) === 0) {
|
$this->commands[] = "rm -rf $this->configuration_dir/docker-entrypoint-initdb.d/*";
|
||||||
|
|
||||||
|
if (blank($this->database->init_scripts) || count($this->database->init_scripts) === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->database->init_scripts as $init_script) {
|
foreach ($this->database->init_scripts as $init_script) {
|
||||||
$filename = data_get($init_script, 'filename');
|
$filename = data_get($init_script, 'filename');
|
||||||
$content = data_get($init_script, 'content');
|
$content = data_get($init_script, 'content');
|
||||||
@@ -213,10 +215,15 @@ class StartPostgresql
|
|||||||
|
|
||||||
private function add_custom_conf()
|
private function add_custom_conf()
|
||||||
{
|
{
|
||||||
if (is_null($this->database->postgres_conf) || empty($this->database->postgres_conf)) {
|
$filename = 'custom-postgres.conf';
|
||||||
|
$config_file_path = "$this->configuration_dir/$filename";
|
||||||
|
|
||||||
|
if (blank($this->database->postgres_conf)) {
|
||||||
|
$this->commands[] = "rm -f $config_file_path";
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$filename = 'custom-postgres.conf';
|
|
||||||
$content = $this->database->postgres_conf;
|
$content = $this->database->postgres_conf;
|
||||||
if (! str($content)->contains('listen_addresses')) {
|
if (! str($content)->contains('listen_addresses')) {
|
||||||
$content .= "\nlisten_addresses = '*'";
|
$content .= "\nlisten_addresses = '*'";
|
||||||
@@ -224,6 +231,6 @@ class StartPostgresql
|
|||||||
$this->database->save();
|
$this->database->save();
|
||||||
}
|
}
|
||||||
$content_base64 = base64_encode($content);
|
$content_base64 = base64_encode($content);
|
||||||
$this->commands[] = "echo '{$content_base64}' | base64 -d | tee $this->configuration_dir/{$filename} > /dev/null";
|
$this->commands[] = "echo '{$content_base64}' | base64 -d | tee $config_file_path > /dev/null";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -48,11 +48,7 @@ class StartRedis
|
|||||||
'networks' => [
|
'networks' => [
|
||||||
$this->database->destination->network,
|
$this->database->destination->network,
|
||||||
],
|
],
|
||||||
'labels' => [
|
'labels' => defaultDatabaseLabels($this->database)->toArray(),
|
||||||
'coolify.managed' => 'true',
|
|
||||||
'coolify.type' => 'database',
|
|
||||||
'coolify.databaseId' => $this->database->id,
|
|
||||||
],
|
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => [
|
'test' => [
|
||||||
'CMD-SHELL',
|
'CMD-SHELL',
|
||||||
|
@@ -112,7 +112,7 @@ class GetContainersStatus
|
|||||||
$preview->update(['last_online_at' => now()]);
|
$preview->update(['last_online_at' => now()]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Notify user that this container should not be there.
|
// Notify user that this container should not be there.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$application = $this->applications->where('id', $applicationId)->first();
|
$application = $this->applications->where('id', $applicationId)->first();
|
||||||
@@ -125,7 +125,7 @@ class GetContainersStatus
|
|||||||
$application->update(['last_online_at' => now()]);
|
$application->update(['last_online_at' => now()]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Notify user that this container should not be there.
|
// Notify user that this container should not be there.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -183,7 +183,7 @@ class Emails extends Command
|
|||||||
'team_id' => 0,
|
'team_id' => 0,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
//$this->mail = (new BackupSuccess($backup->frequency, $db->name))->toMail();
|
// $this->mail = (new BackupSuccess($backup->frequency, $db->name))->toMail();
|
||||||
$this->sendEmail();
|
$this->sendEmail();
|
||||||
break;
|
break;
|
||||||
// case 'invitation-link':
|
// case 'invitation-link':
|
||||||
|
@@ -133,14 +133,14 @@ class Kernel extends ConsoleKernel
|
|||||||
|
|
||||||
foreach ($servers as $server) {
|
foreach ($servers as $server) {
|
||||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||||
|
if (validate_timezone($serverTimezone) === false) {
|
||||||
|
$serverTimezone = config('app.timezone');
|
||||||
|
}
|
||||||
|
|
||||||
// Sentinel check
|
// Sentinel check
|
||||||
$lastSentinelUpdate = $server->sentinel_updated_at;
|
$lastSentinelUpdate = $server->sentinel_updated_at;
|
||||||
if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) {
|
if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) {
|
||||||
// Check container status every minute if Sentinel does not activated
|
// Check container status every minute if Sentinel does not activated
|
||||||
if (validate_timezone($serverTimezone) === false) {
|
|
||||||
$serverTimezone = config('app.timezone');
|
|
||||||
}
|
|
||||||
if (isCloud()) {
|
if (isCloud()) {
|
||||||
$this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyFiveMinutes()->onOneServer();
|
$this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyFiveMinutes()->onOneServer();
|
||||||
} else {
|
} else {
|
||||||
@@ -148,15 +148,11 @@ class Kernel extends ConsoleKernel
|
|||||||
}
|
}
|
||||||
// $this->scheduleInstance->job(new \App\Jobs\ServerCheckNewJob($server))->everyFiveMinutes()->onOneServer();
|
// $this->scheduleInstance->job(new \App\Jobs\ServerCheckNewJob($server))->everyFiveMinutes()->onOneServer();
|
||||||
|
|
||||||
// Check storage usage every 10 minutes if Sentinel does not activated
|
$this->scheduleInstance->job(new ServerStorageCheckJob($server))->cron($server->settings->server_disk_usage_check_frequency)->timezone($serverTimezone)->onOneServer();
|
||||||
$this->scheduleInstance->job(new ServerStorageCheckJob($server))->everyTenMinutes()->onOneServer();
|
|
||||||
}
|
|
||||||
if ($server->settings->force_docker_cleanup) {
|
|
||||||
$this->scheduleInstance->job(new DockerCleanupJob($server))->cron($server->settings->docker_cleanup_frequency)->timezone($serverTimezone)->onOneServer();
|
|
||||||
} else {
|
|
||||||
$this->scheduleInstance->job(new DockerCleanupJob($server))->everyTenMinutes()->timezone($serverTimezone)->onOneServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->scheduleInstance->job(new DockerCleanupJob($server))->cron($server->settings->docker_cleanup_frequency)->timezone($serverTimezone)->onOneServer();
|
||||||
|
|
||||||
// Cleanup multiplexed connections every hour
|
// Cleanup multiplexed connections every hour
|
||||||
// $this->scheduleInstance->job(new ServerCleanupMux($server))->hourly()->onOneServer();
|
// $this->scheduleInstance->job(new ServerCleanupMux($server))->hourly()->onOneServer();
|
||||||
|
|
||||||
@@ -187,13 +183,13 @@ class Kernel extends ConsoleKernel
|
|||||||
if (is_null($server)) {
|
if (is_null($server)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) {
|
if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) {
|
||||||
$scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency];
|
$scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency];
|
||||||
}
|
}
|
||||||
|
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||||
$this->scheduleInstance->job(new DatabaseBackupJob(
|
$this->scheduleInstance->job(new DatabaseBackupJob(
|
||||||
backup: $scheduled_backup
|
backup: $scheduled_backup
|
||||||
))->cron($scheduled_backup->frequency)->timezone($this->instanceTimezone)->onOneServer();
|
))->cron($scheduled_backup->frequency)->timezone($serverTimezone)->onOneServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,9 +227,10 @@ class Kernel extends ConsoleKernel
|
|||||||
if (isset(VALID_CRON_STRINGS[$scheduled_task->frequency])) {
|
if (isset(VALID_CRON_STRINGS[$scheduled_task->frequency])) {
|
||||||
$scheduled_task->frequency = VALID_CRON_STRINGS[$scheduled_task->frequency];
|
$scheduled_task->frequency = VALID_CRON_STRINGS[$scheduled_task->frequency];
|
||||||
}
|
}
|
||||||
|
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||||
$this->scheduleInstance->job(new ScheduledTaskJob(
|
$this->scheduleInstance->job(new ScheduledTaskJob(
|
||||||
task: $scheduled_task
|
task: $scheduled_task
|
||||||
))->cron($scheduled_task->frequency)->timezone($this->instanceTimezone)->onOneServer();
|
))->cron($scheduled_task->frequency)->timezone($serverTimezone)->onOneServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
app/Events/RestoreJobFinished.php
Normal file
34
app/Events/RestoreJobFinished.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Events;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class RestoreJobFinished
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
|
||||||
|
public function __construct($data)
|
||||||
|
{
|
||||||
|
$scriptPath = data_get($data, 'scriptPath');
|
||||||
|
$tmpPath = data_get($data, 'tmpPath');
|
||||||
|
$container = data_get($data, 'container');
|
||||||
|
$serverId = data_get($data, 'serverId');
|
||||||
|
if (filled($scriptPath) && filled($tmpPath) && filled($container) && filled($serverId)) {
|
||||||
|
if (str($tmpPath)->startsWith('/tmp/')
|
||||||
|
&& str($scriptPath)->startsWith('/tmp/')
|
||||||
|
&& ! str($tmpPath)->contains('..')
|
||||||
|
&& ! str($scriptPath)->contains('..')
|
||||||
|
&& strlen($tmpPath) > 5 // longer than just "/tmp/"
|
||||||
|
&& strlen($scriptPath) > 5
|
||||||
|
) {
|
||||||
|
$commands[] = "docker exec {$container} sh -c 'rm {$scriptPath}'";
|
||||||
|
$commands[] = "docker exec {$container} sh -c 'rm {$tmpPath}'";
|
||||||
|
instant_remote_process($commands, Server::find($serverId), throwError: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -27,6 +27,9 @@ class ApplicationsController extends Controller
|
|||||||
{
|
{
|
||||||
$application->makeHidden([
|
$application->makeHidden([
|
||||||
'id',
|
'id',
|
||||||
|
'resourceable',
|
||||||
|
'resourceable_id',
|
||||||
|
'resourceable_type',
|
||||||
]);
|
]);
|
||||||
if (request()->attributes->get('can_read_sensitive', false) === false) {
|
if (request()->attributes->get('can_read_sensitive', false) === false) {
|
||||||
$application->makeHidden([
|
$application->makeHidden([
|
||||||
@@ -114,11 +117,12 @@ class ApplicationsController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
||||||
properties: [
|
properties: [
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'The environment name.'],
|
'environment_name' => ['type' => 'string', 'description' => 'The environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'The environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'git_repository' => ['type' => 'string', 'description' => 'The git repository URL.'],
|
'git_repository' => ['type' => 'string', 'description' => 'The git repository URL.'],
|
||||||
'git_branch' => ['type' => 'string', 'description' => 'The git branch.'],
|
'git_branch' => ['type' => 'string', 'description' => 'The git branch.'],
|
||||||
'build_pack' => ['type' => 'string', 'enum' => ['nixpacks', 'static', 'dockerfile', 'dockercompose'], 'description' => 'The build pack type.'],
|
'build_pack' => ['type' => 'string', 'enum' => ['nixpacks', 'static', 'dockerfile', 'dockercompose'], 'description' => 'The build pack type.'],
|
||||||
@@ -185,8 +189,17 @@ class ApplicationsController extends Controller
|
|||||||
),
|
),
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 200,
|
response: 201,
|
||||||
description: 'Application created successfully.',
|
description: 'Application created successfully.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'uuid' => ['type' => 'string'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 401,
|
response: 401,
|
||||||
@@ -220,11 +233,12 @@ class ApplicationsController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'github_app_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'github_app_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
||||||
properties: [
|
properties: [
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'The environment name.'],
|
'environment_name' => ['type' => 'string', 'description' => 'The environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'The environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'github_app_uuid' => ['type' => 'string', 'description' => 'The Github App UUID.'],
|
'github_app_uuid' => ['type' => 'string', 'description' => 'The Github App UUID.'],
|
||||||
'git_repository' => ['type' => 'string', 'description' => 'The git repository URL.'],
|
'git_repository' => ['type' => 'string', 'description' => 'The git repository URL.'],
|
||||||
'git_branch' => ['type' => 'string', 'description' => 'The git branch.'],
|
'git_branch' => ['type' => 'string', 'description' => 'The git branch.'],
|
||||||
@@ -291,8 +305,17 @@ class ApplicationsController extends Controller
|
|||||||
),
|
),
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 200,
|
response: 201,
|
||||||
description: 'Application created successfully.',
|
description: 'Application created successfully.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'uuid' => ['type' => 'string'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 401,
|
response: 401,
|
||||||
@@ -326,11 +349,12 @@ class ApplicationsController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'private_key_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'private_key_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
||||||
properties: [
|
properties: [
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'The environment name.'],
|
'environment_name' => ['type' => 'string', 'description' => 'The environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'The environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'private_key_uuid' => ['type' => 'string', 'description' => 'The private key UUID.'],
|
'private_key_uuid' => ['type' => 'string', 'description' => 'The private key UUID.'],
|
||||||
'git_repository' => ['type' => 'string', 'description' => 'The git repository URL.'],
|
'git_repository' => ['type' => 'string', 'description' => 'The git repository URL.'],
|
||||||
'git_branch' => ['type' => 'string', 'description' => 'The git branch.'],
|
'git_branch' => ['type' => 'string', 'description' => 'The git branch.'],
|
||||||
@@ -397,8 +421,17 @@ class ApplicationsController extends Controller
|
|||||||
),
|
),
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 200,
|
response: 201,
|
||||||
description: 'Application created successfully.',
|
description: 'Application created successfully.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'uuid' => ['type' => 'string'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 401,
|
response: 401,
|
||||||
@@ -432,11 +465,12 @@ class ApplicationsController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'dockerfile'],
|
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'dockerfile'],
|
||||||
properties: [
|
properties: [
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'The environment name.'],
|
'environment_name' => ['type' => 'string', 'description' => 'The environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'The environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'],
|
'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'],
|
||||||
'build_pack' => ['type' => 'string', 'enum' => ['nixpacks', 'static', 'dockerfile', 'dockercompose'], 'description' => 'The build pack type.'],
|
'build_pack' => ['type' => 'string', 'enum' => ['nixpacks', 'static', 'dockerfile', 'dockercompose'], 'description' => 'The build pack type.'],
|
||||||
'ports_exposes' => ['type' => 'string', 'description' => 'The ports to expose.'],
|
'ports_exposes' => ['type' => 'string', 'description' => 'The ports to expose.'],
|
||||||
@@ -487,8 +521,17 @@ class ApplicationsController extends Controller
|
|||||||
),
|
),
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 200,
|
response: 201,
|
||||||
description: 'Application created successfully.',
|
description: 'Application created successfully.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'uuid' => ['type' => 'string'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 401,
|
response: 401,
|
||||||
@@ -522,11 +565,12 @@ class ApplicationsController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'docker_registry_image_name', 'ports_exposes'],
|
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'docker_registry_image_name', 'ports_exposes'],
|
||||||
properties: [
|
properties: [
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'The environment name.'],
|
'environment_name' => ['type' => 'string', 'description' => 'The environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'The environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
||||||
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
||||||
'ports_exposes' => ['type' => 'string', 'description' => 'The ports to expose.'],
|
'ports_exposes' => ['type' => 'string', 'description' => 'The ports to expose.'],
|
||||||
@@ -574,8 +618,17 @@ class ApplicationsController extends Controller
|
|||||||
),
|
),
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 200,
|
response: 201,
|
||||||
description: 'Application created successfully.',
|
description: 'Application created successfully.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'uuid' => ['type' => 'string'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 401,
|
response: 401,
|
||||||
@@ -609,11 +662,12 @@ class ApplicationsController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'docker_compose_raw'],
|
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'docker_compose_raw'],
|
||||||
properties: [
|
properties: [
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'The environment name.'],
|
'environment_name' => ['type' => 'string', 'description' => 'The environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'The environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'],
|
'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'The destination UUID if the server has more than one destinations.'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'The destination UUID if the server has more than one destinations.'],
|
||||||
'name' => ['type' => 'string', 'description' => 'The application name.'],
|
'name' => ['type' => 'string', 'description' => 'The application name.'],
|
||||||
@@ -627,8 +681,17 @@ class ApplicationsController extends Controller
|
|||||||
),
|
),
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 200,
|
response: 201,
|
||||||
description: 'Application created successfully.',
|
description: 'Application created successfully.',
|
||||||
|
content: new OA\MediaType(
|
||||||
|
mediaType: 'application/json',
|
||||||
|
schema: new OA\Schema(
|
||||||
|
type: 'object',
|
||||||
|
properties: [
|
||||||
|
'uuid' => ['type' => 'string'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
response: 401,
|
response: 401,
|
||||||
@@ -647,7 +710,7 @@ class ApplicationsController extends Controller
|
|||||||
|
|
||||||
private function create_application(Request $request, $type)
|
private function create_application(Request $request, $type)
|
||||||
{
|
{
|
||||||
$allowedFields = ['project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', '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', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration'];
|
$allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', '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', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration'];
|
||||||
$teamId = getTeamIdFromToken();
|
$teamId = getTeamIdFromToken();
|
||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
return invalidTokenResponse();
|
return invalidTokenResponse();
|
||||||
@@ -661,7 +724,8 @@ class ApplicationsController extends Controller
|
|||||||
'name' => 'string|max:255',
|
'name' => 'string|max:255',
|
||||||
'description' => 'string|nullable',
|
'description' => 'string|nullable',
|
||||||
'project_uuid' => 'string|required',
|
'project_uuid' => 'string|required',
|
||||||
'environment_name' => 'string|required',
|
'environment_name' => 'string|nullable',
|
||||||
|
'environment_uuid' => 'string|nullable',
|
||||||
'server_uuid' => 'string|required',
|
'server_uuid' => 'string|required',
|
||||||
'destination_uuid' => 'string',
|
'destination_uuid' => 'string',
|
||||||
]);
|
]);
|
||||||
@@ -681,6 +745,11 @@ class ApplicationsController extends Controller
|
|||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$environmentUuid = $request->environment_uuid;
|
||||||
|
$environmentName = $request->environment_name;
|
||||||
|
if (blank($environmentUuid) && blank($environmentName)) {
|
||||||
|
return response()->json(['message' => 'You need to provide at least one of environment_name or environment_uuid.'], 422);
|
||||||
|
}
|
||||||
$serverUuid = $request->server_uuid;
|
$serverUuid = $request->server_uuid;
|
||||||
$fqdn = $request->domains;
|
$fqdn = $request->domains;
|
||||||
$instantDeploy = $request->instant_deploy;
|
$instantDeploy = $request->instant_deploy;
|
||||||
@@ -713,7 +782,10 @@ class ApplicationsController extends Controller
|
|||||||
if (! $project) {
|
if (! $project) {
|
||||||
return response()->json(['message' => 'Project not found.'], 404);
|
return response()->json(['message' => 'Project not found.'], 404);
|
||||||
}
|
}
|
||||||
$environment = $project->environments()->where('name', $request->environment_name)->first();
|
$environment = $project->environments()->where('name', $environmentName)->first();
|
||||||
|
if (! $environment) {
|
||||||
|
$environment = $project->environments()->where('uuid', $environmentUuid)->first();
|
||||||
|
}
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return response()->json(['message' => 'Environment not found.'], 404);
|
return response()->json(['message' => 'Environment not found.'], 404);
|
||||||
}
|
}
|
||||||
@@ -730,12 +802,6 @@ class ApplicationsController extends Controller
|
|||||||
}
|
}
|
||||||
$destination = $destinations->first();
|
$destination = $destinations->first();
|
||||||
if ($type === 'public') {
|
if ($type === 'public') {
|
||||||
if (! $request->has('name')) {
|
|
||||||
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
|
||||||
}
|
|
||||||
if ($request->build_pack === 'dockercompose') {
|
|
||||||
$request->offsetSet('ports_exposes', '80');
|
|
||||||
}
|
|
||||||
$validationRules = [
|
$validationRules = [
|
||||||
'git_repository' => 'string|required',
|
'git_repository' => 'string|required',
|
||||||
'git_branch' => 'string|required',
|
'git_branch' => 'string|required',
|
||||||
@@ -745,7 +811,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_compose_raw' => 'string|nullable',
|
'docker_compose_raw' => 'string|nullable',
|
||||||
'docker_compose_domains' => 'array|nullable',
|
'docker_compose_domains' => 'array|nullable',
|
||||||
];
|
];
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -753,6 +819,12 @@ class ApplicationsController extends Controller
|
|||||||
'errors' => $validator->errors(),
|
'errors' => $validator->errors(),
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
if (! $request->has('name')) {
|
||||||
|
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
||||||
|
}
|
||||||
|
if ($request->build_pack === 'dockercompose') {
|
||||||
|
$request->offsetSet('ports_exposes', '80');
|
||||||
|
}
|
||||||
|
|
||||||
$return = $this->validateDataApplications($request, $server);
|
$return = $this->validateDataApplications($request, $server);
|
||||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
@@ -815,14 +887,8 @@ class ApplicationsController extends Controller
|
|||||||
return response()->json(serializeApiResponse([
|
return response()->json(serializeApiResponse([
|
||||||
'uuid' => data_get($application, 'uuid'),
|
'uuid' => data_get($application, 'uuid'),
|
||||||
'domains' => data_get($application, 'domains'),
|
'domains' => data_get($application, 'domains'),
|
||||||
]));
|
]))->setStatusCode(201);
|
||||||
} elseif ($type === 'private-gh-app') {
|
} elseif ($type === 'private-gh-app') {
|
||||||
if (! $request->has('name')) {
|
|
||||||
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
|
||||||
}
|
|
||||||
if ($request->build_pack === 'dockercompose') {
|
|
||||||
$request->offsetSet('ports_exposes', '80');
|
|
||||||
}
|
|
||||||
$validationRules = [
|
$validationRules = [
|
||||||
'git_repository' => 'string|required',
|
'git_repository' => 'string|required',
|
||||||
'git_branch' => 'string|required',
|
'git_branch' => 'string|required',
|
||||||
@@ -833,7 +899,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_compose_location' => 'string',
|
'docker_compose_location' => 'string',
|
||||||
'docker_compose_raw' => 'string|nullable',
|
'docker_compose_raw' => 'string|nullable',
|
||||||
];
|
];
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||||
|
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
@@ -842,6 +908,14 @@ class ApplicationsController extends Controller
|
|||||||
'errors' => $validator->errors(),
|
'errors' => $validator->errors(),
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! $request->has('name')) {
|
||||||
|
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
||||||
|
}
|
||||||
|
if ($request->build_pack === 'dockercompose') {
|
||||||
|
$request->offsetSet('ports_exposes', '80');
|
||||||
|
}
|
||||||
|
|
||||||
$return = $this->validateDataApplications($request, $server);
|
$return = $this->validateDataApplications($request, $server);
|
||||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
return $return;
|
return $return;
|
||||||
@@ -884,12 +958,12 @@ class ApplicationsController extends Controller
|
|||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
$application->source_type = $githubApp->getMorphClass();
|
$application->source_type = $githubApp->getMorphClass();
|
||||||
$application->source_id = $githubApp->id;
|
$application->source_id = $githubApp->id;
|
||||||
|
$application->save();
|
||||||
|
$application->refresh();
|
||||||
if (isset($useBuildServer)) {
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
}
|
}
|
||||||
$application->save();
|
|
||||||
$application->refresh();
|
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
||||||
$application->save();
|
$application->save();
|
||||||
@@ -914,14 +988,8 @@ class ApplicationsController extends Controller
|
|||||||
return response()->json(serializeApiResponse([
|
return response()->json(serializeApiResponse([
|
||||||
'uuid' => data_get($application, 'uuid'),
|
'uuid' => data_get($application, 'uuid'),
|
||||||
'domains' => data_get($application, 'domains'),
|
'domains' => data_get($application, 'domains'),
|
||||||
]));
|
]))->setStatusCode(201);
|
||||||
} elseif ($type === 'private-deploy-key') {
|
} elseif ($type === 'private-deploy-key') {
|
||||||
if (! $request->has('name')) {
|
|
||||||
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
|
||||||
}
|
|
||||||
if ($request->build_pack === 'dockercompose') {
|
|
||||||
$request->offsetSet('ports_exposes', '80');
|
|
||||||
}
|
|
||||||
|
|
||||||
$validationRules = [
|
$validationRules = [
|
||||||
'git_repository' => 'string|required',
|
'git_repository' => 'string|required',
|
||||||
@@ -934,7 +1002,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_compose_raw' => 'string|nullable',
|
'docker_compose_raw' => 'string|nullable',
|
||||||
];
|
];
|
||||||
|
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
@@ -943,6 +1011,13 @@ class ApplicationsController extends Controller
|
|||||||
'errors' => $validator->errors(),
|
'errors' => $validator->errors(),
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
if (! $request->has('name')) {
|
||||||
|
$request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch));
|
||||||
|
}
|
||||||
|
if ($request->build_pack === 'dockercompose') {
|
||||||
|
$request->offsetSet('ports_exposes', '80');
|
||||||
|
}
|
||||||
|
|
||||||
$return = $this->validateDataApplications($request, $server);
|
$return = $this->validateDataApplications($request, $server);
|
||||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
return $return;
|
return $return;
|
||||||
@@ -980,12 +1055,12 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
|
$application->save();
|
||||||
|
$application->refresh();
|
||||||
if (isset($useBuildServer)) {
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
}
|
}
|
||||||
$application->save();
|
|
||||||
$application->refresh();
|
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
||||||
$application->save();
|
$application->save();
|
||||||
@@ -1010,16 +1085,12 @@ class ApplicationsController extends Controller
|
|||||||
return response()->json(serializeApiResponse([
|
return response()->json(serializeApiResponse([
|
||||||
'uuid' => data_get($application, 'uuid'),
|
'uuid' => data_get($application, 'uuid'),
|
||||||
'domains' => data_get($application, 'domains'),
|
'domains' => data_get($application, 'domains'),
|
||||||
]));
|
]))->setStatusCode(201);
|
||||||
} elseif ($type === 'dockerfile') {
|
} elseif ($type === 'dockerfile') {
|
||||||
if (! $request->has('name')) {
|
|
||||||
$request->offsetSet('name', 'dockerfile-'.new Cuid2);
|
|
||||||
}
|
|
||||||
|
|
||||||
$validationRules = [
|
$validationRules = [
|
||||||
'dockerfile' => 'string|required',
|
'dockerfile' => 'string|required',
|
||||||
];
|
];
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
@@ -1028,6 +1099,10 @@ class ApplicationsController extends Controller
|
|||||||
'errors' => $validator->errors(),
|
'errors' => $validator->errors(),
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
if (! $request->has('name')) {
|
||||||
|
$request->offsetSet('name', 'dockerfile-'.new Cuid2);
|
||||||
|
}
|
||||||
|
|
||||||
$return = $this->validateDataApplications($request, $server);
|
$return = $this->validateDataApplications($request, $server);
|
||||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
return $return;
|
return $return;
|
||||||
@@ -1066,15 +1141,15 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
if (isset($useBuildServer)) {
|
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
|
||||||
$application->settings->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
$application->git_repository = 'coollabsio/coolify';
|
$application->git_repository = 'coollabsio/coolify';
|
||||||
$application->git_branch = 'main';
|
$application->git_branch = 'main';
|
||||||
$application->save();
|
$application->save();
|
||||||
$application->refresh();
|
$application->refresh();
|
||||||
|
if (isset($useBuildServer)) {
|
||||||
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
|
$application->settings->save();
|
||||||
|
}
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
||||||
$application->save();
|
$application->save();
|
||||||
@@ -1095,17 +1170,14 @@ class ApplicationsController extends Controller
|
|||||||
return response()->json(serializeApiResponse([
|
return response()->json(serializeApiResponse([
|
||||||
'uuid' => data_get($application, 'uuid'),
|
'uuid' => data_get($application, 'uuid'),
|
||||||
'domains' => data_get($application, 'domains'),
|
'domains' => data_get($application, 'domains'),
|
||||||
]));
|
]))->setStatusCode(201);
|
||||||
} elseif ($type === 'dockerimage') {
|
} elseif ($type === 'dockerimage') {
|
||||||
if (! $request->has('name')) {
|
|
||||||
$request->offsetSet('name', 'docker-image-'.new Cuid2);
|
|
||||||
}
|
|
||||||
$validationRules = [
|
$validationRules = [
|
||||||
'docker_registry_image_name' => 'string|required',
|
'docker_registry_image_name' => 'string|required',
|
||||||
'docker_registry_image_tag' => 'string',
|
'docker_registry_image_tag' => 'string',
|
||||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||||
];
|
];
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
@@ -1114,6 +1186,9 @@ class ApplicationsController extends Controller
|
|||||||
'errors' => $validator->errors(),
|
'errors' => $validator->errors(),
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
if (! $request->has('name')) {
|
||||||
|
$request->offsetSet('name', 'docker-image-'.new Cuid2);
|
||||||
|
}
|
||||||
$return = $this->validateDataApplications($request, $server);
|
$return = $this->validateDataApplications($request, $server);
|
||||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
return $return;
|
return $return;
|
||||||
@@ -1130,15 +1205,15 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
if (isset($useBuildServer)) {
|
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
|
||||||
$application->settings->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
$application->git_repository = 'coollabsio/coolify';
|
$application->git_repository = 'coollabsio/coolify';
|
||||||
$application->git_branch = 'main';
|
$application->git_branch = 'main';
|
||||||
$application->save();
|
$application->save();
|
||||||
$application->refresh();
|
$application->refresh();
|
||||||
|
if (isset($useBuildServer)) {
|
||||||
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
|
$application->settings->save();
|
||||||
|
}
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
||||||
$application->save();
|
$application->save();
|
||||||
@@ -1159,9 +1234,9 @@ class ApplicationsController extends Controller
|
|||||||
return response()->json(serializeApiResponse([
|
return response()->json(serializeApiResponse([
|
||||||
'uuid' => data_get($application, 'uuid'),
|
'uuid' => data_get($application, 'uuid'),
|
||||||
'domains' => data_get($application, 'domains'),
|
'domains' => data_get($application, 'domains'),
|
||||||
]));
|
]))->setStatusCode(201);
|
||||||
} elseif ($type === 'dockercompose') {
|
} elseif ($type === 'dockercompose') {
|
||||||
$allowedFields = ['project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'instant_deploy', 'docker_compose_raw'];
|
$allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'instant_deploy', 'docker_compose_raw'];
|
||||||
|
|
||||||
$extraFields = array_diff(array_keys($request->all()), $allowedFields);
|
$extraFields = array_diff(array_keys($request->all()), $allowedFields);
|
||||||
if ($validator->fails() || ! empty($extraFields)) {
|
if ($validator->fails() || ! empty($extraFields)) {
|
||||||
@@ -1183,7 +1258,7 @@ class ApplicationsController extends Controller
|
|||||||
$validationRules = [
|
$validationRules = [
|
||||||
'docker_compose_raw' => 'string|required',
|
'docker_compose_raw' => 'string|required',
|
||||||
];
|
];
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
@@ -1241,7 +1316,7 @@ class ApplicationsController extends Controller
|
|||||||
return response()->json(serializeApiResponse([
|
return response()->json(serializeApiResponse([
|
||||||
'uuid' => data_get($service, 'uuid'),
|
'uuid' => data_get($service, 'uuid'),
|
||||||
'domains' => data_get($service, 'domains'),
|
'domains' => data_get($service, 'domains'),
|
||||||
]));
|
]))->setStatusCode(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(['message' => 'Invalid type.'], 400);
|
return response()->json(['message' => 'Invalid type.'], 400);
|
||||||
@@ -1551,7 +1626,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_compose_custom_build_command' => 'string|nullable',
|
'docker_compose_custom_build_command' => 'string|nullable',
|
||||||
'custom_nginx_configuration' => 'string|nullable',
|
'custom_nginx_configuration' => 'string|nullable',
|
||||||
];
|
];
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
// Validate ports_exposes
|
// Validate ports_exposes
|
||||||
@@ -1668,7 +1743,10 @@ class ApplicationsController extends Controller
|
|||||||
removeUnnecessaryFieldsFromRequest($request);
|
removeUnnecessaryFieldsFromRequest($request);
|
||||||
|
|
||||||
$data = $request->all();
|
$data = $request->all();
|
||||||
data_set($data, 'fqdn', $domains);
|
if ($request->has('domains') && $server->isProxyShouldRun()) {
|
||||||
|
data_set($data, 'fqdn', $domains);
|
||||||
|
}
|
||||||
|
|
||||||
if ($dockerComposeDomainsJson->count() > 0) {
|
if ($dockerComposeDomainsJson->count() > 0) {
|
||||||
data_set($data, 'docker_compose_domains', json_encode($dockerComposeDomainsJson));
|
data_set($data, 'docker_compose_domains', json_encode($dockerComposeDomainsJson));
|
||||||
}
|
}
|
||||||
@@ -1893,8 +1971,9 @@ class ApplicationsController extends Controller
|
|||||||
$is_preview = $request->is_preview ?? false;
|
$is_preview = $request->is_preview ?? false;
|
||||||
$is_build_time = $request->is_build_time ?? false;
|
$is_build_time = $request->is_build_time ?? false;
|
||||||
$is_literal = $request->is_literal ?? false;
|
$is_literal = $request->is_literal ?? false;
|
||||||
|
$key = str($request->key)->trim()->replace(' ', '_')->value;
|
||||||
if ($is_preview) {
|
if ($is_preview) {
|
||||||
$env = $application->environment_variables_preview->where('key', $request->key)->first();
|
$env = $application->environment_variables_preview->where('key', $key)->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
$env->value = $request->value;
|
$env->value = $request->value;
|
||||||
if ($env->is_build_time != $is_build_time) {
|
if ($env->is_build_time != $is_build_time) {
|
||||||
@@ -1921,7 +2000,7 @@ class ApplicationsController extends Controller
|
|||||||
], 404);
|
], 404);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$env = $application->environment_variables->where('key', $request->key)->first();
|
$env = $application->environment_variables->where('key', $key)->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
$env->value = $request->value;
|
$env->value = $request->value;
|
||||||
if ($env->is_build_time != $is_build_time) {
|
if ($env->is_build_time != $is_build_time) {
|
||||||
@@ -2064,6 +2143,7 @@ class ApplicationsController extends Controller
|
|||||||
$bulk_data = collect($bulk_data)->map(function ($item) {
|
$bulk_data = collect($bulk_data)->map(function ($item) {
|
||||||
return collect($item)->only(['key', 'value', 'is_preview', 'is_build_time', 'is_literal']);
|
return collect($item)->only(['key', 'value', 'is_preview', 'is_build_time', 'is_literal']);
|
||||||
});
|
});
|
||||||
|
$returnedEnvs = collect();
|
||||||
foreach ($bulk_data as $item) {
|
foreach ($bulk_data as $item) {
|
||||||
$validator = customApiValidator($item, [
|
$validator = customApiValidator($item, [
|
||||||
'key' => 'string|required',
|
'key' => 'string|required',
|
||||||
@@ -2085,8 +2165,9 @@ class ApplicationsController extends Controller
|
|||||||
$is_literal = $item->get('is_literal') ?? false;
|
$is_literal = $item->get('is_literal') ?? false;
|
||||||
$is_multi_line = $item->get('is_multiline') ?? false;
|
$is_multi_line = $item->get('is_multiline') ?? false;
|
||||||
$is_shown_once = $item->get('is_shown_once') ?? false;
|
$is_shown_once = $item->get('is_shown_once') ?? false;
|
||||||
|
$key = str($item->get('key'))->trim()->replace(' ', '_')->value;
|
||||||
if ($is_preview) {
|
if ($is_preview) {
|
||||||
$env = $application->environment_variables_preview->where('key', $item->get('key'))->first();
|
$env = $application->environment_variables_preview->where('key', $key)->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
$env->value = $item->get('value');
|
$env->value = $item->get('value');
|
||||||
if ($env->is_build_time != $is_build_time) {
|
if ($env->is_build_time != $is_build_time) {
|
||||||
@@ -2111,10 +2192,12 @@ class ApplicationsController extends Controller
|
|||||||
'is_literal' => $is_literal,
|
'is_literal' => $is_literal,
|
||||||
'is_multiline' => $is_multi_line,
|
'is_multiline' => $is_multi_line,
|
||||||
'is_shown_once' => $is_shown_once,
|
'is_shown_once' => $is_shown_once,
|
||||||
|
'resourceable_type' => get_class($application),
|
||||||
|
'resourceable_id' => $application->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$env = $application->environment_variables->where('key', $item->get('key'))->first();
|
$env = $application->environment_variables->where('key', $key)->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
$env->value = $item->get('value');
|
$env->value = $item->get('value');
|
||||||
if ($env->is_build_time != $is_build_time) {
|
if ($env->is_build_time != $is_build_time) {
|
||||||
@@ -2139,12 +2222,15 @@ class ApplicationsController extends Controller
|
|||||||
'is_literal' => $is_literal,
|
'is_literal' => $is_literal,
|
||||||
'is_multiline' => $is_multi_line,
|
'is_multiline' => $is_multi_line,
|
||||||
'is_shown_once' => $is_shown_once,
|
'is_shown_once' => $is_shown_once,
|
||||||
|
'resourceable_type' => get_class($application),
|
||||||
|
'resourceable_id' => $application->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$returnedEnvs->push($this->removeSensitiveData($env));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($this->removeSensitiveData($env))->setStatusCode(201);
|
return response()->json($returnedEnvs)->setStatusCode(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[OA\Post(
|
#[OA\Post(
|
||||||
@@ -2257,8 +2343,10 @@ class ApplicationsController extends Controller
|
|||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
$is_preview = $request->is_preview ?? false;
|
$is_preview = $request->is_preview ?? false;
|
||||||
|
$key = str($request->key)->trim()->replace(' ', '_')->value;
|
||||||
|
|
||||||
if ($is_preview) {
|
if ($is_preview) {
|
||||||
$env = $application->environment_variables_preview->where('key', $request->key)->first();
|
$env = $application->environment_variables_preview->where('key', $key)->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Environment variable already exists. Use PATCH request to update it.',
|
'message' => 'Environment variable already exists. Use PATCH request to update it.',
|
||||||
@@ -2272,6 +2360,8 @@ class ApplicationsController extends Controller
|
|||||||
'is_literal' => $request->is_literal ?? false,
|
'is_literal' => $request->is_literal ?? false,
|
||||||
'is_multiline' => $request->is_multiline ?? false,
|
'is_multiline' => $request->is_multiline ?? false,
|
||||||
'is_shown_once' => $request->is_shown_once ?? false,
|
'is_shown_once' => $request->is_shown_once ?? false,
|
||||||
|
'resourceable_type' => get_class($application),
|
||||||
|
'resourceable_id' => $application->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -2279,7 +2369,7 @@ class ApplicationsController extends Controller
|
|||||||
])->setStatusCode(201);
|
])->setStatusCode(201);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$env = $application->environment_variables->where('key', $request->key)->first();
|
$env = $application->environment_variables->where('key', $key)->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Environment variable already exists. Use PATCH request to update it.',
|
'message' => 'Environment variable already exists. Use PATCH request to update it.',
|
||||||
@@ -2293,6 +2383,8 @@ class ApplicationsController extends Controller
|
|||||||
'is_literal' => $request->is_literal ?? false,
|
'is_literal' => $request->is_literal ?? false,
|
||||||
'is_multiline' => $request->is_multiline ?? false,
|
'is_multiline' => $request->is_multiline ?? false,
|
||||||
'is_shown_once' => $request->is_shown_once ?? false,
|
'is_shown_once' => $request->is_shown_once ?? false,
|
||||||
|
'resourceable_type' => get_class($application),
|
||||||
|
'resourceable_id' => $application->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -2380,7 +2472,10 @@ class ApplicationsController extends Controller
|
|||||||
'message' => 'Application not found.',
|
'message' => 'Application not found.',
|
||||||
], 404);
|
], 404);
|
||||||
}
|
}
|
||||||
$found_env = EnvironmentVariable::where('uuid', $request->env_uuid)->where('application_id', $application->id)->first();
|
$found_env = EnvironmentVariable::where('uuid', $request->env_uuid)
|
||||||
|
->where('resourceable_type', Application::class)
|
||||||
|
->where('resourceable_id', $application->id)
|
||||||
|
->first();
|
||||||
if (! $found_env) {
|
if (! $found_env) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Environment variable not found.',
|
'message' => 'Environment variable not found.',
|
||||||
|
@@ -523,11 +523,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'postgres_user' => ['type' => 'string', 'description' => 'PostgreSQL user'],
|
'postgres_user' => ['type' => 'string', 'description' => 'PostgreSQL user'],
|
||||||
'postgres_password' => ['type' => 'string', 'description' => 'PostgreSQL password'],
|
'postgres_password' => ['type' => 'string', 'description' => 'PostgreSQL password'],
|
||||||
'postgres_db' => ['type' => 'string', 'description' => 'PostgreSQL database'],
|
'postgres_db' => ['type' => 'string', 'description' => 'PostgreSQL database'],
|
||||||
@@ -589,11 +590,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
||||||
'clickhouse_admin_user' => ['type' => 'string', 'description' => 'Clickhouse admin user'],
|
'clickhouse_admin_user' => ['type' => 'string', 'description' => 'Clickhouse admin user'],
|
||||||
'clickhouse_admin_password' => ['type' => 'string', 'description' => 'Clickhouse admin password'],
|
'clickhouse_admin_password' => ['type' => 'string', 'description' => 'Clickhouse admin password'],
|
||||||
@@ -651,11 +653,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
||||||
'dragonfly_password' => ['type' => 'string', 'description' => 'DragonFly password'],
|
'dragonfly_password' => ['type' => 'string', 'description' => 'DragonFly password'],
|
||||||
'name' => ['type' => 'string', 'description' => 'Name of the database'],
|
'name' => ['type' => 'string', 'description' => 'Name of the database'],
|
||||||
@@ -712,11 +715,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
||||||
'redis_password' => ['type' => 'string', 'description' => 'Redis password'],
|
'redis_password' => ['type' => 'string', 'description' => 'Redis password'],
|
||||||
'redis_conf' => ['type' => 'string', 'description' => 'Redis conf'],
|
'redis_conf' => ['type' => 'string', 'description' => 'Redis conf'],
|
||||||
@@ -774,11 +778,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
||||||
'keydb_password' => ['type' => 'string', 'description' => 'KeyDB password'],
|
'keydb_password' => ['type' => 'string', 'description' => 'KeyDB password'],
|
||||||
'keydb_conf' => ['type' => 'string', 'description' => 'KeyDB conf'],
|
'keydb_conf' => ['type' => 'string', 'description' => 'KeyDB conf'],
|
||||||
@@ -836,11 +841,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
||||||
'mariadb_conf' => ['type' => 'string', 'description' => 'MariaDB conf'],
|
'mariadb_conf' => ['type' => 'string', 'description' => 'MariaDB conf'],
|
||||||
'mariadb_root_password' => ['type' => 'string', 'description' => 'MariaDB root password'],
|
'mariadb_root_password' => ['type' => 'string', 'description' => 'MariaDB root password'],
|
||||||
@@ -901,11 +907,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
||||||
'mysql_root_password' => ['type' => 'string', 'description' => 'MySQL root password'],
|
'mysql_root_password' => ['type' => 'string', 'description' => 'MySQL root password'],
|
||||||
'mysql_password' => ['type' => 'string', 'description' => 'MySQL password'],
|
'mysql_password' => ['type' => 'string', 'description' => 'MySQL password'],
|
||||||
@@ -966,11 +973,12 @@ class DatabasesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
|
||||||
properties: [
|
properties: [
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment'],
|
'environment_name' => ['type' => 'string', 'description' => 'Name of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'UUID of the environment. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'UUID of the destination if the server has multiple destinations'],
|
||||||
'mongo_conf' => ['type' => 'string', 'description' => 'MongoDB conf'],
|
'mongo_conf' => ['type' => 'string', 'description' => 'MongoDB conf'],
|
||||||
'mongo_initdb_root_username' => ['type' => 'string', 'description' => 'MongoDB initdb root username'],
|
'mongo_initdb_root_username' => ['type' => 'string', 'description' => 'MongoDB initdb root username'],
|
||||||
@@ -1013,7 +1021,7 @@ class DatabasesController extends Controller
|
|||||||
|
|
||||||
public function create_database(Request $request, NewDatabaseTypes $type)
|
public function create_database(Request $request, NewDatabaseTypes $type)
|
||||||
{
|
{
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'postgres_user', 'postgres_password', 'postgres_db', 'postgres_initdb_args', 'postgres_host_auth_method', 'postgres_conf', 'clickhouse_admin_user', 'clickhouse_admin_password', 'dragonfly_password', 'redis_password', 'redis_conf', 'keydb_password', 'keydb_conf', 'mariadb_conf', 'mariadb_root_password', 'mariadb_user', 'mariadb_password', 'mariadb_database', 'mongo_conf', 'mongo_initdb_root_username', 'mongo_initdb_root_password', 'mongo_initdb_database', 'mysql_root_password', 'mysql_password', 'mysql_user', 'mysql_database', 'mysql_conf'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'postgres_user', 'postgres_password', 'postgres_db', 'postgres_initdb_args', 'postgres_host_auth_method', 'postgres_conf', 'clickhouse_admin_user', 'clickhouse_admin_password', 'dragonfly_password', 'redis_password', 'redis_conf', 'keydb_password', 'keydb_conf', 'mariadb_conf', 'mariadb_root_password', 'mariadb_user', 'mariadb_password', 'mariadb_database', 'mongo_conf', 'mongo_initdb_root_username', 'mongo_initdb_root_password', 'mongo_initdb_database', 'mysql_root_password', 'mysql_password', 'mysql_user', 'mysql_database', 'mysql_conf'];
|
||||||
|
|
||||||
$teamId = getTeamIdFromToken();
|
$teamId = getTeamIdFromToken();
|
||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
@@ -1039,6 +1047,11 @@ class DatabasesController extends Controller
|
|||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
$environmentUuid = $request->environment_uuid;
|
||||||
|
$environmentName = $request->environment_name;
|
||||||
|
if (blank($environmentUuid) && blank($environmentName)) {
|
||||||
|
return response()->json(['message' => 'You need to provide at least one of environment_name or environment_uuid.'], 422);
|
||||||
|
}
|
||||||
$serverUuid = $request->server_uuid;
|
$serverUuid = $request->server_uuid;
|
||||||
$instantDeploy = $request->instant_deploy ?? false;
|
$instantDeploy = $request->instant_deploy ?? false;
|
||||||
if ($request->is_public && ! $request->public_port) {
|
if ($request->is_public && ! $request->public_port) {
|
||||||
@@ -1048,9 +1061,12 @@ class DatabasesController extends Controller
|
|||||||
if (! $project) {
|
if (! $project) {
|
||||||
return response()->json(['message' => 'Project not found.'], 404);
|
return response()->json(['message' => 'Project not found.'], 404);
|
||||||
}
|
}
|
||||||
$environment = $project->environments()->where('name', $request->environment_name)->first();
|
$environment = $project->environments()->where('name', $environmentName)->first();
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return response()->json(['message' => 'Environment not found.'], 404);
|
$environment = $project->environments()->where('uuid', $environmentUuid)->first();
|
||||||
|
}
|
||||||
|
if (! $environment) {
|
||||||
|
return response()->json(['message' => 'You need to provide a valid environment_name or environment_uuid.'], 422);
|
||||||
}
|
}
|
||||||
$server = Server::whereTeamId($teamId)->whereUuid($serverUuid)->first();
|
$server = Server::whereTeamId($teamId)->whereUuid($serverUuid)->first();
|
||||||
if (! $server) {
|
if (! $server) {
|
||||||
@@ -1074,7 +1090,8 @@ class DatabasesController extends Controller
|
|||||||
'description' => 'string|nullable',
|
'description' => 'string|nullable',
|
||||||
'image' => 'string',
|
'image' => 'string',
|
||||||
'project_uuid' => 'string|required',
|
'project_uuid' => 'string|required',
|
||||||
'environment_name' => 'string|required',
|
'environment_name' => 'string|nullable',
|
||||||
|
'environment_uuid' => 'string|nullable',
|
||||||
'server_uuid' => 'string|required',
|
'server_uuid' => 'string|required',
|
||||||
'destination_uuid' => 'string',
|
'destination_uuid' => 'string',
|
||||||
'is_public' => 'boolean',
|
'is_public' => 'boolean',
|
||||||
@@ -1105,7 +1122,7 @@ class DatabasesController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($type === NewDatabaseTypes::POSTGRESQL) {
|
if ($type === NewDatabaseTypes::POSTGRESQL) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'postgres_user', 'postgres_password', 'postgres_db', 'postgres_initdb_args', 'postgres_host_auth_method', 'postgres_conf'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'postgres_user', 'postgres_password', 'postgres_db', 'postgres_initdb_args', 'postgres_host_auth_method', 'postgres_conf'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'postgres_user' => 'string',
|
'postgres_user' => 'string',
|
||||||
'postgres_password' => 'string',
|
'postgres_password' => 'string',
|
||||||
@@ -1164,7 +1181,7 @@ class DatabasesController extends Controller
|
|||||||
|
|
||||||
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
||||||
} elseif ($type === NewDatabaseTypes::MARIADB) {
|
} elseif ($type === NewDatabaseTypes::MARIADB) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'mariadb_conf', 'mariadb_root_password', 'mariadb_user', 'mariadb_password', 'mariadb_database'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'mariadb_conf', 'mariadb_root_password', 'mariadb_user', 'mariadb_password', 'mariadb_database'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'clickhouse_admin_user' => 'string',
|
'clickhouse_admin_user' => 'string',
|
||||||
'clickhouse_admin_password' => 'string',
|
'clickhouse_admin_password' => 'string',
|
||||||
@@ -1220,7 +1237,7 @@ class DatabasesController extends Controller
|
|||||||
|
|
||||||
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
||||||
} elseif ($type === NewDatabaseTypes::MYSQL) {
|
} elseif ($type === NewDatabaseTypes::MYSQL) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'mysql_root_password', 'mysql_password', 'mysql_user', 'mysql_database', 'mysql_conf'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'mysql_root_password', 'mysql_password', 'mysql_user', 'mysql_database', 'mysql_conf'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'mysql_root_password' => 'string',
|
'mysql_root_password' => 'string',
|
||||||
'mysql_password' => 'string',
|
'mysql_password' => 'string',
|
||||||
@@ -1279,7 +1296,7 @@ class DatabasesController extends Controller
|
|||||||
|
|
||||||
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
||||||
} elseif ($type === NewDatabaseTypes::REDIS) {
|
} elseif ($type === NewDatabaseTypes::REDIS) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'redis_password', 'redis_conf'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'redis_password', 'redis_conf'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'redis_password' => 'string',
|
'redis_password' => 'string',
|
||||||
'redis_conf' => 'string',
|
'redis_conf' => 'string',
|
||||||
@@ -1335,7 +1352,7 @@ class DatabasesController extends Controller
|
|||||||
|
|
||||||
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
||||||
} elseif ($type === NewDatabaseTypes::DRAGONFLY) {
|
} elseif ($type === NewDatabaseTypes::DRAGONFLY) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'dragonfly_password'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'dragonfly_password'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'dragonfly_password' => 'string',
|
'dragonfly_password' => 'string',
|
||||||
]);
|
]);
|
||||||
@@ -1365,7 +1382,7 @@ class DatabasesController extends Controller
|
|||||||
'uuid' => $database->uuid,
|
'uuid' => $database->uuid,
|
||||||
]))->setStatusCode(201);
|
]))->setStatusCode(201);
|
||||||
} elseif ($type === NewDatabaseTypes::KEYDB) {
|
} elseif ($type === NewDatabaseTypes::KEYDB) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'keydb_password', 'keydb_conf'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'keydb_password', 'keydb_conf'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'keydb_password' => 'string',
|
'keydb_password' => 'string',
|
||||||
'keydb_conf' => 'string',
|
'keydb_conf' => 'string',
|
||||||
@@ -1421,7 +1438,7 @@ class DatabasesController extends Controller
|
|||||||
|
|
||||||
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
||||||
} elseif ($type === NewDatabaseTypes::CLICKHOUSE) {
|
} elseif ($type === NewDatabaseTypes::CLICKHOUSE) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'clickhouse_admin_user', 'clickhouse_admin_password'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'clickhouse_admin_user', 'clickhouse_admin_password'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'clickhouse_admin_user' => 'string',
|
'clickhouse_admin_user' => 'string',
|
||||||
'clickhouse_admin_password' => 'string',
|
'clickhouse_admin_password' => 'string',
|
||||||
@@ -1457,7 +1474,7 @@ class DatabasesController extends Controller
|
|||||||
|
|
||||||
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
return response()->json(serializeApiResponse($payload))->setStatusCode(201);
|
||||||
} elseif ($type === NewDatabaseTypes::MONGODB) {
|
} elseif ($type === NewDatabaseTypes::MONGODB) {
|
||||||
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'mongo_conf', 'mongo_initdb_root_username', 'mongo_initdb_root_password', 'mongo_initdb_database'];
|
$allowedFields = ['name', 'description', 'image', 'public_port', 'is_public', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'mongo_conf', 'mongo_initdb_root_username', 'mongo_initdb_root_password', 'mongo_initdb_database'];
|
||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'mongo_conf' => 'string',
|
'mongo_conf' => 'string',
|
||||||
'mongo_initdb_root_username' => 'string',
|
'mongo_initdb_root_username' => 'string',
|
||||||
|
@@ -90,11 +90,13 @@ class ProjectController extends Controller
|
|||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
return invalidTokenResponse();
|
return invalidTokenResponse();
|
||||||
}
|
}
|
||||||
$project = Project::whereTeamId($teamId)->whereUuid(request()->uuid)->first()->load(['environments']);
|
$project = Project::whereTeamId($teamId)->whereUuid(request()->uuid)->first();
|
||||||
if (! $project) {
|
if (! $project) {
|
||||||
return response()->json(['message' => 'Project not found.'], 404);
|
return response()->json(['message' => 'Project not found.'], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$project->load(['environments']);
|
||||||
|
|
||||||
return response()->json(
|
return response()->json(
|
||||||
serializeApiResponse($project),
|
serializeApiResponse($project),
|
||||||
);
|
);
|
||||||
@@ -102,16 +104,16 @@ class ProjectController extends Controller
|
|||||||
|
|
||||||
#[OA\Get(
|
#[OA\Get(
|
||||||
summary: 'Environment',
|
summary: 'Environment',
|
||||||
description: 'Get environment by name.',
|
description: 'Get environment by name or UUID.',
|
||||||
path: '/projects/{uuid}/{environment_name}',
|
path: '/projects/{uuid}/{environment_name_or_uuid}',
|
||||||
operationId: 'get-environment-by-name',
|
operationId: 'get-environment-by-name-or-uuid',
|
||||||
security: [
|
security: [
|
||||||
['bearerAuth' => []],
|
['bearerAuth' => []],
|
||||||
],
|
],
|
||||||
tags: ['Projects'],
|
tags: ['Projects'],
|
||||||
parameters: [
|
parameters: [
|
||||||
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')),
|
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')),
|
||||||
new OA\Parameter(name: 'environment_name', in: 'path', required: true, description: 'Environment name', schema: new OA\Schema(type: 'string')),
|
new OA\Parameter(name: 'environment_name_or_uuid', in: 'path', required: true, description: 'Environment name or UUID', schema: new OA\Schema(type: 'string')),
|
||||||
],
|
],
|
||||||
responses: [
|
responses: [
|
||||||
new OA\Response(
|
new OA\Response(
|
||||||
@@ -141,14 +143,17 @@ class ProjectController extends Controller
|
|||||||
if (! $request->uuid) {
|
if (! $request->uuid) {
|
||||||
return response()->json(['message' => 'UUID is required.'], 422);
|
return response()->json(['message' => 'UUID is required.'], 422);
|
||||||
}
|
}
|
||||||
if (! $request->environment_name) {
|
if (! $request->environment_name_or_uuid) {
|
||||||
return response()->json(['message' => 'Environment name is required.'], 422);
|
return response()->json(['message' => 'Environment name or UUID is required.'], 422);
|
||||||
}
|
}
|
||||||
$project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first();
|
$project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first();
|
||||||
if (! $project) {
|
if (! $project) {
|
||||||
return response()->json(['message' => 'Project not found.'], 404);
|
return response()->json(['message' => 'Project not found.'], 404);
|
||||||
}
|
}
|
||||||
$environment = $project->environments()->whereName($request->environment_name)->first();
|
$environment = $project->environments()->whereName($request->environment_name_or_uuid)->first();
|
||||||
|
if (! $environment) {
|
||||||
|
$environment = $project->environments()->whereUuid($request->environment_name_or_uuid)->first();
|
||||||
|
}
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return response()->json(['message' => 'Environment not found.'], 404);
|
return response()->json(['message' => 'Environment not found.'], 404);
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,9 @@ class ServicesController extends Controller
|
|||||||
{
|
{
|
||||||
$service->makeHidden([
|
$service->makeHidden([
|
||||||
'id',
|
'id',
|
||||||
|
'resourceable',
|
||||||
|
'resourceable_id',
|
||||||
|
'resourceable_type',
|
||||||
]);
|
]);
|
||||||
if (request()->attributes->get('can_read_sensitive', false) === false) {
|
if (request()->attributes->get('can_read_sensitive', false) === false) {
|
||||||
$service->makeHidden([
|
$service->makeHidden([
|
||||||
@@ -99,7 +102,7 @@ class ServicesController extends Controller
|
|||||||
mediaType: 'application/json',
|
mediaType: 'application/json',
|
||||||
schema: new OA\Schema(
|
schema: new OA\Schema(
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['server_uuid', 'project_uuid', 'environment_name', 'type'],
|
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid', 'type'],
|
||||||
properties: [
|
properties: [
|
||||||
'type' => [
|
'type' => [
|
||||||
'description' => 'The one-click service type',
|
'description' => 'The one-click service type',
|
||||||
@@ -196,7 +199,8 @@ class ServicesController extends Controller
|
|||||||
'name' => ['type' => 'string', 'maxLength' => 255, 'description' => 'Name of the service.'],
|
'name' => ['type' => 'string', 'maxLength' => 255, 'description' => 'Name of the service.'],
|
||||||
'description' => ['type' => 'string', 'nullable' => true, 'description' => 'Description of the service.'],
|
'description' => ['type' => 'string', 'nullable' => true, 'description' => 'Description of the service.'],
|
||||||
'project_uuid' => ['type' => 'string', 'description' => 'Project UUID.'],
|
'project_uuid' => ['type' => 'string', 'description' => 'Project UUID.'],
|
||||||
'environment_name' => ['type' => 'string', 'description' => 'Environment name.'],
|
'environment_name' => ['type' => 'string', 'description' => 'Environment name. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
|
'environment_uuid' => ['type' => 'string', 'description' => 'Environment UUID. You need to provide at least one of environment_name or environment_uuid.'],
|
||||||
'server_uuid' => ['type' => 'string', 'description' => 'Server UUID.'],
|
'server_uuid' => ['type' => 'string', 'description' => 'Server UUID.'],
|
||||||
'destination_uuid' => ['type' => 'string', 'description' => 'Destination UUID. Required if server has multiple destinations.'],
|
'destination_uuid' => ['type' => 'string', 'description' => 'Destination UUID. Required if server has multiple destinations.'],
|
||||||
'instant_deploy' => ['type' => 'boolean', 'default' => false, 'description' => 'Start the service immediately after creation.'],
|
'instant_deploy' => ['type' => 'boolean', 'default' => false, 'description' => 'Start the service immediately after creation.'],
|
||||||
@@ -233,7 +237,7 @@ class ServicesController extends Controller
|
|||||||
)]
|
)]
|
||||||
public function create_service(Request $request)
|
public function create_service(Request $request)
|
||||||
{
|
{
|
||||||
$allowedFields = ['type', 'name', 'description', 'project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'instant_deploy'];
|
$allowedFields = ['type', 'name', 'description', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy'];
|
||||||
|
|
||||||
$teamId = getTeamIdFromToken();
|
$teamId = getTeamIdFromToken();
|
||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
@@ -247,7 +251,8 @@ class ServicesController extends Controller
|
|||||||
$validator = customApiValidator($request->all(), [
|
$validator = customApiValidator($request->all(), [
|
||||||
'type' => 'string|required',
|
'type' => 'string|required',
|
||||||
'project_uuid' => 'string|required',
|
'project_uuid' => 'string|required',
|
||||||
'environment_name' => 'string|required',
|
'environment_name' => 'string|nullable',
|
||||||
|
'environment_uuid' => 'string|nullable',
|
||||||
'server_uuid' => 'string|required',
|
'server_uuid' => 'string|required',
|
||||||
'destination_uuid' => 'string',
|
'destination_uuid' => 'string',
|
||||||
'name' => 'string|max:255',
|
'name' => 'string|max:255',
|
||||||
@@ -269,6 +274,11 @@ class ServicesController extends Controller
|
|||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
$environmentUuid = $request->environment_uuid;
|
||||||
|
$environmentName = $request->environment_name;
|
||||||
|
if (blank($environmentUuid) && blank($environmentName)) {
|
||||||
|
return response()->json(['message' => 'You need to provide at least one of environment_name or environment_uuid.'], 422);
|
||||||
|
}
|
||||||
$serverUuid = $request->server_uuid;
|
$serverUuid = $request->server_uuid;
|
||||||
$instantDeploy = $request->instant_deploy ?? false;
|
$instantDeploy = $request->instant_deploy ?? false;
|
||||||
if ($request->is_public && ! $request->public_port) {
|
if ($request->is_public && ! $request->public_port) {
|
||||||
@@ -278,7 +288,10 @@ class ServicesController extends Controller
|
|||||||
if (! $project) {
|
if (! $project) {
|
||||||
return response()->json(['message' => 'Project not found.'], 404);
|
return response()->json(['message' => 'Project not found.'], 404);
|
||||||
}
|
}
|
||||||
$environment = $project->environments()->where('name', $request->environment_name)->first();
|
$environment = $project->environments()->where('name', $environmentName)->first();
|
||||||
|
if (! $environment) {
|
||||||
|
$environment = $project->environments()->where('uuid', $environmentUuid)->first();
|
||||||
|
}
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return response()->json(['message' => 'Environment not found.'], 404);
|
return response()->json(['message' => 'Environment not found.'], 404);
|
||||||
}
|
}
|
||||||
@@ -333,7 +346,8 @@ class ServicesController extends Controller
|
|||||||
EnvironmentVariable::create([
|
EnvironmentVariable::create([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $generatedValue,
|
'value' => $generatedValue,
|
||||||
'service_id' => $service->id,
|
'resourceable_id' => $service->id,
|
||||||
|
'resourceable_type' => $service->getMorphClass(),
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
]);
|
]);
|
||||||
@@ -345,7 +359,11 @@ class ServicesController extends Controller
|
|||||||
}
|
}
|
||||||
$domains = $service->applications()->get()->pluck('fqdn')->sort();
|
$domains = $service->applications()->get()->pluck('fqdn')->sort();
|
||||||
$domains = $domains->map(function ($domain) {
|
$domains = $domains->map(function ($domain) {
|
||||||
return str($domain)->beforeLast(':')->value();
|
if (count(explode(':', $domain)) > 2) {
|
||||||
|
return str($domain)->beforeLast(':')->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $domain;
|
||||||
});
|
});
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -673,7 +691,8 @@ class ServicesController extends Controller
|
|||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$env = $service->environment_variables()->where('key', $request->key)->first();
|
$key = str($request->key)->trim()->replace(' ', '_')->value;
|
||||||
|
$env = $service->environment_variables()->where('key', $key)->first();
|
||||||
if (! $env) {
|
if (! $env) {
|
||||||
return response()->json(['message' => 'Environment variable not found.'], 404);
|
return response()->json(['message' => 'Environment variable not found.'], 404);
|
||||||
}
|
}
|
||||||
@@ -799,9 +818,9 @@ class ServicesController extends Controller
|
|||||||
'errors' => $validator->errors(),
|
'errors' => $validator->errors(),
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
$key = str($item['key'])->trim()->replace(' ', '_')->value;
|
||||||
$env = $service->environment_variables()->updateOrCreate(
|
$env = $service->environment_variables()->updateOrCreate(
|
||||||
['key' => $item['key']],
|
['key' => $key],
|
||||||
$item
|
$item
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -909,7 +928,8 @@ class ServicesController extends Controller
|
|||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$existingEnv = $service->environment_variables()->where('key', $request->key)->first();
|
$key = str($request->key)->trim()->replace(' ', '_')->value;
|
||||||
|
$existingEnv = $service->environment_variables()->where('key', $key)->first();
|
||||||
if ($existingEnv) {
|
if ($existingEnv) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Environment variable already exists. Use PATCH request to update it.',
|
'message' => 'Environment variable already exists. Use PATCH request to update it.',
|
||||||
@@ -995,7 +1015,8 @@ class ServicesController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$env = EnvironmentVariable::where('uuid', $request->env_uuid)
|
$env = EnvironmentVariable::where('uuid', $request->env_uuid)
|
||||||
->where('service_id', $service->id)
|
->where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $service->id)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if (! $env) {
|
if (! $env) {
|
||||||
|
@@ -39,6 +39,8 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
{
|
{
|
||||||
use Dispatchable, ExecuteRemoteCommand, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, ExecuteRemoteCommand, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
public $tries = 1;
|
||||||
|
|
||||||
public $timeout = 3600;
|
public $timeout = 3600;
|
||||||
|
|
||||||
public static int $batch_counter = 0;
|
public static int $batch_counter = 0;
|
||||||
@@ -126,6 +128,8 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
|
|
||||||
private ?string $nixpacks_plan = null;
|
private ?string $nixpacks_plan = null;
|
||||||
|
|
||||||
|
private Collection $nixpacks_plan_json;
|
||||||
|
|
||||||
private ?string $nixpacks_type = null;
|
private ?string $nixpacks_type = null;
|
||||||
|
|
||||||
private string $dockerfile_location = '/Dockerfile';
|
private string $dockerfile_location = '/Dockerfile';
|
||||||
@@ -164,12 +168,12 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
|
|
||||||
private bool $preserveRepository = false;
|
private bool $preserveRepository = false;
|
||||||
|
|
||||||
public $tries = 1;
|
|
||||||
|
|
||||||
public function __construct(int $application_deployment_queue_id)
|
public function __construct(int $application_deployment_queue_id)
|
||||||
{
|
{
|
||||||
$this->onQueue('high');
|
$this->onQueue('high');
|
||||||
|
|
||||||
|
$this->nixpacks_plan_json = collect([]);
|
||||||
|
|
||||||
$this->application_deployment_queue = ApplicationDeploymentQueue::find($application_deployment_queue_id);
|
$this->application_deployment_queue = ApplicationDeploymentQueue::find($application_deployment_queue_id);
|
||||||
$this->application = Application::find($this->application_deployment_queue->application_id);
|
$this->application = Application::find($this->application_deployment_queue->application_id);
|
||||||
$this->build_pack = data_get($this->application, 'build_pack');
|
$this->build_pack = data_get($this->application, 'build_pack');
|
||||||
@@ -1405,7 +1409,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
'project_uuid' => data_get($this->application, 'environment.project.uuid'),
|
'project_uuid' => data_get($this->application, 'environment.project.uuid'),
|
||||||
'application_uuid' => data_get($this->application, 'uuid'),
|
'application_uuid' => data_get($this->application, 'uuid'),
|
||||||
'deployment_uuid' => $deployment_uuid,
|
'deployment_uuid' => $deployment_uuid,
|
||||||
'environment_name' => data_get($this->application, 'environment.name'),
|
'environment_uuid' => data_get($this->application, 'environment.uuid'),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1545,7 +1549,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
|
|
||||||
// Do any modifications here
|
// Do any modifications here
|
||||||
$this->generate_env_variables();
|
$this->generate_env_variables();
|
||||||
$merged_envs = $this->env_args->merge(collect(data_get($parsed, 'variables', [])));
|
$merged_envs = collect(data_get($parsed, 'variables', []))->merge($this->env_args);
|
||||||
$aptPkgs = data_get($parsed, 'phases.setup.aptPkgs', []);
|
$aptPkgs = data_get($parsed, 'phases.setup.aptPkgs', []);
|
||||||
if (count($aptPkgs) === 0) {
|
if (count($aptPkgs) === 0) {
|
||||||
$aptPkgs = ['curl', 'wget'];
|
$aptPkgs = ['curl', 'wget'];
|
||||||
@@ -1570,6 +1574,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
$this->elixir_finetunes();
|
$this->elixir_finetunes();
|
||||||
}
|
}
|
||||||
$this->nixpacks_plan = json_encode($parsed, JSON_PRETTY_PRINT);
|
$this->nixpacks_plan = json_encode($parsed, JSON_PRETTY_PRINT);
|
||||||
|
$this->nixpacks_plan_json = collect($parsed);
|
||||||
$this->application_deployment_queue->addLogEntry("Final Nixpacks plan: {$this->nixpacks_plan}", hidden: true);
|
$this->application_deployment_queue->addLogEntry("Final Nixpacks plan: {$this->nixpacks_plan}", hidden: true);
|
||||||
if ($this->nixpacks_type === 'rust') {
|
if ($this->nixpacks_type === 'rust') {
|
||||||
// temporary: disable healthcheck for rust because the start phase does not have curl/wget
|
// temporary: disable healthcheck for rust because the start phase does not have curl/wget
|
||||||
@@ -1690,7 +1695,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
return escapeDollarSign($value);
|
return escapeDollarSign($value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$labels = $labels->merge(defaultLabels($this->application->id, $this->application->uuid, $this->pull_request_id))->toArray();
|
$labels = $labels->merge(defaultLabels($this->application->id, $this->application->uuid, $this->application->project()->name, $this->application->name, $this->application->environment->name, $this->pull_request_id))->toArray();
|
||||||
|
|
||||||
// Check for custom HEALTHCHECK
|
// Check for custom HEALTHCHECK
|
||||||
if ($this->application->build_pack === 'dockerfile' || $this->application->dockerfile) {
|
if ($this->application->build_pack === 'dockerfile' || $this->application->dockerfile) {
|
||||||
@@ -2278,18 +2283,10 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
|
|
||||||
private function generate_build_env_variables()
|
private function generate_build_env_variables()
|
||||||
{
|
{
|
||||||
$this->build_args = collect(["--build-arg SOURCE_COMMIT=\"{$this->commit}\""]);
|
$variables = collect($this->nixpacks_plan_json->get('variables'));
|
||||||
if ($this->pull_request_id === 0) {
|
$this->build_args = $variables->map(function ($value, $key) {
|
||||||
foreach ($this->application->build_environment_variables as $env) {
|
return "--build-arg {$key}={$value}";
|
||||||
$value = escapeshellarg($env->real_value);
|
});
|
||||||
$this->build_args->push("--build-arg {$env->key}={$value}");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach ($this->application->build_environment_variables_preview as $env) {
|
|
||||||
$value = escapeshellarg($env->real_value);
|
|
||||||
$this->build_args->push("--build-arg {$env->key}={$value}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function add_build_env_variables_to_dockerfile()
|
private function add_build_env_variables_to_dockerfile()
|
||||||
|
@@ -32,8 +32,6 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
|
|
||||||
public ScheduledDatabaseBackup $backup;
|
|
||||||
|
|
||||||
public StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|ServiceDatabase $database;
|
public StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|ServiceDatabase $database;
|
||||||
|
|
||||||
public ?string $container_name = null;
|
public ?string $container_name = null;
|
||||||
@@ -58,10 +56,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
|
|
||||||
public ?S3Storage $s3 = null;
|
public ?S3Storage $s3 = null;
|
||||||
|
|
||||||
public function __construct($backup)
|
public function __construct(public ScheduledDatabaseBackup $backup)
|
||||||
{
|
{
|
||||||
$this->onQueue('high');
|
$this->onQueue('high');
|
||||||
$this->backup = $backup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
|
@@ -44,7 +44,7 @@ class SendMessageToPushoverJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
{
|
{
|
||||||
$response = Http::post('https://api.pushover.net/1/messages.json', $this->message->toPayload($this->token, $this->user));
|
$response = Http::post('https://api.pushover.net/1/messages.json', $this->message->toPayload($this->token, $this->user));
|
||||||
if ($response->failed()) {
|
if ($response->failed()) {
|
||||||
throw new \RuntimeException('Pushover notification failed with ' . $response->status() . ' status code.' . $response->body());
|
throw new \RuntimeException('Pushover notification failed with '.$response->status().' status code.'.$response->body());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,16 +21,28 @@ class Index extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
if (! isCloud()) {
|
if (! isCloud() && ! isDev()) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
|
if (Auth::id() !== 0 && ! session('impersonating')) {
|
||||||
if (Auth::id() !== 0) {
|
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$this->getSubscribers();
|
$this->getSubscribers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function back()
|
||||||
|
{
|
||||||
|
if (session('impersonating')) {
|
||||||
|
session()->forget('impersonating');
|
||||||
|
$user = User::find(0);
|
||||||
|
$team_to_switch_to = $user->teams->first();
|
||||||
|
Auth::login($user);
|
||||||
|
refreshSession($team_to_switch_to);
|
||||||
|
|
||||||
|
return redirect(request()->header('Referer'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function submitSearch()
|
public function submitSearch()
|
||||||
{
|
{
|
||||||
if ($this->search !== '') {
|
if ($this->search !== '') {
|
||||||
@@ -52,9 +64,10 @@ class Index extends Component
|
|||||||
if (Auth::id() !== 0) {
|
if (Auth::id() !== 0) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
|
session(['impersonating' => true]);
|
||||||
$user = User::find($user_id);
|
$user = User::find($user_id);
|
||||||
$team_to_switch_to = $user->teams->first();
|
$team_to_switch_to = $user->teams->first();
|
||||||
Cache::forget("team:{$user->id}");
|
// Cache::forget("team:{$user->id}");
|
||||||
Auth::login($user);
|
Auth::login($user);
|
||||||
refreshSession($team_to_switch_to);
|
refreshSession($team_to_switch_to);
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@ use App\Models\Server;
|
|||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
class Index extends Component
|
class Index extends Component
|
||||||
{
|
{
|
||||||
@@ -334,6 +335,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
|||||||
$this->createdProject = Project::create([
|
$this->createdProject = Project::create([
|
||||||
'name' => 'My first project',
|
'name' => 'My first project',
|
||||||
'team_id' => currentTeam()->id,
|
'team_id' => currentTeam()->id,
|
||||||
|
'uuid' => (string) new Cuid2,
|
||||||
]);
|
]);
|
||||||
$this->currentState = 'create-resource';
|
$this->currentState = 'create-resource';
|
||||||
}
|
}
|
||||||
@@ -346,7 +348,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
|||||||
'project.resource.create',
|
'project.resource.create',
|
||||||
[
|
[
|
||||||
'project_uuid' => $this->createdProject->uuid,
|
'project_uuid' => $this->createdProject->uuid,
|
||||||
'environment_name' => 'production',
|
'environment_uuid' => $this->createdProject->environments->first()->uuid,
|
||||||
'server' => $this->createdServer->id,
|
'server' => $this->createdServer->id,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@@ -8,6 +8,7 @@ use App\Models\Project;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Illuminate\Support\Facades\Redirect;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Dashboard extends Component
|
class Dashboard extends Component
|
||||||
@@ -49,6 +50,20 @@ class Dashboard extends Component
|
|||||||
])->sortBy('id')->groupBy('server_name')->toArray();
|
])->sortBy('id')->groupBy('server_name')->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function navigateToProject($projectUuid)
|
||||||
|
{
|
||||||
|
$project = Project::where('uuid', $projectUuid)->first();
|
||||||
|
|
||||||
|
if ($project && $project->environments->count() === 1) {
|
||||||
|
return Redirect::route('project.resource.index', [
|
||||||
|
'project_uuid' => $projectUuid,
|
||||||
|
'environment_uuid' => $project->environments->first()->uuid,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect::route('project.show', ['project_uuid' => $projectUuid]);
|
||||||
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.dashboard');
|
return view('livewire.dashboard');
|
||||||
|
@@ -5,6 +5,7 @@ namespace App\Livewire\Project;
|
|||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use Livewire\Attributes\Validate;
|
use Livewire\Attributes\Validate;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
class AddEmpty extends Component
|
class AddEmpty extends Component
|
||||||
{
|
{
|
||||||
@@ -22,6 +23,7 @@ class AddEmpty extends Component
|
|||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'description' => $this->description,
|
'description' => $this->description,
|
||||||
'team_id' => currentTeam()->id,
|
'team_id' => currentTeam()->id,
|
||||||
|
'uuid' => (string) new Cuid2,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('project.show', $project->uuid);
|
return redirect()->route('project.show', $project->uuid);
|
||||||
|
@@ -3,43 +3,42 @@
|
|||||||
namespace App\Livewire\Project\Application;
|
namespace App\Livewire\Project\Application;
|
||||||
|
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use App\Models\Server;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Configuration extends Component
|
class Configuration extends Component
|
||||||
{
|
{
|
||||||
|
public $currentRoute;
|
||||||
|
|
||||||
public Application $application;
|
public Application $application;
|
||||||
|
|
||||||
|
public $project;
|
||||||
|
|
||||||
|
public $environment;
|
||||||
|
|
||||||
public $servers;
|
public $servers;
|
||||||
|
|
||||||
protected $listeners = ['buildPackUpdated' => '$refresh'];
|
protected $listeners = ['buildPackUpdated' => '$refresh'];
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
$this->currentRoute = request()->route()->getName();
|
||||||
$project = currentTeam()
|
$project = currentTeam()
|
||||||
->projects()
|
->projects()
|
||||||
->select('id', 'uuid', 'team_id')
|
->select('id', 'uuid', 'team_id')
|
||||||
->where('uuid', request()->route('project_uuid'))
|
->where('uuid', request()->route('project_uuid'))
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
$environment = $project->environments()
|
$environment = $project->environments()
|
||||||
->select('id', 'name', 'project_id')
|
->select('id', 'uuid', 'name', 'project_id')
|
||||||
->where('name', request()->route('environment_name'))
|
->where('uuid', request()->route('environment_uuid'))
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
$application = $environment->applications()
|
$application = $environment->applications()
|
||||||
->with(['destination'])
|
->with(['destination'])
|
||||||
->where('uuid', request()->route('application_uuid'))
|
->where('uuid', request()->route('application_uuid'))
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
|
|
||||||
|
$this->project = $project;
|
||||||
|
$this->environment = $environment;
|
||||||
$this->application = $application;
|
$this->application = $application;
|
||||||
if ($application->destination && $application->destination->server) {
|
|
||||||
$mainServer = $application->destination->server;
|
|
||||||
$this->servers = Server::ownedByCurrentTeam()
|
|
||||||
->select('id', 'name')
|
|
||||||
->where('id', '!=', $mainServer->id)
|
|
||||||
->get();
|
|
||||||
} else {
|
|
||||||
$this->servers = collect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
|
@@ -34,7 +34,7 @@ class Index extends Component
|
|||||||
if (! $project) {
|
if (! $project) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
|
$environment = $project->load(['environments'])->environments->where('uuid', request()->route('environment_uuid'))->first()->load(['applications']);
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ class Show extends Component
|
|||||||
if (! $project) {
|
if (! $project) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
|
$environment = $project->load(['environments'])->environments->where('uuid', request()->route('environment_uuid'))->first()->load(['applications']);
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
@@ -34,19 +34,11 @@ class Show extends Component
|
|||||||
if (! $application) {
|
if (! $application) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
// $activity = Activity::where('properties->type_uuid', '=', $deploymentUuid)->first();
|
|
||||||
// if (!$activity) {
|
|
||||||
// return redirect()->route('project.application.deployment.index', [
|
|
||||||
// 'project_uuid' => $project->uuid,
|
|
||||||
// 'environment_name' => $environment->name,
|
|
||||||
// 'application_uuid' => $application->uuid,
|
|
||||||
// ]);
|
|
||||||
// }
|
|
||||||
$application_deployment_queue = ApplicationDeploymentQueue::where('deployment_uuid', $deploymentUuid)->first();
|
$application_deployment_queue = ApplicationDeploymentQueue::where('deployment_uuid', $deploymentUuid)->first();
|
||||||
if (! $application_deployment_queue) {
|
if (! $application_deployment_queue) {
|
||||||
return redirect()->route('project.application.deployment.index', [
|
return redirect()->route('project.application.deployment.index', [
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'application_uuid' => $application->uuid,
|
'application_uuid' => $application->uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@ class DeploymentNavbar extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->application = Application::find($this->application_deployment_queue->application_id);
|
$this->application = Application::ownedByCurrentTeam()->find($this->application_deployment_queue->application_id);
|
||||||
$this->server = $this->application->destination->server;
|
$this->server = $this->application->destination->server;
|
||||||
$this->is_debug_enabled = $this->application->settings->is_debug_enabled;
|
$this->is_debug_enabled = $this->application->settings->is_debug_enabled;
|
||||||
}
|
}
|
||||||
|
@@ -327,7 +327,7 @@ class General extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function set_redirect()
|
public function setRedirect()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$has_www = collect($this->application->fqdns)->filter(fn ($fqdn) => str($fqdn)->contains('www.'))->count();
|
$has_www = collect($this->application->fqdns)->filter(fn ($fqdn) => str($fqdn)->contains('www.'))->count();
|
||||||
@@ -360,10 +360,10 @@ class General extends Component
|
|||||||
if ($warning) {
|
if ($warning) {
|
||||||
$this->dispatch('warning', __('warning.sslipdomain'));
|
$this->dispatch('warning', __('warning.sslipdomain'));
|
||||||
}
|
}
|
||||||
$this->resetDefaultLabels();
|
// $this->resetDefaultLabels();
|
||||||
|
|
||||||
if ($this->application->isDirty('redirect')) {
|
if ($this->application->isDirty('redirect')) {
|
||||||
$this->set_redirect();
|
$this->setRedirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkFqdns();
|
$this->checkFqdns();
|
||||||
|
@@ -38,7 +38,7 @@ class Heading extends Component
|
|||||||
{
|
{
|
||||||
$this->parameters = [
|
$this->parameters = [
|
||||||
'project_uuid' => $this->application->project()->uuid,
|
'project_uuid' => $this->application->project()->uuid,
|
||||||
'environment_name' => $this->application->environment->name,
|
'environment_uuid' => $this->application->environment->uuid,
|
||||||
'application_uuid' => $this->application->uuid,
|
'application_uuid' => $this->application->uuid,
|
||||||
];
|
];
|
||||||
$lastDeployment = $this->application->get_last_successful_deployment();
|
$lastDeployment = $this->application->get_last_successful_deployment();
|
||||||
@@ -94,7 +94,7 @@ class Heading extends Component
|
|||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'application_uuid' => $this->parameters['application_uuid'],
|
'application_uuid' => $this->parameters['application_uuid'],
|
||||||
'deployment_uuid' => $this->deploymentUuid,
|
'deployment_uuid' => $this->deploymentUuid,
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
'environment_uuid' => $this->parameters['environment_uuid'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ class Heading extends Component
|
|||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'application_uuid' => $this->parameters['application_uuid'],
|
'application_uuid' => $this->parameters['application_uuid'],
|
||||||
'deployment_uuid' => $this->deploymentUuid,
|
'deployment_uuid' => $this->deploymentUuid,
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
'environment_uuid' => $this->parameters['environment_uuid'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -171,7 +171,7 @@ class Previews extends Component
|
|||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'application_uuid' => $this->parameters['application_uuid'],
|
'application_uuid' => $this->parameters['application_uuid'],
|
||||||
'deployment_uuid' => $this->deployment_uuid,
|
'deployment_uuid' => $this->deployment_uuid,
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
'environment_uuid' => $this->parameters['environment_uuid'],
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
|
@@ -37,7 +37,7 @@ class Rollback extends Component
|
|||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'application_uuid' => $this->parameters['application_uuid'],
|
'application_uuid' => $this->parameters['application_uuid'],
|
||||||
'deployment_uuid' => $deployment_uuid,
|
'deployment_uuid' => $deployment_uuid,
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
'environment_uuid' => $this->parameters['environment_uuid'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ class CloneMe extends Component
|
|||||||
{
|
{
|
||||||
public string $project_uuid;
|
public string $project_uuid;
|
||||||
|
|
||||||
public string $environment_name;
|
public string $environment_uuid;
|
||||||
|
|
||||||
public int $project_id;
|
public int $project_id;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ class CloneMe extends Component
|
|||||||
{
|
{
|
||||||
$this->project_uuid = $project_uuid;
|
$this->project_uuid = $project_uuid;
|
||||||
$this->project = Project::where('uuid', $project_uuid)->firstOrFail();
|
$this->project = Project::where('uuid', $project_uuid)->firstOrFail();
|
||||||
$this->environment = $this->project->environments->where('name', $this->environment_name)->first();
|
$this->environment = $this->project->environments->where('uuid', $this->environment_uuid)->first();
|
||||||
$this->project_id = $this->project->id;
|
$this->project_id = $this->project->id;
|
||||||
$this->servers = currentTeam()->servers;
|
$this->servers = currentTeam()->servers;
|
||||||
$this->newName = str($this->project->name.'-clone-'.(string) new Cuid2)->slug();
|
$this->newName = str($this->project->name.'-clone-'.(string) new Cuid2)->slug();
|
||||||
@@ -89,6 +89,7 @@ class CloneMe extends Component
|
|||||||
if ($this->environment->name !== 'production') {
|
if ($this->environment->name !== 'production') {
|
||||||
$project->environments()->create([
|
$project->environments()->create([
|
||||||
'name' => $this->environment->name,
|
'name' => $this->environment->name,
|
||||||
|
'uuid' => (string) new Cuid2,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$environment = $project->environments->where('name', $this->environment->name)->first();
|
$environment = $project->environments->where('name', $this->environment->name)->first();
|
||||||
@@ -100,6 +101,7 @@ class CloneMe extends Component
|
|||||||
$project = $this->project;
|
$project = $this->project;
|
||||||
$environment = $this->project->environments()->create([
|
$environment = $this->project->environments()->create([
|
||||||
'name' => $this->newName,
|
'name' => $this->newName,
|
||||||
|
'uuid' => (string) new Cuid2,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$applications = $this->environment->applications;
|
$applications = $this->environment->applications;
|
||||||
@@ -119,7 +121,7 @@ class CloneMe extends Component
|
|||||||
$environmentVaribles = $application->environment_variables()->get();
|
$environmentVaribles = $application->environment_variables()->get();
|
||||||
foreach ($environmentVaribles as $environmentVarible) {
|
foreach ($environmentVaribles as $environmentVarible) {
|
||||||
$newEnvironmentVariable = $environmentVarible->replicate()->fill([
|
$newEnvironmentVariable = $environmentVarible->replicate()->fill([
|
||||||
'application_id' => $newApplication->id,
|
'resourceable_id' => $newApplication->id,
|
||||||
]);
|
]);
|
||||||
$newEnvironmentVariable->save();
|
$newEnvironmentVariable->save();
|
||||||
}
|
}
|
||||||
@@ -145,17 +147,8 @@ class CloneMe extends Component
|
|||||||
$environmentVaribles = $database->environment_variables()->get();
|
$environmentVaribles = $database->environment_variables()->get();
|
||||||
foreach ($environmentVaribles as $environmentVarible) {
|
foreach ($environmentVaribles as $environmentVarible) {
|
||||||
$payload = [];
|
$payload = [];
|
||||||
if ($database->type() === 'standalone-postgresql') {
|
$payload['resourceable_id'] = $newDatabase->id;
|
||||||
$payload['standalone_postgresql_id'] = $newDatabase->id;
|
$payload['resourceable_type'] = $newDatabase->getMorphClass();
|
||||||
} elseif ($database->type() === 'standalone-redis') {
|
|
||||||
$payload['standalone_redis_id'] = $newDatabase->id;
|
|
||||||
} elseif ($database->type() === 'standalone-mongodb') {
|
|
||||||
$payload['standalone_mongodb_id'] = $newDatabase->id;
|
|
||||||
} elseif ($database->type() === 'standalone-mysql') {
|
|
||||||
$payload['standalone_mysql_id'] = $newDatabase->id;
|
|
||||||
} elseif ($database->type() === 'standalone-mariadb') {
|
|
||||||
$payload['standalone_mariadb_id'] = $newDatabase->id;
|
|
||||||
}
|
|
||||||
$newEnvironmentVariable = $environmentVarible->replicate()->fill($payload);
|
$newEnvironmentVariable = $environmentVarible->replicate()->fill($payload);
|
||||||
$newEnvironmentVariable->save();
|
$newEnvironmentVariable->save();
|
||||||
}
|
}
|
||||||
@@ -183,7 +176,7 @@ class CloneMe extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.resource.index', [
|
return redirect()->route('project.resource.index', [
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
]);
|
]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
|
@@ -22,7 +22,7 @@ class Execution extends Component
|
|||||||
if (! $project) {
|
if (! $project) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
|
$environment = $project->load(['environments'])->environments->where('uuid', request()->route('environment_uuid'))->first()->load(['applications']);
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ class Index extends Component
|
|||||||
if (! $project) {
|
if (! $project) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
|
$environment = $project->load(['environments'])->environments->where('uuid', request()->route('environment_uuid'))->first()->load(['applications']);
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ class Index extends Component
|
|||||||
) {
|
) {
|
||||||
return redirect()->route('project.database.configuration', [
|
return redirect()->route('project.database.configuration', [
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'database_uuid' => $database->uuid,
|
'database_uuid' => $database->uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,9 @@ class BackupEdit extends Component
|
|||||||
#[Validate(['required', 'string'])]
|
#[Validate(['required', 'string'])]
|
||||||
public string $frequency = '';
|
public string $frequency = '';
|
||||||
|
|
||||||
|
#[Validate(['string'])]
|
||||||
|
public string $timezone = '';
|
||||||
|
|
||||||
#[Validate(['required', 'integer', 'min:1'])]
|
#[Validate(['required', 'integer', 'min:1'])]
|
||||||
public int $numberOfBackupsLocally = 1;
|
public int $numberOfBackupsLocally = 1;
|
||||||
|
|
||||||
@@ -68,7 +71,6 @@ class BackupEdit extends Component
|
|||||||
public function syncData(bool $toModel = false)
|
public function syncData(bool $toModel = false)
|
||||||
{
|
{
|
||||||
if ($toModel) {
|
if ($toModel) {
|
||||||
$this->customValidate();
|
|
||||||
$this->backup->enabled = $this->backupEnabled;
|
$this->backup->enabled = $this->backupEnabled;
|
||||||
$this->backup->frequency = $this->frequency;
|
$this->backup->frequency = $this->frequency;
|
||||||
$this->backup->number_of_backups_locally = $this->numberOfBackupsLocally;
|
$this->backup->number_of_backups_locally = $this->numberOfBackupsLocally;
|
||||||
@@ -76,10 +78,12 @@ class BackupEdit extends Component
|
|||||||
$this->backup->s3_storage_id = $this->s3StorageId;
|
$this->backup->s3_storage_id = $this->s3StorageId;
|
||||||
$this->backup->databases_to_backup = $this->databasesToBackup;
|
$this->backup->databases_to_backup = $this->databasesToBackup;
|
||||||
$this->backup->dump_all = $this->dumpAll;
|
$this->backup->dump_all = $this->dumpAll;
|
||||||
|
$this->customValidate();
|
||||||
$this->backup->save();
|
$this->backup->save();
|
||||||
} else {
|
} else {
|
||||||
$this->backupEnabled = $this->backup->enabled;
|
$this->backupEnabled = $this->backup->enabled;
|
||||||
$this->frequency = $this->backup->frequency;
|
$this->frequency = $this->backup->frequency;
|
||||||
|
$this->timezone = data_get($this->backup->server(), 'settings.server_timezone', 'Instance timezone');
|
||||||
$this->numberOfBackupsLocally = $this->backup->number_of_backups_locally;
|
$this->numberOfBackupsLocally = $this->backup->number_of_backups_locally;
|
||||||
$this->saveS3 = $this->backup->save_s3;
|
$this->saveS3 = $this->backup->save_s3;
|
||||||
$this->s3StorageId = $this->backup->s3_storage_id;
|
$this->s3StorageId = $this->backup->s3_storage_id;
|
||||||
@@ -183,12 +187,12 @@ class BackupEdit extends Component
|
|||||||
|
|
||||||
private function deleteAssociatedBackupsS3()
|
private function deleteAssociatedBackupsS3()
|
||||||
{
|
{
|
||||||
//Add function to delete backups from S3
|
// Add function to delete backups from S3
|
||||||
}
|
}
|
||||||
|
|
||||||
private function deleteAssociatedBackupsSftp()
|
private function deleteAssociatedBackupsSftp()
|
||||||
{
|
{
|
||||||
//Add function to delete backups from SFTP
|
// Add function to delete backups from SFTP
|
||||||
}
|
}
|
||||||
|
|
||||||
private function deleteEmptyBackupFolder($folderPath, $server)
|
private function deleteEmptyBackupFolder($folderPath, $server)
|
||||||
|
@@ -9,11 +9,9 @@ class BackupNow extends Component
|
|||||||
{
|
{
|
||||||
public $backup;
|
public $backup;
|
||||||
|
|
||||||
public function backup_now()
|
public function backupNow()
|
||||||
{
|
{
|
||||||
dispatch(new DatabaseBackupJob(
|
DatabaseBackupJob::dispatch($this->backup);
|
||||||
backup: $this->backup
|
|
||||||
));
|
|
||||||
$this->dispatch('success', 'Backup queued. It will be available in a few minutes.');
|
$this->dispatch('success', 'Backup queued. It will be available in a few minutes.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,23 +6,34 @@ use Livewire\Component;
|
|||||||
|
|
||||||
class Configuration extends Component
|
class Configuration extends Component
|
||||||
{
|
{
|
||||||
|
public $currentRoute;
|
||||||
|
|
||||||
public $database;
|
public $database;
|
||||||
|
|
||||||
|
public $project;
|
||||||
|
|
||||||
|
public $environment;
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
|
$this->currentRoute = request()->route()->getName();
|
||||||
if (! $project) {
|
|
||||||
return redirect()->route('dashboard');
|
$project = currentTeam()
|
||||||
}
|
->projects()
|
||||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
|
->select('id', 'uuid', 'team_id')
|
||||||
if (! $environment) {
|
->where('uuid', request()->route('project_uuid'))
|
||||||
return redirect()->route('dashboard');
|
->firstOrFail();
|
||||||
}
|
$environment = $project->environments()
|
||||||
$database = $environment->databases()->where('uuid', request()->route('database_uuid'))->first();
|
->select('id', 'name', 'project_id', 'uuid')
|
||||||
if (! $database) {
|
->where('uuid', request()->route('environment_uuid'))
|
||||||
return redirect()->route('dashboard');
|
->firstOrFail();
|
||||||
}
|
$database = $environment->databases()
|
||||||
|
->where('uuid', request()->route('database_uuid'))
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
$this->database = $database;
|
$this->database = $database;
|
||||||
|
$this->project = $project;
|
||||||
|
$this->environment = $environment;
|
||||||
if (str($this->database->status)->startsWith('running') && is_null($this->database->config_hash)) {
|
if (str($this->database->status)->startsWith('running') && is_null($this->database->config_hash)) {
|
||||||
$this->database->isConfigurationChanged(true);
|
$this->database->isConfigurationChanged(true);
|
||||||
$this->dispatch('configurationChanged');
|
$this->dispatch('configurationChanged');
|
||||||
|
@@ -37,6 +37,12 @@ class Import extends Component
|
|||||||
|
|
||||||
public array $importCommands = [];
|
public array $importCommands = [];
|
||||||
|
|
||||||
|
public bool $dumpAll = false;
|
||||||
|
|
||||||
|
public string $restoreCommandText = '';
|
||||||
|
|
||||||
|
public string $customLocation = '';
|
||||||
|
|
||||||
public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB';
|
public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB';
|
||||||
|
|
||||||
public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE';
|
public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE';
|
||||||
@@ -56,10 +62,62 @@ class Import extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
if (isDev()) {
|
||||||
|
$this->customLocation = '/data/coolify/pg-dump-all-1736245863.gz';
|
||||||
|
}
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
$this->getContainers();
|
$this->getContainers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updatedDumpAll($value)
|
||||||
|
{
|
||||||
|
switch ($this->resource->getMorphClass()) {
|
||||||
|
case \App\Models\StandaloneMariadb::class:
|
||||||
|
if ($value === true) {
|
||||||
|
$this->mariadbRestoreCommand = <<<'EOD'
|
||||||
|
for pid in $(mariadb -u root -p$MARIADB_ROOT_PASSWORD -N -e "SELECT id FROM information_schema.processlist WHERE user != 'root';"); do
|
||||||
|
mariadb -u root -p$MARIADB_ROOT_PASSWORD -e "KILL $pid" 2>/dev/null || true
|
||||||
|
done && \
|
||||||
|
mariadb -u root -p$MARIADB_ROOT_PASSWORD -N -e "SELECT CONCAT('DROP DATABASE IF EXISTS \`',schema_name,'\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');" | mariadb -u root -p$MARIADB_ROOT_PASSWORD && \
|
||||||
|
mariadb -u root -p$MARIADB_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`default\`;" && \
|
||||||
|
(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mariadb -u root -p$MARIADB_ROOT_PASSWORD default
|
||||||
|
EOD;
|
||||||
|
$this->restoreCommandText = $this->mariadbRestoreCommand.' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | mariadb -u root -p$MARIADB_ROOT_PASSWORD default';
|
||||||
|
} else {
|
||||||
|
$this->mariadbRestoreCommand = 'mariadb -u $MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case \App\Models\StandaloneMysql::class:
|
||||||
|
if ($value === true) {
|
||||||
|
$this->mysqlRestoreCommand = <<<'EOD'
|
||||||
|
for pid in $(mysql -u root -p$MYSQL_ROOT_PASSWORD -N -e "SELECT id FROM information_schema.processlist WHERE user != 'root';"); do
|
||||||
|
mysql -u root -p$MYSQL_ROOT_PASSWORD -e "KILL $pid" 2>/dev/null || true
|
||||||
|
done && \
|
||||||
|
mysql -u root -p$MYSQL_ROOT_PASSWORD -N -e "SELECT CONCAT('DROP DATABASE IF EXISTS \`',schema_name,'\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');" | mysql -u root -p$MYSQL_ROOT_PASSWORD && \
|
||||||
|
mysql -u root -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`default\`;" && \
|
||||||
|
(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mysql -u root -p$MYSQL_ROOT_PASSWORD default
|
||||||
|
EOD;
|
||||||
|
$this->restoreCommandText = $this->mysqlRestoreCommand.' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | mysql -u root -p$MYSQL_ROOT_PASSWORD default';
|
||||||
|
} else {
|
||||||
|
$this->mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case \App\Models\StandalonePostgresql::class:
|
||||||
|
if ($value === true) {
|
||||||
|
$this->postgresqlRestoreCommand = <<<'EOD'
|
||||||
|
psql -U $POSTGRES_USER -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IS NOT NULL AND pid <> pg_backend_pid()" && \
|
||||||
|
psql -U $POSTGRES_USER -t -c "SELECT datname FROM pg_database WHERE NOT datistemplate" | xargs -I {} dropdb -U $POSTGRES_USER --if-exists {} && \
|
||||||
|
createdb -U $POSTGRES_USER postgres
|
||||||
|
EOD;
|
||||||
|
$this->restoreCommandText = $this->postgresqlRestoreCommand.' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | psql -U $POSTGRES_USER postgres';
|
||||||
|
} else {
|
||||||
|
$this->postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function getContainers()
|
public function getContainers()
|
||||||
{
|
{
|
||||||
$this->containers = collect();
|
$this->containers = collect();
|
||||||
@@ -87,6 +145,24 @@ class Import extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkFile()
|
||||||
|
{
|
||||||
|
if (filled($this->customLocation)) {
|
||||||
|
try {
|
||||||
|
$result = instant_remote_process(["ls -l {$this->customLocation}"], $this->server, throwError: false);
|
||||||
|
if (blank($result)) {
|
||||||
|
$this->dispatch('error', 'The file does not exist or has been deleted.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->filename = $this->customLocation;
|
||||||
|
$this->dispatch('success', 'The file exists.');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function runImport()
|
public function runImport()
|
||||||
{
|
{
|
||||||
if ($this->filename === '') {
|
if ($this->filename === '') {
|
||||||
@@ -95,46 +171,83 @@ class Import extends Component
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$uploadedFilename = "upload/{$this->resource->uuid}/restore";
|
$this->importCommands = [];
|
||||||
$path = Storage::path($uploadedFilename);
|
if (filled($this->customLocation)) {
|
||||||
if (! Storage::exists($uploadedFilename)) {
|
$backupFileName = '/tmp/restore_'.$this->resource->uuid;
|
||||||
$this->dispatch('error', 'The file does not exist or has been deleted.');
|
$this->importCommands[] = "docker cp {$this->customLocation} {$this->container}:{$backupFileName}";
|
||||||
|
$tmpPath = $backupFileName;
|
||||||
|
} else {
|
||||||
|
$backupFileName = "upload/{$this->resource->uuid}/restore";
|
||||||
|
$path = Storage::path($backupFileName);
|
||||||
|
if (! Storage::exists($backupFileName)) {
|
||||||
|
$this->dispatch('error', 'The file does not exist or has been deleted.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
$tmpPath = '/tmp/'.basename($backupFileName).'_'.$this->resource->uuid;
|
||||||
|
instant_scp($path, $tmpPath, $this->server);
|
||||||
|
Storage::delete($backupFileName);
|
||||||
|
$this->importCommands[] = "docker cp {$tmpPath} {$this->container}:{$tmpPath}";
|
||||||
}
|
}
|
||||||
$tmpPath = '/tmp/'.basename($uploadedFilename);
|
|
||||||
instant_scp($path, $tmpPath, $this->server);
|
// Copy the restore command to a script file
|
||||||
Storage::delete($uploadedFilename);
|
$scriptPath = "/tmp/restore_{$this->resource->uuid}.sh";
|
||||||
$this->importCommands[] = "docker cp {$tmpPath} {$this->container}:{$tmpPath}";
|
|
||||||
|
|
||||||
switch ($this->resource->getMorphClass()) {
|
switch ($this->resource->getMorphClass()) {
|
||||||
case \App\Models\StandaloneMariadb::class:
|
case \App\Models\StandaloneMariadb::class:
|
||||||
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->mariadbRestoreCommand} < {$tmpPath}'";
|
$restoreCommand = $this->mariadbRestoreCommand;
|
||||||
$this->importCommands[] = "rm {$tmpPath}";
|
if ($this->dumpAll) {
|
||||||
|
$restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mariadb -u root -p\$MARIADB_ROOT_PASSWORD";
|
||||||
|
} else {
|
||||||
|
$restoreCommand .= " < {$tmpPath}";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case \App\Models\StandaloneMysql::class:
|
case \App\Models\StandaloneMysql::class:
|
||||||
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->mysqlRestoreCommand} < {$tmpPath}'";
|
$restoreCommand = $this->mysqlRestoreCommand;
|
||||||
$this->importCommands[] = "rm {$tmpPath}";
|
if ($this->dumpAll) {
|
||||||
|
$restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mysql -u root -p\$MYSQL_ROOT_PASSWORD";
|
||||||
|
} else {
|
||||||
|
$restoreCommand .= " < {$tmpPath}";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case \App\Models\StandalonePostgresql::class:
|
case \App\Models\StandalonePostgresql::class:
|
||||||
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->postgresqlRestoreCommand} {$tmpPath}'";
|
$restoreCommand = $this->postgresqlRestoreCommand;
|
||||||
$this->importCommands[] = "rm {$tmpPath}";
|
if ($this->dumpAll) {
|
||||||
|
$restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | psql -U \$POSTGRES_USER postgres";
|
||||||
|
} else {
|
||||||
|
$restoreCommand .= " {$tmpPath}";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case \App\Models\StandaloneMongodb::class:
|
case \App\Models\StandaloneMongodb::class:
|
||||||
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->mongodbRestoreCommand}{$tmpPath}'";
|
$restoreCommand = $this->mongodbRestoreCommand;
|
||||||
$this->importCommands[] = "rm {$tmpPath}";
|
if ($this->dumpAll === false) {
|
||||||
|
$restoreCommand .= " {$tmpPath}";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->importCommands[] = "docker exec {$this->container} sh -c 'rm {$tmpPath}'";
|
$restoreCommandBase64 = base64_encode($restoreCommand);
|
||||||
|
$this->importCommands[] = "echo \"{$restoreCommandBase64}\" | base64 -d > {$scriptPath}";
|
||||||
|
$this->importCommands[] = "chmod +x {$scriptPath}";
|
||||||
|
$this->importCommands[] = "docker cp {$scriptPath} {$this->container}:{$scriptPath}";
|
||||||
|
|
||||||
|
$this->importCommands[] = "docker exec {$this->container} sh -c '{$scriptPath}'";
|
||||||
$this->importCommands[] = "docker exec {$this->container} sh -c 'echo \"Import finished with exit code $?\"'";
|
$this->importCommands[] = "docker exec {$this->container} sh -c 'echo \"Import finished with exit code $?\"'";
|
||||||
|
|
||||||
if (! empty($this->importCommands)) {
|
if (! empty($this->importCommands)) {
|
||||||
$activity = remote_process($this->importCommands, $this->server, ignore_errors: true);
|
$activity = remote_process($this->importCommands, $this->server, ignore_errors: true, callEventOnFinish: 'RestoreJobFinished', callEventData: [
|
||||||
|
'scriptPath' => $scriptPath,
|
||||||
|
'tmpPath' => $tmpPath,
|
||||||
|
'container' => $this->container,
|
||||||
|
'serverId' => $this->server->id,
|
||||||
|
]);
|
||||||
$this->dispatch('activityMonitor', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
|
} finally {
|
||||||
|
$this->filename = null;
|
||||||
|
$this->importCommands = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,8 +9,6 @@ use App\Models\StandalonePostgresql;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
use function Aws\filter;
|
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
public StandalonePostgresql $database;
|
public StandalonePostgresql $database;
|
||||||
@@ -126,10 +124,52 @@ class General extends Component
|
|||||||
|
|
||||||
public function save_init_script($script)
|
public function save_init_script($script)
|
||||||
{
|
{
|
||||||
$this->database->init_scripts = filter($this->database->init_scripts, fn ($s) => $s['filename'] !== $script['filename']);
|
$initScripts = collect($this->database->init_scripts ?? []);
|
||||||
$this->database->init_scripts = array_merge($this->database->init_scripts, [$script]);
|
|
||||||
|
$existingScript = $initScripts->firstWhere('filename', $script['filename']);
|
||||||
|
$oldScript = $initScripts->firstWhere('index', $script['index']);
|
||||||
|
|
||||||
|
if ($existingScript && $existingScript['index'] !== $script['index']) {
|
||||||
|
$this->dispatch('error', 'A script with this filename already exists.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$container_name = $this->database->uuid;
|
||||||
|
$configuration_dir = database_configuration_dir().'/'.$container_name;
|
||||||
|
|
||||||
|
if ($oldScript && $oldScript['filename'] !== $script['filename']) {
|
||||||
|
$old_file_path = "$configuration_dir/docker-entrypoint-initdb.d/{$oldScript['filename']}";
|
||||||
|
$delete_command = "rm -f $old_file_path";
|
||||||
|
try {
|
||||||
|
instant_remote_process([$delete_command], $this->server);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->dispatch('error', 'Failed to remove old init script from server: '.$e->getMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$index = $initScripts->search(function ($item) use ($script) {
|
||||||
|
return $item['index'] === $script['index'];
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($index !== false) {
|
||||||
|
$initScripts[$index] = $script;
|
||||||
|
} else {
|
||||||
|
$initScripts->push($script);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->database->init_scripts = $initScripts->values()
|
||||||
|
->map(function ($item, $index) {
|
||||||
|
$item['index'] = $index;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
})
|
||||||
|
->all();
|
||||||
|
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'Init script saved.');
|
$this->dispatch('success', 'Init script saved and updated.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete_init_script($script)
|
public function delete_init_script($script)
|
||||||
@@ -137,12 +177,32 @@ class General extends Component
|
|||||||
$collection = collect($this->database->init_scripts);
|
$collection = collect($this->database->init_scripts);
|
||||||
$found = $collection->firstWhere('filename', $script['filename']);
|
$found = $collection->firstWhere('filename', $script['filename']);
|
||||||
if ($found) {
|
if ($found) {
|
||||||
$this->database->init_scripts = $collection->filter(fn ($s) => $s['filename'] !== $script['filename'])->toArray();
|
$container_name = $this->database->uuid;
|
||||||
|
$configuration_dir = database_configuration_dir().'/'.$container_name;
|
||||||
|
$file_path = "$configuration_dir/docker-entrypoint-initdb.d/{$script['filename']}";
|
||||||
|
|
||||||
|
$command = "rm -f $file_path";
|
||||||
|
try {
|
||||||
|
instant_remote_process([$command], $this->server);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->dispatch('error', 'Failed to remove init script from server: '.$e->getMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$updatedScripts = $collection->filter(fn ($s) => $s['filename'] !== $script['filename'])
|
||||||
|
->values()
|
||||||
|
->map(function ($item, $index) {
|
||||||
|
$item['index'] = $index;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
})
|
||||||
|
->all();
|
||||||
|
|
||||||
|
$this->database->init_scripts = $updatedScripts;
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->refresh();
|
$this->refresh();
|
||||||
$this->dispatch('success', 'Init script deleted.');
|
$this->dispatch('success', 'Init script deleted from the database and the server.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,11 +23,11 @@ class EnvironmentEdit extends Component
|
|||||||
#[Validate(['nullable', 'string', 'max:255'])]
|
#[Validate(['nullable', 'string', 'max:255'])]
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
public function mount(string $project_uuid, string $environment_name)
|
public function mount(string $project_uuid, string $environment_uuid)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->project = Project::ownedByCurrentTeam()->where('uuid', $project_uuid)->firstOrFail();
|
$this->project = Project::ownedByCurrentTeam()->where('uuid', $project_uuid)->firstOrFail();
|
||||||
$this->environment = $this->project->environments()->where('name', $environment_name)->firstOrFail();
|
$this->environment = $this->project->environments()->where('uuid', $environment_uuid)->firstOrFail();
|
||||||
$this->syncData();
|
$this->syncData();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
@@ -52,7 +52,10 @@ class EnvironmentEdit extends Component
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->syncData(true);
|
$this->syncData(true);
|
||||||
$this->redirectRoute('project.environment.edit', ['environment_name' => $this->environment->name, 'project_uuid' => $this->project->uuid]);
|
$this->redirectRoute('project.environment.edit', [
|
||||||
|
'environment_uuid' => $this->environment->uuid,
|
||||||
|
'project_uuid' => $this->project->uuid,
|
||||||
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ namespace App\Livewire\Project;
|
|||||||
use App\Models\PrivateKey;
|
use App\Models\PrivateKey;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use Illuminate\Support\Facades\Redirect;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Index extends Component
|
class Index extends Component
|
||||||
@@ -30,4 +31,18 @@ class Index extends Component
|
|||||||
{
|
{
|
||||||
return view('livewire.project.index');
|
return view('livewire.project.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function navigateToProject($projectUuid)
|
||||||
|
{
|
||||||
|
$project = Project::where('uuid', $projectUuid)->first();
|
||||||
|
|
||||||
|
if ($project && $project->environments->count() === 1) {
|
||||||
|
return Redirect::route('project.resource.index', [
|
||||||
|
'project_uuid' => $projectUuid,
|
||||||
|
'environment_uuid' => $project->environments->first()->uuid,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect::route('project.show', ['project_uuid' => $projectUuid]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -59,7 +59,7 @@ class DockerCompose extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
$environment = $project->load(['environments'])->environments->where('uuid', $this->parameters['environment_uuid'])->first();
|
||||||
|
|
||||||
$destination_uuid = $this->query['destination'];
|
$destination_uuid = $this->query['destination'];
|
||||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||||
@@ -87,7 +87,8 @@ class DockerCompose extends Component
|
|||||||
'value' => $variable,
|
'value' => $variable,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
'service_id' => $service->id,
|
'resourceable_id' => $service->id,
|
||||||
|
'resourceable_type' => $service->getMorphClass(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$service->name = "service-$service->uuid";
|
$service->name = "service-$service->uuid";
|
||||||
@@ -96,7 +97,7 @@ class DockerCompose extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.service.configuration', [
|
return redirect()->route('project.service.configuration', [
|
||||||
'service_uuid' => $service->uuid,
|
'service_uuid' => $service->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@@ -45,7 +45,7 @@ class DockerImage extends Component
|
|||||||
$destination_class = $destination->getMorphClass();
|
$destination_class = $destination->getMorphClass();
|
||||||
|
|
||||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
$environment = $project->load(['environments'])->environments->where('uuid', $this->parameters['environment_uuid'])->first();
|
||||||
$application = Application::create([
|
$application = Application::create([
|
||||||
'name' => 'docker-image-'.new Cuid2,
|
'name' => 'docker-image-'.new Cuid2,
|
||||||
'repository_project_id' => 0,
|
'repository_project_id' => 0,
|
||||||
@@ -69,7 +69,7 @@ class DockerImage extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.application.configuration', [
|
return redirect()->route('project.application.configuration', [
|
||||||
'application_uuid' => $application->uuid,
|
'application_uuid' => $application->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\New;
|
|||||||
|
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
class EmptyProject extends Component
|
class EmptyProject extends Component
|
||||||
{
|
{
|
||||||
@@ -12,8 +13,9 @@ class EmptyProject extends Component
|
|||||||
$project = Project::create([
|
$project = Project::create([
|
||||||
'name' => generate_random_name(),
|
'name' => generate_random_name(),
|
||||||
'team_id' => currentTeam()->id,
|
'team_id' => currentTeam()->id,
|
||||||
|
'uuid' => (string) new Cuid2,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('project.show', ['project_uuid' => $project->uuid, 'environment_name' => 'production']);
|
return redirect()->route('project.show', ['project_uuid' => $project->uuid, 'environment_uuid' => $project->environments->first()->uuid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -177,7 +177,7 @@ class GithubPrivateRepository extends Component
|
|||||||
$destination_class = $destination->getMorphClass();
|
$destination_class = $destination->getMorphClass();
|
||||||
|
|
||||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
$environment = $project->load(['environments'])->environments->where('uuid', $this->parameters['environment_uuid'])->first();
|
||||||
|
|
||||||
$application = Application::create([
|
$application = Application::create([
|
||||||
'name' => generate_application_name($this->selected_repository_owner.'/'.$this->selected_repository_repo, $this->selected_branch_name),
|
'name' => generate_application_name($this->selected_repository_owner.'/'.$this->selected_repository_repo, $this->selected_branch_name),
|
||||||
@@ -211,7 +211,7 @@ class GithubPrivateRepository extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.application.configuration', [
|
return redirect()->route('project.application.configuration', [
|
||||||
'application_uuid' => $application->uuid,
|
'application_uuid' => $application->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@@ -136,7 +136,7 @@ class GithubPrivateRepositoryDeployKey extends Component
|
|||||||
$this->get_git_source();
|
$this->get_git_source();
|
||||||
|
|
||||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
$environment = $project->load(['environments'])->environments->where('uuid', $this->parameters['environment_uuid'])->first();
|
||||||
if ($this->git_source === 'other') {
|
if ($this->git_source === 'other') {
|
||||||
$application_init = [
|
$application_init = [
|
||||||
'name' => generate_random_name(),
|
'name' => generate_random_name(),
|
||||||
@@ -184,7 +184,7 @@ class GithubPrivateRepositoryDeployKey extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.application.configuration', [
|
return redirect()->route('project.application.configuration', [
|
||||||
'application_uuid' => $application->uuid,
|
'application_uuid' => $application->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@@ -225,7 +225,7 @@ class PublicGitRepository extends Component
|
|||||||
$this->validate();
|
$this->validate();
|
||||||
$destination_uuid = $this->query['destination'];
|
$destination_uuid = $this->query['destination'];
|
||||||
$project_uuid = $this->parameters['project_uuid'];
|
$project_uuid = $this->parameters['project_uuid'];
|
||||||
$environment_name = $this->parameters['environment_name'];
|
$environment_uuid = $this->parameters['environment_uuid'];
|
||||||
|
|
||||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||||
if (! $destination) {
|
if (! $destination) {
|
||||||
@@ -237,7 +237,7 @@ class PublicGitRepository extends Component
|
|||||||
$destination_class = $destination->getMorphClass();
|
$destination_class = $destination->getMorphClass();
|
||||||
|
|
||||||
$project = Project::where('uuid', $project_uuid)->first();
|
$project = Project::where('uuid', $project_uuid)->first();
|
||||||
$environment = $project->load(['environments'])->environments->where('name', $environment_name)->first();
|
$environment = $project->load(['environments'])->environments->where('uuid', $environment_uuid)->first();
|
||||||
|
|
||||||
if ($this->build_pack === 'dockercompose' && isDev() && $this->new_compose_services) {
|
if ($this->build_pack === 'dockercompose' && isDev() && $this->new_compose_services) {
|
||||||
$server = $destination->server;
|
$server = $destination->server;
|
||||||
@@ -260,7 +260,7 @@ class PublicGitRepository extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.service.configuration', [
|
return redirect()->route('project.service.configuration', [
|
||||||
'service_uuid' => $service->uuid,
|
'service_uuid' => $service->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ class PublicGitRepository extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.application.configuration', [
|
return redirect()->route('project.application.configuration', [
|
||||||
'application_uuid' => $application->uuid,
|
'application_uuid' => $application->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@@ -23,6 +23,8 @@ class Select extends Component
|
|||||||
|
|
||||||
public Collection|null|Server $servers;
|
public Collection|null|Server $servers;
|
||||||
|
|
||||||
|
public bool $onlyBuildServerAvailable = false;
|
||||||
|
|
||||||
public ?Collection $standaloneDockers;
|
public ?Collection $standaloneDockers;
|
||||||
|
|
||||||
public ?Collection $swarmDockers;
|
public ?Collection $swarmDockers;
|
||||||
@@ -61,7 +63,7 @@ class Select extends Component
|
|||||||
}
|
}
|
||||||
$projectUuid = data_get($this->parameters, 'project_uuid');
|
$projectUuid = data_get($this->parameters, 'project_uuid');
|
||||||
$this->environments = Project::whereUuid($projectUuid)->first()->environments;
|
$this->environments = Project::whereUuid($projectUuid)->first()->environments;
|
||||||
$this->selectedEnvironment = data_get($this->parameters, 'environment_name');
|
$this->selectedEnvironment = data_get($this->parameters, 'environment_uuid');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
@@ -73,20 +75,10 @@ class Select extends Component
|
|||||||
{
|
{
|
||||||
return redirect()->route('project.resource.create', [
|
return redirect()->route('project.resource.create', [
|
||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'environment_name' => $this->selectedEnvironment,
|
'environment_uuid' => $this->selectedEnvironment,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public function addExistingPostgresql()
|
|
||||||
// {
|
|
||||||
// try {
|
|
||||||
// instantCommand("psql {$this->existingPostgresqlUrl} -c 'SELECT 1'");
|
|
||||||
// $this->dispatch('success', 'Successfully connected to the database.');
|
|
||||||
// } catch (\Throwable $e) {
|
|
||||||
// return handleError($e, $this);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public function loadServices()
|
public function loadServices()
|
||||||
{
|
{
|
||||||
$services = get_service_templates(true);
|
$services = get_service_templates(true);
|
||||||
@@ -308,7 +300,7 @@ class Select extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.resource.create', [
|
return redirect()->route('project.resource.create', [
|
||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
'environment_uuid' => $this->parameters['environment_uuid'],
|
||||||
'type' => $this->type,
|
'type' => $this->type,
|
||||||
'destination' => $this->destination_uuid,
|
'destination' => $this->destination_uuid,
|
||||||
'server_id' => $this->server_id,
|
'server_id' => $this->server_id,
|
||||||
@@ -323,7 +315,7 @@ class Select extends Component
|
|||||||
} else {
|
} else {
|
||||||
return redirect()->route('project.resource.create', [
|
return redirect()->route('project.resource.create', [
|
||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
'environment_uuid' => $this->parameters['environment_uuid'],
|
||||||
'type' => $this->type,
|
'type' => $this->type,
|
||||||
'destination' => $this->destination_uuid,
|
'destination' => $this->destination_uuid,
|
||||||
'server_id' => $this->server_id,
|
'server_id' => $this->server_id,
|
||||||
@@ -335,5 +327,11 @@ class Select extends Component
|
|||||||
{
|
{
|
||||||
$this->servers = Server::isUsable()->get()->sortBy('name');
|
$this->servers = Server::isUsable()->get()->sortBy('name');
|
||||||
$this->allServers = $this->servers;
|
$this->allServers = $this->servers;
|
||||||
|
|
||||||
|
if ($this->allServers && $this->allServers->isNotEmpty()) {
|
||||||
|
$this->onlyBuildServerAvailable = $this->allServers->every(function ($server) {
|
||||||
|
return $server->isBuildServer();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ CMD ["nginx", "-g", "daemon off;"]
|
|||||||
$destination_class = $destination->getMorphClass();
|
$destination_class = $destination->getMorphClass();
|
||||||
|
|
||||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
$environment = $project->load(['environments'])->environments->where('uuid', $this->parameters['environment_uuid'])->first();
|
||||||
|
|
||||||
$port = get_port_from_dockerfile($this->dockerfile);
|
$port = get_port_from_dockerfile($this->dockerfile);
|
||||||
if (! $port) {
|
if (! $port) {
|
||||||
@@ -78,7 +78,7 @@ CMD ["nginx", "-g", "daemon off;"]
|
|||||||
|
|
||||||
return redirect()->route('project.application.configuration', [
|
return redirect()->route('project.application.configuration', [
|
||||||
'application_uuid' => $application->uuid,
|
'application_uuid' => $application->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ class Create extends Component
|
|||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$this->project = $project;
|
$this->project = $project;
|
||||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first();
|
$environment = $project->load(['environments'])->environments->where('uuid', request()->route('environment_uuid'))->first();
|
||||||
if (! $environment) {
|
if (! $environment) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ class Create extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.database.configuration', [
|
return redirect()->route('project.database.configuration', [
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'database_uuid' => $database->uuid,
|
'database_uuid' => $database->uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,8 @@ class Create extends Component
|
|||||||
EnvironmentVariable::create([
|
EnvironmentVariable::create([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'service_id' => $service->id,
|
'resourceable_id' => $service->id,
|
||||||
|
'resourceable_type' => $service->getMorphClass(),
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
]);
|
]);
|
||||||
@@ -106,7 +107,7 @@ class Create extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.service.configuration', [
|
return redirect()->route('project.service.configuration', [
|
||||||
'service_uuid' => $service->uuid,
|
'service_uuid' => $service->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
'project_uuid' => $project->uuid,
|
'project_uuid' => $project->uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ class EnvironmentSelect extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->selectedEnvironment = request()->route('environment_name');
|
$this->selectedEnvironment = request()->route('environment_uuid');
|
||||||
$this->project_uuid = request()->route('project_uuid');
|
$this->project_uuid = request()->route('project_uuid');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ class EnvironmentSelect extends Component
|
|||||||
} else {
|
} else {
|
||||||
return redirect()->route('project.resource.index', [
|
return redirect()->route('project.resource.index', [
|
||||||
'project_uuid' => $this->project_uuid,
|
'project_uuid' => $this->project_uuid,
|
||||||
'environment_name' => $value,
|
'environment_uuid' => $value,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Resource;
|
|||||||
|
|
||||||
use App\Models\Environment;
|
use App\Models\Environment;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Index extends Component
|
class Index extends Component
|
||||||
@@ -12,39 +13,42 @@ class Index extends Component
|
|||||||
|
|
||||||
public Environment $environment;
|
public Environment $environment;
|
||||||
|
|
||||||
public $applications = [];
|
public Collection $applications;
|
||||||
|
|
||||||
public $postgresqls = [];
|
public Collection $postgresqls;
|
||||||
|
|
||||||
public $redis = [];
|
public Collection $redis;
|
||||||
|
|
||||||
public $mongodbs = [];
|
public Collection $mongodbs;
|
||||||
|
|
||||||
public $mysqls = [];
|
public Collection $mysqls;
|
||||||
|
|
||||||
public $mariadbs = [];
|
public Collection $mariadbs;
|
||||||
|
|
||||||
public $keydbs = [];
|
public Collection $keydbs;
|
||||||
|
|
||||||
public $dragonflies = [];
|
public Collection $dragonflies;
|
||||||
|
|
||||||
public $clickhouses = [];
|
public Collection $clickhouses;
|
||||||
|
|
||||||
public $services = [];
|
public Collection $services;
|
||||||
|
|
||||||
public array $parameters;
|
public array $parameters;
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
$this->applications = $this->postgresqls = $this->redis = $this->mongodbs = $this->mysqls = $this->mariadbs = $this->keydbs = $this->dragonflies = $this->clickhouses = $this->services = collect();
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
$project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
|
$project = currentTeam()
|
||||||
if (! $project) {
|
->projects()
|
||||||
return redirect()->route('dashboard');
|
->select('id', 'uuid', 'team_id', 'name')
|
||||||
}
|
->where('uuid', request()->route('project_uuid'))
|
||||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first();
|
->firstOrFail();
|
||||||
if (! $environment) {
|
$environment = $project->environments()
|
||||||
return redirect()->route('dashboard');
|
->select('id', 'uuid', 'name', 'project_id')
|
||||||
}
|
->where('uuid', request()->route('environment_uuid'))
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
$this->project = $project;
|
$this->project = $project;
|
||||||
$this->environment = $environment->loadCount([
|
$this->environment = $environment->loadCount([
|
||||||
'applications',
|
'applications',
|
||||||
@@ -69,9 +73,9 @@ class Index extends Component
|
|||||||
])->get()->sortBy('name');
|
])->get()->sortBy('name');
|
||||||
$this->applications = $this->applications->map(function ($application) {
|
$this->applications = $this->applications->map(function ($application) {
|
||||||
$application->hrefLink = route('project.application.configuration', [
|
$application->hrefLink = route('project.application.configuration', [
|
||||||
'project_uuid' => $this->project->uuid,
|
'project_uuid' => data_get($application, 'environment.project.uuid'),
|
||||||
'application_uuid' => $application->uuid,
|
'environment_uuid' => data_get($application, 'environment.uuid'),
|
||||||
'environment_name' => $this->environment->name,
|
'application_uuid' => data_get($application, 'uuid'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $application;
|
return $application;
|
||||||
@@ -89,14 +93,6 @@ class Index extends Component
|
|||||||
'clickhouses' => 'clickhouses',
|
'clickhouses' => 'clickhouses',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Load all server-related data first to prevent duplicate queries
|
|
||||||
$serverData = $this->environment->applications()
|
|
||||||
->with(['destination.server.settings'])
|
|
||||||
->get()
|
|
||||||
->pluck('destination.server')
|
|
||||||
->filter()
|
|
||||||
->unique('id');
|
|
||||||
|
|
||||||
foreach ($databaseTypes as $property => $relation) {
|
foreach ($databaseTypes as $property => $relation) {
|
||||||
$this->{$property} = $this->environment->{$relation}()->with([
|
$this->{$property} = $this->environment->{$relation}()->with([
|
||||||
'tags',
|
'tags',
|
||||||
@@ -106,7 +102,7 @@ class Index extends Component
|
|||||||
$db->hrefLink = route('project.database.configuration', [
|
$db->hrefLink = route('project.database.configuration', [
|
||||||
'project_uuid' => $this->project->uuid,
|
'project_uuid' => $this->project->uuid,
|
||||||
'database_uuid' => $db->uuid,
|
'database_uuid' => $db->uuid,
|
||||||
'environment_name' => $this->environment->name,
|
'environment_uuid' => data_get($this->environment, 'uuid'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $db;
|
return $db;
|
||||||
@@ -120,9 +116,9 @@ class Index extends Component
|
|||||||
])->get()->sortBy('name');
|
])->get()->sortBy('name');
|
||||||
$this->services = $this->services->map(function ($service) {
|
$this->services = $this->services->map(function ($service) {
|
||||||
$service->hrefLink = route('project.service.configuration', [
|
$service->hrefLink = route('project.service.configuration', [
|
||||||
'project_uuid' => $this->project->uuid,
|
'project_uuid' => data_get($service, 'environment.project.uuid'),
|
||||||
'service_uuid' => $service->uuid,
|
'environment_uuid' => data_get($service, 'environment.uuid'),
|
||||||
'environment_name' => $this->environment->name,
|
'service_uuid' => data_get($service, 'uuid'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $service;
|
return $service;
|
||||||
|
@@ -9,16 +9,22 @@ use Livewire\Component;
|
|||||||
|
|
||||||
class Configuration extends Component
|
class Configuration extends Component
|
||||||
{
|
{
|
||||||
|
public $currentRoute;
|
||||||
|
|
||||||
|
public $project;
|
||||||
|
|
||||||
|
public $environment;
|
||||||
|
|
||||||
public ?Service $service = null;
|
public ?Service $service = null;
|
||||||
|
|
||||||
public $applications;
|
public $applications;
|
||||||
|
|
||||||
public $databases;
|
public $databases;
|
||||||
|
|
||||||
public array $parameters;
|
|
||||||
|
|
||||||
public array $query;
|
public array $query;
|
||||||
|
|
||||||
|
public array $parameters;
|
||||||
|
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
{
|
{
|
||||||
$userId = Auth::id();
|
$userId = Auth::id();
|
||||||
@@ -38,11 +44,21 @@ class Configuration extends Component
|
|||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
|
$this->currentRoute = request()->route()->getName();
|
||||||
$this->query = request()->query();
|
$this->query = request()->query();
|
||||||
$this->service = Service::whereUuid($this->parameters['service_uuid'])->first();
|
$project = currentTeam()
|
||||||
if (! $this->service) {
|
->projects()
|
||||||
return redirect()->route('dashboard');
|
->select('id', 'uuid', 'team_id')
|
||||||
}
|
->where('uuid', request()->route('project_uuid'))
|
||||||
|
->firstOrFail();
|
||||||
|
$environment = $project->environments()
|
||||||
|
->select('id', 'uuid', 'name', 'project_id')
|
||||||
|
->where('uuid', request()->route('environment_uuid'))
|
||||||
|
->firstOrFail();
|
||||||
|
$this->service = $environment->services()->whereUuid(request()->route('service_uuid'))->firstOrFail();
|
||||||
|
|
||||||
|
$this->project = $project;
|
||||||
|
$this->environment = $environment;
|
||||||
$this->applications = $this->service->applications->sort();
|
$this->applications = $this->service->applications->sort();
|
||||||
$this->databases = $this->service->databases->sort();
|
$this->databases = $this->service->databases->sort();
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,7 @@ class Danger extends Component
|
|||||||
|
|
||||||
public $projectUuid;
|
public $projectUuid;
|
||||||
|
|
||||||
public $environmentName;
|
public $environmentUuid;
|
||||||
|
|
||||||
public bool $delete_configurations = true;
|
public bool $delete_configurations = true;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ class Danger extends Component
|
|||||||
$parameters = get_route_parameters();
|
$parameters = get_route_parameters();
|
||||||
$this->modalId = new Cuid2;
|
$this->modalId = new Cuid2;
|
||||||
$this->projectUuid = data_get($parameters, 'project_uuid');
|
$this->projectUuid = data_get($parameters, 'project_uuid');
|
||||||
$this->environmentName = data_get($parameters, 'environment_name');
|
$this->environmentUuid = data_get($parameters, 'environment_uuid');
|
||||||
|
|
||||||
if ($this->resource === null) {
|
if ($this->resource === null) {
|
||||||
if (isset($parameters['service_uuid'])) {
|
if (isset($parameters['service_uuid'])) {
|
||||||
@@ -107,7 +107,7 @@ class Danger extends Component
|
|||||||
|
|
||||||
return redirect()->route('project.resource.index', [
|
return redirect()->route('project.resource.index', [
|
||||||
'project_uuid' => $this->projectUuid,
|
'project_uuid' => $this->projectUuid,
|
||||||
'environment_name' => $this->environmentName,
|
'environment_uuid' => $this->environmentUuid,
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
|
@@ -8,6 +8,7 @@ use App\Events\ApplicationStatusChanged;
|
|||||||
use App\Models\InstanceSettings;
|
use App\Models\InstanceSettings;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\StandaloneDocker;
|
use App\Models\StandaloneDocker;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
@@ -17,7 +18,7 @@ class Destination extends Component
|
|||||||
{
|
{
|
||||||
public $resource;
|
public $resource;
|
||||||
|
|
||||||
public $networks = [];
|
public Collection $networks;
|
||||||
|
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
{
|
{
|
||||||
@@ -30,6 +31,7 @@ class Destination extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
$this->networks = collect([]);
|
||||||
$this->loadData();
|
$this->loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,38 +57,46 @@ class Destination extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stop(int $server_id)
|
public function stop($serverId)
|
||||||
{
|
{
|
||||||
$server = Server::find($server_id);
|
try {
|
||||||
StopApplicationOneServer::run($this->resource, $server);
|
$server = Server::ownedByCurrentTeam()->findOrFail($serverId);
|
||||||
$this->refreshServers();
|
StopApplicationOneServer::run($this->resource, $server);
|
||||||
|
$this->refreshServers();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function redeploy(int $network_id, int $server_id)
|
public function redeploy(int $network_id, int $server_id)
|
||||||
{
|
{
|
||||||
if ($this->resource->additional_servers->count() > 0 && str($this->resource->docker_registry_image_name)->isEmpty()) {
|
try {
|
||||||
$this->dispatch('error', 'Failed to deploy.', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/multiple-servers">documentation</a>');
|
if ($this->resource->additional_servers->count() > 0 && str($this->resource->docker_registry_image_name)->isEmpty()) {
|
||||||
|
$this->dispatch('error', 'Failed to deploy.', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/multiple-servers">documentation</a>');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
$deployment_uuid = new Cuid2;
|
||||||
|
$server = Server::ownedByCurrentTeam()->findOrFail($server_id);
|
||||||
|
$destination = $server->standaloneDockers->where('id', $network_id)->firstOrFail();
|
||||||
|
queue_application_deployment(
|
||||||
|
deployment_uuid: $deployment_uuid,
|
||||||
|
application: $this->resource,
|
||||||
|
server: $server,
|
||||||
|
destination: $destination,
|
||||||
|
only_this_server: true,
|
||||||
|
no_questions_asked: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
return redirect()->route('project.application.deployment.show', [
|
||||||
|
'project_uuid' => data_get($this->resource, 'environment.project.uuid'),
|
||||||
|
'application_uuid' => data_get($this->resource, 'uuid'),
|
||||||
|
'deployment_uuid' => $deployment_uuid,
|
||||||
|
'environment_uuid' => data_get($this->resource, 'environment.uuid'),
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
$deployment_uuid = new Cuid2;
|
|
||||||
$server = Server::find($server_id);
|
|
||||||
$destination = StandaloneDocker::find($network_id);
|
|
||||||
queue_application_deployment(
|
|
||||||
deployment_uuid: $deployment_uuid,
|
|
||||||
application: $this->resource,
|
|
||||||
server: $server,
|
|
||||||
destination: $destination,
|
|
||||||
only_this_server: true,
|
|
||||||
no_questions_asked: true,
|
|
||||||
);
|
|
||||||
|
|
||||||
return redirect()->route('project.application.deployment.show', [
|
|
||||||
'project_uuid' => data_get($this->resource, 'environment.project.uuid'),
|
|
||||||
'application_uuid' => data_get($this->resource, 'uuid'),
|
|
||||||
'deployment_uuid' => $deployment_uuid,
|
|
||||||
'environment_name' => data_get($this->resource, 'environment.name'),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function promote(int $network_id, int $server_id)
|
public function promote(int $network_id, int $server_id)
|
||||||
@@ -119,23 +129,27 @@ class Destination extends Component
|
|||||||
|
|
||||||
public function removeServer(int $network_id, int $server_id, $password)
|
public function removeServer(int $network_id, int $server_id, $password)
|
||||||
{
|
{
|
||||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
try {
|
||||||
if (! Hash::check($password, Auth::user()->password)) {
|
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||||
$this->addError('password', 'The provided password is incorrect.');
|
if (! Hash::check($password, Auth::user()->password)) {
|
||||||
|
$this->addError('password', 'The provided password is incorrect.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->resource->destination->server->id == $server_id && $this->resource->destination->id == $network_id) {
|
||||||
|
$this->dispatch('error', 'You cannot remove this destination server.', 'You are trying to remove the main server.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$server = Server::ownedByCurrentTeam()->findOrFail($server_id);
|
||||||
|
StopApplicationOneServer::run($this->resource, $server);
|
||||||
|
$this->resource->additional_networks()->detach($network_id, ['server_id' => $server_id]);
|
||||||
|
$this->loadData();
|
||||||
|
ApplicationStatusChanged::dispatch(data_get($this->resource, 'environment.project.team.id'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->resource->destination->server->id == $server_id && $this->resource->destination->id == $network_id) {
|
|
||||||
$this->dispatch('error', 'You cannot remove this destination server.', 'You are trying to remove the main server.');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$server = Server::find($server_id);
|
|
||||||
StopApplicationOneServer::run($this->resource, $server);
|
|
||||||
$this->resource->additional_networks()->detach($network_id, ['server_id' => $server_id]);
|
|
||||||
$this->loadData();
|
|
||||||
ApplicationStatusChanged::dispatch(data_get($this->resource, 'environment.project.team.id'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable;
|
|||||||
|
|
||||||
use App\Models\EnvironmentVariable;
|
use App\Models\EnvironmentVariable;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Visus\Cuid2\Cuid2;
|
|
||||||
|
|
||||||
class All extends Component
|
class All extends Component
|
||||||
{
|
{
|
||||||
@@ -14,38 +13,35 @@ class All extends Component
|
|||||||
|
|
||||||
public bool $showPreview = false;
|
public bool $showPreview = false;
|
||||||
|
|
||||||
public ?string $modalId = null;
|
|
||||||
|
|
||||||
public ?string $variables = null;
|
public ?string $variables = null;
|
||||||
|
|
||||||
public ?string $variablesPreview = null;
|
public ?string $variablesPreview = null;
|
||||||
|
|
||||||
public string $view = 'normal';
|
public string $view = 'normal';
|
||||||
|
|
||||||
|
public bool $is_env_sorting_enabled = false;
|
||||||
|
|
||||||
protected $listeners = [
|
protected $listeners = [
|
||||||
'saveKey' => 'submit',
|
'saveKey' => 'submit',
|
||||||
'refreshEnvs',
|
'refreshEnvs',
|
||||||
'environmentVariableDeleted' => 'refreshEnvs',
|
'environmentVariableDeleted' => 'refreshEnvs',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $rules = [
|
|
||||||
'resource.settings.is_env_sorting_enabled' => 'required|boolean',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
$this->is_env_sorting_enabled = data_get($this->resource, 'settings.is_env_sorting_enabled', false);
|
||||||
$this->resourceClass = get_class($this->resource);
|
$this->resourceClass = get_class($this->resource);
|
||||||
$resourceWithPreviews = [\App\Models\Application::class];
|
$resourceWithPreviews = [\App\Models\Application::class];
|
||||||
$simpleDockerfile = ! is_null(data_get($this->resource, 'dockerfile'));
|
$simpleDockerfile = filled(data_get($this->resource, 'dockerfile'));
|
||||||
if (str($this->resourceClass)->contains($resourceWithPreviews) && ! $simpleDockerfile) {
|
if (str($this->resourceClass)->contains($resourceWithPreviews) && ! $simpleDockerfile) {
|
||||||
$this->showPreview = true;
|
$this->showPreview = true;
|
||||||
}
|
}
|
||||||
$this->modalId = new Cuid2;
|
|
||||||
$this->sortEnvironmentVariables();
|
$this->sortEnvironmentVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
|
$this->resource->settings->is_env_sorting_enabled = $this->is_env_sorting_enabled;
|
||||||
$this->resource->settings->save();
|
$this->resource->settings->save();
|
||||||
$this->sortEnvironmentVariables();
|
$this->sortEnvironmentVariables();
|
||||||
$this->dispatch('success', 'Environment variable settings updated.');
|
$this->dispatch('success', 'Environment variable settings updated.');
|
||||||
@@ -53,7 +49,7 @@ class All extends Component
|
|||||||
|
|
||||||
public function sortEnvironmentVariables()
|
public function sortEnvironmentVariables()
|
||||||
{
|
{
|
||||||
if (! data_get($this->resource, 'settings.is_env_sorting_enabled')) {
|
if ($this->is_env_sorting_enabled === false) {
|
||||||
if ($this->resource->environment_variables) {
|
if ($this->resource->environment_variables) {
|
||||||
$this->resource->environment_variables = $this->resource->environment_variables->sortBy('order')->values();
|
$this->resource->environment_variables = $this->resource->environment_variables->sortBy('order')->values();
|
||||||
}
|
}
|
||||||
@@ -178,35 +174,12 @@ class All extends Component
|
|||||||
$environment->is_multiline = $data['is_multiline'] ?? false;
|
$environment->is_multiline = $data['is_multiline'] ?? false;
|
||||||
$environment->is_literal = $data['is_literal'] ?? false;
|
$environment->is_literal = $data['is_literal'] ?? false;
|
||||||
$environment->is_preview = $data['is_preview'] ?? false;
|
$environment->is_preview = $data['is_preview'] ?? false;
|
||||||
|
$environment->resourceable_id = $this->resource->id;
|
||||||
$resourceType = $this->resource->type();
|
$environment->resourceable_type = $this->resource->getMorphClass();
|
||||||
$resourceIdField = $this->getResourceIdField($resourceType);
|
|
||||||
|
|
||||||
if ($resourceIdField) {
|
|
||||||
$environment->$resourceIdField = $this->resource->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $environment;
|
return $environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getResourceIdField($resourceType)
|
|
||||||
{
|
|
||||||
$resourceTypes = [
|
|
||||||
'application' => 'application_id',
|
|
||||||
'standalone-postgresql' => 'standalone_postgresql_id',
|
|
||||||
'standalone-redis' => 'standalone_redis_id',
|
|
||||||
'standalone-mongodb' => 'standalone_mongodb_id',
|
|
||||||
'standalone-mysql' => 'standalone_mysql_id',
|
|
||||||
'standalone-mariadb' => 'standalone_mariadb_id',
|
|
||||||
'standalone-keydb' => 'standalone_keydb_id',
|
|
||||||
'standalone-dragonfly' => 'standalone_dragonfly_id',
|
|
||||||
'standalone-clickhouse' => 'standalone_clickhouse_id',
|
|
||||||
'service' => 'service_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
return $resourceTypes[$resourceType] ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function deleteRemovedVariables($isPreview, $variables)
|
private function deleteRemovedVariables($isPreview, $variables)
|
||||||
{
|
{
|
||||||
$method = $isPreview ? 'environment_variables_preview' : 'environment_variables';
|
$method = $isPreview ? 'environment_variables_preview' : 'environment_variables';
|
||||||
@@ -231,34 +204,14 @@ class All extends Component
|
|||||||
$environment->is_build_time = false;
|
$environment->is_build_time = false;
|
||||||
$environment->is_multiline = false;
|
$environment->is_multiline = false;
|
||||||
$environment->is_preview = $isPreview;
|
$environment->is_preview = $isPreview;
|
||||||
|
$environment->resourceable_id = $this->resource->id;
|
||||||
|
$environment->resourceable_type = $this->resource->getMorphClass();
|
||||||
|
|
||||||
$this->setEnvironmentResourceId($environment);
|
|
||||||
$environment->save();
|
$environment->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setEnvironmentResourceId($environment)
|
|
||||||
{
|
|
||||||
$resourceTypes = [
|
|
||||||
'application' => 'application_id',
|
|
||||||
'standalone-postgresql' => 'standalone_postgresql_id',
|
|
||||||
'standalone-redis' => 'standalone_redis_id',
|
|
||||||
'standalone-mongodb' => 'standalone_mongodb_id',
|
|
||||||
'standalone-mysql' => 'standalone_mysql_id',
|
|
||||||
'standalone-mariadb' => 'standalone_mariadb_id',
|
|
||||||
'standalone-keydb' => 'standalone_keydb_id',
|
|
||||||
'standalone-dragonfly' => 'standalone_dragonfly_id',
|
|
||||||
'standalone-clickhouse' => 'standalone_clickhouse_id',
|
|
||||||
'service' => 'service_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
$resourceType = $this->resource->type();
|
|
||||||
if (isset($resourceTypes[$resourceType])) {
|
|
||||||
$environment->{$resourceTypes[$resourceType]} = $this->resource->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function refreshEnvs()
|
public function refreshEnvs()
|
||||||
{
|
{
|
||||||
$this->resource->refresh();
|
$this->resource->refresh();
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable;
|
|||||||
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
|
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
|
||||||
use App\Models\SharedEnvironmentVariable;
|
use App\Models\SharedEnvironmentVariable;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Visus\Cuid2\Cuid2;
|
|
||||||
|
|
||||||
class Show extends Component
|
class Show extends Component
|
||||||
{
|
{
|
||||||
@@ -13,8 +12,6 @@ class Show extends Component
|
|||||||
|
|
||||||
public ModelsEnvironmentVariable|SharedEnvironmentVariable $env;
|
public ModelsEnvironmentVariable|SharedEnvironmentVariable $env;
|
||||||
|
|
||||||
public ?string $modalId = null;
|
|
||||||
|
|
||||||
public bool $isDisabled = false;
|
public bool $isDisabled = false;
|
||||||
|
|
||||||
public bool $isLocked = false;
|
public bool $isLocked = false;
|
||||||
@@ -23,6 +20,26 @@ class Show extends Component
|
|||||||
|
|
||||||
public string $type;
|
public string $type;
|
||||||
|
|
||||||
|
public string $key;
|
||||||
|
|
||||||
|
public ?string $value = null;
|
||||||
|
|
||||||
|
public ?string $real_value = null;
|
||||||
|
|
||||||
|
public bool $is_shared = false;
|
||||||
|
|
||||||
|
public bool $is_build_time = false;
|
||||||
|
|
||||||
|
public bool $is_multiline = false;
|
||||||
|
|
||||||
|
public bool $is_literal = false;
|
||||||
|
|
||||||
|
public bool $is_shown_once = false;
|
||||||
|
|
||||||
|
public bool $is_required = false;
|
||||||
|
|
||||||
|
public bool $is_really_required = false;
|
||||||
|
|
||||||
protected $listeners = [
|
protected $listeners = [
|
||||||
'refreshEnvs' => 'refresh',
|
'refreshEnvs' => 'refresh',
|
||||||
'refresh',
|
'refresh',
|
||||||
@@ -30,40 +47,59 @@ class Show extends Component
|
|||||||
];
|
];
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'env.key' => 'required|string',
|
'key' => 'required|string',
|
||||||
'env.value' => 'nullable',
|
'value' => 'nullable',
|
||||||
'env.is_build_time' => 'required|boolean',
|
'is_build_time' => 'required|boolean',
|
||||||
'env.is_multiline' => 'required|boolean',
|
'is_multiline' => 'required|boolean',
|
||||||
'env.is_literal' => 'required|boolean',
|
'is_literal' => 'required|boolean',
|
||||||
'env.is_shown_once' => 'required|boolean',
|
'is_shown_once' => 'required|boolean',
|
||||||
'env.real_value' => 'nullable',
|
'real_value' => 'nullable',
|
||||||
'env.is_required' => 'required|boolean',
|
'is_required' => 'required|boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $validationAttributes = [
|
|
||||||
'env.key' => 'Key',
|
|
||||||
'env.value' => 'Value',
|
|
||||||
'env.is_build_time' => 'Build Time',
|
|
||||||
'env.is_multiline' => 'Multiline',
|
|
||||||
'env.is_literal' => 'Literal',
|
|
||||||
'env.is_shown_once' => 'Shown Once',
|
|
||||||
'env.is_required' => 'Required',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function refresh()
|
|
||||||
{
|
|
||||||
$this->env->refresh();
|
|
||||||
$this->checkEnvs();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
$this->syncData();
|
||||||
if ($this->env->getMorphClass() === \App\Models\SharedEnvironmentVariable::class) {
|
if ($this->env->getMorphClass() === \App\Models\SharedEnvironmentVariable::class) {
|
||||||
$this->isSharedVariable = true;
|
$this->isSharedVariable = true;
|
||||||
}
|
}
|
||||||
$this->modalId = new Cuid2;
|
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
$this->checkEnvs();
|
$this->checkEnvs();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refresh()
|
||||||
|
{
|
||||||
|
$this->syncData();
|
||||||
|
$this->checkEnvs();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function syncData(bool $toModel = false)
|
||||||
|
{
|
||||||
|
if ($toModel) {
|
||||||
|
$this->validate();
|
||||||
|
$this->env->key = $this->key;
|
||||||
|
$this->env->value = $this->value;
|
||||||
|
$this->env->is_build_time = $this->is_build_time;
|
||||||
|
$this->env->is_multiline = $this->is_multiline;
|
||||||
|
$this->env->is_literal = $this->is_literal;
|
||||||
|
$this->env->is_shown_once = $this->is_shown_once;
|
||||||
|
$this->env->is_required = $this->is_required;
|
||||||
|
$this->env->is_shared = $this->is_shared;
|
||||||
|
$this->env->save();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$this->key = $this->env->key;
|
||||||
|
$this->value = $this->env->value;
|
||||||
|
$this->is_build_time = $this->env->is_build_time ?? false;
|
||||||
|
$this->is_multiline = $this->env->is_multiline;
|
||||||
|
$this->is_literal = $this->env->is_literal;
|
||||||
|
$this->is_shown_once = $this->env->is_shown_once;
|
||||||
|
$this->is_required = $this->env->is_required ?? false;
|
||||||
|
$this->is_really_required = $this->env->is_really_required ?? false;
|
||||||
|
$this->is_shared = $this->env->is_shared ?? false;
|
||||||
|
$this->real_value = $this->env->real_value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkEnvs()
|
public function checkEnvs()
|
||||||
@@ -107,17 +143,17 @@ class Show extends Component
|
|||||||
try {
|
try {
|
||||||
if ($this->isSharedVariable) {
|
if ($this->isSharedVariable) {
|
||||||
$this->validate([
|
$this->validate([
|
||||||
'env.key' => 'required|string',
|
'key' => 'required|string',
|
||||||
'env.value' => 'nullable',
|
'value' => 'nullable',
|
||||||
'env.is_shown_once' => 'required|boolean',
|
'is_shown_once' => 'required|boolean',
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$this->validate();
|
$this->validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $this->isSharedVariable && $this->env->is_required && str($this->env->real_value)->isEmpty()) {
|
if (! $this->isSharedVariable && $this->is_required && str($this->value)->isEmpty()) {
|
||||||
$oldValue = $this->env->getOriginal('value');
|
$oldValue = $this->env->getOriginal('value');
|
||||||
$this->env->value = $oldValue;
|
$this->value = $oldValue;
|
||||||
$this->dispatch('error', 'Required environment variable cannot be empty.');
|
$this->dispatch('error', 'Required environment variable cannot be empty.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -126,10 +162,10 @@ class Show extends Component
|
|||||||
$this->serialize();
|
$this->serialize();
|
||||||
|
|
||||||
if ($this->isSharedVariable) {
|
if ($this->isSharedVariable) {
|
||||||
unset($this->env->is_required);
|
unset($this->is_required);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->env->save();
|
$this->syncData(true);
|
||||||
$this->dispatch('success', 'Environment variable updated.');
|
$this->dispatch('success', 'Environment variable updated.');
|
||||||
$this->dispatch('envsUpdated');
|
$this->dispatch('envsUpdated');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
@@ -15,7 +15,7 @@ class ResourceOperations extends Component
|
|||||||
|
|
||||||
public $projectUuid;
|
public $projectUuid;
|
||||||
|
|
||||||
public $environmentName;
|
public $environmentUuid;
|
||||||
|
|
||||||
public $projects;
|
public $projects;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class ResourceOperations extends Component
|
|||||||
{
|
{
|
||||||
$parameters = get_route_parameters();
|
$parameters = get_route_parameters();
|
||||||
$this->projectUuid = data_get($parameters, 'project_uuid');
|
$this->projectUuid = data_get($parameters, 'project_uuid');
|
||||||
$this->environmentName = data_get($parameters, 'environment_name');
|
$this->environmentUuid = data_get($parameters, 'environment_uuid');
|
||||||
$this->projects = Project::ownedByCurrentTeam()->get();
|
$this->projects = Project::ownedByCurrentTeam()->get();
|
||||||
$this->servers = currentTeam()->servers;
|
$this->servers = currentTeam()->servers;
|
||||||
}
|
}
|
||||||
@@ -42,9 +42,11 @@ class ResourceOperations extends Component
|
|||||||
$uuid = (string) new Cuid2;
|
$uuid = (string) new Cuid2;
|
||||||
$server = $new_destination->server;
|
$server = $new_destination->server;
|
||||||
if ($this->resource->getMorphClass() === \App\Models\Application::class) {
|
if ($this->resource->getMorphClass() === \App\Models\Application::class) {
|
||||||
|
$name = 'clone-of-'.str($this->resource->name)->limit(20).'-'.$uuid;
|
||||||
|
|
||||||
$new_resource = $this->resource->replicate()->fill([
|
$new_resource = $this->resource->replicate()->fill([
|
||||||
'uuid' => $uuid,
|
'uuid' => $uuid,
|
||||||
'name' => $this->resource->name.'-clone-'.$uuid,
|
'name' => $name,
|
||||||
'fqdn' => generateFqdn($server, $uuid),
|
'fqdn' => generateFqdn($server, $uuid),
|
||||||
'status' => 'exited',
|
'status' => 'exited',
|
||||||
'destination_id' => $new_destination->id,
|
'destination_id' => $new_destination->id,
|
||||||
@@ -58,21 +60,26 @@ class ResourceOperations extends Component
|
|||||||
$environmentVaribles = $this->resource->environment_variables()->get();
|
$environmentVaribles = $this->resource->environment_variables()->get();
|
||||||
foreach ($environmentVaribles as $environmentVarible) {
|
foreach ($environmentVaribles as $environmentVarible) {
|
||||||
$newEnvironmentVariable = $environmentVarible->replicate()->fill([
|
$newEnvironmentVariable = $environmentVarible->replicate()->fill([
|
||||||
'application_id' => $new_resource->id,
|
'resourceable_id' => $new_resource->id,
|
||||||
|
'resourceable_type' => $new_resource->getMorphClass(),
|
||||||
]);
|
]);
|
||||||
$newEnvironmentVariable->save();
|
$newEnvironmentVariable->save();
|
||||||
}
|
}
|
||||||
$persistentVolumes = $this->resource->persistentStorages()->get();
|
$persistentVolumes = $this->resource->persistentStorages()->get();
|
||||||
foreach ($persistentVolumes as $volume) {
|
foreach ($persistentVolumes as $volume) {
|
||||||
|
$volumeName = str($volume->name)->replace($this->resource->uuid, $new_resource->uuid)->value();
|
||||||
|
if ($volumeName === $volume->name) {
|
||||||
|
$volumeName = $new_resource->uuid.'-'.str($volume->name)->afterLast('-');
|
||||||
|
}
|
||||||
$newPersistentVolume = $volume->replicate()->fill([
|
$newPersistentVolume = $volume->replicate()->fill([
|
||||||
'name' => $new_resource->uuid.'-'.str($volume->name)->afterLast('-'),
|
'name' => $volumeName,
|
||||||
'resource_id' => $new_resource->id,
|
'resource_id' => $new_resource->id,
|
||||||
]);
|
]);
|
||||||
$newPersistentVolume->save();
|
$newPersistentVolume->save();
|
||||||
}
|
}
|
||||||
$route = route('project.application.configuration', [
|
$route = route('project.application.configuration', [
|
||||||
'project_uuid' => $this->projectUuid,
|
'project_uuid' => $this->projectUuid,
|
||||||
'environment_name' => $this->environmentName,
|
'environment_uuid' => $this->environmentUuid,
|
||||||
'application_uuid' => $new_resource->uuid,
|
'application_uuid' => $new_resource->uuid,
|
||||||
]).'#resource-operations';
|
]).'#resource-operations';
|
||||||
|
|
||||||
@@ -115,7 +122,7 @@ class ResourceOperations extends Component
|
|||||||
}
|
}
|
||||||
$route = route('project.database.configuration', [
|
$route = route('project.database.configuration', [
|
||||||
'project_uuid' => $this->projectUuid,
|
'project_uuid' => $this->projectUuid,
|
||||||
'environment_name' => $this->environmentName,
|
'environment_uuid' => $this->environmentUuid,
|
||||||
'database_uuid' => $new_resource->uuid,
|
'database_uuid' => $new_resource->uuid,
|
||||||
]).'#resource-operations';
|
]).'#resource-operations';
|
||||||
|
|
||||||
@@ -141,7 +148,7 @@ class ResourceOperations extends Component
|
|||||||
$new_resource->parse();
|
$new_resource->parse();
|
||||||
$route = route('project.service.configuration', [
|
$route = route('project.service.configuration', [
|
||||||
'project_uuid' => $this->projectUuid,
|
'project_uuid' => $this->projectUuid,
|
||||||
'environment_name' => $this->environmentName,
|
'environment_uuid' => $this->environmentUuid,
|
||||||
'service_uuid' => $new_resource->uuid,
|
'service_uuid' => $new_resource->uuid,
|
||||||
]).'#resource-operations';
|
]).'#resource-operations';
|
||||||
|
|
||||||
@@ -159,7 +166,7 @@ class ResourceOperations extends Component
|
|||||||
if ($this->resource->type() === 'application') {
|
if ($this->resource->type() === 'application') {
|
||||||
$route = route('project.application.configuration', [
|
$route = route('project.application.configuration', [
|
||||||
'project_uuid' => $new_environment->project->uuid,
|
'project_uuid' => $new_environment->project->uuid,
|
||||||
'environment_name' => $new_environment->name,
|
'environment_uuid' => $new_environment->uuid,
|
||||||
'application_uuid' => $this->resource->uuid,
|
'application_uuid' => $this->resource->uuid,
|
||||||
]).'#resource-operations';
|
]).'#resource-operations';
|
||||||
|
|
||||||
@@ -167,7 +174,7 @@ class ResourceOperations extends Component
|
|||||||
} elseif (str($this->resource->type())->startsWith('standalone-')) {
|
} elseif (str($this->resource->type())->startsWith('standalone-')) {
|
||||||
$route = route('project.database.configuration', [
|
$route = route('project.database.configuration', [
|
||||||
'project_uuid' => $new_environment->project->uuid,
|
'project_uuid' => $new_environment->project->uuid,
|
||||||
'environment_name' => $new_environment->name,
|
'environment_uuid' => $new_environment->uuid,
|
||||||
'database_uuid' => $this->resource->uuid,
|
'database_uuid' => $this->resource->uuid,
|
||||||
]).'#resource-operations';
|
]).'#resource-operations';
|
||||||
|
|
||||||
@@ -175,7 +182,7 @@ class ResourceOperations extends Component
|
|||||||
} elseif ($this->resource->type() === 'service') {
|
} elseif ($this->resource->type() === 'service') {
|
||||||
$route = route('project.service.configuration', [
|
$route = route('project.service.configuration', [
|
||||||
'project_uuid' => $new_environment->project->uuid,
|
'project_uuid' => $new_environment->project->uuid,
|
||||||
'environment_name' => $new_environment->name,
|
'environment_uuid' => $new_environment->uuid,
|
||||||
'service_uuid' => $this->resource->uuid,
|
'service_uuid' => $this->resource->uuid,
|
||||||
]).'#resource-operations';
|
]).'#resource-operations';
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@ class Show extends Component
|
|||||||
#[Locked]
|
#[Locked]
|
||||||
public string $task_uuid;
|
public string $task_uuid;
|
||||||
|
|
||||||
public function mount(string $task_uuid, string $project_uuid, string $environment_name, ?string $application_uuid = null, ?string $service_uuid = null)
|
public function mount(string $task_uuid, string $project_uuid, string $environment_uuid, ?string $application_uuid = null, ?string $service_uuid = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->task_uuid = $task_uuid;
|
$this->task_uuid = $task_uuid;
|
||||||
@@ -60,7 +60,7 @@ class Show extends Component
|
|||||||
$this->resource = Service::ownedByCurrentTeam()->where('uuid', $service_uuid)->firstOrFail();
|
$this->resource = Service::ownedByCurrentTeam()->where('uuid', $service_uuid)->firstOrFail();
|
||||||
}
|
}
|
||||||
$this->parameters = [
|
$this->parameters = [
|
||||||
'environment_name' => $environment_name,
|
'environment_uuid' => $environment_uuid,
|
||||||
'project_uuid' => $project_uuid,
|
'project_uuid' => $project_uuid,
|
||||||
'application_uuid' => $application_uuid,
|
'application_uuid' => $application_uuid,
|
||||||
'service_uuid' => $service_uuid,
|
'service_uuid' => $service_uuid,
|
||||||
|
@@ -6,6 +6,7 @@ use App\Models\Environment;
|
|||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use Livewire\Attributes\Validate;
|
use Livewire\Attributes\Validate;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
class Show extends Component
|
class Show extends Component
|
||||||
{
|
{
|
||||||
@@ -33,17 +34,26 @@ class Show extends Component
|
|||||||
$environment = Environment::create([
|
$environment = Environment::create([
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'project_id' => $this->project->id,
|
'project_id' => $this->project->id,
|
||||||
|
'uuid' => (string) new Cuid2,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('project.resource.index', [
|
return redirect()->route('project.resource.index', [
|
||||||
'project_uuid' => $this->project->uuid,
|
'project_uuid' => $this->project->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_uuid' => $environment->uuid,
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
handleError($e, $this);
|
handleError($e, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function navigateToEnvironment($projectUuid, $environmentUuid)
|
||||||
|
{
|
||||||
|
return redirect()->route('project.resource.index', [
|
||||||
|
'project_uuid' => $projectUuid,
|
||||||
|
'environment_uuid' => $environmentUuid,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.project.show');
|
return view('livewire.project.show');
|
||||||
|
@@ -13,14 +13,11 @@ class Advanced extends Component
|
|||||||
|
|
||||||
public array $parameters = [];
|
public array $parameters = [];
|
||||||
|
|
||||||
#[Validate(['integer', 'min:1'])]
|
#[Validate(['string'])]
|
||||||
public int $concurrentBuilds = 1;
|
public string $serverDiskUsageCheckFrequency = '0 23 * * *';
|
||||||
|
|
||||||
#[Validate(['integer', 'min:1'])]
|
#[Validate(['integer', 'min:1', 'max:99'])]
|
||||||
public int $dynamicTimeout = 1;
|
public int $serverDiskUsageNotificationThreshold = 50;
|
||||||
|
|
||||||
#[Validate('boolean')]
|
|
||||||
public bool $forceDockerCleanup = false;
|
|
||||||
|
|
||||||
#[Validate(['string', 'required'])]
|
#[Validate(['string', 'required'])]
|
||||||
public string $dockerCleanupFrequency = '*/10 * * * *';
|
public string $dockerCleanupFrequency = '*/10 * * * *';
|
||||||
@@ -28,8 +25,8 @@ class Advanced extends Component
|
|||||||
#[Validate(['integer', 'min:1', 'max:99'])]
|
#[Validate(['integer', 'min:1', 'max:99'])]
|
||||||
public int $dockerCleanupThreshold = 10;
|
public int $dockerCleanupThreshold = 10;
|
||||||
|
|
||||||
#[Validate(['integer', 'min:1', 'max:99'])]
|
#[Validate('boolean')]
|
||||||
public int $serverDiskUsageNotificationThreshold = 50;
|
public bool $forceDockerCleanup = false;
|
||||||
|
|
||||||
#[Validate('boolean')]
|
#[Validate('boolean')]
|
||||||
public bool $deleteUnusedVolumes = false;
|
public bool $deleteUnusedVolumes = false;
|
||||||
@@ -37,6 +34,12 @@ class Advanced extends Component
|
|||||||
#[Validate('boolean')]
|
#[Validate('boolean')]
|
||||||
public bool $deleteUnusedNetworks = false;
|
public bool $deleteUnusedNetworks = false;
|
||||||
|
|
||||||
|
#[Validate(['integer', 'min:1'])]
|
||||||
|
public int $concurrentBuilds = 1;
|
||||||
|
|
||||||
|
#[Validate(['integer', 'min:1'])]
|
||||||
|
public int $dynamicTimeout = 1;
|
||||||
|
|
||||||
public function mount(string $server_uuid)
|
public function mount(string $server_uuid)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -60,6 +63,7 @@ class Advanced extends Component
|
|||||||
$this->server->settings->server_disk_usage_notification_threshold = $this->serverDiskUsageNotificationThreshold;
|
$this->server->settings->server_disk_usage_notification_threshold = $this->serverDiskUsageNotificationThreshold;
|
||||||
$this->server->settings->delete_unused_volumes = $this->deleteUnusedVolumes;
|
$this->server->settings->delete_unused_volumes = $this->deleteUnusedVolumes;
|
||||||
$this->server->settings->delete_unused_networks = $this->deleteUnusedNetworks;
|
$this->server->settings->delete_unused_networks = $this->deleteUnusedNetworks;
|
||||||
|
$this->server->settings->server_disk_usage_check_frequency = $this->serverDiskUsageCheckFrequency;
|
||||||
$this->server->settings->save();
|
$this->server->settings->save();
|
||||||
} else {
|
} else {
|
||||||
$this->concurrentBuilds = $this->server->settings->concurrent_builds;
|
$this->concurrentBuilds = $this->server->settings->concurrent_builds;
|
||||||
@@ -70,6 +74,7 @@ class Advanced extends Component
|
|||||||
$this->serverDiskUsageNotificationThreshold = $this->server->settings->server_disk_usage_notification_threshold;
|
$this->serverDiskUsageNotificationThreshold = $this->server->settings->server_disk_usage_notification_threshold;
|
||||||
$this->deleteUnusedVolumes = $this->server->settings->delete_unused_volumes;
|
$this->deleteUnusedVolumes = $this->server->settings->delete_unused_volumes;
|
||||||
$this->deleteUnusedNetworks = $this->server->settings->delete_unused_networks;
|
$this->deleteUnusedNetworks = $this->server->settings->delete_unused_networks;
|
||||||
|
$this->serverDiskUsageCheckFrequency = $this->server->settings->server_disk_usage_check_frequency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +105,10 @@ class Advanced extends Component
|
|||||||
$this->dockerCleanupFrequency = $this->server->settings->getOriginal('docker_cleanup_frequency');
|
$this->dockerCleanupFrequency = $this->server->settings->getOriginal('docker_cleanup_frequency');
|
||||||
throw new \Exception('Invalid Cron / Human expression for Docker Cleanup Frequency.');
|
throw new \Exception('Invalid Cron / Human expression for Docker Cleanup Frequency.');
|
||||||
}
|
}
|
||||||
|
if (! validate_cron_expression($this->serverDiskUsageCheckFrequency)) {
|
||||||
|
$this->serverDiskUsageCheckFrequency = $this->server->settings->getOriginal('server_disk_usage_check_frequency');
|
||||||
|
throw new \Exception('Invalid Cron / Human expression for Disk Usage Check Frequency.');
|
||||||
|
}
|
||||||
$this->syncData(true);
|
$this->syncData(true);
|
||||||
$this->dispatch('success', 'Server updated.');
|
$this->dispatch('success', 'Server updated.');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@@ -226,16 +226,18 @@ class Index extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toggleTwoStepConfirmation($password)
|
public function toggleTwoStepConfirmation($password): bool
|
||||||
{
|
{
|
||||||
if (! Hash::check($password, Auth::user()->password)) {
|
if (! Hash::check($password, Auth::user()->password)) {
|
||||||
$this->addError('password', 'The provided password is incorrect.');
|
$this->addError('password', 'The provided password is incorrect.');
|
||||||
|
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation = true;
|
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation = true;
|
||||||
$this->settings->save();
|
$this->settings->save();
|
||||||
$this->dispatch('success', 'Two step confirmation has been disabled.');
|
$this->dispatch('success', 'Two step confirmation has been disabled.');
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,8 +42,8 @@ class Show extends Component
|
|||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
$this->project = Project::ownedByCurrentTeam()->where('uuid', request()->route('project_uuid'))->first();
|
$this->project = Project::ownedByCurrentTeam()->where('uuid', request()->route('project_uuid'))->firstOrFail();
|
||||||
$this->environment = $this->project->environments()->where('name', request()->route('environment_name'))->first();
|
$this->environment = $this->project->environments()->where('uuid', request()->route('environment_uuid'))->firstOrFail();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
|
@@ -130,14 +130,14 @@ class Change extends Component
|
|||||||
} else {
|
} else {
|
||||||
$parameters = data_get(session('from'), 'parameters');
|
$parameters = data_get(session('from'), 'parameters');
|
||||||
$back = data_get(session('from'), 'back');
|
$back = data_get(session('from'), 'back');
|
||||||
$environment_name = data_get($parameters, 'environment_name');
|
$environment_uuid = data_get($parameters, 'environment_uuid');
|
||||||
$project_uuid = data_get($parameters, 'project_uuid');
|
$project_uuid = data_get($parameters, 'project_uuid');
|
||||||
$type = data_get($parameters, 'type');
|
$type = data_get($parameters, 'type');
|
||||||
$destination = data_get($parameters, 'destination');
|
$destination = data_get($parameters, 'destination');
|
||||||
session()->forget('from');
|
session()->forget('from');
|
||||||
|
|
||||||
return redirect()->route($back, [
|
return redirect()->route($back, [
|
||||||
'environment_name' => $environment_name,
|
'environment_uuid' => $environment_uuid,
|
||||||
'project_uuid' => $project_uuid,
|
'project_uuid' => $project_uuid,
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'destination' => $destination,
|
'destination' => $destination,
|
||||||
|
@@ -325,7 +325,7 @@ class Application extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.application.configuration', [
|
return route('project.application.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'application_uuid' => data_get($this, 'uuid'),
|
'application_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -338,7 +338,7 @@ class Application extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
$route = route('project.application.scheduled-tasks', [
|
$route = route('project.application.scheduled-tasks', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'application_uuid' => data_get($this, 'uuid'),
|
'application_uuid' => data_get($this, 'uuid'),
|
||||||
'task_uuid' => $task_uuid,
|
'task_uuid' => $task_uuid,
|
||||||
]);
|
]);
|
||||||
@@ -610,7 +610,7 @@ class Application extends BaseModel
|
|||||||
},
|
},
|
||||||
get: function ($value) {
|
get: function ($value) {
|
||||||
if ($this->additional_servers->count() === 0) {
|
if ($this->additional_servers->count() === 0) {
|
||||||
//running (healthy)
|
// running (healthy)
|
||||||
if (str($value)->contains('(')) {
|
if (str($value)->contains('(')) {
|
||||||
$status = str($value)->before('(')->trim()->value();
|
$status = str($value)->before('(')->trim()->value();
|
||||||
$health = str($value)->after('(')->before(')')->trim()->value() ?? 'unhealthy';
|
$health = str($value)->after('(')->before(')')->trim()->value() ?? 'unhealthy';
|
||||||
@@ -695,46 +695,62 @@ class Application extends BaseModel
|
|||||||
return $this->settings->is_static ? [80] : $this->ports_exposes_array;
|
return $this->settings->is_static ? [80] : $this->ports_exposes_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->orderBy('key', 'asc');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', false)
|
||||||
|
->orderBy('key', 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'not like', 'NIXPACKS_%');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', false)
|
||||||
|
->where('key', 'not like', 'NIXPACKS_%');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preview Deployments
|
public function build_environment_variables()
|
||||||
|
|
||||||
public function build_environment_variables(): HasMany
|
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', false)
|
||||||
|
->where('is_build_time', true)
|
||||||
|
->where('key', 'not like', 'NIXPACKS_%');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function nixpacks_environment_variables(): HasMany
|
public function nixpacks_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'like', 'NIXPACKS_%');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', false)
|
||||||
|
->where('key', 'like', 'NIXPACKS_%');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables_preview(): HasMany
|
public function environment_variables_preview()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->orderBy('key', 'asc');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', true)
|
||||||
|
->orderByRaw("LOWER(key) LIKE LOWER('SERVICE%') DESC, LOWER(key) ASC");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runtime_environment_variables_preview(): HasMany
|
public function runtime_environment_variables_preview()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'not like', 'NIXPACKS_%');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', true)
|
||||||
|
->where('key', 'not like', 'NIXPACKS_%');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function build_environment_variables_preview(): HasMany
|
public function build_environment_variables_preview()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', true)
|
||||||
|
->where('is_build_time', true)
|
||||||
|
->where('key', 'not like', 'NIXPACKS_%');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function nixpacks_environment_variables_preview(): HasMany
|
public function nixpacks_environment_variables_preview()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'like', 'NIXPACKS_%');
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', true)
|
||||||
|
->where('key', 'like', 'NIXPACKS_%');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scheduled_tasks(): HasMany
|
public function scheduled_tasks(): HasMany
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
|
||||||
#[OA\Schema(
|
#[OA\Schema(
|
||||||
@@ -18,7 +17,7 @@ use OpenApi\Attributes as OA;
|
|||||||
'description' => ['type' => 'string'],
|
'description' => ['type' => 'string'],
|
||||||
]
|
]
|
||||||
)]
|
)]
|
||||||
class Environment extends Model
|
class Environment extends BaseModel
|
||||||
{
|
{
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
|
@@ -14,9 +14,8 @@ use Visus\Cuid2\Cuid2;
|
|||||||
properties: [
|
properties: [
|
||||||
'id' => ['type' => 'integer'],
|
'id' => ['type' => 'integer'],
|
||||||
'uuid' => ['type' => 'string'],
|
'uuid' => ['type' => 'string'],
|
||||||
'application_id' => ['type' => 'integer'],
|
'resourceable_type' => ['type' => 'string'],
|
||||||
'service_id' => ['type' => 'integer'],
|
'resourceable_id' => ['type' => 'integer'],
|
||||||
'database_id' => ['type' => 'integer'],
|
|
||||||
'is_build_time' => ['type' => 'boolean'],
|
'is_build_time' => ['type' => 'boolean'],
|
||||||
'is_literal' => ['type' => 'boolean'],
|
'is_literal' => ['type' => 'boolean'],
|
||||||
'is_multiline' => ['type' => 'boolean'],
|
'is_multiline' => ['type' => 'boolean'],
|
||||||
@@ -42,6 +41,8 @@ class EnvironmentVariable extends Model
|
|||||||
'is_multiline' => 'boolean',
|
'is_multiline' => 'boolean',
|
||||||
'is_preview' => 'boolean',
|
'is_preview' => 'boolean',
|
||||||
'version' => 'string',
|
'version' => 'string',
|
||||||
|
'resourceable_type' => 'string',
|
||||||
|
'resourceable_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $appends = ['real_value', 'is_shared', 'is_really_required'];
|
protected $appends = ['real_value', 'is_shared', 'is_really_required'];
|
||||||
@@ -53,18 +54,25 @@ class EnvironmentVariable extends Model
|
|||||||
$model->uuid = (string) new Cuid2;
|
$model->uuid = (string) new Cuid2;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
static::created(function (EnvironmentVariable $environment_variable) {
|
static::created(function (EnvironmentVariable $environment_variable) {
|
||||||
if ($environment_variable->application_id && ! $environment_variable->is_preview) {
|
if ($environment_variable->resourceable_type === Application::class && ! $environment_variable->is_preview) {
|
||||||
$found = ModelsEnvironmentVariable::where('key', $environment_variable->key)->where('application_id', $environment_variable->application_id)->where('is_preview', true)->first();
|
$found = ModelsEnvironmentVariable::where('key', $environment_variable->key)
|
||||||
|
->where('resourceable_type', Application::class)
|
||||||
|
->where('resourceable_id', $environment_variable->resourceable_id)
|
||||||
|
->where('is_preview', true)
|
||||||
|
->first();
|
||||||
|
|
||||||
if (! $found) {
|
if (! $found) {
|
||||||
$application = Application::find($environment_variable->application_id);
|
$application = Application::find($environment_variable->resourceable_id);
|
||||||
if ($application->build_pack !== 'dockerfile') {
|
if ($application && $application->build_pack !== 'dockerfile') {
|
||||||
ModelsEnvironmentVariable::create([
|
ModelsEnvironmentVariable::create([
|
||||||
'key' => $environment_variable->key,
|
'key' => $environment_variable->key,
|
||||||
'value' => $environment_variable->value,
|
'value' => $environment_variable->value,
|
||||||
'is_build_time' => $environment_variable->is_build_time,
|
'is_build_time' => $environment_variable->is_build_time,
|
||||||
'is_multiline' => $environment_variable->is_multiline ?? false,
|
'is_multiline' => $environment_variable->is_multiline ?? false,
|
||||||
'application_id' => $environment_variable->application_id,
|
'resourceable_type' => Application::class,
|
||||||
|
'resourceable_id' => $environment_variable->resourceable_id,
|
||||||
'is_preview' => true,
|
'is_preview' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -74,6 +82,7 @@ class EnvironmentVariable extends Model
|
|||||||
'version' => config('constants.coolify.version'),
|
'version' => config('constants.coolify.version'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
static::saving(function (EnvironmentVariable $environmentVariable) {
|
static::saving(function (EnvironmentVariable $environmentVariable) {
|
||||||
$environmentVariable->updateIsShared();
|
$environmentVariable->updateIsShared();
|
||||||
});
|
});
|
||||||
@@ -92,43 +101,32 @@ class EnvironmentVariable extends Model
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parent resourceable model.
|
||||||
|
*/
|
||||||
|
public function resourceable()
|
||||||
|
{
|
||||||
|
return $this->morphTo();
|
||||||
|
}
|
||||||
|
|
||||||
public function resource()
|
public function resource()
|
||||||
{
|
{
|
||||||
$resource = null;
|
return $this->resourceable;
|
||||||
if ($this->application_id) {
|
|
||||||
$resource = Application::find($this->application_id);
|
|
||||||
} elseif ($this->service_id) {
|
|
||||||
$resource = Service::find($this->service_id);
|
|
||||||
} elseif ($this->standalone_postgresql_id) {
|
|
||||||
$resource = StandalonePostgresql::find($this->standalone_postgresql_id);
|
|
||||||
} elseif ($this->standalone_redis_id) {
|
|
||||||
$resource = StandaloneRedis::find($this->standalone_redis_id);
|
|
||||||
} elseif ($this->standalone_mongodb_id) {
|
|
||||||
$resource = StandaloneMongodb::find($this->standalone_mongodb_id);
|
|
||||||
} elseif ($this->standalone_mysql_id) {
|
|
||||||
$resource = StandaloneMysql::find($this->standalone_mysql_id);
|
|
||||||
} elseif ($this->standalone_mariadb_id) {
|
|
||||||
$resource = StandaloneMariadb::find($this->standalone_mariadb_id);
|
|
||||||
} elseif ($this->standalone_keydb_id) {
|
|
||||||
$resource = StandaloneKeydb::find($this->standalone_keydb_id);
|
|
||||||
} elseif ($this->standalone_dragonfly_id) {
|
|
||||||
$resource = StandaloneDragonfly::find($this->standalone_dragonfly_id);
|
|
||||||
} elseif ($this->standalone_clickhouse_id) {
|
|
||||||
$resource = StandaloneClickhouse::find($this->standalone_clickhouse_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $resource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function realValue(): Attribute
|
public function realValue(): Attribute
|
||||||
{
|
{
|
||||||
$resource = $this->resource();
|
|
||||||
|
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
get: function () use ($resource) {
|
get: function () {
|
||||||
$env = $this->get_real_environment_variables($this->value, $resource);
|
if (! $this->relationLoaded('resourceable')) {
|
||||||
|
$this->load('resourceable');
|
||||||
|
}
|
||||||
|
$resource = $this->resourceable;
|
||||||
|
if (! $resource) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return data_get($env, 'value', $env);
|
return $this->get_real_environment_variables($this->value, $resource);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -164,7 +162,6 @@ class EnvironmentVariable extends Model
|
|||||||
if ($sharedEnvsFound->isEmpty()) {
|
if ($sharedEnvsFound->isEmpty()) {
|
||||||
return $environment_variable;
|
return $environment_variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($sharedEnvsFound as $sharedEnv) {
|
foreach ($sharedEnvsFound as $sharedEnv) {
|
||||||
$type = str($sharedEnv)->match('/(.*?)\./');
|
$type = str($sharedEnv)->match('/(.*?)\./');
|
||||||
if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
|
if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
#[OA\Schema(
|
#[OA\Schema(
|
||||||
description: 'Project model',
|
description: 'Project model',
|
||||||
@@ -24,8 +25,6 @@ class Project extends BaseModel
|
|||||||
{
|
{
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $appends = ['default_environment'];
|
|
||||||
|
|
||||||
public static function ownedByCurrentTeam()
|
public static function ownedByCurrentTeam()
|
||||||
{
|
{
|
||||||
return Project::whereTeamId(currentTeam()->id)->orderByRaw('LOWER(name)');
|
return Project::whereTeamId(currentTeam()->id)->orderByRaw('LOWER(name)');
|
||||||
@@ -40,6 +39,7 @@ class Project extends BaseModel
|
|||||||
Environment::create([
|
Environment::create([
|
||||||
'name' => 'production',
|
'name' => 'production',
|
||||||
'project_id' => $project->id,
|
'project_id' => $project->id,
|
||||||
|
'uuid' => (string) new Cuid2,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
static::deleting(function ($project) {
|
static::deleting(function ($project) {
|
||||||
@@ -140,18 +140,4 @@ class Project extends BaseModel
|
|||||||
{
|
{
|
||||||
return $this->postgresqls()->get()->merge($this->redis()->get())->merge($this->mongodbs()->get())->merge($this->mysqls()->get())->merge($this->mariadbs()->get())->merge($this->keydbs()->get())->merge($this->dragonflies()->get())->merge($this->clickhouses()->get());
|
return $this->postgresqls()->get()->merge($this->redis()->get())->merge($this->mongodbs()->get())->merge($this->mysqls()->get())->merge($this->mariadbs()->get())->merge($this->keydbs()->get())->merge($this->dragonflies()->get())->merge($this->clickhouses()->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultEnvironmentAttribute()
|
|
||||||
{
|
|
||||||
$default = $this->environments()->where('name', 'production')->first();
|
|
||||||
if ($default) {
|
|
||||||
return $default->name;
|
|
||||||
}
|
|
||||||
$default = $this->environments()->get();
|
|
||||||
if ($default->count() > 0) {
|
|
||||||
return $default->sortBy('created_at')->first()->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1120,7 +1120,8 @@ class Service extends BaseModel
|
|||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'service_id' => $this->id,
|
'resourceable_id' => $this->id,
|
||||||
|
'resourceable_type' => $this->getMorphClass(),
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1132,7 +1133,7 @@ class Service extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.service.configuration', [
|
return route('project.service.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'service_uuid' => data_get($this, 'uuid'),
|
'service_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1145,7 +1146,7 @@ class Service extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
$route = route('project.service.scheduled-tasks', [
|
$route = route('project.service.scheduled-tasks', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'service_uuid' => data_get($this, 'uuid'),
|
'service_uuid' => data_get($this, 'uuid'),
|
||||||
'task_uuid' => $task_uuid,
|
'task_uuid' => $task_uuid,
|
||||||
]);
|
]);
|
||||||
@@ -1232,14 +1233,17 @@ class Service extends BaseModel
|
|||||||
return $this->hasMany(ScheduledTask::class)->orderBy('name', 'asc');
|
return $this->hasMany(ScheduledTask::class)->orderBy('name', 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->orderByRaw("LOWER(key) LIKE LOWER('SERVICE%') DESC, LOWER(key) ASC");
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables_preview(): HasMany
|
public function environment_variables_preview()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->orderByRaw("LOWER(key) LIKE LOWER('SERVICE%') DESC, LOWER(key) ASC");
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->where('is_preview', true)
|
||||||
|
->orderByRaw("LOWER(key) LIKE LOWER('SERVICE%') DESC, LOWER(key) ASC");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function workdir()
|
public function workdir()
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandaloneClickhouse extends BaseModel
|
class StandaloneClickhouse extends BaseModel
|
||||||
@@ -169,7 +168,7 @@ class StandaloneClickhouse extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -251,14 +250,15 @@ class StandaloneClickhouse extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandaloneDragonfly extends BaseModel
|
class StandaloneDragonfly extends BaseModel
|
||||||
@@ -174,7 +173,7 @@ class StandaloneDragonfly extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -251,14 +250,9 @@ class StandaloneDragonfly extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
@@ -319,4 +313,10 @@ class StandaloneDragonfly extends BaseModel
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function environment_variables()
|
||||||
|
{
|
||||||
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandaloneKeydb extends BaseModel
|
class StandaloneKeydb extends BaseModel
|
||||||
@@ -174,7 +173,7 @@ class StandaloneKeydb extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -251,14 +250,9 @@ class StandaloneKeydb extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
@@ -319,4 +313,10 @@ class StandaloneKeydb extends BaseModel
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function environment_variables()
|
||||||
|
{
|
||||||
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandaloneMariadb extends BaseModel
|
class StandaloneMariadb extends BaseModel
|
||||||
@@ -174,7 +173,7 @@ class StandaloneMariadb extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -251,14 +250,15 @@ class StandaloneMariadb extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandaloneMongodb extends BaseModel
|
class StandaloneMongodb extends BaseModel
|
||||||
@@ -183,7 +182,7 @@ class StandaloneMongodb extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -271,14 +270,9 @@ class StandaloneMongodb extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
@@ -339,4 +333,10 @@ class StandaloneMongodb extends BaseModel
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function environment_variables()
|
||||||
|
{
|
||||||
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandaloneMysql extends BaseModel
|
class StandaloneMysql extends BaseModel
|
||||||
@@ -175,7 +174,7 @@ class StandaloneMysql extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -252,14 +251,9 @@ class StandaloneMysql extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
@@ -320,4 +314,10 @@ class StandaloneMysql extends BaseModel
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function environment_variables()
|
||||||
|
{
|
||||||
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandalonePostgresql extends BaseModel
|
class StandalonePostgresql extends BaseModel
|
||||||
@@ -170,7 +169,7 @@ class StandalonePostgresql extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -252,14 +251,9 @@ class StandalonePostgresql extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
@@ -320,4 +314,10 @@ class StandalonePostgresql extends BaseModel
|
|||||||
|
|
||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function environment_variables()
|
||||||
|
{
|
||||||
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class StandaloneRedis extends BaseModel
|
class StandaloneRedis extends BaseModel
|
||||||
@@ -170,7 +169,7 @@ class StandaloneRedis extends BaseModel
|
|||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
return route('project.database.configuration', [
|
return route('project.database.configuration', [
|
||||||
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
'project_uuid' => data_get($this, 'environment.project.uuid'),
|
||||||
'environment_name' => data_get($this, 'environment.name'),
|
'environment_uuid' => data_get($this, 'environment.uuid'),
|
||||||
'database_uuid' => data_get($this, 'uuid'),
|
'database_uuid' => data_get($this, 'uuid'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -262,14 +261,9 @@ class StandaloneRedis extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function environment_variables(): HasMany
|
public function runtime_environment_variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable');
|
||||||
}
|
|
||||||
|
|
||||||
public function runtime_environment_variables(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(EnvironmentVariable::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function persistentStorages()
|
public function persistentStorages()
|
||||||
@@ -359,4 +353,10 @@ class StandaloneRedis extends BaseModel
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function environment_variables()
|
||||||
|
{
|
||||||
|
return $this->morphMany(EnvironmentVariable::class, 'resourceable')
|
||||||
|
->orderBy('key', 'asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -120,22 +120,10 @@ class Team extends Model implements SendsDiscord, SendsEmail, SendsPushover, Sen
|
|||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
get: function () {
|
get: function () {
|
||||||
if (config('constants.coolify.self_hosted') || $this->id === 0) {
|
if (config('constants.coolify.self_hosted') || $this->id === 0) {
|
||||||
$subscription = 'self-hosted';
|
return 999999999999;
|
||||||
} else {
|
|
||||||
$subscription = data_get($this, 'subscription');
|
|
||||||
if (is_null($subscription)) {
|
|
||||||
$subscription = 'zero';
|
|
||||||
} else {
|
|
||||||
$subscription = $subscription->type();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($this->custom_server_limit) {
|
|
||||||
$serverLimit = $this->custom_server_limit;
|
|
||||||
} else {
|
|
||||||
$serverLimit = config('constants.limits.server')[strtolower($subscription)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $serverLimit ?? 2;
|
return $this->custom_server_limit ?? 2;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,8 @@ class DeploymentFailed extends CustomEmailNotification
|
|||||||
|
|
||||||
public string $project_uuid;
|
public string $project_uuid;
|
||||||
|
|
||||||
|
public string $environment_uuid;
|
||||||
|
|
||||||
public string $environment_name;
|
public string $environment_name;
|
||||||
|
|
||||||
public ?string $deployment_url = null;
|
public ?string $deployment_url = null;
|
||||||
@@ -36,12 +38,13 @@ class DeploymentFailed extends CustomEmailNotification
|
|||||||
$this->preview = $preview;
|
$this->preview = $preview;
|
||||||
$this->application_name = data_get($application, 'name');
|
$this->application_name = data_get($application, 'name');
|
||||||
$this->project_uuid = data_get($application, 'environment.project.uuid');
|
$this->project_uuid = data_get($application, 'environment.project.uuid');
|
||||||
|
$this->environment_uuid = data_get($application, 'environment.uuid');
|
||||||
$this->environment_name = data_get($application, 'environment.name');
|
$this->environment_name = data_get($application, 'environment.name');
|
||||||
$this->fqdn = data_get($application, 'fqdn');
|
$this->fqdn = data_get($application, 'fqdn');
|
||||||
if (str($this->fqdn)->explode(',')->count() > 1) {
|
if (str($this->fqdn)->explode(',')->count() > 1) {
|
||||||
$this->fqdn = str($this->fqdn)->explode(',')->first();
|
$this->fqdn = str($this->fqdn)->explode(',')->first();
|
||||||
}
|
}
|
||||||
$this->deployment_url = base_url()."/project/{$this->project_uuid}/".urlencode($this->environment_name)."/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}";
|
$this->deployment_url = base_url()."/project/{$this->project_uuid}/environments/{$this->environment_uuid}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function via(object $notifiable): array
|
public function via(object $notifiable): array
|
||||||
|
@@ -22,6 +22,8 @@ class DeploymentSuccess extends CustomEmailNotification
|
|||||||
|
|
||||||
public string $project_uuid;
|
public string $project_uuid;
|
||||||
|
|
||||||
|
public string $environment_uuid;
|
||||||
|
|
||||||
public string $environment_name;
|
public string $environment_name;
|
||||||
|
|
||||||
public ?string $deployment_url = null;
|
public ?string $deployment_url = null;
|
||||||
@@ -36,12 +38,13 @@ class DeploymentSuccess extends CustomEmailNotification
|
|||||||
$this->preview = $preview;
|
$this->preview = $preview;
|
||||||
$this->application_name = data_get($application, 'name');
|
$this->application_name = data_get($application, 'name');
|
||||||
$this->project_uuid = data_get($application, 'environment.project.uuid');
|
$this->project_uuid = data_get($application, 'environment.project.uuid');
|
||||||
|
$this->environment_uuid = data_get($application, 'environment.uuid');
|
||||||
$this->environment_name = data_get($application, 'environment.name');
|
$this->environment_name = data_get($application, 'environment.name');
|
||||||
$this->fqdn = data_get($application, 'fqdn');
|
$this->fqdn = data_get($application, 'fqdn');
|
||||||
if (str($this->fqdn)->explode(',')->count() > 1) {
|
if (str($this->fqdn)->explode(',')->count() > 1) {
|
||||||
$this->fqdn = str($this->fqdn)->explode(',')->first();
|
$this->fqdn = str($this->fqdn)->explode(',')->first();
|
||||||
}
|
}
|
||||||
$this->deployment_url = base_url()."/project/{$this->project_uuid}/".urlencode($this->environment_name)."/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}";
|
$this->deployment_url = base_url()."/project/{$this->project_uuid}/environments/{$this->environment_uuid}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function via(object $notifiable): array
|
public function via(object $notifiable): array
|
||||||
@@ -144,7 +147,7 @@ class DeploymentSuccess extends CustomEmailNotification
|
|||||||
{
|
{
|
||||||
if ($this->preview) {
|
if ($this->preview) {
|
||||||
$title = "Pull request #{$this->preview->pull_request_id} successfully deployed";
|
$title = "Pull request #{$this->preview->pull_request_id} successfully deployed";
|
||||||
$message = 'New PR' . $this->preview->pull_request_id . ' version successfully deployed of ' . $this->application_name . '';
|
$message = 'New PR'.$this->preview->pull_request_id.' version successfully deployed of '.$this->application_name.'';
|
||||||
if ($this->preview->fqdn) {
|
if ($this->preview->fqdn) {
|
||||||
$buttons[] = [
|
$buttons[] = [
|
||||||
'text' => 'Open Application',
|
'text' => 'Open Application',
|
||||||
@@ -153,7 +156,7 @@ class DeploymentSuccess extends CustomEmailNotification
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$title = 'New version successfully deployed';
|
$title = 'New version successfully deployed';
|
||||||
$message = 'New version successfully deployed of ' . $this->application_name . '';
|
$message = 'New version successfully deployed of '.$this->application_name.'';
|
||||||
if ($this->fqdn) {
|
if ($this->fqdn) {
|
||||||
$buttons[] = [
|
$buttons[] = [
|
||||||
'text' => 'Open Application',
|
'text' => 'Open Application',
|
||||||
|
@@ -15,6 +15,8 @@ class StatusChanged extends CustomEmailNotification
|
|||||||
|
|
||||||
public string $project_uuid;
|
public string $project_uuid;
|
||||||
|
|
||||||
|
public string $environment_uuid;
|
||||||
|
|
||||||
public string $environment_name;
|
public string $environment_name;
|
||||||
|
|
||||||
public ?string $resource_url = null;
|
public ?string $resource_url = null;
|
||||||
@@ -26,12 +28,13 @@ class StatusChanged extends CustomEmailNotification
|
|||||||
$this->onQueue('high');
|
$this->onQueue('high');
|
||||||
$this->resource_name = data_get($resource, 'name');
|
$this->resource_name = data_get($resource, 'name');
|
||||||
$this->project_uuid = data_get($resource, 'environment.project.uuid');
|
$this->project_uuid = data_get($resource, 'environment.project.uuid');
|
||||||
|
$this->environment_uuid = data_get($resource, 'environment.uuid');
|
||||||
$this->environment_name = data_get($resource, 'environment.name');
|
$this->environment_name = data_get($resource, 'environment.name');
|
||||||
$this->fqdn = data_get($resource, 'fqdn', null);
|
$this->fqdn = data_get($resource, 'fqdn', null);
|
||||||
if (str($this->fqdn)->explode(',')->count() > 1) {
|
if (str($this->fqdn)->explode(',')->count() > 1) {
|
||||||
$this->fqdn = str($this->fqdn)->explode(',')->first();
|
$this->fqdn = str($this->fqdn)->explode(',')->first();
|
||||||
}
|
}
|
||||||
$this->resource_url = base_url()."/project/{$this->project_uuid}/".urlencode($this->environment_name)."/application/{$this->resource->uuid}";
|
$this->resource_url = base_url()."/project/{$this->project_uuid}/environments/{$this->environment_uuid}/application/{$this->resource->uuid}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function via(object $notifiable): array
|
public function via(object $notifiable): array
|
||||||
@@ -80,7 +83,7 @@ class StatusChanged extends CustomEmailNotification
|
|||||||
|
|
||||||
public function toPushover(): PushoverMessage
|
public function toPushover(): PushoverMessage
|
||||||
{
|
{
|
||||||
$message = $this->resource_name . ' has been stopped.';
|
$message = $this->resource_name.' has been stopped.';
|
||||||
|
|
||||||
return new PushoverMessage(
|
return new PushoverMessage(
|
||||||
title: 'Application stopped',
|
title: 'Application stopped',
|
||||||
|
@@ -87,7 +87,6 @@ class ContainerStopped extends CustomEmailNotification
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function toSlack(): SlackMessage
|
public function toSlack(): SlackMessage
|
||||||
{
|
{
|
||||||
$title = 'Resource stopped';
|
$title = 'Resource stopped';
|
||||||
|
@@ -63,7 +63,6 @@ class BackupSuccess extends CustomEmailNotification
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function toPushover(): PushoverMessage
|
public function toPushover(): PushoverMessage
|
||||||
{
|
{
|
||||||
return new PushoverMessage(
|
return new PushoverMessage(
|
||||||
@@ -73,7 +72,6 @@ class BackupSuccess extends CustomEmailNotification
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function toSlack(): SlackMessage
|
public function toSlack(): SlackMessage
|
||||||
{
|
{
|
||||||
$title = 'Database backup successful';
|
$title = 'Database backup successful';
|
||||||
|
@@ -65,8 +65,8 @@ class HighDiskUsage extends CustomEmailNotification
|
|||||||
level: 'warning',
|
level: 'warning',
|
||||||
message: "Server '{$this->server->name}' high disk usage detected!<br/><br/><b>Disk usage:</b> {$this->disk_usage}%.<br/><b>Threshold:</b> {$this->server_disk_usage_notification_threshold}%.<br/>Please cleanup your disk to prevent data-loss.",
|
message: "Server '{$this->server->name}' high disk usage detected!<br/><br/><b>Disk usage:</b> {$this->disk_usage}%.<br/><b>Threshold:</b> {$this->server_disk_usage_notification_threshold}%.<br/>Please cleanup your disk to prevent data-loss.",
|
||||||
buttons: [
|
buttons: [
|
||||||
'Change settings' => base_url().'/server/'.$this->server->uuid."#advanced",
|
'Change settings' => base_url().'/server/'.$this->server->uuid.'#advanced',
|
||||||
'Tips for cleanup' => "https://coolify.io/docs/knowledge-base/server/automated-cleanup",
|
'Tips for cleanup' => 'https://coolify.io/docs/knowledge-base/server/automated-cleanup',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -4,9 +4,9 @@ namespace App\Notifications;
|
|||||||
|
|
||||||
use App\Notifications\Channels\DiscordChannel;
|
use App\Notifications\Channels\DiscordChannel;
|
||||||
use App\Notifications\Channels\EmailChannel;
|
use App\Notifications\Channels\EmailChannel;
|
||||||
|
use App\Notifications\Channels\PushoverChannel;
|
||||||
use App\Notifications\Channels\SlackChannel;
|
use App\Notifications\Channels\SlackChannel;
|
||||||
use App\Notifications\Channels\TelegramChannel;
|
use App\Notifications\Channels\TelegramChannel;
|
||||||
use App\Notifications\Channels\PushoverChannel;
|
|
||||||
use App\Notifications\Dto\DiscordMessage;
|
use App\Notifications\Dto\DiscordMessage;
|
||||||
use App\Notifications\Dto\PushoverMessage;
|
use App\Notifications\Dto\PushoverMessage;
|
||||||
use App\Notifications\Dto\SlackMessage;
|
use App\Notifications\Dto\SlackMessage;
|
||||||
|
@@ -11,6 +11,7 @@ use Illuminate\Foundation\Events\MaintenanceModeEnabled;
|
|||||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
use SocialiteProviders\Authentik\AuthentikExtendSocialite;
|
use SocialiteProviders\Authentik\AuthentikExtendSocialite;
|
||||||
use SocialiteProviders\Azure\AzureExtendSocialite;
|
use SocialiteProviders\Azure\AzureExtendSocialite;
|
||||||
|
use SocialiteProviders\Infomaniak\InfomaniakExtendSocialite;
|
||||||
use SocialiteProviders\Manager\SocialiteWasCalled;
|
use SocialiteProviders\Manager\SocialiteWasCalled;
|
||||||
|
|
||||||
class EventServiceProvider extends ServiceProvider
|
class EventServiceProvider extends ServiceProvider
|
||||||
@@ -25,6 +26,7 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
SocialiteWasCalled::class => [
|
SocialiteWasCalled::class => [
|
||||||
AzureExtendSocialite::class.'@handle',
|
AzureExtendSocialite::class.'@handle',
|
||||||
AuthentikExtendSocialite::class.'@handle',
|
AuthentikExtendSocialite::class.'@handle',
|
||||||
|
InfomaniakExtendSocialite::class.'@handle',
|
||||||
],
|
],
|
||||||
ProxyStarted::class => [
|
ProxyStarted::class => [
|
||||||
ProxyStartedNotification::class,
|
ProxyStartedNotification::class,
|
||||||
|
@@ -15,7 +15,8 @@ class Button extends Component
|
|||||||
public bool $disabled = false,
|
public bool $disabled = false,
|
||||||
public bool $noStyle = false,
|
public bool $noStyle = false,
|
||||||
public ?string $modalId = null,
|
public ?string $modalId = null,
|
||||||
public string $defaultClass = 'button'
|
public string $defaultClass = 'button',
|
||||||
|
public bool $showLoadingIndicator = true,
|
||||||
) {
|
) {
|
||||||
if ($this->noStyle) {
|
if ($this->noStyle) {
|
||||||
$this->defaultClass = '';
|
$this->defaultClass = '';
|
||||||
|
@@ -166,6 +166,7 @@ function removeUnnecessaryFieldsFromRequest(Request $request)
|
|||||||
{
|
{
|
||||||
$request->offsetUnset('project_uuid');
|
$request->offsetUnset('project_uuid');
|
||||||
$request->offsetUnset('environment_name');
|
$request->offsetUnset('environment_name');
|
||||||
|
$request->offsetUnset('environment_uuid');
|
||||||
$request->offsetUnset('destination_uuid');
|
$request->offsetUnset('destination_uuid');
|
||||||
$request->offsetUnset('server_uuid');
|
$request->offsetUnset('server_uuid');
|
||||||
$request->offsetUnset('type');
|
$request->offsetUnset('type');
|
||||||
|
@@ -188,7 +188,22 @@ function get_port_from_dockerfile($dockerfile): ?int
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'application', $subType = null, $subId = null)
|
function defaultDatabaseLabels($database)
|
||||||
|
{
|
||||||
|
$labels = collect([]);
|
||||||
|
$labels->push('coolify.managed=true');
|
||||||
|
$labels->push('coolify.type=database');
|
||||||
|
$labels->push('coolify.databaseId='.$database->id);
|
||||||
|
$labels->push('coolify.resourceName='.Str::slug($database->name));
|
||||||
|
$labels->push('coolify.serviceName='.Str::slug($database->name));
|
||||||
|
$labels->push('coolify.projectName='.Str::slug($database->project()->name));
|
||||||
|
$labels->push('coolify.environmentName='.Str::slug($database->environment->name));
|
||||||
|
$labels->push('coolify.database.subType='.$database->type());
|
||||||
|
|
||||||
|
return $labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
function defaultLabels($id, $name, string $projectName, string $resourceName, string $environment, $pull_request_id = 0, string $type = 'application', $subType = null, $subId = null, $subName = null)
|
||||||
{
|
{
|
||||||
$labels = collect([]);
|
$labels = collect([]);
|
||||||
$labels->push('coolify.managed=true');
|
$labels->push('coolify.managed=true');
|
||||||
@@ -196,14 +211,21 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica
|
|||||||
$labels->push('coolify.'.$type.'Id='.$id);
|
$labels->push('coolify.'.$type.'Id='.$id);
|
||||||
$labels->push("coolify.type=$type");
|
$labels->push("coolify.type=$type");
|
||||||
$labels->push('coolify.name='.$name);
|
$labels->push('coolify.name='.$name);
|
||||||
|
$labels->push('coolify.resourceName='.Str::slug($resourceName));
|
||||||
|
$labels->push('coolify.projectName='.Str::slug($projectName));
|
||||||
|
$labels->push('coolify.serviceName='.Str::slug($subName ?? $resourceName));
|
||||||
|
$labels->push('coolify.environmentName='.Str::slug($environment));
|
||||||
|
|
||||||
$labels->push('coolify.pullRequestId='.$pull_request_id);
|
$labels->push('coolify.pullRequestId='.$pull_request_id);
|
||||||
if ($type === 'service') {
|
if ($type === 'service') {
|
||||||
$subId && $labels->push('coolify.service.subId='.$subId);
|
$subId && $labels->push('coolify.service.subId='.$subId);
|
||||||
$subType && $labels->push('coolify.service.subType='.$subType);
|
$subType && $labels->push('coolify.service.subType='.$subType);
|
||||||
|
$subName && $labels->push('coolify.service.subName='.Str::slug($subName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||||
{
|
{
|
||||||
if ($resource->getMorphClass() === \App\Models\ServiceApplication::class) {
|
if ($resource->getMorphClass() === \App\Models\ServiceApplication::class) {
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use App\Models\EnvironmentVariable;
|
use App\Models\EnvironmentVariable;
|
||||||
|
use App\Models\Service;
|
||||||
use App\Models\ServiceApplication;
|
use App\Models\ServiceApplication;
|
||||||
use App\Models\ServiceDatabase;
|
use App\Models\ServiceDatabase;
|
||||||
use Illuminate\Support\Stringable;
|
use Illuminate\Support\Stringable;
|
||||||
@@ -119,7 +120,10 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
if ($resourceFqdns->count() === 1) {
|
if ($resourceFqdns->count() === 1) {
|
||||||
$resourceFqdns = $resourceFqdns->first();
|
$resourceFqdns = $resourceFqdns->first();
|
||||||
$variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', '');
|
$variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', '');
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', $variableName)
|
||||||
|
->first();
|
||||||
$fqdn = Url::fromString($resourceFqdns);
|
$fqdn = Url::fromString($resourceFqdns);
|
||||||
$port = $fqdn->getPort();
|
$port = $fqdn->getPort();
|
||||||
$path = $fqdn->getPath();
|
$path = $fqdn->getPath();
|
||||||
@@ -134,7 +138,10 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
}
|
}
|
||||||
if ($port) {
|
if ($port) {
|
||||||
$variableName = $variableName."_$port";
|
$variableName = $variableName."_$port";
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', $variableName)
|
||||||
|
->first();
|
||||||
if ($generatedEnv) {
|
if ($generatedEnv) {
|
||||||
if ($path === '/') {
|
if ($path === '/') {
|
||||||
$generatedEnv->value = $fqdn;
|
$generatedEnv->value = $fqdn;
|
||||||
@@ -145,7 +152,10 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', '');
|
$variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', '');
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', $variableName)
|
||||||
|
->first();
|
||||||
$url = Url::fromString($fqdn);
|
$url = Url::fromString($fqdn);
|
||||||
$port = $url->getPort();
|
$port = $url->getPort();
|
||||||
$path = $url->getPath();
|
$path = $url->getPath();
|
||||||
@@ -161,7 +171,10 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
}
|
}
|
||||||
if ($port) {
|
if ($port) {
|
||||||
$variableName = $variableName."_$port";
|
$variableName = $variableName."_$port";
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', $variableName)
|
||||||
|
->first();
|
||||||
if ($generatedEnv) {
|
if ($generatedEnv) {
|
||||||
if ($path === '/') {
|
if ($path === '/') {
|
||||||
$generatedEnv->value = $url;
|
$generatedEnv->value = $url;
|
||||||
@@ -179,10 +192,16 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
$path = $host->getPath();
|
$path = $host->getPath();
|
||||||
$host = $host->getScheme().'://'.$host->getHost();
|
$host = $host->getScheme().'://'.$host->getHost();
|
||||||
if ($port) {
|
if ($port) {
|
||||||
$port_envs = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_FQDN_%_$port")->get();
|
$port_envs = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', 'like', "SERVICE_FQDN_%_$port")
|
||||||
|
->get();
|
||||||
foreach ($port_envs as $port_env) {
|
foreach ($port_envs as $port_env) {
|
||||||
$service_fqdn = str($port_env->key)->beforeLast('_')->after('SERVICE_FQDN_');
|
$service_fqdn = str($port_env->key)->beforeLast('_')->after('SERVICE_FQDN_');
|
||||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_FQDN_'.$service_fqdn)->first();
|
$env = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', 'SERVICE_FQDN_'.$service_fqdn)
|
||||||
|
->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
if ($path === '/') {
|
if ($path === '/') {
|
||||||
$env->value = $host;
|
$env->value = $host;
|
||||||
@@ -198,10 +217,16 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
}
|
}
|
||||||
$port_env->save();
|
$port_env->save();
|
||||||
}
|
}
|
||||||
$port_envs_url = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_URL_%_$port")->get();
|
$port_envs_url = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', 'like', "SERVICE_URL_%_$port")
|
||||||
|
->get();
|
||||||
foreach ($port_envs_url as $port_env_url) {
|
foreach ($port_envs_url as $port_env_url) {
|
||||||
$service_url = str($port_env_url->key)->beforeLast('_')->after('SERVICE_URL_');
|
$service_url = str($port_env_url->key)->beforeLast('_')->after('SERVICE_URL_');
|
||||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_URL_'.$service_url)->first();
|
$env = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', 'SERVICE_URL_'.$service_url)
|
||||||
|
->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
if ($path === '/') {
|
if ($path === '/') {
|
||||||
$env->value = $url;
|
$env->value = $url;
|
||||||
@@ -219,7 +244,10 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', '');
|
$variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', '');
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', $variableName)
|
||||||
|
->first();
|
||||||
$fqdn = Url::fromString($fqdn);
|
$fqdn = Url::fromString($fqdn);
|
||||||
$fqdn = $fqdn->getScheme().'://'.$fqdn->getHost().$fqdn->getPath();
|
$fqdn = $fqdn->getScheme().'://'.$fqdn->getHost().$fqdn->getPath();
|
||||||
if ($generatedEnv) {
|
if ($generatedEnv) {
|
||||||
@@ -227,7 +255,10 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
$generatedEnv->save();
|
$generatedEnv->save();
|
||||||
}
|
}
|
||||||
$variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', '');
|
$variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', '');
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class)
|
||||||
|
->where('resourceable_id', $resource->service_id)
|
||||||
|
->where('key', $variableName)
|
||||||
|
->first();
|
||||||
$url = Url::fromString($fqdn);
|
$url = Url::fromString($fqdn);
|
||||||
$url = $url->getHost().$url->getPath();
|
$url = $url->getHost().$url->getPath();
|
||||||
if ($generatedEnv) {
|
if ($generatedEnv) {
|
||||||
|
@@ -1819,7 +1819,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $fqdn,
|
'value' => $fqdn,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1831,7 +1832,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
}
|
}
|
||||||
$env = EnvironmentVariable::where([
|
$env = EnvironmentVariable::where([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
])->first();
|
])->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
$env_url = Url::fromString($savedService->fqdn);
|
$env_url = Url::fromString($savedService->fqdn);
|
||||||
@@ -1854,14 +1856,16 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
if ($value?->startsWith('$')) {
|
if ($value?->startsWith('$')) {
|
||||||
$foundEnv = EnvironmentVariable::where([
|
$foundEnv = EnvironmentVariable::where([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
])->first();
|
])->first();
|
||||||
$value = replaceVariables($value);
|
$value = replaceVariables($value);
|
||||||
$key = $value;
|
$key = $value;
|
||||||
if ($value->startsWith('SERVICE_')) {
|
if ($value->startsWith('SERVICE_')) {
|
||||||
$foundEnv = EnvironmentVariable::where([
|
$foundEnv = EnvironmentVariable::where([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
])->first();
|
])->first();
|
||||||
['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value);
|
['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value);
|
||||||
if (! is_null($command)) {
|
if (! is_null($command)) {
|
||||||
@@ -1895,7 +1899,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $fqdn,
|
'value' => $fqdn,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1912,7 +1917,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
}
|
}
|
||||||
$env = EnvironmentVariable::where([
|
$env = EnvironmentVariable::where([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
])->first();
|
])->first();
|
||||||
if ($env) {
|
if ($env) {
|
||||||
$env_url = Url::fromString($env->value);
|
$env_url = Url::fromString($env->value);
|
||||||
@@ -1932,7 +1938,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $generatedValue,
|
'value' => $generatedValue,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1957,18 +1964,21 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
}
|
}
|
||||||
$foundEnv = EnvironmentVariable::where([
|
$foundEnv = EnvironmentVariable::where([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
])->first();
|
])->first();
|
||||||
if ($foundEnv) {
|
if ($foundEnv) {
|
||||||
$defaultValue = data_get($foundEnv, 'value');
|
$defaultValue = data_get($foundEnv, 'value');
|
||||||
}
|
}
|
||||||
EnvironmentVariable::updateOrCreate([
|
EnvironmentVariable::updateOrCreate([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $defaultValue,
|
'value' => $defaultValue,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'service_id' => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1980,7 +1990,17 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
} else {
|
} else {
|
||||||
$fqdns = collect(data_get($savedService, 'fqdns'))->filter();
|
$fqdns = collect(data_get($savedService, 'fqdns'))->filter();
|
||||||
}
|
}
|
||||||
$defaultLabels = defaultLabels($resource->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
|
$defaultLabels = defaultLabels(
|
||||||
|
id: $resource->id,
|
||||||
|
name: $containerName,
|
||||||
|
projectName: $resource->project()->name,
|
||||||
|
resourceName: $resource->name,
|
||||||
|
type: 'service',
|
||||||
|
subType: $isDatabase ? 'database' : 'application',
|
||||||
|
subId: $savedService->id,
|
||||||
|
subName: $savedService->name,
|
||||||
|
environment: $resource->environment->name,
|
||||||
|
);
|
||||||
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
||||||
if (! $isDatabase && $fqdns->count() > 0) {
|
if (! $isDatabase && $fqdns->count() > 0) {
|
||||||
if ($fqdns) {
|
if ($fqdns) {
|
||||||
@@ -2808,7 +2828,16 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$defaultLabels = defaultLabels($resource->id, $containerName, $pull_request_id, type: 'application');
|
|
||||||
|
$defaultLabels = defaultLabels(
|
||||||
|
id: $resource->id,
|
||||||
|
name: $containerName,
|
||||||
|
projectName: $resource->project()->name,
|
||||||
|
resourceName: $resource->name,
|
||||||
|
environment: $resource->environment->name,
|
||||||
|
pull_request_id: $pull_request_id,
|
||||||
|
type: 'application'
|
||||||
|
);
|
||||||
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
||||||
|
|
||||||
if ($server->isLogDrainEnabled()) {
|
if ($server->isLogDrainEnabled()) {
|
||||||
@@ -2831,6 +2860,10 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
data_set($service, 'container_name', $containerName);
|
data_set($service, 'container_name', $containerName);
|
||||||
data_forget($service, 'volumes.*.content');
|
data_forget($service, 'volumes.*.content');
|
||||||
data_forget($service, 'volumes.*.isDirectory');
|
data_forget($service, 'volumes.*.isDirectory');
|
||||||
|
data_forget($service, 'volumes.*.is_directory');
|
||||||
|
data_forget($service, 'exclude_from_hc');
|
||||||
|
data_set($service, 'environment', $serviceVariables->toArray());
|
||||||
|
updateCompose($savedService);
|
||||||
|
|
||||||
return $service;
|
return $service;
|
||||||
});
|
});
|
||||||
@@ -2869,13 +2902,11 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($isApplication) {
|
if ($isApplication) {
|
||||||
$nameOfId = 'application_id';
|
|
||||||
$pullRequestId = $pull_request_id;
|
$pullRequestId = $pull_request_id;
|
||||||
$isPullRequest = $pullRequestId == 0 ? false : true;
|
$isPullRequest = $pullRequestId == 0 ? false : true;
|
||||||
$server = data_get($resource, 'destination.server');
|
$server = data_get($resource, 'destination.server');
|
||||||
$fileStorages = $resource->fileStorages();
|
$fileStorages = $resource->fileStorages();
|
||||||
} elseif ($isService) {
|
} elseif ($isService) {
|
||||||
$nameOfId = 'service_id';
|
|
||||||
$server = data_get($resource, 'server');
|
$server = data_get($resource, 'server');
|
||||||
$allServices = get_service_templates();
|
$allServices = get_service_templates();
|
||||||
} else {
|
} else {
|
||||||
@@ -3042,9 +3073,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (substr_count(str($key)->value(), '_') === 2) {
|
if (substr_count(str($key)->value(), '_') === 2) {
|
||||||
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $key->value(),
|
'key' => $key->value(),
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $fqdn,
|
'value' => $fqdn,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3053,9 +3085,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
}
|
}
|
||||||
if (substr_count(str($key)->value(), '_') === 3) {
|
if (substr_count(str($key)->value(), '_') === 3) {
|
||||||
$newKey = str($key)->beforeLast('_');
|
$newKey = str($key)->beforeLast('_');
|
||||||
$resource->environment_variables()->where('key', $newKey->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $newKey->value(),
|
'key' => $newKey->value(),
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $fqdn,
|
'value' => $fqdn,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3071,7 +3104,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
$key = str($key);
|
$key = str($key);
|
||||||
$value = replaceVariables($value);
|
$value = replaceVariables($value);
|
||||||
$command = parseCommandFromMagicEnvVariable($key);
|
$command = parseCommandFromMagicEnvVariable($key);
|
||||||
$found = $resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->first();
|
$found = $resource->environment_variables()->where('key', $key->value())->where('resourceable_type', get_class($resource))->where('resourceable_id', $resource->id)->first();
|
||||||
if ($found) {
|
if ($found) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3085,9 +3118,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
} elseif ($isService) {
|
} elseif ($isService) {
|
||||||
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
||||||
}
|
}
|
||||||
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $key->value(),
|
'key' => $key->value(),
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $fqdn,
|
'value' => $fqdn,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3104,9 +3138,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
||||||
}
|
}
|
||||||
$fqdn = str($fqdn)->replace('http://', '')->replace('https://', '');
|
$fqdn = str($fqdn)->replace('http://', '')->replace('https://', '');
|
||||||
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $key->value(),
|
'key' => $key->value(),
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $fqdn,
|
'value' => $fqdn,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3114,9 +3149,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$value = generateEnvValue($command, $resource);
|
$value = generateEnvValue($command, $resource);
|
||||||
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $key->value(),
|
'key' => $key->value(),
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3464,9 +3500,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
$originalValue = $value;
|
$originalValue = $value;
|
||||||
$parsedValue = replaceVariables($value);
|
$parsedValue = replaceVariables($value);
|
||||||
if ($value->startsWith('$SERVICE_')) {
|
if ($value->startsWith('$SERVICE_')) {
|
||||||
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3480,9 +3517,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
}
|
}
|
||||||
if ($key->value() === $parsedValue->value()) {
|
if ($key->value() === $parsedValue->value()) {
|
||||||
$value = null;
|
$value = null;
|
||||||
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3516,22 +3554,24 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
if ($originalValue->value() === $value->value()) {
|
if ($originalValue->value() === $value->value()) {
|
||||||
// This means the variable does not have a default value, so it needs to be created in Coolify
|
// This means the variable does not have a default value, so it needs to be created in Coolify
|
||||||
$parsedKeyValue = replaceVariables($value);
|
$parsedKeyValue = replaceVariables($value);
|
||||||
$resource->environment_variables()->where('key', $parsedKeyValue)->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $parsedKeyValue,
|
'key' => $parsedKeyValue,
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
'is_preview' => false,
|
'is_preview' => false,
|
||||||
'is_required' => $isRequired,
|
'is_required' => $isRequired,
|
||||||
]);
|
]);
|
||||||
// Add the variable to the environment so it will be shown in the deployable compose file
|
// Add the variable to the environment so it will be shown in the deployable compose file
|
||||||
$environment[$parsedKeyValue->value()] = $resource->environment_variables()->where('key', $parsedKeyValue)->where($nameOfId, $resource->id)->first()->value;
|
$environment[$parsedKeyValue->value()] = $resource->environment_variables()->where('key', $parsedKeyValue)->where('resourceable_type', get_class($resource))->where('resourceable_id', $resource->id)->first()->value;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->firstOrCreate([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
$nameOfId => $resource->id,
|
'resourceable_type' => get_class($resource),
|
||||||
|
'resourceable_id' => $resource->id,
|
||||||
], [
|
], [
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'is_build_time' => false,
|
'is_build_time' => false,
|
||||||
@@ -3591,11 +3631,15 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$defaultLabels = defaultLabels(
|
$defaultLabels = defaultLabels(
|
||||||
id: $resource->id,
|
id: $resource->id,
|
||||||
name: $containerName,
|
name: $containerName,
|
||||||
|
projectName: $resource->project()->name,
|
||||||
|
resourceName: $resource->name,
|
||||||
pull_request_id: $pullRequestId,
|
pull_request_id: $pullRequestId,
|
||||||
type: 'application'
|
type: 'application',
|
||||||
|
environment: $resource->environment->name,
|
||||||
);
|
);
|
||||||
} elseif ($isService) {
|
} elseif ($isService) {
|
||||||
if ($savedService->serviceType()) {
|
if ($savedService->serviceType()) {
|
||||||
@@ -3603,7 +3647,18 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
} else {
|
} else {
|
||||||
$fqdns = collect(data_get($savedService, 'fqdns'))->filter();
|
$fqdns = collect(data_get($savedService, 'fqdns'))->filter();
|
||||||
}
|
}
|
||||||
$defaultLabels = defaultLabels($resource->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
|
|
||||||
|
$defaultLabels = defaultLabels(
|
||||||
|
id: $resource->id,
|
||||||
|
name: $containerName,
|
||||||
|
projectName: $resource->project()->name,
|
||||||
|
resourceName: $resource->name,
|
||||||
|
type: 'service',
|
||||||
|
subType: $isDatabase ? 'database' : 'application',
|
||||||
|
subId: $savedService->id,
|
||||||
|
subName: $savedService->human_name ?? $savedService->name,
|
||||||
|
environment: $resource->environment->name,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Add COOLIFY_FQDN & COOLIFY_URL to environment
|
// Add COOLIFY_FQDN & COOLIFY_URL to environment
|
||||||
if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
|
if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
|
||||||
|
@@ -40,6 +40,7 @@ function get_socialite_provider(string $provider)
|
|||||||
'github' => \Laravel\Socialite\Two\GithubProvider::class,
|
'github' => \Laravel\Socialite\Two\GithubProvider::class,
|
||||||
'gitlab' => \Laravel\Socialite\Two\GitlabProvider::class,
|
'gitlab' => \Laravel\Socialite\Two\GitlabProvider::class,
|
||||||
'google' => \Laravel\Socialite\Two\GoogleProvider::class,
|
'google' => \Laravel\Socialite\Two\GoogleProvider::class,
|
||||||
|
'infomaniak' => \SocialiteProviders\Infomaniak\Provider::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
return Socialite::buildProvider(
|
return Socialite::buildProvider(
|
||||||
|
@@ -69,6 +69,7 @@ function allowedPathsForUnsubscribedAccounts()
|
|||||||
'logout',
|
'logout',
|
||||||
'force-password-reset',
|
'force-password-reset',
|
||||||
'livewire/update',
|
'livewire/update',
|
||||||
|
'admin',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
function allowedPathsForBoardingAccounts()
|
function allowedPathsForBoardingAccounts()
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
"server"
|
"server"
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.4",
|
||||||
"3sidedcube/laravel-redoc": "^1.0",
|
"3sidedcube/laravel-redoc": "^1.0",
|
||||||
"danharrin/livewire-rate-limiting": "2.0.0",
|
"danharrin/livewire-rate-limiting": "2.0.0",
|
||||||
"doctrine/dbal": "^4.2",
|
"doctrine/dbal": "^4.2",
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
"resend/resend-laravel": "^0.15.0",
|
"resend/resend-laravel": "^0.15.0",
|
||||||
"sentry/sentry-laravel": "^4.6",
|
"sentry/sentry-laravel": "^4.6",
|
||||||
"socialiteproviders/authentik": "^5.2",
|
"socialiteproviders/authentik": "^5.2",
|
||||||
|
"socialiteproviders/infomaniak": "^4.0",
|
||||||
"socialiteproviders/microsoft-azure": "^5.1",
|
"socialiteproviders/microsoft-azure": "^5.1",
|
||||||
"spatie/laravel-activitylog": "^4.7.3",
|
"spatie/laravel-activitylog": "^4.7.3",
|
||||||
"spatie/laravel-data": "^4.11",
|
"spatie/laravel-data": "^4.11",
|
||||||
|
53
composer.lock
generated
53
composer.lock
generated
@@ -7415,6 +7415,57 @@
|
|||||||
},
|
},
|
||||||
"time": "2023-11-07T22:21:16+00:00"
|
"time": "2023-11-07T22:21:16+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "socialiteproviders/infomaniak",
|
||||||
|
"version": "4.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/SocialiteProviders/Infomaniak.git",
|
||||||
|
"reference": "9796ad686204443bfdf3ff19a6c409e8771667e1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/SocialiteProviders/Infomaniak/zipball/9796ad686204443bfdf3ff19a6c409e8771667e1",
|
||||||
|
"reference": "9796ad686204443bfdf3ff19a6c409e8771667e1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"php": "^8.0",
|
||||||
|
"socialiteproviders/manager": "^4.4"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"SocialiteProviders\\Infomaniak\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Leopold Jacquot",
|
||||||
|
"email": "leopold.jacquot@infomaniak.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Infomaniak OAuth2 Provider for Laravel Socialite",
|
||||||
|
"keywords": [
|
||||||
|
"infomaniak",
|
||||||
|
"laravel",
|
||||||
|
"oauth",
|
||||||
|
"oauth2",
|
||||||
|
"provider",
|
||||||
|
"socialite"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"docs": "https://socialiteproviders.com/qq",
|
||||||
|
"issues": "https://github.com/socialiteproviders/providers/issues",
|
||||||
|
"source": "https://github.com/socialiteproviders/providers"
|
||||||
|
},
|
||||||
|
"time": "2024-11-20T05:42:36+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "socialiteproviders/manager",
|
"name": "socialiteproviders/manager",
|
||||||
"version": "v4.8.0",
|
"version": "v4.8.0",
|
||||||
@@ -15315,7 +15366,7 @@
|
|||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^8.2"
|
"php": "^8.4"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.6.0"
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'coolify' => [
|
'coolify' => [
|
||||||
'version' => '4.0.0-beta.380',
|
'version' => '4.0.0-beta.381',
|
||||||
'self_hosted' => env('SELF_HOSTED', true),
|
'self_hosted' => env('SELF_HOSTED', true),
|
||||||
'autoupdate' => env('AUTOUPDATE'),
|
'autoupdate' => env('AUTOUPDATE'),
|
||||||
'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'),
|
'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'),
|
||||||
@@ -65,26 +65,6 @@ return [
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'limits' => [
|
|
||||||
'trial_period' => 0,
|
|
||||||
'server' => [
|
|
||||||
'zero' => 0,
|
|
||||||
'self-hosted' => 999999999999,
|
|
||||||
'basic' => env('LIMIT_SERVER_BASIC', 2),
|
|
||||||
'pro' => env('LIMIT_SERVER_PRO', 10),
|
|
||||||
'ultimate' => env('LIMIT_SERVER_ULTIMATE', 25),
|
|
||||||
'dynamic' => env('LIMIT_SERVER_DYNAMIC', 2),
|
|
||||||
],
|
|
||||||
'email' => [
|
|
||||||
'zero' => true,
|
|
||||||
'self-hosted' => true,
|
|
||||||
'basic' => true,
|
|
||||||
'pro' => true,
|
|
||||||
'ultimate' => true,
|
|
||||||
'dynamic' => true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
|
|
||||||
'sentry' => [
|
'sentry' => [
|
||||||
'sentry_dsn' => env('SENTRY_DSN'),
|
'sentry_dsn' => env('SENTRY_DSN'),
|
||||||
],
|
],
|
||||||
|
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('environments', function (Blueprint $table) {
|
||||||
|
$table->string('uuid')->after('id')->nullable()->unique();
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('environments')
|
||||||
|
->whereNull('uuid')
|
||||||
|
->chunkById(100, function ($environments) {
|
||||||
|
foreach ($environments as $environment) {
|
||||||
|
DB::table('environments')
|
||||||
|
->where('id', $environment->id)
|
||||||
|
->update(['uuid' => (string) new Cuid2]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('environments', function (Blueprint $table) {
|
||||||
|
$table->string('uuid')->nullable(false)->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('environments', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('uuid');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@@ -0,0 +1,165 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('environment_variables', function (Blueprint $table) {
|
||||||
|
$table->string('resourceable_type')->nullable();
|
||||||
|
$table->unsignedBigInteger('resourceable_id')->nullable();
|
||||||
|
$table->index(['resourceable_type', 'resourceable_id']);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Populate the new columns
|
||||||
|
DB::table('environment_variables')->whereNotNull('application_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\Application',
|
||||||
|
'resourceable_id' => DB::raw('application_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('service_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\Service',
|
||||||
|
'resourceable_id' => DB::raw('service_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_postgresql_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandalonePostgresql',
|
||||||
|
'resourceable_id' => DB::raw('standalone_postgresql_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_redis_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandaloneRedis',
|
||||||
|
'resourceable_id' => DB::raw('standalone_redis_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_mongodb_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandaloneMongodb',
|
||||||
|
'resourceable_id' => DB::raw('standalone_mongodb_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_mysql_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandaloneMysql',
|
||||||
|
'resourceable_id' => DB::raw('standalone_mysql_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_mariadb_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandaloneMariadb',
|
||||||
|
'resourceable_id' => DB::raw('standalone_mariadb_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_keydb_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandaloneKeydb',
|
||||||
|
'resourceable_id' => DB::raw('standalone_keydb_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_dragonfly_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandaloneDragonfly',
|
||||||
|
'resourceable_id' => DB::raw('standalone_dragonfly_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')->whereNotNull('standalone_clickhouse_id')
|
||||||
|
->update([
|
||||||
|
'resourceable_type' => 'App\\Models\\StandaloneClickhouse',
|
||||||
|
'resourceable_id' => DB::raw('standalone_clickhouse_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// After successful migration, we can drop the old foreign key columns
|
||||||
|
Schema::table('environment_variables', function (Blueprint $table) {
|
||||||
|
$table->dropColumn([
|
||||||
|
'application_id',
|
||||||
|
'service_id',
|
||||||
|
'standalone_postgresql_id',
|
||||||
|
'standalone_redis_id',
|
||||||
|
'standalone_mongodb_id',
|
||||||
|
'standalone_mysql_id',
|
||||||
|
'standalone_mariadb_id',
|
||||||
|
'standalone_keydb_id',
|
||||||
|
'standalone_dragonfly_id',
|
||||||
|
'standalone_clickhouse_id',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('environment_variables', function (Blueprint $table) {
|
||||||
|
// Restore the old columns
|
||||||
|
$table->unsignedBigInteger('application_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('service_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_postgresql_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_redis_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_mongodb_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_mysql_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_mariadb_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_keydb_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_dragonfly_id')->nullable();
|
||||||
|
$table->unsignedBigInteger('standalone_clickhouse_id')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('environment_variables', function (Blueprint $table) {
|
||||||
|
// Restore data from polymorphic relationship
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\Application')
|
||||||
|
->update(['application_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\Service')
|
||||||
|
->update(['service_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandalonePostgresql')
|
||||||
|
->update(['standalone_postgresql_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandaloneRedis')
|
||||||
|
->update(['standalone_redis_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandaloneMongodb')
|
||||||
|
->update(['standalone_mongodb_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandaloneMysql')
|
||||||
|
->update(['standalone_mysql_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandaloneMariadb')
|
||||||
|
->update(['standalone_mariadb_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandaloneKeydb')
|
||||||
|
->update(['standalone_keydb_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandaloneDragonfly')
|
||||||
|
->update(['standalone_dragonfly_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
DB::table('environment_variables')
|
||||||
|
->where('resourceable_type', 'App\\Models\\StandaloneClickhouse')
|
||||||
|
->update(['standalone_clickhouse_id' => DB::raw('resourceable_id')]);
|
||||||
|
|
||||||
|
// Drop the polymorphic columns
|
||||||
|
$table->dropIndex(['resourceable_type', 'resourceable_id']);
|
||||||
|
$table->dropColumn(['resourceable_type', 'resourceable_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('server_settings', function (Blueprint $table) {
|
||||||
|
$table->string('server_disk_usage_check_frequency')->default('0 23 * * *');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('server_settings', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('server_disk_usage_check_frequency');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user