Plugins base (#613)

* wip

* wip

* cleanup

* notification channels

* phpstan

* services

* remove server types

* refactoring

* refactoring
This commit is contained in:
Saeed Vaziry
2025-06-14 14:35:18 +02:00
committed by GitHub
parent adc0653d15
commit 131b828807
311 changed files with 3976 additions and 2660 deletions

View File

@ -3,6 +3,11 @@
namespace App\Providers;
use App\Facades\SSH;
use App\Models\FirewallRule;
use App\Models\PersonalAccessToken;
use App\Models\Script;
use App\Models\ScriptExecution;
use App\Models\ServerLog;
use App\Models\User;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\ServiceProvider;
@ -22,20 +27,20 @@ class DemoServiceProvider extends ServiceProvider
* @var string[]
*/
protected array $canUpdate = [
\App\Models\ServerLog::class,
\App\Models\Script::class,
\App\Models\ScriptExecution::class,
ServerLog::class,
Script::class,
ScriptExecution::class,
];
/**
* @var string[]
*/
protected array $canCreate = [
\App\Models\ServerLog::class,
\App\Models\Script::class,
\App\Models\ScriptExecution::class,
\App\Models\FirewallRule::class,
\App\Models\PersonalAccessToken::class,
ServerLog::class,
Script::class,
ScriptExecution::class,
FirewallRule::class,
PersonalAccessToken::class,
];
public function register(): void

View File

@ -0,0 +1,88 @@
<?php
namespace App\Providers;
use App\DTOs\DynamicField;
use App\DTOs\DynamicForm;
use App\NotificationChannels\Discord;
use App\NotificationChannels\Email;
use App\NotificationChannels\Slack;
use App\NotificationChannels\Telegram;
use App\Plugins\RegisterNotificationChannel;
use Illuminate\Support\ServiceProvider;
class NotificationChannelServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
$this->discord();
$this->slack();
$this->email();
$this->telegram();
}
private function discord(): void
{
RegisterNotificationChannel::make(Discord::id())
->label('Discord')
->handler(Discord::class)
->form(
DynamicForm::make([
DynamicField::make('webhook_url')
->text()
->label('Webhook URL'),
])
)
->register();
}
public function slack(): void
{
RegisterNotificationChannel::make(Slack::id())
->label('Slack')
->handler(Slack::class)
->form(
DynamicForm::make([
DynamicField::make('webhook_url')
->text()
->label('Webhook URL'),
])
)
->register();
}
private function email(): void
{
RegisterNotificationChannel::make(Email::id())
->label('Email')
->handler(Email::class)
->form(
DynamicForm::make([
DynamicField::make('email')
->text()
->label('Email address'),
])
)
->register();
}
private function telegram(): void
{
RegisterNotificationChannel::make(Telegram::id())
->label('Telegram')
->handler(Telegram::class)
->form(
DynamicForm::make([
DynamicField::make('bot_token')
->text()
->label('Bot Token'),
DynamicField::make('chat_id')
->text()
->label('Chat ID'),
]),
)
->register();
}
}

View File

@ -0,0 +1,120 @@
<?php
namespace App\Providers;
use App\DTOs\DynamicField;
use App\DTOs\DynamicForm;
use App\Plugins\RegisterServerProvider;
use App\ServerProviders\AWS;
use App\ServerProviders\Custom;
use App\ServerProviders\DigitalOcean;
use App\ServerProviders\Hetzner;
use App\ServerProviders\Linode;
use App\ServerProviders\Vultr;
use Illuminate\Support\ServiceProvider;
class ServerProviderServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
$this->custom();
$this->aws();
$this->hetzner();
$this->digitalOcean();
$this->linode();
$this->vultr();
}
private function custom(): void
{
RegisterServerProvider::make(Custom::id())
->label('Custom')
->handler(Custom::class)
->register();
}
private function aws(): void
{
RegisterServerProvider::make(AWS::id())
->label('AWS')
->handler(AWS::class)
->form(
DynamicForm::make([
DynamicField::make('key')
->text()
->label('Access Key'),
DynamicField::make('secret')
->text()
->label('Secret'),
])
)
->defaultUser('ubuntu')
->register();
}
private function hetzner(): void
{
RegisterServerProvider::make(Hetzner::id())
->label('Hetzner')
->handler(Hetzner::class)
->form(
DynamicForm::make([
DynamicField::make('token')
->text()
->label('Token'),
])
)
->defaultUser('root')
->register();
}
private function digitalOcean(): void
{
RegisterServerProvider::make(DigitalOcean::id())
->label('DigitalOcean')
->handler(DigitalOcean::class)
->form(
DynamicForm::make([
DynamicField::make('token')
->text()
->label('Token'),
])
)
->defaultUser('root')
->register();
}
private function linode(): void
{
RegisterServerProvider::make(Linode::id())
->label('Linode')
->handler(Linode::class)
->form(
DynamicForm::make([
DynamicField::make('token')
->text()
->label('Token'),
])
)
->defaultUser('root')
->register();
}
private function vultr(): void
{
RegisterServerProvider::make(Vultr::id())
->label('Vultr')
->handler(Vultr::class)
->form(
DynamicForm::make([
DynamicField::make('token')
->text()
->label('Token'),
])
)
->defaultUser('root')
->register();
}
}

