mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-02 22:46:16 +00:00
Plugins base (#613)
* wip * wip * cleanup * notification channels * phpstan * services * remove server types * refactoring * refactoring
This commit is contained in:
@ -29,7 +29,7 @@ public function create(Server $server, array $input): Database
|
|||||||
/** @var Service $service */
|
/** @var Service $service */
|
||||||
$service = $server->database();
|
$service = $server->database();
|
||||||
|
|
||||||
/** @var \App\SSH\Services\Database\Database $databaseHandler */
|
/** @var \App\Services\Database\Database $databaseHandler */
|
||||||
$databaseHandler = $service->handler();
|
$databaseHandler = $service->handler();
|
||||||
$databaseHandler->create($database->name, $database->charset, $database->collation);
|
$databaseHandler->create($database->name, $database->charset, $database->collation);
|
||||||
$database->status = DatabaseStatus::READY;
|
$database->status = DatabaseStatus::READY;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use App\Models\DatabaseUser;
|
use App\Models\DatabaseUser;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\Database\Database;
|
use App\Services\Database\Database;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
@ -13,7 +13,7 @@ public function delete(Server $server, Database $database): void
|
|||||||
{
|
{
|
||||||
/** @var Service $service */
|
/** @var Service $service */
|
||||||
$service = $server->database();
|
$service = $server->database();
|
||||||
/** @var \App\SSH\Services\Database\Database $handler */
|
/** @var \App\Services\Database\Database $handler */
|
||||||
$handler = $service->handler();
|
$handler = $service->handler();
|
||||||
$handler->delete($database->name);
|
$handler->delete($database->name);
|
||||||
$database->delete();
|
$database->delete();
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use App\Models\DatabaseUser;
|
use App\Models\DatabaseUser;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\Database\Database;
|
use App\Services\Database\Database;
|
||||||
|
|
||||||
class DeleteDatabaseUser
|
class DeleteDatabaseUser
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ public function link(DatabaseUser $databaseUser, array $input): DatabaseUser
|
|||||||
/** @var Service $service */
|
/** @var Service $service */
|
||||||
$service = $databaseUser->server->database();
|
$service = $databaseUser->server->database();
|
||||||
|
|
||||||
/** @var \App\SSH\Services\Database\Database $handler */
|
/** @var \App\Services\Database\Database $handler */
|
||||||
$handler = $service->handler();
|
$handler = $service->handler();
|
||||||
|
|
||||||
// Unlink the user from all databases
|
// Unlink the user from all databases
|
||||||
|
@ -28,7 +28,7 @@ public function restore(BackupFile $backupFile, array $input): void
|
|||||||
dispatch(function () use ($backupFile, $database): void {
|
dispatch(function () use ($backupFile, $database): void {
|
||||||
/** @var Service $service */
|
/** @var Service $service */
|
||||||
$service = $database->server->database();
|
$service = $database->server->database();
|
||||||
/** @var \App\SSH\Services\Database\Database $databaseHandler */
|
/** @var \App\Services\Database\Database $databaseHandler */
|
||||||
$databaseHandler = $service->handler();
|
$databaseHandler = $service->handler();
|
||||||
$databaseHandler->restoreBackup($backupFile, $database->name);
|
$databaseHandler->restoreBackup($backupFile, $database->name);
|
||||||
$backupFile->status = BackupFileStatus::RESTORED;
|
$backupFile->status = BackupFileStatus::RESTORED;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
use App\Models\Backup;
|
use App\Models\Backup;
|
||||||
use App\Models\BackupFile;
|
use App\Models\BackupFile;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\Database\Database;
|
use App\Services\Database\Database;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class RunBackup
|
class RunBackup
|
||||||
|
@ -5,14 +5,15 @@
|
|||||||
use App\Enums\DatabaseUserStatus;
|
use App\Enums\DatabaseUserStatus;
|
||||||
use App\Models\DatabaseUser;
|
use App\Models\DatabaseUser;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\SSH\Services\Database\Database;
|
use App\Models\Service;
|
||||||
|
use App\Services\Database\Database;
|
||||||
|
|
||||||
class SyncDatabaseUsers
|
class SyncDatabaseUsers
|
||||||
{
|
{
|
||||||
public function sync(Server $server): void
|
public function sync(Server $server): void
|
||||||
{
|
{
|
||||||
$service = $server->database();
|
$service = $server->database();
|
||||||
if (! $service instanceof \App\Models\Service) {
|
if (! $service instanceof Service) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/** @var Database $handler */
|
/** @var Database $handler */
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
use App\Enums\DatabaseStatus;
|
use App\Enums\DatabaseStatus;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\Database\Database;
|
use App\Services\Database\Database;
|
||||||
|
|
||||||
class SyncDatabases
|
class SyncDatabases
|
||||||
{
|
{
|
||||||
public function sync(Server $server): void
|
public function sync(Server $server): void
|
||||||
{
|
{
|
||||||
$service = $server->database();
|
$service = $server->database();
|
||||||
if (! $service instanceof \App\Models\Service) {
|
if (! $service instanceof Service) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/** @var Database $handler */
|
/** @var Database $handler */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use App\Models\FirewallRule;
|
use App\Models\FirewallRule;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\Firewall\Firewall;
|
use App\Services\Firewall\Firewall;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
class GetMetrics
|
class GetMetrics
|
||||||
{
|
{
|
||||||
@ -70,7 +71,7 @@ private function metrics(
|
|||||||
->groupByRaw('date_interval')
|
->groupByRaw('date_interval')
|
||||||
->orderBy('date_interval')
|
->orderBy('date_interval')
|
||||||
->get()
|
->get()
|
||||||
->map(function ($item): \stdClass {
|
->map(function ($item): stdClass {
|
||||||
$item->date = Carbon::parse($item->date)->format('Y-m-d H:i');
|
$item->date = Carbon::parse($item->date)->format('Y-m-d H:i');
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\ServiceInterface;
|
use App\Services\ServiceInterface;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class UpdateMetricSettings
|
class UpdateMetricSettings
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use App\Exceptions\SSHError;
|
use App\Exceptions\SSHError;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\NodeJS\NodeJS;
|
use App\Services\NodeJS\NodeJS;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
class ChangeDefaultCli
|
class ChangeDefaultCli
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use App\Models\NotificationChannel;
|
use App\Models\NotificationChannel;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\NotificationChannels\Email;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -33,7 +34,7 @@ public function add(User $user, array $input): void
|
|||||||
if (! $channel->provider()->connect()) {
|
if (! $channel->provider()->connect()) {
|
||||||
$channel->delete();
|
$channel->delete();
|
||||||
|
|
||||||
if ($channel->provider === \App\Enums\NotificationChannel::EMAIL) {
|
if ($channel->provider === Email::id()) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'email' => __('Could not connect! Make sure you configured `.env` file correctly.'),
|
'email' => __('Could not connect! Make sure you configured `.env` file correctly.'),
|
||||||
]);
|
]);
|
||||||
@ -64,7 +65,7 @@ public static function rules(array $input): array
|
|||||||
$rules = [
|
$rules = [
|
||||||
'provider' => [
|
'provider' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(config('core.notification_channels_providers')),
|
Rule::in(array_keys(config('notification-channel.providers'))),
|
||||||
],
|
],
|
||||||
'name' => 'required',
|
'name' => 'required',
|
||||||
];
|
];
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use App\Exceptions\SSHError;
|
use App\Exceptions\SSHError;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\PHP\PHP;
|
use App\Services\PHP\PHP;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
class ChangeDefaultCli
|
class ChangeDefaultCli
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use App\Enums\PHPIniType;
|
use App\Enums\PHPIniType;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\PHP\PHP;
|
use App\Services\PHP\PHP;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\SSH\Services\PHP\PHP;
|
use App\Services\PHP\PHP;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
@ -57,7 +57,7 @@ public static function rules(Server $server): array
|
|||||||
return [
|
return [
|
||||||
'extension' => [
|
'extension' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(config('core.php_extensions')),
|
Rule::in(config('service.services.php.data.extensions', []) ?? []),
|
||||||
],
|
],
|
||||||
'version' => [
|
'version' => [
|
||||||
'required',
|
'required',
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use App\Models\Redirect;
|
use App\Models\Redirect;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\SSH\Services\Webserver\Webserver;
|
use App\Services\Webserver\Webserver;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
@ -33,7 +33,9 @@ public function create(Site $site, array $input): Redirect
|
|||||||
$service = $site->server->webserver();
|
$service = $site->server->webserver();
|
||||||
/** @var Webserver $webserver */
|
/** @var Webserver $webserver */
|
||||||
$webserver = $service->handler();
|
$webserver = $service->handler();
|
||||||
$webserver->updateVHost($site);
|
$webserver->updateVHost($site, regenerate: [
|
||||||
|
'redirects',
|
||||||
|
]);
|
||||||
$redirect->status = RedirectStatus::READY;
|
$redirect->status = RedirectStatus::READY;
|
||||||
$redirect->save();
|
$redirect->save();
|
||||||
})
|
})
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use App\Models\Redirect;
|
use App\Models\Redirect;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\SSH\Services\Webserver\Webserver;
|
use App\Services\Webserver\Webserver;
|
||||||
|
|
||||||
class DeleteRedirect
|
class DeleteRedirect
|
||||||
{
|
{
|
||||||
@ -20,7 +20,9 @@ public function delete(Site $site, Redirect $redirect): void
|
|||||||
$service = $site->server->webserver();
|
$service = $site->server->webserver();
|
||||||
/** @var Webserver $webserver */
|
/** @var Webserver $webserver */
|
||||||
$webserver = $service->handler();
|
$webserver = $service->handler();
|
||||||
$webserver->updateVHost($site);
|
$webserver->updateVHost($site, regenerate: [
|
||||||
|
'redirects',
|
||||||
|
]);
|
||||||
$redirect->delete();
|
$redirect->delete();
|
||||||
})->catch(function () use ($redirect): void {
|
})->catch(function () use ($redirect): void {
|
||||||
$redirect->status = RedirectStatus::FAILED;
|
$redirect->status = RedirectStatus::FAILED;
|
||||||
|
@ -11,6 +11,8 @@ public function activate(Ssl $ssl): void
|
|||||||
$ssl->site->ssls()->update(['is_active' => false]);
|
$ssl->site->ssls()->update(['is_active' => false]);
|
||||||
$ssl->is_active = true;
|
$ssl->is_active = true;
|
||||||
$ssl->save();
|
$ssl->save();
|
||||||
$ssl->site->webserver()->updateVHost($ssl->site);
|
$ssl->site->webserver()->updateVHost($ssl->site, regenerate: [
|
||||||
|
'port',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\Models\Ssl;
|
use App\Models\Ssl;
|
||||||
use App\SSH\Services\Webserver\Webserver;
|
use App\Services\Webserver\Webserver;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
@ -54,7 +54,9 @@ public function create(Site $site, array $input): void
|
|||||||
$webserver->setupSSL($ssl);
|
$webserver->setupSSL($ssl);
|
||||||
$ssl->status = SslStatus::CREATED;
|
$ssl->status = SslStatus::CREATED;
|
||||||
$ssl->save();
|
$ssl->save();
|
||||||
$webserver->updateVHost($site);
|
$webserver->updateVHost($site, regenerate: [
|
||||||
|
'port',
|
||||||
|
]);
|
||||||
})->catch(function () use ($ssl): void {
|
})->catch(function () use ($ssl): void {
|
||||||
$ssl->status = SslStatus::FAILED;
|
$ssl->status = SslStatus::FAILED;
|
||||||
$ssl->save();
|
$ssl->save();
|
||||||
|
@ -10,6 +10,8 @@ public function deactivate(Ssl $ssl): void
|
|||||||
{
|
{
|
||||||
$ssl->is_active = false;
|
$ssl->is_active = false;
|
||||||
$ssl->save();
|
$ssl->save();
|
||||||
$ssl->site->webserver()->updateVHost($ssl->site);
|
$ssl->site->webserver()->updateVHost($ssl->site, regenerate: [
|
||||||
|
'port',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use App\Enums\SslStatus;
|
use App\Enums\SslStatus;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Ssl;
|
use App\Models\Ssl;
|
||||||
use App\SSH\Services\Webserver\Webserver;
|
use App\Services\Webserver\Webserver;
|
||||||
|
|
||||||
class DeleteSSL
|
class DeleteSSL
|
||||||
{
|
{
|
||||||
|
@ -3,16 +3,13 @@
|
|||||||
namespace App\Actions\Server;
|
namespace App\Actions\Server;
|
||||||
|
|
||||||
use App\Enums\FirewallRuleStatus;
|
use App\Enums\FirewallRuleStatus;
|
||||||
use App\Enums\ServerProvider;
|
|
||||||
use App\Enums\ServerStatus;
|
use App\Enums\ServerStatus;
|
||||||
use App\Enums\ServerType;
|
|
||||||
use App\Exceptions\SSHConnectionError;
|
|
||||||
use App\Facades\Notifier;
|
use App\Facades\Notifier;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Notifications\ServerInstallationFailed;
|
use App\Notifications\ServerInstallationFailed;
|
||||||
use App\Notifications\ServerInstallationSucceed;
|
use App\ServerProviders\Custom;
|
||||||
use App\ValidationRules\RestrictedIPAddressesRule;
|
use App\ValidationRules\RestrictedIPAddressesRule;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
@ -25,6 +22,8 @@
|
|||||||
|
|
||||||
class CreateServer
|
class CreateServer
|
||||||
{
|
{
|
||||||
|
protected Server $server;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed> $input
|
* @param array<string, mixed> $input
|
||||||
*/
|
*/
|
||||||
@ -32,15 +31,14 @@ public function create(User $creator, Project $project, array $input): Server
|
|||||||
{
|
{
|
||||||
Validator::make($input, self::rules($project, $input))->validate();
|
Validator::make($input, self::rules($project, $input))->validate();
|
||||||
|
|
||||||
$server = new Server([
|
$this->server = new Server([
|
||||||
'project_id' => $project->id,
|
'project_id' => $project->id,
|
||||||
'user_id' => $creator->id,
|
'user_id' => $creator->id,
|
||||||
'name' => $input['name'],
|
'name' => $input['name'],
|
||||||
'ssh_user' => config('core.server_providers_default_user')[$input['provider']][$input['os']],
|
'ssh_user' => data_get(config('server-provider.providers'), $input['provider'].'.default_user') ?? 'root',
|
||||||
'ip' => $input['ip'] ?? '',
|
'ip' => $input['ip'] ?? '',
|
||||||
'port' => $input['port'] ?? 22,
|
'port' => $input['port'] ?? 22,
|
||||||
'os' => $input['os'],
|
'os' => $input['os'],
|
||||||
'type' => ServerType::REGULAR,
|
|
||||||
'provider' => $input['provider'],
|
'provider' => $input['provider'],
|
||||||
'authentication' => [
|
'authentication' => [
|
||||||
'user' => config('core.ssh_user'),
|
'user' => config('core.ssh_user'),
|
||||||
@ -52,32 +50,42 @@ public function create(User $creator, Project $project, array $input): Server
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($server->provider != 'custom') {
|
if ($this->server->provider != 'custom') {
|
||||||
$server->provider_id = $input['server_provider'];
|
$this->server->provider_id = $input['server_provider'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$server->type_data = $server->type()->data($input);
|
$this->server->provider_data = $this->server->provider()->data($input);
|
||||||
|
|
||||||
$server->provider_data = $server->provider()->data($input);
|
|
||||||
|
|
||||||
// save
|
// save
|
||||||
$server->save();
|
$this->server->save();
|
||||||
|
|
||||||
// create firewall rules
|
// create firewall rules
|
||||||
$this->createFirewallRules($server);
|
$this->createFirewallRules($this->server);
|
||||||
|
|
||||||
// create instance
|
// create instance
|
||||||
$server->provider()->create();
|
$this->server->provider()->create();
|
||||||
|
|
||||||
// add services
|
// create services
|
||||||
$server->type()->createServices($input);
|
$this->createServices();
|
||||||
|
|
||||||
// install server
|
// install server
|
||||||
$this->install($server);
|
dispatch(function (): void {
|
||||||
|
app(InstallServer::class)->run($this->server);
|
||||||
|
})
|
||||||
|
->catch(function (Throwable $e): void {
|
||||||
|
$this->server->update([
|
||||||
|
'status' => ServerStatus::INSTALLATION_FAILED,
|
||||||
|
]);
|
||||||
|
Notifier::send($this->server, new ServerInstallationFailed($this->server));
|
||||||
|
Log::error('server-installation-error', [
|
||||||
|
'error' => (string) $e,
|
||||||
|
]);
|
||||||
|
})
|
||||||
|
->onConnection('ssh');
|
||||||
|
|
||||||
return $server;
|
return $this->server;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$server->delete();
|
$this->server->delete();
|
||||||
|
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'provider' => $e->getMessage(),
|
'provider' => $e->getMessage(),
|
||||||
@ -85,41 +93,6 @@ public function create(User $creator, Project $project, array $input): Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function install(Server $server): void
|
|
||||||
{
|
|
||||||
dispatch(function () use ($server): void {
|
|
||||||
$maxWait = 180;
|
|
||||||
while ($maxWait > 0) {
|
|
||||||
sleep(10);
|
|
||||||
$maxWait -= 10;
|
|
||||||
if (! $server->provider()->isRunning()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
$server->ssh()->connect();
|
|
||||||
break;
|
|
||||||
} catch (SSHConnectionError) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$server->type()->install();
|
|
||||||
$server->update([
|
|
||||||
'status' => ServerStatus::READY,
|
|
||||||
]);
|
|
||||||
Notifier::send($server, new ServerInstallationSucceed($server));
|
|
||||||
})
|
|
||||||
->catch(function (Throwable $e) use ($server): void {
|
|
||||||
$server->update([
|
|
||||||
'status' => ServerStatus::INSTALLATION_FAILED,
|
|
||||||
]);
|
|
||||||
Notifier::send($server, new ServerInstallationFailed($server));
|
|
||||||
Log::error('server-installation-error', [
|
|
||||||
'error' => (string) $e,
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
->onConnection('ssh');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed> $input
|
* @param array<string, mixed> $input
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
@ -129,7 +102,7 @@ public static function rules(Project $project, array $input): array
|
|||||||
$rules = [
|
$rules = [
|
||||||
'provider' => [
|
'provider' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(config('core.server_providers')),
|
Rule::in(array_keys(config('server-provider.providers'))),
|
||||||
],
|
],
|
||||||
'name' => [
|
'name' => [
|
||||||
'required',
|
'required',
|
||||||
@ -139,7 +112,7 @@ public static function rules(Project $project, array $input): array
|
|||||||
Rule::in(config('core.operating_systems')),
|
Rule::in(config('core.operating_systems')),
|
||||||
],
|
],
|
||||||
'server_provider' => [
|
'server_provider' => [
|
||||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] != ServerProvider::CUSTOM, [
|
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] != Custom::id(), [
|
||||||
'required',
|
'required',
|
||||||
Rule::exists('server_providers', 'id')->where(function (Builder $query) use ($project): void {
|
Rule::exists('server_providers', 'id')->where(function (Builder $query) use ($project): void {
|
||||||
$query->where('project_id', $project->id)
|
$query->where('project_id', $project->id)
|
||||||
@ -148,13 +121,13 @@ public static function rules(Project $project, array $input): array
|
|||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
'ip' => [
|
'ip' => [
|
||||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM, [
|
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == Custom::id(), [
|
||||||
'required',
|
'required',
|
||||||
new RestrictedIPAddressesRule,
|
new RestrictedIPAddressesRule,
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
'port' => [
|
'port' => [
|
||||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM, [
|
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == Custom::id(), [
|
||||||
'required',
|
'required',
|
||||||
'numeric',
|
'numeric',
|
||||||
'min:1',
|
'min:1',
|
||||||
@ -163,22 +136,7 @@ public static function rules(Project $project, array $input): array
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
return array_merge($rules, self::typeRules($input), self::providerRules($input));
|
return array_merge($rules, self::providerRules($input));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<string, mixed> $input
|
|
||||||
* @return array<string, array<string>>
|
|
||||||
*/
|
|
||||||
private static function typeRules(array $input): array
|
|
||||||
{
|
|
||||||
if (! isset($input['type']) || ! in_array($input['type'], config('core.server_types'))) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$server = new Server(['type' => $input['type']]);
|
|
||||||
|
|
||||||
return $server->type()->createRules($input);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,8 +148,8 @@ private static function providerRules(array $input): array
|
|||||||
if (
|
if (
|
||||||
! isset($input['provider']) ||
|
! isset($input['provider']) ||
|
||||||
! isset($input['server_provider']) ||
|
! isset($input['server_provider']) ||
|
||||||
! in_array($input['provider'], config('core.server_providers')) ||
|
! config('server-provider.providers.'.$input['provider']) ||
|
||||||
$input['provider'] == ServerProvider::CUSTOM
|
$input['provider'] == Custom::id()
|
||||||
) {
|
) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -236,4 +194,49 @@ public function createFirewallRules(Server $server): void
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createServices(): void
|
||||||
|
{
|
||||||
|
$this->server->services()->forceDelete();
|
||||||
|
$this->addSupervisor();
|
||||||
|
$this->addRedis();
|
||||||
|
$this->addUfw();
|
||||||
|
$this->addMonitoring();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addSupervisor(): void
|
||||||
|
{
|
||||||
|
$this->server->services()->create([
|
||||||
|
'type' => 'process_manager',
|
||||||
|
'name' => 'supervisor',
|
||||||
|
'version' => 'latest',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addRedis(): void
|
||||||
|
{
|
||||||
|
$this->server->services()->create([
|
||||||
|
'type' => 'memory_database',
|
||||||
|
'name' => 'redis',
|
||||||
|
'version' => 'latest',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addUfw(): void
|
||||||
|
{
|
||||||
|
$this->server->services()->create([
|
||||||
|
'type' => 'firewall',
|
||||||
|
'name' => 'ufw',
|
||||||
|
'version' => 'latest',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addMonitoring(): void
|
||||||
|
{
|
||||||
|
$this->server->services()->create([
|
||||||
|
'type' => 'monitoring',
|
||||||
|
'name' => 'remote-monitor',
|
||||||
|
'version' => 'latest',
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
97
app/Actions/Server/InstallServer.php
Normal file
97
app/Actions/Server/InstallServer.php
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Server;
|
||||||
|
|
||||||
|
use App\Enums\ServerStatus;
|
||||||
|
use App\Enums\ServiceStatus;
|
||||||
|
use App\Exceptions\SSHConnectionError;
|
||||||
|
use App\Exceptions\SSHError;
|
||||||
|
use App\Facades\Notifier;
|
||||||
|
use App\Models\Server;
|
||||||
|
use App\Notifications\ServerInstallationSucceed;
|
||||||
|
use App\Services\PHP\PHP;
|
||||||
|
|
||||||
|
class InstallServer
|
||||||
|
{
|
||||||
|
protected Server $server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws SSHError
|
||||||
|
*/
|
||||||
|
public function run(Server $server): void
|
||||||
|
{
|
||||||
|
$this->server = $server;
|
||||||
|
|
||||||
|
$maxWait = 180;
|
||||||
|
while ($maxWait > 0) {
|
||||||
|
if (! $this->server->provider()->isRunning()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$this->server->ssh()->connect();
|
||||||
|
break;
|
||||||
|
} catch (SSHConnectionError) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
sleep(10);
|
||||||
|
$maxWait -= 10;
|
||||||
|
}
|
||||||
|
$this->install();
|
||||||
|
$this->server->update([
|
||||||
|
'status' => ServerStatus::READY,
|
||||||
|
]);
|
||||||
|
Notifier::send($this->server, new ServerInstallationSucceed($this->server));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws SSHError
|
||||||
|
*/
|
||||||
|
public function install(): void
|
||||||
|
{
|
||||||
|
$this->createUser();
|
||||||
|
$this->progress(15, 'installing-updates');
|
||||||
|
$this->server->os()->upgrade();
|
||||||
|
$this->progress(25, 'installing-dependencies');
|
||||||
|
$this->server->os()->installDependencies();
|
||||||
|
$services = $this->server->services;
|
||||||
|
$currentProgress = 45;
|
||||||
|
$progressPerService = (100 - $currentProgress) / count($services);
|
||||||
|
foreach ($services as $service) {
|
||||||
|
$currentProgress += $progressPerService;
|
||||||
|
$this->progress($currentProgress, 'installing- '.$service->name);
|
||||||
|
$service->handler()->install();
|
||||||
|
$service->update(['status' => ServiceStatus::READY]);
|
||||||
|
if ($service->type == 'php') {
|
||||||
|
$this->progress($currentProgress, 'installing-composer');
|
||||||
|
/** @var PHP $handler */
|
||||||
|
$handler = $service->handler();
|
||||||
|
$handler->installComposer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->progress(100, 'finishing');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws SSHError
|
||||||
|
*/
|
||||||
|
protected function createUser(): void
|
||||||
|
{
|
||||||
|
$this->server->os()->createUser(
|
||||||
|
$this->server->authentication['user'],
|
||||||
|
$this->server->authentication['pass'],
|
||||||
|
$this->server->sshKey()['public_key']
|
||||||
|
);
|
||||||
|
$this->server->ssh_user = config('core.ssh_user');
|
||||||
|
$this->server->save();
|
||||||
|
$this->server->refresh();
|
||||||
|
$this->server->public_key = $this->server->os()->getPublicKey($this->server->getSshUser());
|
||||||
|
$this->server->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function progress(int|float $percentage, ?string $step = null): void
|
||||||
|
{
|
||||||
|
$this->server->progress = $percentage;
|
||||||
|
$this->server->progress_step = $step;
|
||||||
|
$this->server->save();
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,7 @@ public function create(User $user, Project $project, array $input): ServerProvid
|
|||||||
|
|
||||||
private static function getProvider(string $name): ServerProviderContract
|
private static function getProvider(string $name): ServerProviderContract
|
||||||
{
|
{
|
||||||
$providerClass = config('core.server_providers_class.'.$name);
|
$providerClass = config('server-provider.providers.'.$name.'.handler');
|
||||||
/** @var ServerProviderContract $provider */
|
/** @var ServerProviderContract $provider */
|
||||||
$provider = new $providerClass(new ServerProvider, new Server);
|
$provider = new $providerClass(new ServerProvider, new Server);
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ public static function rules(array $input): array
|
|||||||
],
|
],
|
||||||
'provider' => [
|
'provider' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(config('core.server_providers')),
|
Rule::in(array_keys(config('server-provider.providers'))),
|
||||||
Rule::notIn('custom'),
|
Rule::notIn('custom'),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -17,7 +17,12 @@ public function install(Server $server, array $input): Service
|
|||||||
{
|
{
|
||||||
Validator::make($input, self::rules($input))->validate();
|
Validator::make($input, self::rules($input))->validate();
|
||||||
|
|
||||||
$input['type'] = config('core.service_types')[$input['name']];
|
$name = $input['name'];
|
||||||
|
$input['type'] = config("service.services.$name.type");
|
||||||
|
|
||||||
|
if (! $input['type']) {
|
||||||
|
throw new \InvalidArgumentException("Service type is not defined for $name");
|
||||||
|
}
|
||||||
|
|
||||||
$service = new Service([
|
$service = new Service([
|
||||||
'server_id' => $server->id,
|
'server_id' => $server->id,
|
||||||
@ -55,14 +60,14 @@ public static function rules(array $input): array
|
|||||||
$rules = [
|
$rules = [
|
||||||
'name' => [
|
'name' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(array_keys(config('core.service_types'))),
|
Rule::in(array_keys(config('service.services'))),
|
||||||
],
|
],
|
||||||
'version' => [
|
'version' => [
|
||||||
'required',
|
'required',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
if (isset($input['name'])) {
|
if (isset($input['name'])) {
|
||||||
$rules['version'][] = Rule::in(config("core.service_versions.{$input['name']}"));
|
$rules['version'][] = Rule::in(config("service.services.{$input['name']}.versions", []));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
|
@ -4,15 +4,17 @@
|
|||||||
|
|
||||||
use App\Enums\ServiceStatus;
|
use App\Enums\ServiceStatus;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
class Manage
|
class Manage
|
||||||
{
|
{
|
||||||
public function start(Service $service): void
|
public function start(Service $service): void
|
||||||
{
|
{
|
||||||
|
$this->validate($service);
|
||||||
$service->status = ServiceStatus::STARTING;
|
$service->status = ServiceStatus::STARTING;
|
||||||
$service->save();
|
$service->save();
|
||||||
dispatch(function () use ($service): void {
|
dispatch(function () use ($service): void {
|
||||||
$status = $service->server->systemd()->start($service->unit);
|
$status = $service->server->systemd()->start($service->handler()->unit());
|
||||||
if (str($status)->contains('Active: active')) {
|
if (str($status)->contains('Active: active')) {
|
||||||
$service->status = ServiceStatus::READY;
|
$service->status = ServiceStatus::READY;
|
||||||
} else {
|
} else {
|
||||||
@ -24,10 +26,11 @@ public function start(Service $service): void
|
|||||||
|
|
||||||
public function stop(Service $service): void
|
public function stop(Service $service): void
|
||||||
{
|
{
|
||||||
|
$this->validate($service);
|
||||||
$service->status = ServiceStatus::STOPPING;
|
$service->status = ServiceStatus::STOPPING;
|
||||||
$service->save();
|
$service->save();
|
||||||
dispatch(function () use ($service): void {
|
dispatch(function () use ($service): void {
|
||||||
$status = $service->server->systemd()->stop($service->unit);
|
$status = $service->server->systemd()->stop($service->handler()->unit());
|
||||||
if (str($status)->contains('Active: inactive')) {
|
if (str($status)->contains('Active: inactive')) {
|
||||||
$service->status = ServiceStatus::STOPPED;
|
$service->status = ServiceStatus::STOPPED;
|
||||||
} else {
|
} else {
|
||||||
@ -39,10 +42,11 @@ public function stop(Service $service): void
|
|||||||
|
|
||||||
public function restart(Service $service): void
|
public function restart(Service $service): void
|
||||||
{
|
{
|
||||||
|
$this->validate($service);
|
||||||
$service->status = ServiceStatus::RESTARTING;
|
$service->status = ServiceStatus::RESTARTING;
|
||||||
$service->save();
|
$service->save();
|
||||||
dispatch(function () use ($service): void {
|
dispatch(function () use ($service): void {
|
||||||
$status = $service->server->systemd()->restart($service->unit);
|
$status = $service->server->systemd()->restart($service->handler()->unit());
|
||||||
if (str($status)->contains('Active: active')) {
|
if (str($status)->contains('Active: active')) {
|
||||||
$service->status = ServiceStatus::READY;
|
$service->status = ServiceStatus::READY;
|
||||||
} else {
|
} else {
|
||||||
@ -54,10 +58,11 @@ public function restart(Service $service): void
|
|||||||
|
|
||||||
public function enable(Service $service): void
|
public function enable(Service $service): void
|
||||||
{
|
{
|
||||||
|
$this->validate($service);
|
||||||
$service->status = ServiceStatus::ENABLING;
|
$service->status = ServiceStatus::ENABLING;
|
||||||
$service->save();
|
$service->save();
|
||||||
dispatch(function () use ($service): void {
|
dispatch(function () use ($service): void {
|
||||||
$status = $service->server->systemd()->enable($service->unit);
|
$status = $service->server->systemd()->enable($service->handler()->unit());
|
||||||
if (str($status)->contains('Active: active')) {
|
if (str($status)->contains('Active: active')) {
|
||||||
$service->status = ServiceStatus::READY;
|
$service->status = ServiceStatus::READY;
|
||||||
} else {
|
} else {
|
||||||
@ -69,10 +74,11 @@ public function enable(Service $service): void
|
|||||||
|
|
||||||
public function disable(Service $service): void
|
public function disable(Service $service): void
|
||||||
{
|
{
|
||||||
|
$this->validate($service);
|
||||||
$service->status = ServiceStatus::DISABLING;
|
$service->status = ServiceStatus::DISABLING;
|
||||||
$service->save();
|
$service->save();
|
||||||
dispatch(function () use ($service): void {
|
dispatch(function () use ($service): void {
|
||||||
$status = $service->server->systemd()->disable($service->unit);
|
$status = $service->server->systemd()->disable($service->handler()->unit());
|
||||||
if (str($status)->contains('Active: inactive')) {
|
if (str($status)->contains('Active: inactive')) {
|
||||||
$service->status = ServiceStatus::DISABLED;
|
$service->status = ServiceStatus::DISABLED;
|
||||||
} else {
|
} else {
|
||||||
@ -81,4 +87,13 @@ public function disable(Service $service): void
|
|||||||
$service->save();
|
$service->save();
|
||||||
})->onConnection('ssh');
|
})->onConnection('ssh');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function validate(Service $service): void
|
||||||
|
{
|
||||||
|
if (! $service->handler()->unit()) {
|
||||||
|
throw ValidationException::withMessages([
|
||||||
|
'service' => __('This service does not have a systemd unit configured.'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
use App\Notifications\SiteInstallationSucceed;
|
use App\Notifications\SiteInstallationSucceed;
|
||||||
use App\ValidationRules\DomainRule;
|
use App\ValidationRules\DomainRule;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Database\Query\Builder;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -39,7 +38,6 @@ public function create(Server $server, array $input): Site
|
|||||||
'type' => $input['type'],
|
'type' => $input['type'],
|
||||||
'domain' => $input['domain'],
|
'domain' => $input['domain'],
|
||||||
'aliases' => $input['aliases'] ?? [],
|
'aliases' => $input['aliases'] ?? [],
|
||||||
'port' => $input['port'] ?? null,
|
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
'path' => '/home/'.$user.'/'.$input['domain'],
|
'path' => '/home/'.$user.'/'.$input['domain'],
|
||||||
'status' => SiteStatus::INSTALLING,
|
'status' => SiteStatus::INSTALLING,
|
||||||
@ -116,7 +114,7 @@ public static function rules(Server $server, array $input): array
|
|||||||
$rules = [
|
$rules = [
|
||||||
'type' => [
|
'type' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(config('core.site_types')),
|
Rule::in(array_keys(config('site.types'))),
|
||||||
],
|
],
|
||||||
'domain' => [
|
'domain' => [
|
||||||
'required',
|
'required',
|
||||||
@ -134,14 +132,6 @@ public static function rules(Server $server, array $input): array
|
|||||||
Rule::unique('sites', 'user')->where('server_id', $server->id),
|
Rule::unique('sites', 'user')->where('server_id', $server->id),
|
||||||
Rule::notIn($server->getSshUsers()),
|
Rule::notIn($server->getSshUsers()),
|
||||||
],
|
],
|
||||||
'port' => [
|
|
||||||
'nullable',
|
|
||||||
'integer',
|
|
||||||
'min:1',
|
|
||||||
'max:65535',
|
|
||||||
Rule::unique('sites', 'port')
|
|
||||||
->where(fn (Builder $query) => $query->where('server_id', $server->id)),
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return array_merge($rules, self::typeRules($server, $input));
|
return array_merge($rules, self::typeRules($server, $input));
|
||||||
@ -153,7 +143,7 @@ public static function rules(Server $server, array $input): array
|
|||||||
*/
|
*/
|
||||||
private static function typeRules(Server $server, array $input): array
|
private static function typeRules(Server $server, array $input): array
|
||||||
{
|
{
|
||||||
if (! isset($input['type']) || ! in_array($input['type'], config('core.site_types'))) {
|
if (! isset($input['type']) || ! config('site.types.'.$input['type'])) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
use App\Exceptions\SSHError;
|
use App\Exceptions\SSHError;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\SSH\Services\PHP\PHP;
|
use App\Services\PHP\PHP;
|
||||||
use App\SSH\Services\Webserver\Webserver;
|
use App\Services\Webserver\Webserver;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\SSH\Services\Webserver\Webserver;
|
use App\Services\Webserver\Webserver;
|
||||||
use App\ValidationRules\DomainRule;
|
use App\ValidationRules\DomainRule;
|
||||||
|
|
||||||
class UpdateAliases
|
class UpdateAliases
|
||||||
@ -21,7 +21,9 @@ public function update(Site $site, array $input): void
|
|||||||
|
|
||||||
/** @var Webserver $webserver */
|
/** @var Webserver $webserver */
|
||||||
$webserver = $service->handler();
|
$webserver = $service->handler();
|
||||||
$webserver->updateVHost($site);
|
$webserver->updateVHost($site, regenerate: [
|
||||||
|
'core',
|
||||||
|
]);
|
||||||
|
|
||||||
$site->save();
|
$site->save();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use App\Exceptions\SSHError;
|
use App\Exceptions\SSHError;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\SSH\Git\Git;
|
use App\SSH\OS\Git;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class UpdateBranch
|
class UpdateBranch
|
||||||
|
@ -30,7 +30,10 @@ public function update(Site $site, array $input): void
|
|||||||
$loadBalancerServer->save();
|
$loadBalancerServer->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$site->webserver()->updateVHost($site);
|
$site->webserver()->updateVHost($site, regenerate: [
|
||||||
|
'load-balancer-upstream',
|
||||||
|
'load-balancer',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +51,7 @@ public static function rules(array $input): array
|
|||||||
],
|
],
|
||||||
'provider' => [
|
'provider' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(config('core.source_control_providers')),
|
Rule::in(array_keys(config('source-control.providers'))),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
class CreateStorageProvider
|
class CreateStorageProvider
|
||||||
{
|
{
|
||||||
@ -35,7 +36,7 @@ public function create(User $user, Project $project, array $input): StorageProvi
|
|||||||
'provider' => __("Couldn't connect to the provider"),
|
'provider' => __("Couldn't connect to the provider"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'provider' => $e->getMessage(),
|
'provider' => $e->getMessage(),
|
||||||
]);
|
]);
|
||||||
@ -55,7 +56,7 @@ public static function rules(array $input): array
|
|||||||
$rules = [
|
$rules = [
|
||||||
'provider' => [
|
'provider' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in(config('core.storage_providers')),
|
Rule::in(array_keys(config('storage-provider.providers'))),
|
||||||
],
|
],
|
||||||
'name' => [
|
'name' => [
|
||||||
'required',
|
'required',
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\Models\Worker;
|
use App\Models\Worker;
|
||||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
use App\Services\ProcessManager\ProcessManager;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
@ -26,6 +26,7 @@ public function create(Server $server, array $input, ?Site $site = null): void
|
|||||||
$worker = new Worker([
|
$worker = new Worker([
|
||||||
'server_id' => $server->id,
|
'server_id' => $server->id,
|
||||||
'site_id' => $site?->id,
|
'site_id' => $site?->id,
|
||||||
|
'name' => $input['name'],
|
||||||
'command' => $input['command'],
|
'command' => $input['command'],
|
||||||
'user' => $input['user'],
|
'user' => $input['user'],
|
||||||
'auto_start' => $input['auto_start'] ? 1 : 0,
|
'auto_start' => $input['auto_start'] ? 1 : 0,
|
||||||
@ -63,6 +64,19 @@ public function create(Server $server, array $input, ?Site $site = null): void
|
|||||||
public static function rules(Server $server, ?Site $site = null): array
|
public static function rules(Server $server, ?Site $site = null): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'name' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique('workers')->where(function ($query) use ($server, $site) {
|
||||||
|
return $query->where('server_id', $server->id)
|
||||||
|
->where(function ($query) use ($site) {
|
||||||
|
if ($site) {
|
||||||
|
$query->where('site_id', $site->id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
],
|
||||||
'command' => [
|
'command' => [
|
||||||
'required',
|
'required',
|
||||||
],
|
],
|
||||||
|
@ -3,11 +3,10 @@
|
|||||||
namespace App\Actions\Worker;
|
namespace App\Actions\Worker;
|
||||||
|
|
||||||
use App\Enums\WorkerStatus;
|
use App\Enums\WorkerStatus;
|
||||||
use App\Models\Server;
|
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
use App\Models\Worker;
|
use App\Models\Worker;
|
||||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
use App\Services\ProcessManager\ProcessManager;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
@ -21,9 +20,10 @@ class EditWorker
|
|||||||
*/
|
*/
|
||||||
public function edit(Worker $worker, array $input): void
|
public function edit(Worker $worker, array $input): void
|
||||||
{
|
{
|
||||||
Validator::make($input, self::rules($worker->server, $worker->site))->validate();
|
Validator::make($input, self::rules($worker, $worker->site))->validate();
|
||||||
|
|
||||||
$worker->fill([
|
$worker->fill([
|
||||||
|
'name' => $input['name'],
|
||||||
'command' => $input['command'],
|
'command' => $input['command'],
|
||||||
'user' => $input['user'],
|
'user' => $input['user'],
|
||||||
'auto_start' => $input['auto_start'] ? 1 : 0,
|
'auto_start' => $input['auto_start'] ? 1 : 0,
|
||||||
@ -61,15 +61,29 @@ public function edit(Worker $worker, array $input): void
|
|||||||
/**
|
/**
|
||||||
* @return array<string, array<string>>
|
* @return array<string, array<string>>
|
||||||
*/
|
*/
|
||||||
public static function rules(Server $server, ?Site $site = null): array
|
public static function rules(Worker $worker, ?Site $site = null): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'name' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique('workers')->where(function ($query) use ($worker, $site) {
|
||||||
|
return $query->where('server_id', $worker->server_id)
|
||||||
|
->where(function ($query) use ($site) {
|
||||||
|
if ($site) {
|
||||||
|
$query->where('site_id', $site->id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->ignore($worker->id),
|
||||||
|
],
|
||||||
'command' => [
|
'command' => [
|
||||||
'required',
|
'required',
|
||||||
],
|
],
|
||||||
'user' => [
|
'user' => [
|
||||||
'required',
|
'required',
|
||||||
Rule::in($site?->getSshUsers() ?? $server->getSshUsers()),
|
Rule::in($site?->getSshUsers() ?? $worker->server->getSshUsers()),
|
||||||
],
|
],
|
||||||
'numprocs' => [
|
'numprocs' => [
|
||||||
'required',
|
'required',
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Worker;
|
use App\Models\Worker;
|
||||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
use App\Services\ProcessManager\ProcessManager;
|
||||||
|
|
||||||
class GetWorkerLogs
|
class GetWorkerLogs
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use App\Enums\WorkerStatus;
|
use App\Enums\WorkerStatus;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use App\Models\Worker;
|
use App\Models\Worker;
|
||||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
use App\Services\ProcessManager\ProcessManager;
|
||||||
|
|
||||||
class ManageWorker
|
class ManageWorker
|
||||||
{
|
{
|
||||||
|
@ -18,9 +18,14 @@ public function handle(): void
|
|||||||
ServerStatus::READY,
|
ServerStatus::READY,
|
||||||
ServerStatus::DISCONNECTED,
|
ServerStatus::DISCONNECTED,
|
||||||
])->chunk(50, function ($servers) {
|
])->chunk(50, function ($servers) {
|
||||||
|
$dispatchTime = now();
|
||||||
/** @var Server $server */
|
/** @var Server $server */
|
||||||
foreach ($servers as $server) {
|
foreach ($servers as $server) {
|
||||||
dispatch(function () use ($server) {
|
dispatch(function () use ($server, $dispatchTime) {
|
||||||
|
// check connection if dispatch time is less than 5 minutes ago
|
||||||
|
if ($dispatchTime->diffInMinutes(now()) > 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$server->checkConnection();
|
$server->checkConnection();
|
||||||
})->onConnection('ssh');
|
})->onConnection('ssh');
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Enums\ServerStatus;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
@ -15,17 +16,19 @@ class GetMetricsCommand extends Command
|
|||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
$checkedMetrics = 0;
|
$checkedMetrics = 0;
|
||||||
Server::query()->whereHas('services', function (Builder $query): void {
|
Server::query()
|
||||||
$query->where('type', 'monitoring')
|
->where('status', ServerStatus::READY)
|
||||||
->where('name', 'remote-monitor');
|
->whereHas('services', function (Builder $query): void {
|
||||||
})->chunk(10, function ($servers) use (&$checkedMetrics): void {
|
$query->where('type', 'monitoring')
|
||||||
/** @var Server $server */
|
->where('name', 'remote-monitor');
|
||||||
foreach ($servers as $server) {
|
})->chunk(10, function ($servers) use (&$checkedMetrics): void {
|
||||||
$info = $server->os()->resourceInfo();
|
/** @var Server $server */
|
||||||
$server->metrics()->create(array_merge($info, ['server_id' => $server->id]));
|
foreach ($servers as $server) {
|
||||||
$checkedMetrics++;
|
$info = $server->os()->resourceInfo();
|
||||||
}
|
$server->metrics()->create(array_merge($info, ['server_id' => $server->id]));
|
||||||
});
|
$checkedMetrics++;
|
||||||
|
}
|
||||||
|
});
|
||||||
$this->info("Checked $checkedMetrics metrics");
|
$this->info("Checked $checkedMetrics metrics");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,28 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\Backup;
|
||||||
|
use App\Models\BackupFile;
|
||||||
|
use App\Models\CronJob;
|
||||||
|
use App\Models\Database;
|
||||||
|
use App\Models\DatabaseUser;
|
||||||
|
use App\Models\Deployment;
|
||||||
|
use App\Models\DeploymentScript;
|
||||||
|
use App\Models\FirewallRule;
|
||||||
|
use App\Models\GitHook;
|
||||||
|
use App\Models\NotificationChannel;
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Models\Server;
|
||||||
|
use App\Models\ServerLog;
|
||||||
|
use App\Models\ServerProvider;
|
||||||
|
use App\Models\Service;
|
||||||
|
use App\Models\Site;
|
||||||
|
use App\Models\SourceControl;
|
||||||
|
use App\Models\SshKey;
|
||||||
|
use App\Models\Ssl;
|
||||||
|
use App\Models\StorageProvider;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Worker;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\File;
|
use Illuminate\Support\Facades\File;
|
||||||
@ -26,28 +48,28 @@ public function handle(): void
|
|||||||
|
|
||||||
$this->call('migrate', ['--force' => true]);
|
$this->call('migrate', ['--force' => true]);
|
||||||
|
|
||||||
$this->migrateModel(\App\Models\Backup::class);
|
$this->migrateModel(Backup::class);
|
||||||
$this->migrateModel(\App\Models\BackupFile::class);
|
$this->migrateModel(BackupFile::class);
|
||||||
$this->migrateModel(\App\Models\CronJob::class);
|
$this->migrateModel(CronJob::class);
|
||||||
$this->migrateModel(\App\Models\Database::class);
|
$this->migrateModel(Database::class);
|
||||||
$this->migrateModel(\App\Models\DatabaseUser::class);
|
$this->migrateModel(DatabaseUser::class);
|
||||||
$this->migrateModel(\App\Models\Deployment::class);
|
$this->migrateModel(Deployment::class);
|
||||||
$this->migrateModel(\App\Models\DeploymentScript::class);
|
$this->migrateModel(DeploymentScript::class);
|
||||||
$this->migrateModel(\App\Models\FirewallRule::class);
|
$this->migrateModel(FirewallRule::class);
|
||||||
$this->migrateModel(\App\Models\GitHook::class);
|
$this->migrateModel(GitHook::class);
|
||||||
$this->migrateModel(\App\Models\NotificationChannel::class);
|
$this->migrateModel(NotificationChannel::class);
|
||||||
$this->migrateModel(\App\Models\Project::class);
|
$this->migrateModel(Project::class);
|
||||||
$this->migrateModel(\App\Models\Worker::class);
|
$this->migrateModel(Worker::class);
|
||||||
$this->migrateModel(\App\Models\Server::class);
|
$this->migrateModel(Server::class);
|
||||||
$this->migrateModel(\App\Models\ServerLog::class);
|
$this->migrateModel(ServerLog::class);
|
||||||
$this->migrateModel(\App\Models\ServerProvider::class);
|
$this->migrateModel(ServerProvider::class);
|
||||||
$this->migrateModel(\App\Models\Service::class);
|
$this->migrateModel(Service::class);
|
||||||
$this->migrateModel(\App\Models\Site::class);
|
$this->migrateModel(Site::class);
|
||||||
$this->migrateModel(\App\Models\SourceControl::class);
|
$this->migrateModel(SourceControl::class);
|
||||||
$this->migrateModel(\App\Models\SshKey::class);
|
$this->migrateModel(SshKey::class);
|
||||||
$this->migrateModel(\App\Models\Ssl::class);
|
$this->migrateModel(Ssl::class);
|
||||||
$this->migrateModel(\App\Models\StorageProvider::class);
|
$this->migrateModel(StorageProvider::class);
|
||||||
$this->migrateModel(\App\Models\User::class);
|
$this->migrateModel(User::class);
|
||||||
|
|
||||||
$env = File::get(base_path('.env'));
|
$env = File::get(base_path('.env'));
|
||||||
$env = str_replace('DB_CONNECTION=mysql', 'DB_CONNECTION=sqlite', $env);
|
$env = str_replace('DB_CONNECTION=mysql', 'DB_CONNECTION=sqlite', $env);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace App\DTOs;
|
namespace App\DTOs;
|
||||||
|
|
||||||
class DynamicFieldDTO
|
class DynamicField
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param array<int, mixed>|null $options
|
* @param array<int, mixed>|null $options
|
||||||
@ -50,6 +50,13 @@ public function checkbox(): self
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function alert(): self
|
||||||
|
{
|
||||||
|
$this->type = 'alert';
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function name(string $name): self
|
public function name(string $name): self
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
@ -2,15 +2,23 @@
|
|||||||
|
|
||||||
namespace App\DTOs;
|
namespace App\DTOs;
|
||||||
|
|
||||||
readonly class DynamicFieldsCollectionDTO
|
readonly class DynamicForm
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param array<int, DynamicFieldDTO> $fields
|
* @param array<int, DynamicField> $fields
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private array $fields = [],
|
private array $fields = [],
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, DynamicField> $fields
|
||||||
|
*/
|
||||||
|
public static function make(array $fields): self
|
||||||
|
{
|
||||||
|
return new self($fields);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<int, mixed>
|
* @return array<int, mixed>
|
||||||
*/
|
*/
|
@ -4,17 +4,17 @@
|
|||||||
|
|
||||||
final class BackupFileStatus
|
final class BackupFileStatus
|
||||||
{
|
{
|
||||||
const CREATED = 'created';
|
const string CREATED = 'created';
|
||||||
|
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
|
|
||||||
const RESTORING = 'restoring';
|
const string RESTORING = 'restoring';
|
||||||
|
|
||||||
const RESTORED = 'restored';
|
const string RESTORED = 'restored';
|
||||||
|
|
||||||
const RESTORE_FAILED = 'restore_failed';
|
const string RESTORE_FAILED = 'restore_failed';
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
final class BackupStatus
|
final class BackupStatus
|
||||||
{
|
{
|
||||||
const RUNNING = 'running';
|
const string RUNNING = 'running';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
|
|
||||||
const STOPPED = 'stopped';
|
const string STOPPED = 'stopped';
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
final class CommandExecutionStatus
|
final class CommandExecutionStatus
|
||||||
{
|
{
|
||||||
const EXECUTING = 'executing';
|
const string EXECUTING = 'executing';
|
||||||
|
|
||||||
const COMPLETED = 'completed';
|
const string COMPLETED = 'completed';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
}
|
}
|
||||||
|
@ -4,17 +4,17 @@
|
|||||||
|
|
||||||
final class CronjobStatus
|
final class CronjobStatus
|
||||||
{
|
{
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
|
|
||||||
const ENABLING = 'enabling';
|
const string ENABLING = 'enabling';
|
||||||
|
|
||||||
const DISABLING = 'disabling';
|
const string DISABLING = 'disabling';
|
||||||
|
|
||||||
const UPDATING = 'updating';
|
const string UPDATING = 'updating';
|
||||||
|
|
||||||
const DISABLED = 'disabled';
|
const string DISABLED = 'disabled';
|
||||||
}
|
}
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Traits\Enum;
|
|
||||||
|
|
||||||
final class Database
|
|
||||||
{
|
|
||||||
use Enum;
|
|
||||||
|
|
||||||
const NONE = 'none';
|
|
||||||
|
|
||||||
const MYSQL57 = 'mysql57';
|
|
||||||
|
|
||||||
const MYSQL80 = 'mysql80';
|
|
||||||
|
|
||||||
const MYSQL84 = 'mysql84';
|
|
||||||
|
|
||||||
const MARIADB103 = 'mariadb103';
|
|
||||||
|
|
||||||
const MARIADB104 = 'mariadb104';
|
|
||||||
|
|
||||||
const MARIADB106 = 'mariadb1006';
|
|
||||||
|
|
||||||
const MARIADB1011 = 'mariadb1011';
|
|
||||||
|
|
||||||
const MARIADB114 = 'mariadb114';
|
|
||||||
|
|
||||||
const POSTGRESQL12 = 'postgresql12';
|
|
||||||
|
|
||||||
const POSTGRESQL13 = 'postgresql13';
|
|
||||||
|
|
||||||
const POSTGRESQL14 = 'postgresql14';
|
|
||||||
|
|
||||||
const POSTGRESQL15 = 'postgresql15';
|
|
||||||
|
|
||||||
const POSTGRESQL16 = 'postgresql16';
|
|
||||||
}
|
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
final class DatabaseStatus
|
final class DatabaseStatus
|
||||||
{
|
{
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
final class DatabaseUserStatus
|
final class DatabaseUserStatus
|
||||||
{
|
{
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
final class DeploymentStatus
|
final class DeploymentStatus
|
||||||
{
|
{
|
||||||
const DEPLOYING = 'deploying';
|
const string DEPLOYING = 'deploying';
|
||||||
|
|
||||||
const FINISHED = 'finished';
|
const string FINISHED = 'finished';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
final class FirewallRuleStatus
|
final class FirewallRuleStatus
|
||||||
{
|
{
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const UPDATING = 'updating';
|
const string UPDATING = 'updating';
|
||||||
|
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class LogType
|
|
||||||
{
|
|
||||||
const SERVER = 'server';
|
|
||||||
|
|
||||||
const SITE = 'site';
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Traits\Enum;
|
|
||||||
|
|
||||||
final class NodeJS
|
|
||||||
{
|
|
||||||
use Enum;
|
|
||||||
|
|
||||||
const NONE = 'none';
|
|
||||||
|
|
||||||
const V4 = '4';
|
|
||||||
|
|
||||||
const V6 = '6';
|
|
||||||
|
|
||||||
const V8 = '8';
|
|
||||||
|
|
||||||
const V10 = '10';
|
|
||||||
|
|
||||||
const V12 = '12';
|
|
||||||
|
|
||||||
const V14 = '14';
|
|
||||||
|
|
||||||
const V16 = '16';
|
|
||||||
|
|
||||||
const V18 = '18';
|
|
||||||
|
|
||||||
const V20 = '20';
|
|
||||||
|
|
||||||
const V22 = '22';
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class NotificationChannel
|
|
||||||
{
|
|
||||||
const EMAIL = 'email';
|
|
||||||
|
|
||||||
const SLACK = 'slack';
|
|
||||||
|
|
||||||
const DISCORD = 'discord';
|
|
||||||
|
|
||||||
const TELEGRAM = 'telegram';
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Traits\Enum;
|
|
||||||
|
|
||||||
final class PHP
|
|
||||||
{
|
|
||||||
use Enum;
|
|
||||||
|
|
||||||
const NONE = 'none';
|
|
||||||
|
|
||||||
const V70 = '7.0';
|
|
||||||
|
|
||||||
const V71 = '7.1';
|
|
||||||
|
|
||||||
const V72 = '7.2';
|
|
||||||
|
|
||||||
const V73 = '7.3';
|
|
||||||
|
|
||||||
const V74 = '7.4';
|
|
||||||
|
|
||||||
const V80 = '8.0';
|
|
||||||
|
|
||||||
const V81 = '8.1';
|
|
||||||
|
|
||||||
const V82 = '8.2';
|
|
||||||
|
|
||||||
const V83 = '8.3';
|
|
||||||
|
|
||||||
const V84 = '8.4';
|
|
||||||
}
|
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
final class PHPIniType
|
final class PHPIniType
|
||||||
{
|
{
|
||||||
const CLI = 'cli';
|
const string CLI = 'cli';
|
||||||
|
|
||||||
const FPM = 'fpm';
|
const string FPM = 'fpm';
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
final class RedirectStatus
|
final class RedirectStatus
|
||||||
{
|
{
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
final class ScriptExecutionStatus
|
final class ScriptExecutionStatus
|
||||||
{
|
{
|
||||||
const EXECUTING = 'executing';
|
const string EXECUTING = 'executing';
|
||||||
|
|
||||||
const COMPLETED = 'completed';
|
const string COMPLETED = 'completed';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class ServerProvider
|
|
||||||
{
|
|
||||||
const CUSTOM = 'custom';
|
|
||||||
|
|
||||||
const AWS = 'aws';
|
|
||||||
|
|
||||||
const LINODE = 'linode';
|
|
||||||
|
|
||||||
const DIGITALOCEAN = 'digitalocean';
|
|
||||||
|
|
||||||
const VULTR = 'vultr';
|
|
||||||
|
|
||||||
const HETZNER = 'hetzner';
|
|
||||||
}
|
|
@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
final class ServerStatus
|
final class ServerStatus
|
||||||
{
|
{
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const INSTALLING = 'installing';
|
const string INSTALLING = 'installing';
|
||||||
|
|
||||||
const INSTALLATION_FAILED = 'installation_failed';
|
const string INSTALLATION_FAILED = 'installation_failed';
|
||||||
|
|
||||||
const DISCONNECTED = 'disconnected';
|
const string DISCONNECTED = 'disconnected';
|
||||||
|
|
||||||
const UPDATING = 'updating';
|
const string UPDATING = 'updating';
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated server types will be dropped
|
|
||||||
*/
|
|
||||||
final class ServerType
|
|
||||||
{
|
|
||||||
const REGULAR = 'regular';
|
|
||||||
|
|
||||||
const DATABASE = 'database';
|
|
||||||
}
|
|
@ -4,27 +4,27 @@
|
|||||||
|
|
||||||
final class ServiceStatus
|
final class ServiceStatus
|
||||||
{
|
{
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const INSTALLING = 'installing';
|
const string INSTALLING = 'installing';
|
||||||
|
|
||||||
const INSTALLATION_FAILED = 'installation_failed';
|
const string INSTALLATION_FAILED = 'installation_failed';
|
||||||
|
|
||||||
const UNINSTALLING = 'uninstalling';
|
const string UNINSTALLING = 'uninstalling';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
|
|
||||||
const STARTING = 'starting';
|
const string STARTING = 'starting';
|
||||||
|
|
||||||
const STOPPING = 'stopping';
|
const string STOPPING = 'stopping';
|
||||||
|
|
||||||
const RESTARTING = 'restarting';
|
const string RESTARTING = 'restarting';
|
||||||
|
|
||||||
const STOPPED = 'stopped';
|
const string STOPPED = 'stopped';
|
||||||
|
|
||||||
const ENABLING = 'enabling';
|
const string ENABLING = 'enabling';
|
||||||
|
|
||||||
const DISABLING = 'disabling';
|
const string DISABLING = 'disabling';
|
||||||
|
|
||||||
const DISABLED = 'disabled';
|
const string DISABLED = 'disabled';
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class SiteFeature
|
|
||||||
{
|
|
||||||
const DEPLOYMENT = 'deployment';
|
|
||||||
|
|
||||||
const ENV = 'env';
|
|
||||||
|
|
||||||
const SSL = 'ssl';
|
|
||||||
|
|
||||||
const WORKERS = 'workers';
|
|
||||||
|
|
||||||
const COMMANDS = 'commands';
|
|
||||||
}
|
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
final class SiteStatus
|
final class SiteStatus
|
||||||
{
|
{
|
||||||
const READY = 'ready';
|
const string READY = 'ready';
|
||||||
|
|
||||||
const INSTALLING = 'installing';
|
const string INSTALLING = 'installing';
|
||||||
|
|
||||||
const INSTALLATION_FAILED = 'installation_failed';
|
const string INSTALLATION_FAILED = 'installation_failed';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class SiteType
|
|
||||||
{
|
|
||||||
const PHP = 'php';
|
|
||||||
|
|
||||||
const PHP_BLANK = 'php-blank';
|
|
||||||
|
|
||||||
const LARAVEL = 'laravel';
|
|
||||||
|
|
||||||
const WORDPRESS = 'wordpress';
|
|
||||||
|
|
||||||
const PHPMYADMIN = 'phpmyadmin';
|
|
||||||
|
|
||||||
const LOAD_BALANCER = 'load-balancer';
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class SourceControl
|
|
||||||
{
|
|
||||||
const GITHUB = 'github';
|
|
||||||
|
|
||||||
const GITLAB = 'gitlab';
|
|
||||||
|
|
||||||
const BITBUCKET = 'bitbucket';
|
|
||||||
}
|
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
final class SshKeyStatus
|
final class SshKeyStatus
|
||||||
{
|
{
|
||||||
const ADDING = 'adding';
|
const string ADDING = 'adding';
|
||||||
|
|
||||||
const ADDED = 'added';
|
const string ADDED = 'added';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
final class SslStatus
|
final class SslStatus
|
||||||
{
|
{
|
||||||
const CREATED = 'created';
|
const string CREATED = 'created';
|
||||||
|
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
final class SslType
|
final class SslType
|
||||||
{
|
{
|
||||||
const LETSENCRYPT = 'letsencrypt';
|
const string LETSENCRYPT = 'letsencrypt';
|
||||||
|
|
||||||
const CUSTOM = 'custom';
|
const string CUSTOM = 'custom';
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class StorageProvider
|
|
||||||
{
|
|
||||||
const DROPBOX = 'dropbox';
|
|
||||||
|
|
||||||
const FTP = 'ftp';
|
|
||||||
|
|
||||||
const LOCAL = 'local';
|
|
||||||
|
|
||||||
const S3 = 's3';
|
|
||||||
}
|
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
final class UserRole
|
final class UserRole
|
||||||
{
|
{
|
||||||
const USER = 'user';
|
const string USER = 'user';
|
||||||
|
|
||||||
const ADMIN = 'admin';
|
const string ADMIN = 'admin';
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
final class Webserver
|
|
||||||
{
|
|
||||||
const NONE = 'none';
|
|
||||||
|
|
||||||
const NGINX = 'nginx';
|
|
||||||
|
|
||||||
const CADDY = 'caddy';
|
|
||||||
}
|
|
@ -4,19 +4,19 @@
|
|||||||
|
|
||||||
final class WorkerStatus
|
final class WorkerStatus
|
||||||
{
|
{
|
||||||
const RUNNING = 'running';
|
const string RUNNING = 'running';
|
||||||
|
|
||||||
const CREATING = 'creating';
|
const string CREATING = 'creating';
|
||||||
|
|
||||||
const DELETING = 'deleting';
|
const string DELETING = 'deleting';
|
||||||
|
|
||||||
const FAILED = 'failed';
|
const string FAILED = 'failed';
|
||||||
|
|
||||||
const STARTING = 'starting';
|
const string STARTING = 'starting';
|
||||||
|
|
||||||
const STOPPING = 'stopping';
|
const string STOPPING = 'stopping';
|
||||||
|
|
||||||
const RESTARTING = 'restarting';
|
const string RESTARTING = 'restarting';
|
||||||
|
|
||||||
const STOPPED = 'stopped';
|
const string STOPPED = 'stopped';
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
namespace App\Facades;
|
namespace App\Facades;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use App\Models\ServerLog;
|
||||||
use App\Support\Testing\SSHFake;
|
use App\Support\Testing\SSHFake;
|
||||||
use Illuminate\Support\Facades\Facade as FacadeAlias;
|
use Illuminate\Support\Facades\Facade as FacadeAlias;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class SSH
|
* Class SSH
|
||||||
*
|
*
|
||||||
* @method static \App\Helpers\SSH|SSHFake init(\App\Models\Server $server, string $asUser = null)
|
* @method static \App\Helpers\SSH|SSHFake init(Server $server, string $asUser = null)
|
||||||
* @method static setLog(?\App\Models\ServerLog $log)
|
* @method static setLog(?ServerLog $log)
|
||||||
* @method static connect()
|
* @method static connect()
|
||||||
* @method static string exec(string $command, string $log = '', int $siteId = null, ?bool $stream = false, callable $streamCallback = null)
|
* @method static string exec(string $command, string $log = '', int $siteId = null, ?bool $stream = false, callable $streamCallback = null)
|
||||||
* @method static string upload(string $local, string $remote, ?string $owner = null)
|
* @method static string upload(string $local, string $remote, ?string $owner = null)
|
||||||
|
@ -126,7 +126,7 @@ protected function findDetectionRulesAgainstUserAgent(array $rules)
|
|||||||
/**
|
/**
|
||||||
* Retrieve from the given key from the cache or resolve the value.
|
* Retrieve from the given key from the cache or resolve the value.
|
||||||
*
|
*
|
||||||
* @param \Closure():mixed $callback
|
* @param Closure():mixed $callback
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected function retrieveUsingCacheOrResolve(string $key, Closure $callback)
|
protected function retrieveUsingCacheOrResolve(string $key, Closure $callback)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\API;
|
namespace App\Http\Controllers\API;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Knuckles\Scribe\Attributes\Endpoint;
|
use Knuckles\Scribe\Attributes\Endpoint;
|
||||||
use Knuckles\Scribe\Attributes\Group;
|
use Knuckles\Scribe\Attributes\Group;
|
||||||
use Knuckles\Scribe\Attributes\Unauthenticated;
|
use Knuckles\Scribe\Attributes\Unauthenticated;
|
||||||
@ -14,7 +15,7 @@ class HealthController extends Controller
|
|||||||
#[Get('api/health', name: 'api.health')]
|
#[Get('api/health', name: 'api.health')]
|
||||||
#[Unauthenticated]
|
#[Unauthenticated]
|
||||||
#[Endpoint(title: 'health-check')]
|
#[Endpoint(title: 'health-check')]
|
||||||
public function __invoke(): \Illuminate\Http\JsonResponse
|
public function __invoke(): JsonResponse
|
||||||
{
|
{
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => true,
|
'success' => true,
|
||||||
|
@ -5,10 +5,6 @@
|
|||||||
use App\Actions\Server\CreateServer;
|
use App\Actions\Server\CreateServer;
|
||||||
use App\Actions\Server\RebootServer;
|
use App\Actions\Server\RebootServer;
|
||||||
use App\Actions\Server\Update;
|
use App\Actions\Server\Update;
|
||||||
use App\Enums\Database;
|
|
||||||
use App\Enums\PHP;
|
|
||||||
use App\Enums\ServerProvider;
|
|
||||||
use App\Enums\Webserver;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Resources\ServerResource;
|
use App\Http\Resources\ServerResource;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
@ -45,16 +41,16 @@ public function index(Project $project): ResourceCollection
|
|||||||
#[Post('/', name: 'api.projects.servers.create', middleware: 'ability:write')]
|
#[Post('/', name: 'api.projects.servers.create', middleware: 'ability:write')]
|
||||||
#[Endpoint(title: 'create', description: 'Create a new server.')]
|
#[Endpoint(title: 'create', description: 'Create a new server.')]
|
||||||
#[BodyParam(name: 'provider', description: 'The server provider type', required: true)]
|
#[BodyParam(name: 'provider', description: 'The server provider type', required: true)]
|
||||||
#[BodyParam(name: 'server_provider', description: 'If the provider is not custom, the ID of the server provider profile', enum: [ServerProvider::CUSTOM, ServerProvider::HETZNER, ServerProvider::DIGITALOCEAN, ServerProvider::LINODE, ServerProvider::VULTR])]
|
#[BodyParam(name: 'server_provider', description: 'If the provider is not custom, the ID of the server provider profile')]
|
||||||
#[BodyParam(name: 'region', description: 'Provider region if the provider is not custom')]
|
#[BodyParam(name: 'region', description: 'Provider region if the provider is not custom')]
|
||||||
#[BodyParam(name: 'plan', description: 'Provider plan if the provider is not custom')]
|
#[BodyParam(name: 'plan', description: 'Provider plan if the provider is not custom')]
|
||||||
#[BodyParam(name: 'ip', description: 'SSH IP address if the provider is custom')]
|
#[BodyParam(name: 'ip', description: 'SSH IP address if the provider is custom')]
|
||||||
#[BodyParam(name: 'port', description: 'SSH Port if the provider is custom')]
|
#[BodyParam(name: 'port', description: 'SSH Port if the provider is custom')]
|
||||||
#[BodyParam(name: 'name', description: 'The name of the server.', required: true)]
|
#[BodyParam(name: 'name', description: 'The name of the server.', required: true)]
|
||||||
#[BodyParam(name: 'os', description: 'The os of the server', required: true)]
|
#[BodyParam(name: 'os', description: 'The os of the server', required: true)]
|
||||||
#[BodyParam(name: 'webserver', description: 'Web server', required: true, enum: [Webserver::NONE, Webserver::NGINX, Webserver::CADDY])]
|
#[BodyParam(name: 'webserver', description: 'Web server', required: true)]
|
||||||
#[BodyParam(name: 'database', description: 'Database', required: true, enum: [Database::NONE, Database::MYSQL57, Database::MYSQL80, Database::MARIADB103, Database::MARIADB104, Database::MARIADB103, Database::POSTGRESQL12, Database::POSTGRESQL13, Database::POSTGRESQL14, Database::POSTGRESQL15, Database::POSTGRESQL16], )]
|
#[BodyParam(name: 'database', description: 'Database', required: true)]
|
||||||
#[BodyParam(name: 'php', description: 'PHP version', required: true, enum: [PHP::V70, PHP::V71, PHP::V72, PHP::V73, PHP::V74, PHP::V80, PHP::V81, PHP::V82, PHP::V83])]
|
#[BodyParam(name: 'php', description: 'PHP version', required: true)]
|
||||||
#[ResponseFromApiResource(ServerResource::class, Server::class)]
|
#[ResponseFromApiResource(ServerResource::class, Server::class)]
|
||||||
public function create(Request $request, Project $project): ServerResource
|
public function create(Request $request, Project $project): ServerResource
|
||||||
{
|
{
|
||||||
|
@ -9,13 +9,13 @@
|
|||||||
use App\Actions\Site\UpdateEnv;
|
use App\Actions\Site\UpdateEnv;
|
||||||
use App\Actions\Site\UpdateLoadBalancer;
|
use App\Actions\Site\UpdateLoadBalancer;
|
||||||
use App\Enums\LoadBalancerMethod;
|
use App\Enums\LoadBalancerMethod;
|
||||||
use App\Enums\SiteType;
|
|
||||||
use App\Exceptions\DeploymentScriptIsEmptyException;
|
use App\Exceptions\DeploymentScriptIsEmptyException;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Resources\SiteResource;
|
use App\Http\Resources\SiteResource;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Site;
|
use App\Models\Site;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||||
use Knuckles\Scribe\Attributes\BodyParam;
|
use Knuckles\Scribe\Attributes\BodyParam;
|
||||||
@ -49,7 +49,7 @@ public function index(Project $project, Server $server): ResourceCollection
|
|||||||
|
|
||||||
#[Post('/', name: 'api.projects.servers.sites.create', middleware: 'ability:write')]
|
#[Post('/', name: 'api.projects.servers.sites.create', middleware: 'ability:write')]
|
||||||
#[Endpoint(title: 'create', description: 'Create a new site.')]
|
#[Endpoint(title: 'create', description: 'Create a new site.')]
|
||||||
#[BodyParam(name: 'type', required: true, enum: [SiteType::PHP, SiteType::PHP_BLANK, SiteType::PHPMYADMIN, SiteType::LARAVEL, SiteType::WORDPRESS, SiteType::LOAD_BALANCER])]
|
#[BodyParam(name: 'type', required: true)]
|
||||||
#[BodyParam(name: 'domain', required: true)]
|
#[BodyParam(name: 'domain', required: true)]
|
||||||
#[BodyParam(name: 'aliases', type: 'array')]
|
#[BodyParam(name: 'aliases', type: 'array')]
|
||||||
#[BodyParam(name: 'php_version', description: 'One of the installed PHP Versions', required: true, example: '7.4')]
|
#[BodyParam(name: 'php_version', description: 'One of the installed PHP Versions', required: true, example: '7.4')]
|
||||||
@ -172,7 +172,7 @@ public function updateDeploymentScript(Request $request, Project $project, Serve
|
|||||||
#[Get('{site}/deployment-script', name: 'api.projects.servers.sites.deployment-script.show', middleware: 'ability:read')]
|
#[Get('{site}/deployment-script', name: 'api.projects.servers.sites.deployment-script.show', middleware: 'ability:read')]
|
||||||
#[Endpoint(title: 'deployment-script', description: 'Get site deployment script content')]
|
#[Endpoint(title: 'deployment-script', description: 'Get site deployment script content')]
|
||||||
#[Response(status: 200)]
|
#[Response(status: 200)]
|
||||||
public function showDeploymentScript(Project $project, Server $server, Site $site): \Illuminate\Http\JsonResponse
|
public function showDeploymentScript(Project $project, Server $server, Site $site): JsonResponse
|
||||||
{
|
{
|
||||||
$this->authorize('view', [$site, $server]);
|
$this->authorize('view', [$site, $server]);
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ public function showDeploymentScript(Project $project, Server $server, Site $sit
|
|||||||
'env' => 'APP_NAME=Laravel\nAPP_ENV=production',
|
'env' => 'APP_NAME=Laravel\nAPP_ENV=production',
|
||||||
],
|
],
|
||||||
], status: 200)]
|
], status: 200)]
|
||||||
public function showEnv(Project $project, Server $server, Site $site): \Illuminate\Http\JsonResponse
|
public function showEnv(Project $project, Server $server, Site $site): JsonResponse
|
||||||
{
|
{
|
||||||
$this->authorize('view', [$site, $server]);
|
$this->authorize('view', [$site, $server]);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public function index(Project $project): ResourceCollection
|
|||||||
|
|
||||||
#[Post('/', name: 'api.projects.source-controls.create', middleware: 'ability:write')]
|
#[Post('/', name: 'api.projects.source-controls.create', middleware: 'ability:write')]
|
||||||
#[Endpoint(title: 'create')]
|
#[Endpoint(title: 'create')]
|
||||||
#[BodyParam(name: 'provider', description: 'The provider', required: true, enum: [\App\Enums\SourceControl::GITLAB, \App\Enums\SourceControl::GITHUB, \App\Enums\SourceControl::BITBUCKET])]
|
#[BodyParam(name: 'provider', description: 'The provider', required: true)]
|
||||||
#[BodyParam(name: 'name', description: 'The name of the storage provider.', required: true)]
|
#[BodyParam(name: 'name', description: 'The name of the storage provider.', required: true)]
|
||||||
#[BodyParam(name: 'token', description: 'The token if provider requires api token')]
|
#[BodyParam(name: 'token', description: 'The token if provider requires api token')]
|
||||||
#[BodyParam(name: 'url', description: 'The URL if the provider is Gitlab and it is self-hosted')]
|
#[BodyParam(name: 'url', description: 'The URL if the provider is Gitlab and it is self-hosted')]
|
||||||
@ -61,7 +61,7 @@ public function create(Request $request, Project $project): SourceControlResourc
|
|||||||
#[Get('{sourceControl}', name: 'api.projects.source-controls.show', middleware: 'ability:read')]
|
#[Get('{sourceControl}', name: 'api.projects.source-controls.show', middleware: 'ability:read')]
|
||||||
#[Endpoint(title: 'show')]
|
#[Endpoint(title: 'show')]
|
||||||
#[ResponseFromApiResource(SourceControlResource::class, SourceControl::class)]
|
#[ResponseFromApiResource(SourceControlResource::class, SourceControl::class)]
|
||||||
public function show(Project $project, SourceControl $sourceControl): \App\Http\Resources\SourceControlResource
|
public function show(Project $project, SourceControl $sourceControl): SourceControlResource
|
||||||
{
|
{
|
||||||
$this->authorize('view', $sourceControl);
|
$this->authorize('view', $sourceControl);
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ public function show(Project $project, SourceControl $sourceControl): \App\Http\
|
|||||||
#[BodyParam(name: 'password', description: 'The password if the provider is Bitbucket')]
|
#[BodyParam(name: 'password', description: 'The password if the provider is Bitbucket')]
|
||||||
#[BodyParam(name: 'global', description: 'Accessible in all projects', enum: [true, false])]
|
#[BodyParam(name: 'global', description: 'Accessible in all projects', enum: [true, false])]
|
||||||
#[ResponseFromApiResource(SourceControlResource::class, SourceControl::class)]
|
#[ResponseFromApiResource(SourceControlResource::class, SourceControl::class)]
|
||||||
public function update(Request $request, Project $project, SourceControl $sourceControl): \App\Http\Resources\SourceControlResource
|
public function update(Request $request, Project $project, SourceControl $sourceControl): SourceControlResource
|
||||||
{
|
{
|
||||||
$this->authorize('update', $sourceControl);
|
$this->authorize('update', $sourceControl);
|
||||||
|
|
||||||
|
@ -63,7 +63,9 @@ public function enableForceSSL(Server $server, Site $site): RedirectResponse
|
|||||||
|
|
||||||
$site->force_ssl = true;
|
$site->force_ssl = true;
|
||||||
$site->save();
|
$site->save();
|
||||||
$site->webserver()->updateVHost($site);
|
$site->webserver()->updateVHost($site, regenerate: [
|
||||||
|
'force-ssl',
|
||||||
|
]);
|
||||||
|
|
||||||
return back()
|
return back()
|
||||||
->with('success', 'Force SSL enabled successfully.');
|
->with('success', 'Force SSL enabled successfully.');
|
||||||
@ -76,7 +78,9 @@ public function disableForceSSL(Server $server, Site $site): RedirectResponse
|
|||||||
|
|
||||||
$site->force_ssl = false;
|
$site->force_ssl = false;
|
||||||
$site->save();
|
$site->save();
|
||||||
$site->webserver()->updateVHost($site);
|
$site->webserver()->updateVHost($site, regenerate: [
|
||||||
|
'force-ssl',
|
||||||
|
]);
|
||||||
|
|
||||||
return back()
|
return back()
|
||||||
->with('success', 'Force SSL disabled successfully.');
|
->with('success', 'Force SSL disabled successfully.');
|
||||||
|
45
app/Http/Controllers/SiteFeatureController.php
Normal file
45
app/Http/Controllers/SiteFeatureController.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use App\Models\Site;
|
||||||
|
use App\SiteFeatures\ActionInterface;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Inertia\Inertia;
|
||||||
|
use Inertia\Response;
|
||||||
|
use Spatie\RouteAttributes\Attributes\Get;
|
||||||
|
use Spatie\RouteAttributes\Attributes\Middleware;
|
||||||
|
use Spatie\RouteAttributes\Attributes\Post;
|
||||||
|
use Spatie\RouteAttributes\Attributes\Prefix;
|
||||||
|
|
||||||
|
#[Prefix('/servers/{server}/sites/{site}/features')]
|
||||||
|
#[Middleware(['auth', 'has-project'])]
|
||||||
|
class SiteFeatureController extends Controller
|
||||||
|
{
|
||||||
|
#[Get('/', name: 'site-features')]
|
||||||
|
public function index(Server $server, Site $site): Response
|
||||||
|
{
|
||||||
|
$this->authorize('view', [$site, $server]);
|
||||||
|
|
||||||
|
return Inertia::render('site-features/index', [
|
||||||
|
'features' => $site->features(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Post('/{feature}/{action}', name: 'site-features.action')]
|
||||||
|
public function action(Request $request, Server $server, Site $site, string $feature, string $action): RedirectResponse
|
||||||
|
{
|
||||||
|
$this->authorize('update', [$site, $server]);
|
||||||
|
|
||||||
|
$handler = config('site.types.'.$site->type.'.features.'.$feature.'.actions.'.$action.'.handler');
|
||||||
|
if ($handler && class_exists($handler)) {
|
||||||
|
/** @var ActionInterface $actionHandler */
|
||||||
|
$actionHandler = new $handler($site);
|
||||||
|
$actionHandler->handle($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,37 @@
|
|||||||
|
|
||||||
namespace App\Http;
|
namespace App\Http;
|
||||||
|
|
||||||
|
use App\Http\Middleware\Authenticate;
|
||||||
|
use App\Http\Middleware\CanSeeProjectMiddleware;
|
||||||
|
use App\Http\Middleware\EncryptCookies;
|
||||||
|
use App\Http\Middleware\HandleAppearance;
|
||||||
|
use App\Http\Middleware\HandleInertiaRequests;
|
||||||
|
use App\Http\Middleware\HasProjectMiddleware;
|
||||||
|
use App\Http\Middleware\MustBeAdminMiddleware;
|
||||||
|
use App\Http\Middleware\PreventRequestsDuringMaintenance;
|
||||||
|
use App\Http\Middleware\RedirectIfAuthenticated;
|
||||||
|
use App\Http\Middleware\TrimStrings;
|
||||||
|
use App\Http\Middleware\TrustProxies;
|
||||||
|
use App\Http\Middleware\ValidateSignature;
|
||||||
|
use App\Http\Middleware\VerifyCsrfToken;
|
||||||
|
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
||||||
|
use Illuminate\Auth\Middleware\Authorize;
|
||||||
|
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
|
||||||
|
use Illuminate\Auth\Middleware\RequirePassword;
|
||||||
|
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||||
|
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
|
||||||
|
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
||||||
|
use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets;
|
||||||
|
use Illuminate\Http\Middleware\HandleCors;
|
||||||
|
use Illuminate\Http\Middleware\SetCacheHeaders;
|
||||||
|
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||||
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
|
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||||
|
use Illuminate\Session\Middleware\StartSession;
|
||||||
|
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||||
|
use Laravel\Sanctum\Http\Middleware\CheckAbilities;
|
||||||
|
use Laravel\Sanctum\Http\Middleware\CheckForAnyAbility;
|
||||||
|
|
||||||
class Kernel extends HttpKernel
|
class Kernel extends HttpKernel
|
||||||
{
|
{
|
||||||
@ -15,12 +45,12 @@ class Kernel extends HttpKernel
|
|||||||
*/
|
*/
|
||||||
protected $middleware = [
|
protected $middleware = [
|
||||||
// \App\Http\Middleware\TrustHosts::class,
|
// \App\Http\Middleware\TrustHosts::class,
|
||||||
\App\Http\Middleware\TrustProxies::class,
|
TrustProxies::class,
|
||||||
\Illuminate\Http\Middleware\HandleCors::class,
|
HandleCors::class,
|
||||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
PreventRequestsDuringMaintenance::class,
|
||||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
ValidatePostSize::class,
|
||||||
\App\Http\Middleware\TrimStrings::class,
|
TrimStrings::class,
|
||||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
ConvertEmptyStringsToNull::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,20 +60,20 @@ class Kernel extends HttpKernel
|
|||||||
*/
|
*/
|
||||||
protected $middlewareGroups = [
|
protected $middlewareGroups = [
|
||||||
'web' => [
|
'web' => [
|
||||||
\App\Http\Middleware\EncryptCookies::class,
|
EncryptCookies::class,
|
||||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
AddQueuedCookiesToResponse::class,
|
||||||
\Illuminate\Session\Middleware\StartSession::class,
|
StartSession::class,
|
||||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
ShareErrorsFromSession::class,
|
||||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
VerifyCsrfToken::class,
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
SubstituteBindings::class,
|
||||||
\App\Http\Middleware\HandleInertiaRequests::class,
|
HandleInertiaRequests::class,
|
||||||
\App\Http\Middleware\HandleAppearance::class,
|
HandleAppearance::class,
|
||||||
\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
|
AddLinkHeadersForPreloadedAssets::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
'api' => [
|
'api' => [
|
||||||
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
|
ThrottleRequests::class.':api',
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
SubstituteBindings::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -55,20 +85,20 @@ class Kernel extends HttpKernel
|
|||||||
* @var array<string, class-string|string>
|
* @var array<string, class-string|string>
|
||||||
*/
|
*/
|
||||||
protected $middlewareAliases = [
|
protected $middlewareAliases = [
|
||||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
'auth' => Authenticate::class,
|
||||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
'auth.basic' => AuthenticateWithBasicAuth::class,
|
||||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
'auth.session' => AuthenticateSession::class,
|
||||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
'cache.headers' => SetCacheHeaders::class,
|
||||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
'can' => Authorize::class,
|
||||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
'guest' => RedirectIfAuthenticated::class,
|
||||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
'password.confirm' => RequirePassword::class,
|
||||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
'signed' => ValidateSignature::class,
|
||||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
'throttle' => ThrottleRequests::class,
|
||||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
'verified' => EnsureEmailIsVerified::class,
|
||||||
'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
|
'abilities' => CheckAbilities::class,
|
||||||
'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
|
'ability' => CheckForAnyAbility::class,
|
||||||
'has-project' => \App\Http\Middleware\HasProjectMiddleware::class,
|
'has-project' => HasProjectMiddleware::class,
|
||||||
'can-see-project' => \App\Http\Middleware\CanSeeProjectMiddleware::class,
|
'can-see-project' => CanSeeProjectMiddleware::class,
|
||||||
'must-be-admin' => \App\Http\Middleware\MustBeAdminMiddleware::class,
|
'must-be-admin' => MustBeAdminMiddleware::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public function share(Request $request): array
|
|||||||
$sites = SiteResource::collection($server->sites);
|
$sites = SiteResource::collection($server->sites);
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['serverSites'] = $sites;
|
$data['server_sites'] = $sites;
|
||||||
|
|
||||||
if ($request->route('site')) {
|
if ($request->route('site')) {
|
||||||
$data['site'] = SiteResource::make($request->route('site'));
|
$data['site'] = SiteResource::make($request->route('site'));
|
||||||
@ -82,15 +82,37 @@ public function share(Request $request): array
|
|||||||
'projects' => $user?->allProjects()->get(),
|
'projects' => $user?->allProjects()->get(),
|
||||||
'currentProject' => $user?->currentProject,
|
'currentProject' => $user?->currentProject,
|
||||||
],
|
],
|
||||||
'publicKeyText' => __('servers.create.public_key_text', ['public_key' => get_public_key_content()]),
|
'public_key_text' => __('servers.create.public_key_text', ['public_key' => get_public_key_content()]),
|
||||||
'projectServers' => $servers,
|
'project_servers' => $servers,
|
||||||
'configs' => config('core'),
|
'configs' => [
|
||||||
|
'operating_systems' => config('core.operating_systems'),
|
||||||
|
'colors' => config('core.colors'),
|
||||||
|
'cronjob_intervals' => config('core.cronjob_intervals'),
|
||||||
|
'metrics_periods' => config('core.metrics_periods'),
|
||||||
|
'site' => [
|
||||||
|
'types' => config('site.types'),
|
||||||
|
],
|
||||||
|
'source_control' => [
|
||||||
|
'providers' => config('source-control.providers'),
|
||||||
|
],
|
||||||
|
'server_provider' => [
|
||||||
|
'providers' => config('server-provider.providers'),
|
||||||
|
],
|
||||||
|
'storage_provider' => [
|
||||||
|
'providers' => config('storage-provider.providers'),
|
||||||
|
],
|
||||||
|
'notification_channel' => [
|
||||||
|
'providers' => config('notification-channel.providers'),
|
||||||
|
],
|
||||||
|
'service' => [
|
||||||
|
'services' => config('service.services'),
|
||||||
|
],
|
||||||
|
],
|
||||||
'ziggy' => fn (): array => [
|
'ziggy' => fn (): array => [
|
||||||
...(new Ziggy)->toArray(),
|
...(new Ziggy)->toArray(),
|
||||||
'location' => $request->url(),
|
'location' => $request->url(),
|
||||||
],
|
],
|
||||||
'csrf_token' => csrf_token(),
|
'csrf_token' => csrf_token(),
|
||||||
'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
|
|
||||||
'flash' => [
|
'flash' => [
|
||||||
'success' => fn () => $request->session()->get('success'),
|
'success' => fn () => $request->session()->get('success'),
|
||||||
'error' => fn () => $request->session()->get('error'),
|
'error' => fn () => $request->session()->get('error'),
|
||||||
|
@ -13,7 +13,7 @@ class RedirectIfAuthenticated
|
|||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
* @param Closure(Request): (Response) $next
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next, string ...$guards): Response
|
public function handle(Request $request, Closure $next, string ...$guards): Response
|
||||||
{
|
{
|
||||||
|
@ -27,8 +27,6 @@ public function toArray(Request $request): array
|
|||||||
'local_ip' => $this->local_ip,
|
'local_ip' => $this->local_ip,
|
||||||
'port' => $this->port,
|
'port' => $this->port,
|
||||||
'os' => $this->os,
|
'os' => $this->os,
|
||||||
'type' => $this->type,
|
|
||||||
'type_data' => $this->type_data,
|
|
||||||
'provider' => $this->provider,
|
'provider' => $this->provider,
|
||||||
'provider_data' => $this->provider_data,
|
'provider_data' => $this->provider_data,
|
||||||
'public_key' => $this->public_key,
|
'public_key' => $this->public_key,
|
||||||
|
@ -21,11 +21,10 @@ public function toArray(Request $request): array
|
|||||||
'source_control_id' => $this->source_control_id,
|
'source_control_id' => $this->source_control_id,
|
||||||
'type' => $this->type,
|
'type' => $this->type,
|
||||||
'type_data' => $this->type_data,
|
'type_data' => $this->type_data,
|
||||||
'features' => $this->type()->supportedFeatures(),
|
|
||||||
'domain' => $this->domain,
|
'domain' => $this->domain,
|
||||||
'aliases' => $this->aliases,
|
'aliases' => $this->aliases,
|
||||||
'web_directory' => $this->web_directory,
|
'web_directory' => $this->web_directory,
|
||||||
'webserver' => $this->webserver()->name(),
|
'webserver' => $this->webserver()->id(),
|
||||||
'path' => $this->path,
|
'path' => $this->path,
|
||||||
'php_version' => $this->php_version,
|
'php_version' => $this->php_version,
|
||||||
'repository' => $this->repository,
|
'repository' => $this->repository,
|
||||||
|
@ -17,6 +17,7 @@ public function toArray(Request $request): array
|
|||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'server_id' => $this->server_id,
|
'server_id' => $this->server_id,
|
||||||
|
'name' => $this->name,
|
||||||
'command' => $this->command,
|
'command' => $this->command,
|
||||||
'user' => $this->user,
|
'user' => $this->user,
|
||||||
'auto_start' => $this->auto_start,
|
'auto_start' => $this->auto_start,
|
||||||
|
@ -4,7 +4,10 @@
|
|||||||
|
|
||||||
use App\Actions\Database\ManageBackupFile;
|
use App\Actions\Database\ManageBackupFile;
|
||||||
use App\Enums\BackupFileStatus;
|
use App\Enums\BackupFileStatus;
|
||||||
use App\Enums\StorageProvider as StorageProviderAlias;
|
use App\StorageProviders\Dropbox;
|
||||||
|
use App\StorageProviders\FTP;
|
||||||
|
use App\StorageProviders\Local;
|
||||||
|
use App\StorageProviders\S3;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Database\Factories\BackupFileFactory;
|
use Database\Factories\BackupFileFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
@ -81,7 +84,7 @@ public function isAvailable(): bool
|
|||||||
|
|
||||||
public function isLocal(): bool
|
public function isLocal(): bool
|
||||||
{
|
{
|
||||||
return $this->backup->storage->provider === StorageProviderAlias::LOCAL;
|
return $this->backup->storage->provider === Local::id();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,8 +106,8 @@ public function path(): string
|
|||||||
$databaseName = $this->backup->database->name;
|
$databaseName = $this->backup->database->name;
|
||||||
|
|
||||||
return match ($storage->provider) {
|
return match ($storage->provider) {
|
||||||
StorageProviderAlias::DROPBOX => '/'.$databaseName.'/'.$this->name.'.zip',
|
Dropbox::id() => '/'.$databaseName.'/'.$this->name.'.zip',
|
||||||
StorageProviderAlias::S3, StorageProviderAlias::FTP, StorageProviderAlias::LOCAL => implode('/', [
|
S3::id(), FTP::id(), Local::id() => implode('/', [
|
||||||
rtrim((string) $storage->credentials['path'], '/'),
|
rtrim((string) $storage->credentials['path'], '/'),
|
||||||
$databaseName,
|
$databaseName,
|
||||||
$this->name.'.zip',
|
$this->name.'.zip',
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enums\CronjobStatus;
|
use App\Enums\CronjobStatus;
|
||||||
|
use Database\Factories\CronJobFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
@ -18,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
class CronJob extends AbstractModel
|
class CronJob extends AbstractModel
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\CronJobFactory> */
|
/** @use HasFactory<CronJobFactory> */
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enums\DatabaseUserStatus;
|
use App\Enums\DatabaseUserStatus;
|
||||||
|
use Database\Factories\DatabaseUserFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
class DatabaseUser extends AbstractModel
|
class DatabaseUser extends AbstractModel
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\DatabaseUserFactory> */
|
/** @use HasFactory<DatabaseUserFactory> */
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Database\Factories\FileFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
@ -23,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
class File extends AbstractModel
|
class File extends AbstractModel
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\FileFactory> */
|
/** @use HasFactory<FileFactory> */
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Exceptions\FailedToDestroyGitHook;
|
use App\Exceptions\FailedToDestroyGitHook;
|
||||||
|
use Database\Factories\GitHookFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
@ -19,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
class GitHook extends AbstractModel
|
class GitHook extends AbstractModel
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\GitHookFactory> */
|
/** @use HasFactory<GitHookFactory> */
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
@ -42,7 +42,7 @@ class NotificationChannel extends AbstractModel
|
|||||||
|
|
||||||
public function provider(): \App\NotificationChannels\NotificationChannel
|
public function provider(): \App\NotificationChannels\NotificationChannel
|
||||||
{
|
{
|
||||||
$class = config('core.notification_channels_providers_class')[$this->provider];
|
$class = config('notification-channel.providers.'.$this->provider.'.handler');
|
||||||
|
|
||||||
/** @var \App\NotificationChannels\NotificationChannel $provider */
|
/** @var \App\NotificationChannels\NotificationChannel $provider */
|
||||||
$provider = new $class($this);
|
$provider = new $class($this);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Database\Factories\ScriptFactory;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
@ -25,7 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
class Script extends AbstractModel
|
class Script extends AbstractModel
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\ScriptFactory> */
|
/** @use HasFactory<ScriptFactory> */
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use App\Enums\ScriptExecutionStatus;
|
use App\Enums\ScriptExecutionStatus;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Database\Factories\ScriptExecutionFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
@ -23,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
class ScriptExecution extends AbstractModel
|
class ScriptExecution extends AbstractModel
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\ScriptExecutionFactory> */
|
/** @use HasFactory<ScriptExecutionFactory> */
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
@ -7,10 +7,9 @@
|
|||||||
use App\Enums\ServiceStatus;
|
use App\Enums\ServiceStatus;
|
||||||
use App\Exceptions\SSHError;
|
use App\Exceptions\SSHError;
|
||||||
use App\Facades\SSH;
|
use App\Facades\SSH;
|
||||||
use App\ServerTypes\ServerType;
|
use App\SSH\OS\Cron;
|
||||||
use App\SSH\Cron\Cron;
|
|
||||||
use App\SSH\OS\OS;
|
use App\SSH\OS\OS;
|
||||||
use App\SSH\Systemd\Systemd;
|
use App\SSH\OS\Systemd;
|
||||||
use App\Support\Testing\SSHFake;
|
use App\Support\Testing\SSHFake;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Database\Factories\ServerFactory;
|
use Database\Factories\ServerFactory;
|
||||||
@ -81,8 +80,6 @@ class Server extends AbstractModel
|
|||||||
'local_ip',
|
'local_ip',
|
||||||
'port',
|
'port',
|
||||||
'os',
|
'os',
|
||||||
'type',
|
|
||||||
'type_data',
|
|
||||||
'provider',
|
'provider',
|
||||||
'provider_id',
|
'provider_id',
|
||||||
'provider_data',
|
'provider_data',
|
||||||
@ -101,7 +98,6 @@ class Server extends AbstractModel
|
|||||||
protected $casts = [
|
protected $casts = [
|
||||||
'project_id' => 'integer',
|
'project_id' => 'integer',
|
||||||
'user_id' => 'integer',
|
'user_id' => 'integer',
|
||||||
'type_data' => 'json',
|
|
||||||
'port' => 'integer',
|
'port' => 'integer',
|
||||||
'provider_data' => 'json',
|
'provider_data' => 'json',
|
||||||
'authentication' => 'encrypted:json',
|
'authentication' => 'encrypted:json',
|
||||||
@ -410,19 +406,9 @@ public function installedNodejsVersions(): array
|
|||||||
return $versions;
|
return $versions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function type(): ServerType
|
|
||||||
{
|
|
||||||
$typeClass = config('core.server_types_class')[$this->type];
|
|
||||||
|
|
||||||
/** @var ServerType $type */
|
|
||||||
$type = new $typeClass($this);
|
|
||||||
|
|
||||||
return $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function provider(): \App\ServerProviders\ServerProvider
|
public function provider(): \App\ServerProviders\ServerProvider
|
||||||
{
|
{
|
||||||
$providerClass = config('core.server_providers_class')[$this->provider];
|
$providerClass = config('server-provider.providers.'.$this->provider.'.handler');
|
||||||
|
|
||||||
/** @var \App\ServerProviders\ServerProvider $provider */
|
/** @var \App\ServerProviders\ServerProvider $provider */
|
||||||
$provider = new $providerClass($this->serverProvider ?? new ServerProvider, $this);
|
$provider = new $providerClass($this->serverProvider ?? new ServerProvider, $this);
|
||||||
|
@ -67,7 +67,7 @@ public function servers(): HasMany
|
|||||||
|
|
||||||
public function provider(): \App\ServerProviders\ServerProvider
|
public function provider(): \App\ServerProviders\ServerProvider
|
||||||
{
|
{
|
||||||
$providerClass = config('core.server_providers_class')[$this->provider];
|
$providerClass = config('server-provider.providers.'.$this->provider.'.handler');
|
||||||
|
|
||||||
/** @var \App\ServerProviders\ServerProvider $provider */
|
/** @var \App\ServerProviders\ServerProvider $provider */
|
||||||
$provider = new $providerClass($this, new Server);
|
$provider = new $providerClass($this, new Server);
|
||||||
|
@ -5,15 +5,16 @@
|
|||||||
use App\Actions\Service\Manage;
|
use App\Actions\Service\Manage;
|
||||||
use App\Enums\ServiceStatus;
|
use App\Enums\ServiceStatus;
|
||||||
use App\Exceptions\ServiceInstallationFailed;
|
use App\Exceptions\ServiceInstallationFailed;
|
||||||
use App\SSH\Services\Firewall\Firewall;
|
use App\Services\Firewall\Firewall;
|
||||||
use App\SSH\Services\PHP\PHP;
|
use App\Services\PHP\PHP;
|
||||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
use App\Services\ProcessManager\ProcessManager;
|
||||||
use App\SSH\Services\ServiceInterface;
|
use App\Services\ServiceInterface;
|
||||||
use App\SSH\Services\Webserver\Webserver;
|
use App\Services\Webserver\Webserver;
|
||||||
use Database\Factories\ServiceFactory;
|
use Database\Factories\ServiceFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property int $server_id
|
* @property int $server_id
|
||||||
@ -50,17 +51,6 @@ class Service extends AbstractModel
|
|||||||
'is_default' => 'boolean',
|
'is_default' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function boot(): void
|
|
||||||
{
|
|
||||||
parent::boot();
|
|
||||||
|
|
||||||
static::creating(function (Service $service): void {
|
|
||||||
if (array_key_exists($service->name, config('core.service_units'))) {
|
|
||||||
$service->unit = config('core.service_units')[$service->name][$service->server->os][$service->version];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<string, string>
|
* @var array<string, string>
|
||||||
*/
|
*/
|
||||||
@ -87,9 +77,14 @@ public function server(): BelongsTo
|
|||||||
return $this->belongsTo(Server::class);
|
return $this->belongsTo(Server::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handler(): ServiceInterface|Webserver|PHP|Firewall|\App\SSH\Services\Database\Database|ProcessManager
|
public function handler(): ServiceInterface|Webserver|PHP|Firewall|\App\Services\Database\Database|ProcessManager
|
||||||
{
|
{
|
||||||
$handler = config('core.service_handlers')[$this->name];
|
$name = $this->name;
|
||||||
|
$handler = config("service.services.$name.handler");
|
||||||
|
|
||||||
|
if (! $handler) {
|
||||||
|
throw new InvalidArgumentException("Service handler for $name is not defined.");
|
||||||
|
}
|
||||||
|
|
||||||
/** @var ServiceInterface $service */
|
/** @var ServiceInterface $service */
|
||||||
$service = new $handler($this);
|
$service = new $handler($this);
|
||||||
@ -109,26 +104,26 @@ public function validateInstall(string $result): void
|
|||||||
|
|
||||||
public function start(): void
|
public function start(): void
|
||||||
{
|
{
|
||||||
$this->unit && app(Manage::class)->start($this);
|
$this->handler()->unit() && app(Manage::class)->start($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stop(): void
|
public function stop(): void
|
||||||
{
|
{
|
||||||
$this->unit && app(Manage::class)->stop($this);
|
$this->handler()->unit() && app(Manage::class)->stop($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function restart(): void
|
public function restart(): void
|
||||||
{
|
{
|
||||||
$this->unit && app(Manage::class)->restart($this);
|
$this->handler()->unit() && app(Manage::class)->restart($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function enable(): void
|
public function enable(): void
|
||||||
{
|
{
|
||||||
$this->unit && app(Manage::class)->enable($this);
|
$this->handler()->unit() && app(Manage::class)->enable($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function disable(): void
|
public function disable(): void
|
||||||
{
|
{
|
||||||
$this->unit && app(Manage::class)->disable($this);
|
$this->handler()->unit() && app(Manage::class)->disable($this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user