Skip to content

Commit

Permalink
Merge pull request coollabsio#4476 from coollabsio/next
Browse files Browse the repository at this point in the history
v4.0.0-beta.375
  • Loading branch information
andrasbacsai authored Dec 4, 2024
2 parents 3eefd7c + f535ed2 commit 8405f7b
Show file tree
Hide file tree
Showing 37 changed files with 367 additions and 78 deletions.
2 changes: 1 addition & 1 deletion app/Actions/Database/StartClickhouse.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function handle(StandaloneClickhouse $database)
$this->configuration_dir = database_configuration_dir().'/'.$container_name;

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
];

Expand Down
2 changes: 1 addition & 1 deletion app/Actions/Database/StartDragonfly.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function handle(StandaloneDragonfly $database)
$this->configuration_dir = database_configuration_dir().'/'.$container_name;

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
];

Expand Down
2 changes: 1 addition & 1 deletion app/Actions/Database/StartKeydb.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function handle(StandaloneKeydb $database)
$this->configuration_dir = database_configuration_dir().'/'.$container_name;

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
];

Expand Down
2 changes: 1 addition & 1 deletion app/Actions/Database/StartMariadb.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function handle(StandaloneMariadb $database)
$this->configuration_dir = database_configuration_dir().'/'.$container_name;

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
];

Expand Down
2 changes: 1 addition & 1 deletion app/Actions/Database/StartMongodb.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function handle(StandaloneMongodb $database)
}

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
];

Expand Down
2 changes: 1 addition & 1 deletion app/Actions/Database/StartMysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function handle(StandaloneMysql $database)
$this->configuration_dir = database_configuration_dir().'/'.$container_name;

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
];

Expand Down
2 changes: 1 addition & 1 deletion app/Actions/Database/StartPostgresql.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function handle(StandalonePostgresql $database)
$this->configuration_dir = database_configuration_dir().'/'.$container_name;

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
"mkdir -p $this->configuration_dir/docker-entrypoint-initdb.d/",
];
Expand Down
2 changes: 1 addition & 1 deletion app/Actions/Database/StartRedis.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function handle(StandaloneRedis $database)
$this->configuration_dir = database_configuration_dir().'/'.$container_name;

$this->commands = [
"echo 'Starting {$database->name}.'",
"echo 'Starting database.'",
"mkdir -p $this->configuration_dir",
];

