mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 15:02:34 +00:00
Plugins base (#613)
* wip * wip * cleanup * notification channels * phpstan * services * remove server types * refactoring * refactoring
This commit is contained in:
@ -3,16 +3,13 @@
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Enums\FirewallRuleStatus;
|
||||
use App\Enums\ServerProvider;
|
||||
use App\Enums\ServerStatus;
|
||||
use App\Enums\ServerType;
|
||||
use App\Exceptions\SSHConnectionError;
|
||||
use App\Facades\Notifier;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use App\Notifications\ServerInstallationFailed;
|
||||
use App\Notifications\ServerInstallationSucceed;
|
||||
use App\ServerProviders\Custom;
|
||||
use App\ValidationRules\RestrictedIPAddressesRule;
|
||||
use Exception;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
@ -25,6 +22,8 @@
|
||||
|
||||
class CreateServer
|
||||
{
|
||||
protected Server $server;
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
$server = new Server([
|
||||
$this->server = new Server([
|
||||
'project_id' => $project->id,
|
||||
'user_id' => $creator->id,
|
||||
'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'] ?? '',
|
||||
'port' => $input['port'] ?? 22,
|
||||
'os' => $input['os'],
|
||||
'type' => ServerType::REGULAR,
|
||||
'provider' => $input['provider'],
|
||||
'authentication' => [
|
||||
'user' => config('core.ssh_user'),
|
||||
@ -52,32 +50,42 @@ public function create(User $creator, Project $project, array $input): Server
|
||||
]);
|
||||
|
||||
try {
|
||||
if ($server->provider != 'custom') {
|
||||
$server->provider_id = $input['server_provider'];
|
||||
if ($this->server->provider != 'custom') {
|
||||
$this->server->provider_id = $input['server_provider'];
|
||||
}
|
||||
|
||||
$server->type_data = $server->type()->data($input);
|
||||
|
||||
$server->provider_data = $server->provider()->data($input);
|
||||
$this->server->provider_data = $this->server->provider()->data($input);
|
||||
|
||||
// save
|
||||
$server->save();
|
||||
$this->server->save();
|
||||
|
||||
// create firewall rules
|
||||
$this->createFirewallRules($server);
|
||||
$this->createFirewallRules($this->server);
|
||||
|
||||
// create instance
|
||||
$server->provider()->create();
|
||||
$this->server->provider()->create();
|
||||
|
||||
// add services
|
||||
$server->type()->createServices($input);
|
||||
// create services
|
||||
$this->createServices();
|
||||
|
||||
// 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) {
|
||||
$server->delete();
|
||||
$this->server->delete();
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'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
|
||||
* @return array<string, mixed>
|
||||
@ -129,7 +102,7 @@ public static function rules(Project $project, array $input): array
|
||||
$rules = [
|
||||
'provider' => [
|
||||
'required',
|
||||
Rule::in(config('core.server_providers')),
|
||||
Rule::in(array_keys(config('server-provider.providers'))),
|
||||
],
|
||||
'name' => [
|
||||
'required',
|
||||
@ -139,7 +112,7 @@ public static function rules(Project $project, array $input): array
|
||||
Rule::in(config('core.operating_systems')),
|
||||
],
|
||||
'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',
|
||||
Rule::exists('server_providers', 'id')->where(function (Builder $query) use ($project): void {
|
||||
$query->where('project_id', $project->id)
|
||||
@ -148,13 +121,13 @@ public static function rules(Project $project, array $input): array
|
||||
]),
|
||||
],
|
||||
'ip' => [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM, [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == Custom::id(), [
|
||||
'required',
|
||||
new RestrictedIPAddressesRule,
|
||||
]),
|
||||
],
|
||||
'port' => [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM, [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == Custom::id(), [
|
||||
'required',
|
||||
'numeric',
|
||||
'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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
return array_merge($rules, self::providerRules($input));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,8 +148,8 @@ private static function providerRules(array $input): array
|
||||
if (
|
||||
! isset($input['provider']) ||
|
||||
! isset($input['server_provider']) ||
|
||||
! in_array($input['provider'], config('core.server_providers')) ||
|
||||
$input['provider'] == ServerProvider::CUSTOM
|
||||
! config('server-provider.providers.'.$input['provider']) ||
|
||||
$input['provider'] == Custom::id()
|
||||
) {
|
||||
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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user