View File

@ -0,0 +1,180 @@
<?php
namespace App\Providers;
use App\Plugins\RegisterServiceType;
use App\Services\Database\Mariadb;
use App\Services\Database\Mysql;
use App\Services\Database\Postgresql;
use App\Services\Firewall\Ufw;
use App\Services\Monitoring\RemoteMonitor\RemoteMonitor;
use App\Services\Monitoring\VitoAgent\VitoAgent;
use App\Services\NodeJS\NodeJS;
use App\Services\PHP\PHP;
use App\Services\ProcessManager\Supervisor;
use App\Services\Redis\Redis;
use App\Services\Webserver\Caddy;
use App\Services\Webserver\Nginx;
use Illuminate\Support\ServiceProvider;
class ServiceTypeServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
$this->webservers();
$this->databases();
$this->memoryDatabases();
$this->firewalls();
$this->processManagers();
$this->monitoring();
$this->php();
$this->node();
}
private function webservers(): void
{
RegisterServiceType::make(Nginx::id())
->type(Nginx::type())
->label('Nginx')
->handler(Nginx::class)
->register();
RegisterServiceType::make(Caddy::id())
->type(Caddy::type())
->label('Caddy (beta)')
->handler(Caddy::class)
->register();
}
private function databases(): void
{
RegisterServiceType::make(Mysql::id())
->type(Mysql::type())
->label('MySQL')
->handler(Mysql::class)
->versions([
'8.4',
'8.0',
'5.7',
])
->register();
RegisterServiceType::make(Postgresql::id())
->type(Postgresql::type())
->label('PostgreSQL')
->handler(Postgresql::class)
->versions([
'16',
'15',
'14',
'13',
'12',
])
->register();
RegisterServiceType::make(Mariadb::id())
->type(Mariadb::type())
->label('MariaDB')
->handler(Mariadb::class)
->versions([
'11.4',
'10.11',
'10.6',
'10.4',
'10.3',
])
->register();
}
private function memoryDatabases(): void
{
RegisterServiceType::make(Redis::id())
->type(Redis::type())
->label('Redis')
->handler(Redis::class)
->register();
}
private function firewalls(): void
{
RegisterServiceType::make(Ufw::id())
->type(Ufw::type())
->label('UFW')
->handler(Ufw::class)
->register();
}
private function processManagers(): void
{
RegisterServiceType::make(Supervisor::id())
->type(Supervisor::type())
->label('Supervisor')
->handler(Supervisor::class)
->register();
}
private function monitoring(): void
{
RegisterServiceType::make(VitoAgent::id())
->type(VitoAgent::type())
->label('VitoAgent')
->handler(VitoAgent::class)
->register();
RegisterServiceType::make(RemoteMonitor::id())
->type(RemoteMonitor::type())
->label('RemoteMonitor')
->handler(RemoteMonitor::class)
->register();
}
private function php(): void
{
RegisterServiceType::make(PHP::id())
->type(PHP::type())
->label('PHP')
->handler(PHP::class)
->versions([
'8.4',
'8.3',
'8.2',
'8.1',
'8.0',
'7.4',
'7.3',
'7.2',
'7.1',
'7.0',
'5.6',
])
->data([
'extensions' => [
'imagick',
'exif',
'gmagick',
'gmp',
'intl',
'sqlite3',
'opcache',
],
])
->register();
}
private function node(): void
{
RegisterServiceType::make(NodeJS::id())
->type(NodeJS::type())
->label('Node.js')
->handler(NodeJS::class)
->versions([
'22',
'20',
'18',
'16',
'14',
'12',
])
->register();
}
}