Expand Down
6 changes: 3 additions & 3 deletions app/Console/Commands/CloudCleanupSubscriptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function handle()
}
// If the team has no subscription id and the invoice is paid, we need to reset the invoice paid status
if (! (data_get($team, 'subscription.stripe_subscription_id'))) {
$this->info("Resetting invoice paid status for team {$team->id} {$team->name}");
$this->info("Resetting invoice paid status for team {$team->id}");

$team->subscription->update([
'stripe_invoice_paid' => false,
Expand All @@ -61,9 +61,9 @@ public function handle()
$this->info('Subscription id: '.data_get($team, 'subscription.stripe_subscription_id'));
$confirm = $this->confirm('Do you want to cancel the subscription?', true);
if (! $confirm) {
$this->info("Skipping team {$team->id} {$team->name}");
$this->info("Skipping team {$team->id}");
} else {
$this->info("Cancelling subscription for team {$team->id} {$team->name}");
$this->info("Cancelling subscription for team {$team->id}");
$team->subscription->update([
'stripe_invoice_paid' => false,
'stripe_trial_already_ended' => false,
Expand Down
28 changes: 15 additions & 13 deletions app/Livewire/Project/Application/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,26 @@ class Configuration extends Component

public function mount()
{
$this->application = Application::query()
->whereHas('environment.project', function ($query) {
$query->where('team_id', currentTeam()->id)
->where('uuid', request()->route('project_uuid'));
})
->whereHas('environment', function ($query) {
$query->where('name', request()->route('environment_name'));
})
$project = currentTeam()
->projects()
->select('id', 'uuid', 'team_id')
->where('uuid', request()->route('project_uuid'))
->firstOrFail();
$environment = $project->environments()
->select('id', 'name', 'project_id')
->where('name', request()->route('environment_name'))
->firstOrFail();
$application = $environment->applications()
->with(['destination'])
->where('uuid', request()->route('application_uuid'))
->with(['destination' => function ($query) {
$query->select('id', 'server_id');
}])
->firstOrFail();

if ($this->application->destination && $this->application->destination->server_id) {
$this->application = $application;
if ($application->destination && $application->destination->server) {
$mainServer = $application->destination->server;
$this->servers = Server::ownedByCurrentTeam()
->select('id', 'name')
->where('id', '!=', $this->application->destination->server_id)
->where('id', '!=', $mainServer->id)
->get();
} else {
$this->servers = collect();
Expand Down
28 changes: 26 additions & 2 deletions app/Livewire/Project/Shared/ExecuteContainerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,42 @@ public function connectToContainer()
return;
}
try {
// Validate container name format
if (! preg_match('/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/', $this->selected_container)) {
throw new \InvalidArgumentException('Invalid container name format');
}

// Verify container exists in our allowed list
$container = collect($this->containers)->firstWhere('container.Names', $this->selected_container);
if (is_null($container)) {
throw new \RuntimeException('Container not found.');
}
$server = data_get($this->container, 'server');

// Verify server ownership and status
$server = data_get($container, 'server');
if (! $server || ! $server instanceof Server) {
throw new \RuntimeException('Invalid server configuration.');
}

if ($server->isForceDisabled()) {
throw new \RuntimeException('Server is disabled.');
}

// Additional ownership verification based on resource type
$resourceServer = match ($this->type) {
'application' => $this->resource->destination->server,
'database' => $this->resource->destination->server,
'service' => $this->resource->server,
default => throw new \RuntimeException('Invalid resource type.')
};

if ($server->id !== $resourceServer->id && ! $this->resource->additional_servers->contains('id', $server->id)) {
throw new \RuntimeException('Server ownership verification failed.');
}

$this->dispatch(
'send-terminal-command',
isset($container),
true,
data_get($container, 'container.Names'),
data_get($container, 'server.uuid')
);
Expand Down
11 changes: 10 additions & 1 deletion app/Livewire/Project/Shared/Terminal.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,20 @@ public function sendTerminalCommand($isContainer, $identifier, $serverUuid)
$server = Server::ownedByCurrentTeam()->whereUuid($serverUuid)->firstOrFail();

if ($isContainer) {
// Validate container identifier format (alphanumeric, dashes, and underscores only)
if (! preg_match('/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/', $identifier)) {
throw new \InvalidArgumentException('Invalid container identifier format');
}

// Verify container exists and belongs to the user's team
$status = getContainerStatus($server, $identifier);
if ($status !== 'running') {
return;
}
$command = SshMultiplexingHelper::generateSshCommand($server, "docker exec -it {$identifier} sh -c 'PATH=\$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && if [ -f ~/.profile ]; then . ~/.profile; fi && if [ -n \"\$SHELL\" ]; then exec \$SHELL; else sh; fi'");

// Escape the identifier for shell usage
$escapedIdentifier = escapeshellarg($identifier);
$command = SshMultiplexingHelper::generateSshCommand($server, "docker exec -it {$escapedIdentifier} sh -c 'PATH=\$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && if [ -f ~/.profile ]; then . ~/.profile; fi && if [ -n \"\$SHELL\" ]; then exec \$SHELL; else sh; fi'");
} else {
$command = SshMultiplexingHelper::generateSshCommand($server, 'PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && if [ -f ~/.profile ]; then . ~/.profile; fi && if [ -n "$SHELL" ]; then exec $SHELL; else sh; fi');
}
Expand Down
15 changes: 10 additions & 5 deletions app/Livewire/Server/Show.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use App\Actions\Server\StartSentinel;
use App\Actions\Server\StopSentinel;
use App\Models\Server;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Validate;
use Livewire\Component;

Expand Down Expand Up @@ -79,9 +79,6 @@ class Show extends Component
#[Validate(['required'])]
public string $serverTimezone;

#[Locked]
public array $timezones;

public function getListeners()
{
$teamId = auth()->user()->currentTeam()->id;
Expand All @@ -96,13 +93,21 @@ public function mount(string $server_uuid)
{
try {
$this->server = Server::ownedByCurrentTeam()->whereUuid($server_uuid)->firstOrFail();
$this->timezones = collect(timezone_identifiers_list())->sort()->values()->toArray();
$this->syncData();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}

#[Computed]
public function timezones(): array
{
return collect(timezone_identifiers_list())
->sort()
->values()
->toArray();
}

public function syncData(bool $toModel = false)
{
if ($toModel) {
Expand Down
15 changes: 10 additions & 5 deletions app/Livewire/Settings/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use App\Models\Server;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Validate;
use Livewire\Component;

Expand All @@ -17,9 +17,6 @@ class Index extends Component

protected Server $server;

#[Locked]
public $timezones;

#[Validate('boolean')]
public bool $is_auto_update_enabled;

Expand Down Expand Up @@ -101,12 +98,20 @@ public function mount()
$this->is_api_enabled = $this->settings->is_api_enabled;
$this->auto_update_frequency = $this->settings->auto_update_frequency;
$this->update_check_frequency = $this->settings->update_check_frequency;
$this->timezones = collect(timezone_identifiers_list())->sort()->values()->toArray();
$this->instance_timezone = $this->settings->instance_timezone;
$this->disable_two_step_confirmation = $this->settings->disable_two_step_confirmation;
}
}

#[Computed]
public function timezones(): array
{
return collect(timezone_identifiers_list())
->sort()
->values()
->toArray();
}

public function instantSave($isSave = true)
{
$this->validate();
Expand Down
3 changes: 2 additions & 1 deletion app/Models/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Enums\ApplicationDeploymentStatus;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Process\InvokedProcess;
Expand Down Expand Up @@ -104,7 +105,7 @@

class Application extends BaseModel
{
use SoftDeletes;
use HasFactory, SoftDeletes;

private static $parserVersion = '4';

Expand Down
3 changes: 2 additions & 1 deletion app/Models/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use App\Notifications\Server\Unreachable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -48,7 +49,7 @@

class Server extends BaseModel
{
use SchemalessAttributesTrait, SoftDeletes;
use HasFactory, SchemalessAttributesTrait, SoftDeletes;

public static $batch_counter = 0;

Expand Down
7 changes: 0 additions & 7 deletions app/Models/Team.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,6 @@ public function routeNotificationForTelegram()
];
}

public function name(): Attribute
{
return new Attribute(
get: fn () => sanitize_string($this->getRawOriginal('name')),
);
}

public function getRecepients($notification)
{
$recipients = data_get($notification, 'emails', null);
Expand Down
2 changes: 1 addition & 1 deletion bootstrap/helpers/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

// Based on /etc/os-release
const SUPPORTED_OS = [
'ubuntu debian raspbian',
'ubuntu debian raspbian pop',
'centos fedora rhel ol rocky amzn almalinux',
'sles opensuse-leap opensuse-tumbleweed',
'arch',
Expand Down
5 changes: 4 additions & 1 deletion bootstrap/helpers/shared.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ function metrics_dir(): string
return base_configuration_dir().'/metrics';
}

function sanitize_string(string $input): string
function sanitize_string(?string $input = null): ?string
{
if (is_null($input)) {
return null;
}
// Remove any HTML/PHP tags
$sanitized = strip_tags($input);

Expand Down
2 changes: 1 addition & 1 deletion config/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

return [
'coolify' => [
'version' => '4.0.0-beta.374',
'version' => '4.0.0-beta.375',
'self_hosted' => env('SELF_HOSTED', true),
'autoupdate' => env('AUTOUPDATE'),
'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'),
Expand Down
16 changes: 16 additions & 0 deletions config/database.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@
'search_path' => 'public',
'sslmode' => 'prefer',
],

'testing' => [
'driver' => 'pgsql',
'url' => env('DATABASE_TEST_URL'),
'host' => env('DB_TEST_HOST', 'postgres'),
'port' => env('DB_TEST_PORT', '5432'),
'database' => env('DB_TEST_DATABASE', 'coolify_test'),
'username' => env('DB_TEST_USERNAME', 'coolify'),
'password' => env('DB_TEST_PASSWORD', 'password'),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],

],

/*
Expand Down
Loading

0 comments on commit 8405f7b

Please sign in to comment.