'integer', 'user_id' => 'integer', 'type_data' => 'json', 'port' => 'integer', 'provider_data' => 'json', 'authentication' => 'encrypted:json', 'auto_update' => 'boolean', 'available_updates' => 'integer', 'security_updates' => 'integer', 'progress' => 'integer', ]; protected $hidden = [ 'authentication', ]; public static function boot(): void { parent::boot(); static::deleting(function (Server $server) { $server->sites()->each(function (Site $site) { $site->delete(); }); $server->provider()->delete(); $server->logs()->each(function (ServerLog $log) { $log->delete(); }); $server->services()->delete(); $server->databases()->delete(); $server->databaseUsers()->delete(); $server->firewallRules()->delete(); $server->cronJobs()->delete(); $server->queues()->delete(); $server->daemons()->delete(); $server->scriptExecutions()->delete(); $server->sshKeys()->detach(); if (File::exists($server->sshKey()['public_key_path'])) { File::delete($server->sshKey()['public_key_path']); } if (File::exists($server->sshKey()['private_key_path'])) { File::delete($server->sshKey()['private_key_path']); } }); } public function project(): BelongsTo { return $this->belongsTo(Project::class, 'project_id'); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } public function serverProvider(): BelongsTo { return $this->belongsTo(ServerProvider::class, 'provider_id'); } public function logs(): HasMany { return $this->hasMany(ServerLog::class); } public function sites(): HasMany { return $this->hasMany(Site::class); } public function services(): HasMany { return $this->hasMany(Service::class); } public function databases(): HasMany { return $this->hasMany(Database::class); } public function databaseUsers(): HasMany { return $this->hasMany(DatabaseUser::class); } public function firewallRules(): HasMany { return $this->hasMany(FirewallRule::class); } public function cronJobs(): HasMany { return $this->hasMany(CronJob::class); } public function queues(): HasMany { return $this->hasMany(Queue::class); } public function scriptExecutions(): HasMany { return $this->hasMany(ScriptExecution::class); } public function backups(): HasMany { return $this->hasMany(Backup::class); } public function daemons(): HasMany { return $this->queues()->whereNull('site_id'); } public function service($type, $version = null): ?Service { /* @var Service $service */ $service = $this->services() ->where(function ($query) use ($type, $version) { $query->where('type', $type); if ($version) { $query->where('version', $version); } }) ->first(); return $service; } public function defaultService($type): ?Service { /* @var Service $service */ $service = $this->services() ->where('type', $type) ->where('is_default', 1) ->first(); return $service; } public function getServiceByUnit($unit): ?Service { /* @var Service $service */ $service = $this->services() ->where('unit', $unit) ->where('is_default', 1) ->first(); return $service; } public function install(): void { $this->type()->install(); Notifier::send($this, new ServerInstallationStarted($this)); } public function ssh(?string $user = null): \App\Helpers\SSH|SSHFake { return SSH::init($this, $user); } public function installedPHPVersions(): array { $versions = []; $phps = $this->services()->where('type', 'php')->get(['version']); foreach ($phps as $php) { $versions[] = $php->version; } return $versions; } public function type(): ServerType { $typeClass = config('core.server_types_class')[$this->type]; return new $typeClass($this); } public function provider(): \App\Contracts\ServerProvider { $providerClass = config('core.server_providers_class')[$this->provider]; return new $providerClass($this); } public function webserver(?string $version = null): ?Service { if (! $version) { return $this->defaultService('webserver'); } return $this->service('webserver', $version); } public function database(?string $version = null): ?Service { if (! $version) { return $this->defaultService('database'); } return $this->service('database', $version); } public function firewall(?string $version = null): ?Service { if (! $version) { return $this->defaultService('firewall'); } return $this->service('firewall', $version); } public function processManager(?string $version = null): ?Service { if (! $version) { return $this->defaultService('process_manager'); } return $this->service('process_manager', $version); } public function php(?string $version = null): ?Service { if (! $version) { return $this->defaultService('php'); } return $this->service('php', $version); } public function sshKeys(): BelongsToMany { return $this->belongsToMany(SshKey::class, 'server_ssh_keys') ->withPivot('status') ->withTimestamps(); } public function getSshUserAttribute(string $value): string { if ($value) { return $value; } return config('core.ssh_user'); } public function sshKey(): array { if (app()->environment() == 'testing') { return [ 'public_key' => 'public', 'public_key_path' => '/path', 'private_key_path' => '/path', ]; } /** @var FilesystemAdapter $storageDisk */ $storageDisk = Storage::disk(config('core.key_pairs_disk')); return [ 'public_key' => Str::replace("\n", '', Storage::disk(config('core.key_pairs_disk'))->get($this->id.'.pub')), 'public_key_path' => $storageDisk->path($this->id.'.pub'), 'private_key_path' => $storageDisk->path((string) $this->id), ]; } public function getServiceUnits(): array { $units = []; $services = $this->services; foreach ($services as $service) { if ($service->unit) { $units[] = $service->unit; } } return $units; } public function checkConnection(): void { dispatch(new CheckConnection($this))->onConnection('ssh'); } public function installUpdates(): void { $this->available_updates = 0; $this->security_updates = 0; $this->save(); dispatch(new Upgrade($this))->onConnection('ssh'); } public function reboot(): void { $this->status = 'disconnected'; $this->save(); dispatch(new RebootServer($this))->onConnection('ssh'); } public function getHostnameAttribute(): string { return Str::of($this->name)->slug(); } public function isReady(): bool { return $this->status == ServerStatus::READY; } }