mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-07 08:52:35 +00:00
init
This commit is contained in:
16
app/ServiceHandlers/Database/AbstractDatabase.php
Executable file
16
app/ServiceHandlers/Database/AbstractDatabase.php
Executable file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\Database;
|
||||
|
||||
use App\Contracts\Database;
|
||||
use App\Models\Service;
|
||||
|
||||
abstract class AbstractDatabase implements Database
|
||||
{
|
||||
protected Service $service;
|
||||
|
||||
public function __construct(Service $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
}
|
138
app/ServiceHandlers/Database/Mysql.php
Executable file
138
app/ServiceHandlers/Database/Mysql.php
Executable file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\Database;
|
||||
|
||||
use App\Models\BackupFile;
|
||||
use App\SSHCommands\Database\BackupDatabaseCommand;
|
||||
use App\SSHCommands\Database\CreateCommand;
|
||||
use App\SSHCommands\Database\CreateUserCommand;
|
||||
use App\SSHCommands\Database\DeleteCommand;
|
||||
use App\SSHCommands\Database\DeleteUserCommand;
|
||||
use App\SSHCommands\Database\LinkCommand;
|
||||
use App\SSHCommands\Database\RestoreDatabaseCommand;
|
||||
use App\SSHCommands\Database\UnlinkCommand;
|
||||
use Throwable;
|
||||
|
||||
class Mysql extends AbstractDatabase
|
||||
{
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function create(string $name): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new CreateCommand('mysql', $name),
|
||||
'create-database'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function delete(string $name): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new DeleteCommand('mysql', $name),
|
||||
'delete-database'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function createUser(string $username, string $password, string $host): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new CreateUserCommand('mysql', $username, $password, $host),
|
||||
'create-user'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function deleteUser(string $username, string $host): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new DeleteUserCommand('mysql', $username, $host),
|
||||
'delete-user'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function link(string $username, string $host, array $databases): void
|
||||
{
|
||||
$ssh = $this->service->server->ssh();
|
||||
foreach ($databases as $database) {
|
||||
$ssh->exec(
|
||||
new LinkCommand('mysql', $username, $host, $database),
|
||||
'link-user-to-databases'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function unlink(string $username, string $host): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new UnlinkCommand('mysql', $username, $host),
|
||||
'unlink-user-from-database'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function runBackup(BackupFile $backupFile): void
|
||||
{
|
||||
// backup
|
||||
$this->service->server->ssh()->exec(
|
||||
new BackupDatabaseCommand(
|
||||
'mysql',
|
||||
$backupFile->backup->database->name,
|
||||
$backupFile->name
|
||||
),
|
||||
'backup-database'
|
||||
);
|
||||
|
||||
// upload to cloud
|
||||
$upload = $backupFile->backup->storage->provider()->upload(
|
||||
$backupFile->backup->server,
|
||||
$backupFile->path,
|
||||
$backupFile->storage_path,
|
||||
);
|
||||
|
||||
// cleanup
|
||||
$this->service->server->ssh()->exec('rm '.$backupFile->name.'.zip');
|
||||
|
||||
$backupFile->size = $upload['size'];
|
||||
$backupFile->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function restoreBackup(BackupFile $backupFile, string $database): void
|
||||
{
|
||||
// download
|
||||
$backupFile->backup->storage->provider()->download(
|
||||
$backupFile->backup->server,
|
||||
$backupFile->storage_path,
|
||||
$backupFile->name.'.zip',
|
||||
);
|
||||
|
||||
// restore
|
||||
$this->service->server->ssh()->exec(
|
||||
new RestoreDatabaseCommand(
|
||||
'mysql',
|
||||
$database,
|
||||
$backupFile->name
|
||||
),
|
||||
'restore-database'
|
||||
);
|
||||
}
|
||||
}
|
16
app/ServiceHandlers/Firewall/AbstractFirewall.php
Executable file
16
app/ServiceHandlers/Firewall/AbstractFirewall.php
Executable file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\Firewall;
|
||||
|
||||
use App\Contracts\Firewall;
|
||||
use App\Models\Service;
|
||||
|
||||
abstract class AbstractFirewall implements Firewall
|
||||
{
|
||||
protected Service $service;
|
||||
|
||||
public function __construct(Service $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
}
|
32
app/ServiceHandlers/Firewall/Ufw.php
Executable file
32
app/ServiceHandlers/Firewall/Ufw.php
Executable file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\Firewall;
|
||||
|
||||
use App\SSHCommands\Firewall\AddRuleCommand;
|
||||
use App\SSHCommands\Firewall\RemoveRuleCommand;
|
||||
use Throwable;
|
||||
|
||||
class Ufw extends AbstractFirewall
|
||||
{
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function addRule(string $type, string $protocol, int $port, string $source, string $mask): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new AddRuleCommand('ufw', $type, $protocol, $port, $source, $mask),
|
||||
'add-firewall-rule'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function removeRule(string $type, string $protocol, int $port, string $source, string $mask): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new RemoveRuleCommand('ufw', $type, $protocol, $port, $source, $mask),
|
||||
'remove-firewall-rule'
|
||||
);
|
||||
}
|
||||
}
|
36
app/ServiceHandlers/PHP.php
Normal file
36
app/ServiceHandlers/PHP.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers;
|
||||
|
||||
use App\Enums\ServiceStatus;
|
||||
use App\Jobs\PHP\InstallPHPExtension;
|
||||
use App\Jobs\PHP\SetDefaultCli;
|
||||
use App\Jobs\PHP\UpdatePHPSettings;
|
||||
use App\Models\Service;
|
||||
|
||||
class PHP
|
||||
{
|
||||
protected Service $service;
|
||||
|
||||
public function __construct(Service $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
public function setDefaultCli(): void
|
||||
{
|
||||
$this->service->update(['status' => ServiceStatus::RESTARTING]);
|
||||
|
||||
dispatch(new SetDefaultCli($this->service))->onConnection('ssh');
|
||||
}
|
||||
|
||||
public function installExtension($name): void
|
||||
{
|
||||
dispatch(new InstallPHPExtension($this->service, $name))->onConnection('ssh-long');
|
||||
}
|
||||
|
||||
public function updateSettings(array $settings): void
|
||||
{
|
||||
dispatch(new UpdatePHPSettings($this->service, $settings))->onConnection('ssh-long');
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\ProcessManager;
|
||||
|
||||
use App\Contracts\ProcessManager;
|
||||
use App\Models\Service;
|
||||
|
||||
abstract class AbstractProcessManager implements ProcessManager
|
||||
{
|
||||
protected Service $service;
|
||||
|
||||
public function __construct(Service $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
}
|
124
app/ServiceHandlers/ProcessManager/Supervisor.php
Normal file
124
app/ServiceHandlers/ProcessManager/Supervisor.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\ProcessManager;
|
||||
|
||||
use App\SSHCommands\ProcessManager\Supervisor\CreateWorkerCommand;
|
||||
use App\SSHCommands\ProcessManager\Supervisor\DeleteWorkerCommand;
|
||||
use App\SSHCommands\ProcessManager\Supervisor\RestartWorkerCommand;
|
||||
use App\SSHCommands\ProcessManager\Supervisor\StartWorkerCommand;
|
||||
use App\SSHCommands\ProcessManager\Supervisor\StopWorkerCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
|
||||
class Supervisor extends AbstractProcessManager
|
||||
{
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function create(
|
||||
int $id,
|
||||
string $command,
|
||||
string $user,
|
||||
bool $autoStart,
|
||||
bool $autoRestart,
|
||||
int $numprocs,
|
||||
string $logFile,
|
||||
?int $siteId = null
|
||||
): void {
|
||||
$this->service->server->ssh($user)->exec(
|
||||
new CreateWorkerCommand(
|
||||
$id,
|
||||
$this->generateConfigFile(
|
||||
$id,
|
||||
$command,
|
||||
$user,
|
||||
$autoStart,
|
||||
$autoRestart,
|
||||
$numprocs,
|
||||
$logFile
|
||||
)
|
||||
),
|
||||
'create-worker',
|
||||
$siteId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function delete(int $id, int $siteId = null): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new DeleteWorkerCommand($id),
|
||||
'delete-worker',
|
||||
$siteId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function restart(int $id, int $siteId = null): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new RestartWorkerCommand($id),
|
||||
'restart-worker',
|
||||
$siteId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function stop(int $id, int $siteId = null): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new StopWorkerCommand($id),
|
||||
'stop-worker',
|
||||
$siteId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function start(int $id, int $siteId = null): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new StartWorkerCommand($id),
|
||||
'start-worker',
|
||||
$siteId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function getLogs(string $logPath): string
|
||||
{
|
||||
return $this->service->server->ssh()->exec(
|
||||
"tail -100 $logPath"
|
||||
);
|
||||
}
|
||||
|
||||
private function generateConfigFile(
|
||||
int $id,
|
||||
string $command,
|
||||
string $user,
|
||||
bool $autoStart,
|
||||
bool $autoRestart,
|
||||
int $numprocs,
|
||||
string $logFile
|
||||
): string {
|
||||
$config = File::get(base_path('system/command-templates/supervisor/worker.conf'));
|
||||
$config = Str::replace('__name__', (string) $id, $config);
|
||||
$config = Str::replace('__command__', $command, $config);
|
||||
$config = Str::replace('__user__', $user, $config);
|
||||
$config = Str::replace('__auto_start__', var_export($autoStart, true), $config);
|
||||
$config = Str::replace('__auto_restart__', var_export($autoRestart, true), $config);
|
||||
$config = Str::replace('__numprocs__', (string) $numprocs, $config);
|
||||
|
||||
return Str::replace('__log_file__', $logFile, $config);
|
||||
}
|
||||
}
|
16
app/ServiceHandlers/Webserver/AbstractWebserver.php
Executable file
16
app/ServiceHandlers/Webserver/AbstractWebserver.php
Executable file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\Webserver;
|
||||
|
||||
use App\Contracts\Webserver;
|
||||
use App\Models\Service;
|
||||
|
||||
abstract class AbstractWebserver implements Webserver
|
||||
{
|
||||
protected Service $service;
|
||||
|
||||
public function __construct(Service $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
}
|
194
app/ServiceHandlers/Webserver/Nginx.php
Executable file
194
app/ServiceHandlers/Webserver/Nginx.php
Executable file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
namespace App\ServiceHandlers\Webserver;
|
||||
|
||||
use App\Exceptions\ErrorUpdatingRedirects;
|
||||
use App\Exceptions\SSLCreationException;
|
||||
use App\Models\Site;
|
||||
use App\Models\Ssl;
|
||||
use App\SSHCommands\ChangeNginxPHPVersionCommand;
|
||||
use App\SSHCommands\CreateCustomSSLCommand;
|
||||
use App\SSHCommands\CreateLetsencryptSSLCommand;
|
||||
use App\SSHCommands\CreateNginxVHostCommand;
|
||||
use App\SSHCommands\DeleteNginxSiteCommand;
|
||||
use App\SSHCommands\RemoveSSLCommand;
|
||||
use App\SSHCommands\UpdateNginxRedirectsCommand;
|
||||
use App\SSHCommands\UpdateNginxVHostCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
|
||||
class Nginx extends AbstractWebserver
|
||||
{
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function createVHost(Site $site): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new CreateNginxVHostCommand(
|
||||
$site->domain,
|
||||
$site->path,
|
||||
$this->generateVhost($site)
|
||||
),
|
||||
'create-vhost',
|
||||
$site->id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function updateVHost(Site $site, bool $noSSL = false): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new UpdateNginxVHostCommand(
|
||||
$site->domain,
|
||||
$site->path,
|
||||
$this->generateVhost($site, $noSSL)
|
||||
),
|
||||
'update-vhost',
|
||||
$site->id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function deleteSite(Site $site): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new DeleteNginxSiteCommand(
|
||||
$site->domain,
|
||||
$site->path
|
||||
),
|
||||
'delete-site',
|
||||
$site->id
|
||||
);
|
||||
$this->service->restart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function changePHPVersion(Site $site, $version): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new ChangeNginxPHPVersionCommand($site->domain, $site->php_version, $version),
|
||||
'change-php-version',
|
||||
$site->id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function setupSSL(Ssl $ssl): void
|
||||
{
|
||||
$command = new CreateLetsencryptSSLCommand(
|
||||
$ssl->site->server->creator->email,
|
||||
$ssl->site->domain,
|
||||
$ssl->site->web_directory_path
|
||||
);
|
||||
if ($ssl->type == 'custom') {
|
||||
$command = new CreateCustomSSLCommand(
|
||||
$ssl->certs_directory_path,
|
||||
$ssl->certificate,
|
||||
$ssl->pk,
|
||||
$ssl->certificate_path,
|
||||
$ssl->pk_path,
|
||||
);
|
||||
}
|
||||
$result = $this->service->server->ssh()->exec(
|
||||
$command,
|
||||
'create-ssl',
|
||||
$ssl->site_id
|
||||
);
|
||||
if (! $ssl->validateSetup($result)) {
|
||||
throw new SSLCreationException();
|
||||
}
|
||||
|
||||
$this->updateVHost($ssl->site);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function removeSSL(Ssl $ssl): void
|
||||
{
|
||||
$this->service->server->ssh()->exec(
|
||||
new RemoveSSLCommand($ssl->certs_directory_path),
|
||||
'remove-ssl',
|
||||
$ssl->site_id
|
||||
);
|
||||
|
||||
$this->updateVHost($ssl->site, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function updateRedirects(Site $site, array $redirects): void
|
||||
{
|
||||
$redirectsPlain = '';
|
||||
foreach ($redirects as $redirect) {
|
||||
$rd = File::get(base_path('system/command-templates/nginx/redirect.conf'));
|
||||
$rd = Str::replace('__from__', $redirect->from, $rd);
|
||||
$rd = Str::replace('__mode__', $redirect->mode, $rd);
|
||||
$rd = Str::replace('__to__', $redirect->to, $rd);
|
||||
$redirectsPlain .= $rd."\n";
|
||||
}
|
||||
$result = $this->service->server->ssh()->exec(
|
||||
new UpdateNginxRedirectsCommand(
|
||||
$site->domain,
|
||||
$redirectsPlain,
|
||||
),
|
||||
'update-redirects',
|
||||
$site->id
|
||||
);
|
||||
if (Str::contains($result, 'journalctl -xe')) {
|
||||
throw new ErrorUpdatingRedirects();
|
||||
}
|
||||
}
|
||||
|
||||
protected function generateVhost(Site $site, bool $noSSL = false): string
|
||||
{
|
||||
$ssl = $site->activeSsl;
|
||||
if ($noSSL) {
|
||||
$ssl = null;
|
||||
}
|
||||
$vhost = File::get(base_path('system/command-templates/nginx/vhost.conf'));
|
||||
if ($ssl) {
|
||||
$vhost = File::get(base_path('system/command-templates/nginx/vhost-ssl.conf'));
|
||||
}
|
||||
if ($site->type()->language() === 'php') {
|
||||
$vhost = File::get(base_path('system/command-templates/nginx/php-vhost.conf'));
|
||||
if ($ssl) {
|
||||
$vhost = File::get(base_path('system/command-templates/nginx/php-vhost-ssl.conf'));
|
||||
}
|
||||
}
|
||||
if ($site->port) {
|
||||
$vhost = File::get(base_path('system/command-templates/nginx/reverse-vhost.conf'));
|
||||
if ($ssl) {
|
||||
$vhost = File::get(base_path('system/command-templates/nginx/reverse-vhost-ssl.conf'));
|
||||
}
|
||||
$vhost = Str::replace('__port__', (string) $site->port, $vhost);
|
||||
}
|
||||
|
||||
$vhost = Str::replace('__domain__', $site->domain, $vhost);
|
||||
$vhost = Str::replace('__aliases__', $site->aliases_string, $vhost);
|
||||
$vhost = Str::replace('__path__', $site->path, $vhost);
|
||||
$vhost = Str::replace('__web_directory__', $site->web_directory, $vhost);
|
||||
|
||||
if ($ssl) {
|
||||
$vhost = Str::replace('__certificate__', $ssl->certificate_path, $vhost);
|
||||
$vhost = Str::replace('__private_key__', $ssl->pk_path, $vhost);
|
||||
}
|
||||
|
||||
if ($site->php_version) {
|
||||
$vhost = Str::replace('__php_version__', $site->php_version, $vhost);
|
||||
}
|
||||
|
||||
return $vhost;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user