View File

@ -0,0 +1,210 @@
<?php
namespace App\Providers;
use App\DTOs\DynamicField;
use App\DTOs\DynamicForm;
use App\Enums\LoadBalancerMethod;
use App\Plugins\RegisterSiteFeature;
use App\Plugins\RegisterSiteFeatureAction;
use App\Plugins\RegisterSiteType;
use App\SiteFeatures\LaravelOctane\Disable;
use App\SiteFeatures\LaravelOctane\Enable;
use App\SiteTypes\Laravel;
use App\SiteTypes\LoadBalancer;
use App\SiteTypes\PHPBlank;
use App\SiteTypes\PHPMyAdmin;
use App\SiteTypes\PHPSite;
use App\SiteTypes\Wordpress;
use Illuminate\Support\ServiceProvider;
class SiteTypeServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
$this->php();
$this->phpBlank();
$this->laravel();
$this->loadBalancer();
$this->phpMyAdmin();
$this->wordpress();
}
private function php(): void
{
RegisterSiteType::make(PHPSite::id())
->label('PHP')
->handler(PHPSite::class)
->form(DynamicForm::make([
DynamicField::make('php_version')
->component()
->label('PHP Version'),
DynamicField::make('source_control')
->component()
->label('Source Control'),
DynamicField::make('web_directory')
->text()
->label('Web Directory')
->placeholder('For / leave empty')
->description('The relative path of your website from /home/vito/your-domain/'),
DynamicField::make('repository')
->text()
->label('Repository')
->placeholder('organization/repository'),
DynamicField::make('branch')
->text()
->label('Branch')
->default('main'),
DynamicField::make('composer')
->checkbox()
->label('Run `composer install --no-dev`')
->default(false),
]))
->register();
}
private function phpBlank(): void
{
RegisterSiteType::make(PHPBlank::id())
->label('PHP Blank')
->handler(PHPBlank::class)
->form(DynamicForm::make([
DynamicField::make('php_version')
->component()
->label('PHP Version'),
DynamicField::make('web_directory')
->text()
->label('Web Directory')
->placeholder('For / leave empty')
->description('The relative path of your website from /home/vito/your-domain/'),
]))
->register();
}
private function laravel(): void
{
RegisterSiteType::make(Laravel::id())
->label('Laravel')
->handler(Laravel::class)
->form(DynamicForm::make([
DynamicField::make('php_version')
->component()
->label('PHP Version'),
DynamicField::make('source_control')
->component()
->label('Source Control'),
DynamicField::make('web_directory')
->text()
->label('Web Directory')
->placeholder('For / leave empty')
->description('The relative path of your website from /home/vito/your-domain/'),
DynamicField::make('repository')
->text()
->label('Repository')
->placeholder('organization/repository'),
DynamicField::make('branch')
->text()
->label('Branch')
->default('main'),
DynamicField::make('composer')
->checkbox()
->label('Run `composer install --no-dev`')
->default(false),
]))
->register();
RegisterSiteFeature::make('laravel', 'laravel-octane')
->label('Laravel Octane')
->description('Enable Laravel Octane for this site')
->register();
RegisterSiteFeatureAction::make('laravel', 'laravel-octane', 'enable')
->label('Enable')
->form(DynamicForm::make([
DynamicField::make('alert')
->alert()
->label('Alert')
->description('Make sure you have already set the `OCTANE_SERVER` in your `.env` file'),
DynamicField::make('port')
->text()
->label('Octane Port')
->default(8000)
->description('The port on which Laravel Octane will run.'),
]))
->handler(Enable::class)
->register();
RegisterSiteFeatureAction::make('laravel', 'laravel-octane', 'disable')
->label('Disable')
->handler(Disable::class)
->register();
}
public function loadBalancer(): void
{
RegisterSiteType::make(LoadBalancer::id())
->label('Load Balancer')
->handler(LoadBalancer::class)
->form(DynamicForm::make([
DynamicField::make('method')
->select()
->label('Load Balancing Method')
->options([
LoadBalancerMethod::IP_HASH,
LoadBalancerMethod::ROUND_ROBIN,
LoadBalancerMethod::LEAST_CONNECTIONS,
]),
]))
->register();
}
public function phpMyAdmin(): void
{
RegisterSiteType::make(PHPMyAdmin::id())
->label('PHPMyAdmin')
->handler(PHPMyAdmin::class)
->form(DynamicForm::make([
DynamicField::make('php_version')
->component()
->label('PHP Version'),
]))
->register();
}
public function wordpress(): void
{
RegisterSiteType::make(Wordpress::id())
->label('WordPress')
->handler(Wordpress::class)
->form(DynamicForm::make([
DynamicField::make('php_version')
->component()
->label('PHP Version'),
DynamicField::make('title')
->text()
->label('Site Title')
->placeholder('My WordPress Site'),
DynamicField::make('username')
->text()
->label('Admin Username')
->placeholder('admin'),
DynamicField::make('password')
->text()
->label('Admin Password'),
DynamicField::make('email')
->text()
->label('Admin Email'),
DynamicField::make('database')
->text()
->label('Database Name')
->placeholder('wordpress'),
DynamicField::make('database_user')
->text()
->label('Database User')
->placeholder('wp_user'),
DynamicField::make('database_password')
->text()
->label('Database Password'),
]))
->register();
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace App\Providers;
use App\DTOs\DynamicField;
use App\DTOs\DynamicForm;
use App\Plugins\RegisterSourceControl;
use App\SourceControlProviders\Bitbucket;
use App\SourceControlProviders\Github;
use App\SourceControlProviders\Gitlab;
use Illuminate\Support\ServiceProvider;
class SourceControlServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
$this->github();
$this->gitlab();
$this->bitbucket();
}
private function github(): void
{
RegisterSourceControl::make(Github::id())
->label('Github')
->handler(Github::class)
->form(
DynamicForm::make([
DynamicField::make('token')
->text()
->label('Token'),
])
)
->register();
}
private function gitlab(): void
{
RegisterSourceControl::make(Gitlab::id())
->label('Gitlab')
->handler(Gitlab::class)
->form(
DynamicForm::make([
DynamicField::make('token')
->text()
->label('Token'),
DynamicField::make('url')
->text()
->label('Self hosted URL'),
])
)
->register();
}
private function bitbucket(): void
{
RegisterSourceControl::make(Bitbucket::id())
->label('Bitbucket')
->handler(Bitbucket::class)
->form(
DynamicForm::make([
DynamicField::make('username')
->text()
->label('Username'),
DynamicField::make('password')
->text()
->label('Password'),
])
)
->register();
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace App\Providers;
use App\DTOs\DynamicField;
use App\DTOs\DynamicForm;
use App\Plugins\RegisterStorageProvider;
use App\StorageProviders\Dropbox;
use App\StorageProviders\FTP;
use App\StorageProviders\Local;
use App\StorageProviders\S3;
use Illuminate\Support\ServiceProvider;
class StorageProviderServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
$this->local();
$this->aws();
$this->dropbox();
$this->ftp();
}
private function local(): void
{
RegisterStorageProvider::make(Local::id())
->label('Local')
->handler(Local::class)
->form(
DynamicForm::make([
DynamicField::make('path')
->text()
->label('Path'),
])
)
->register();
}
private function aws(): void
{
RegisterStorageProvider::make(S3::id())
->label('S3')
->handler(S3::class)
->form(
DynamicForm::make([
DynamicField::make('api_url')
->text()
->label('API URL'),
DynamicField::make('key')
->text()
->label('Access Key'),
DynamicField::make('secret')
->text()
->label('Secret Key'),
DynamicField::make('region')
->text()
->label('Region'),
DynamicField::make('bucket')
->text()
->label('Bucket Name'),
DynamicField::make('path')
->text()
->label('Path'),
])
)
->register();
}
private function dropbox(): void
{
RegisterStorageProvider::make(Dropbox::id())
->label('Dropbox')
->handler(Dropbox::class)
->form(
DynamicForm::make([
DynamicField::make('token')
->text()
->label('Token'),
])
)
->register();
}
private function ftp(): void
{
RegisterStorageProvider::make(FTP::id())
->label('FTP')
->handler(FTP::class)
->form(
DynamicForm::make([
DynamicField::make('host')
->text()
->label('Host'),
DynamicField::make('port')
->text()
->label('Port')
->default(21),
DynamicField::make('path')
->text()
->label('Path'),
DynamicField::make('username')
->text()
->label('Username'),
DynamicField::make('password')
->text()
->label('Password'),
DynamicField::make('ssl')
->checkbox()
->label('Use SSL')
->default(false),
DynamicField::make('passive')
->checkbox()
->label('Use Passive Mode')
->default(true),
])
)
->register();
}
}