mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 15:02:34 +00:00
#591 - sites
This commit is contained in:
@ -123,9 +123,19 @@ public static function rules(array $input): array
|
||||
'min:1',
|
||||
'max:65535',
|
||||
],
|
||||
'source' => [
|
||||
'nullable',
|
||||
'ip',
|
||||
],
|
||||
'mask' => [
|
||||
'nullable',
|
||||
'numeric',
|
||||
'min:1',
|
||||
'max:32',
|
||||
],
|
||||
];
|
||||
|
||||
if (! ($input['source_any'] ?? false)) {
|
||||
if (isset($input['source_any']) && $input['source_any'] === false) {
|
||||
$rules['source'] = ['required', 'ip'];
|
||||
$rules['mask'] = ['required', 'numeric', 'min:1', 'max:32'];
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CreateRedirect
|
||||
@ -16,6 +17,8 @@ class CreateRedirect
|
||||
*/
|
||||
public function create(Site $site, array $input): Redirect
|
||||
{
|
||||
Validator::make($input, self::rules($site))->validate();
|
||||
|
||||
$redirect = new Redirect;
|
||||
|
||||
$redirect->site_id = $site->id;
|
||||
|
@ -9,6 +9,7 @@
|
||||
use App\Models\Site;
|
||||
use App\Models\Ssl;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
@ -21,6 +22,8 @@ class CreateSSL
|
||||
*/
|
||||
public function create(Site $site, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules($input))->validate();
|
||||
|
||||
$site->ssls()
|
||||
->where('type', $input['type'])
|
||||
->where('status', SslStatus::FAILED)
|
||||
|
15
app/Actions/SSL/DeactivateSSL.php
Normal file
15
app/Actions/SSL/DeactivateSSL.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\SSL;
|
||||
|
||||
use App\Models\Ssl;
|
||||
|
||||
class DeactivateSSL
|
||||
{
|
||||
public function deactivate(Ssl $ssl): void
|
||||
{
|
||||
$ssl->is_active = false;
|
||||
$ssl->save();
|
||||
$ssl->site->webserver()->updateVHost($ssl->site);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Command;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class CreateCommand
|
||||
{
|
||||
@ -12,6 +13,8 @@ class CreateCommand
|
||||
*/
|
||||
public function create(Site $site, array $input): Command
|
||||
{
|
||||
Validator::make($input, self::rules())->validate();
|
||||
|
||||
$script = new Command([
|
||||
'site_id' => $site->id,
|
||||
'name' => $input['name'],
|
||||
|
@ -7,14 +7,20 @@
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class DeleteSite
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function delete(Site $site): void
|
||||
public function delete(Site $site, array $input): void
|
||||
{
|
||||
$this->validate($site, $input);
|
||||
|
||||
/** @var Service $service */
|
||||
$service = $site->server->webserver();
|
||||
|
||||
@ -35,4 +41,14 @@ public function delete(Site $site): void
|
||||
|
||||
$site->delete();
|
||||
}
|
||||
|
||||
private function validate(Site $site, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'domain' => [
|
||||
'required',
|
||||
Rule::in($site->domain),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Enums\DeploymentStatus;
|
||||
use App\Exceptions\DeploymentScriptIsEmptyException;
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Facades\Notifier;
|
||||
use App\Models\Deployment;
|
||||
use App\Models\ServerLog;
|
||||
@ -15,7 +14,6 @@ class Deploy
|
||||
{
|
||||
/**
|
||||
* @throws DeploymentScriptIsEmptyException
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function run(Site $site): Deployment
|
||||
{
|
||||
@ -32,6 +30,11 @@ public function run(Site $site): Deployment
|
||||
'deployment_script_id' => $site->deploymentScript->id,
|
||||
'status' => DeploymentStatus::DEPLOYING,
|
||||
]);
|
||||
$log = ServerLog::newLog($site->server, 'deploy-'.strtotime('now'))
|
||||
->forSite($site);
|
||||
$log->save();
|
||||
$deployment->log_id = $log->id;
|
||||
$deployment->save();
|
||||
$lastCommit = $site->sourceControl?->provider()?->getLastCommit($site->repository, $site->branch);
|
||||
if ($lastCommit) {
|
||||
$deployment->commit_id = $lastCommit['commit_id'];
|
||||
@ -39,12 +42,7 @@ public function run(Site $site): Deployment
|
||||
}
|
||||
$deployment->save();
|
||||
|
||||
dispatch(function () use ($site, $deployment): void {
|
||||
$log = ServerLog::newLog($site->server, 'deploy-'.strtotime('now'))
|
||||
->forSite($site);
|
||||
$log->save();
|
||||
$deployment->log_id = $log->id;
|
||||
$deployment->save();
|
||||
dispatch(function () use ($site, $deployment, $log): void {
|
||||
$site->server->os()->runScript(
|
||||
path: $site->path,
|
||||
script: $site->deploymentScript->content,
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Actions\Site;
|
||||
|
||||
use App\Models\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class EditCommand
|
||||
{
|
||||
@ -11,6 +12,8 @@ class EditCommand
|
||||
*/
|
||||
public function edit(Command $command, array $input): Command
|
||||
{
|
||||
Validator::make($input, self::rules())->validate();
|
||||
|
||||
$command->name = $input['name'];
|
||||
$command->command = $input['command'];
|
||||
$command->save();
|
||||
|
@ -7,6 +7,7 @@
|
||||
use App\Models\CommandExecution;
|
||||
use App\Models\ServerLog;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ExecuteCommand
|
||||
{
|
||||
@ -15,19 +16,31 @@ class ExecuteCommand
|
||||
*/
|
||||
public function execute(Command $command, User $user, array $input): CommandExecution
|
||||
{
|
||||
Validator::make($input, self::rules($command))->validate();
|
||||
|
||||
$variables = [];
|
||||
foreach ($command->getVariables() as $variable) {
|
||||
if (array_key_exists($variable, $input)) {
|
||||
$variables[$variable] = $input[$variable] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
$execution = new CommandExecution([
|
||||
'command_id' => $command->id,
|
||||
'server_id' => $command->site->server_id,
|
||||
'user_id' => $user->id,
|
||||
'variables' => $input['variables'] ?? [],
|
||||
'variables' => $variables,
|
||||
'status' => CommandExecutionStatus::EXECUTING,
|
||||
]);
|
||||
$execution->save();
|
||||
|
||||
dispatch(function () use ($execution, $command): void {
|
||||
$log = ServerLog::newLog($execution->server, 'command-'.$command->id.'-'.strtotime('now'));
|
||||
$log->save();
|
||||
$execution->server_log_id = $log->id;
|
||||
$execution->save();
|
||||
|
||||
dispatch(function () use ($execution, $command, $log): void {
|
||||
$content = $execution->getContent();
|
||||
$log = ServerLog::newLog($execution->server, 'command-'.$command->id.'-'.strtotime('now'));
|
||||
$log->save();
|
||||
$execution->server_log_id = $log->id;
|
||||
$execution->save();
|
||||
$execution->server->os()->runScript(
|
||||
@ -48,18 +61,19 @@ public function execute(Command $command, User $user, array $input): CommandExec
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
* @return array<string, string|array<int, mixed>>
|
||||
*/
|
||||
public static function rules(array $input): array
|
||||
public static function rules(Command $command): array
|
||||
{
|
||||
return [
|
||||
'variables' => 'array',
|
||||
'variables.*' => [
|
||||
$rules = [];
|
||||
foreach ($command->getVariables() as $variable) {
|
||||
$rules[$variable] = [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
];
|
||||
];
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Git\Git;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateBranch
|
||||
{
|
||||
@ -15,6 +16,8 @@ class UpdateBranch
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules())->validate();
|
||||
|
||||
$site->branch = $input['branch'];
|
||||
app(Git::class)->fetchOrigin($site);
|
||||
app(Git::class)->checkout($site);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\DeploymentScript;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateDeploymentScript
|
||||
{
|
||||
@ -12,6 +13,8 @@ class UpdateDeploymentScript
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules())->validate();
|
||||
|
||||
/** @var DeploymentScript $script */
|
||||
$script = $site->deploymentScript;
|
||||
$script->content = $input['script'];
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateEnv
|
||||
{
|
||||
@ -14,10 +15,14 @@ class UpdateEnv
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
$site->server->os()->editFileAs(
|
||||
Validator::make($input, [
|
||||
'env' => ['required', 'string'],
|
||||
])->validate();
|
||||
|
||||
$site->server->os()->write(
|
||||
$site->path.'/.env',
|
||||
$site->user,
|
||||
trim((string) $input['env']),
|
||||
$site->user,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
use App\Enums\LoadBalancerMethod;
|
||||
use App\Models\LoadBalancerServer;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateLoadBalancer
|
||||
@ -14,6 +15,8 @@ class UpdateLoadBalancer
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules($site))->validate();
|
||||
|
||||
$site->loadBalancerServers()->delete();
|
||||
|
||||
foreach ($input['servers'] as $server) {
|
||||
|
@ -4,10 +4,23 @@
|
||||
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdatePHPVersion
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules($site))->validate();
|
||||
|
||||
$site->changePHPVersion($input['version']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<string>>
|
||||
*/
|
||||
@ -22,14 +35,4 @@ public static function rules(Site $site): array
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
$site->changePHPVersion($input['version']);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
use App\Exceptions\RepositoryPermissionDenied;
|
||||
use App\Exceptions\SourceControlIsNotConnected;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
@ -18,6 +19,8 @@ class UpdateSourceControl
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules())->validate();
|
||||
|
||||
$site->source_control_id = $input['source_control'];
|
||||
try {
|
||||
if ($site->sourceControl) {
|
||||
|
@ -3,5 +3,20 @@
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class DeploymentScriptIsEmptyException extends Exception {}
|
||||
class DeploymentScriptIsEmptyException extends Exception
|
||||
{
|
||||
public function render(Request $request): RedirectResponse
|
||||
{
|
||||
if ($request->header('X-Inertia')) {
|
||||
return back()->with('error', 'Cannot deploy an empty deployment script.');
|
||||
}
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'deployment_script' => 'Deployment script cannot be empty.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,17 @@
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FailedToDeployGitHook extends Exception
|
||||
{
|
||||
//
|
||||
public function render(Request $request): ?RedirectResponse
|
||||
{
|
||||
if ($request->header('X-Inertia')) {
|
||||
return back()->with('error', 'Failed to deploy git hook.');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,17 @@
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FailedToDestroyGitHook extends Exception
|
||||
{
|
||||
//
|
||||
public function render(Request $request): ?RedirectResponse
|
||||
{
|
||||
if ($request->header('X-Inertia')) {
|
||||
return back()->with('error', 'Failed to destroy git hook.');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -3,5 +3,17 @@
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SourceControlIsNotConnected extends Exception {}
|
||||
class SourceControlIsNotConnected extends Exception
|
||||
{
|
||||
public function render(Request $request): ?RedirectResponse
|
||||
{
|
||||
if ($request->header('X-Inertia')) {
|
||||
return back()->with('error', 'Source control is not connected.');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
136
app/Http/Controllers/ApplicationController.php
Normal file
136
app/Http/Controllers/ApplicationController.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Site\Deploy;
|
||||
use App\Actions\Site\UpdateDeploymentScript;
|
||||
use App\Actions\Site\UpdateEnv;
|
||||
use App\Actions\Site\UpdateLoadBalancer;
|
||||
use App\Exceptions\DeploymentScriptIsEmptyException;
|
||||
use App\Exceptions\FailedToDestroyGitHook;
|
||||
use App\Exceptions\SourceControlIsNotConnected;
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Http\Resources\DeploymentResource;
|
||||
use App\Http\Resources\LoadBalancerServerResource;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
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;
|
||||
use Spatie\RouteAttributes\Attributes\Put;
|
||||
|
||||
#[Prefix('/servers/{server}/sites/{site}')]
|
||||
#[Middleware(['auth', 'has-project'])]
|
||||
class ApplicationController extends Controller
|
||||
{
|
||||
#[Get('/', name: 'application')]
|
||||
public function index(Server $server, Site $site): Response
|
||||
{
|
||||
$this->authorize('view', [$site, $server]);
|
||||
|
||||
return Inertia::render('application/index', [
|
||||
'deployments' => DeploymentResource::collection($site->deployments()->latest()->simplePaginate(config('web.pagination_size'))),
|
||||
'deploymentScript' => $site->deploymentScript?->content,
|
||||
'loadBalancerServers' => LoadBalancerServerResource::collection($site->loadBalancerServers)
|
||||
]);
|
||||
}
|
||||
|
||||
#[Put('/deployment-script', name: 'application.update-deployment-script')]
|
||||
public function updateDeploymentScript(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(UpdateDeploymentScript::class)->update($site, $request->input());
|
||||
|
||||
return back()->with('success', 'Deployment script updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DeploymentScriptIsEmptyException
|
||||
*/
|
||||
#[Post('/deploy', name: 'application.deploy')]
|
||||
public function deploy(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(Deploy::class)->run($site);
|
||||
|
||||
return back()->with('info', 'Deployment started, please wait...');
|
||||
}
|
||||
|
||||
#[Get('/env', name: 'application.env')]
|
||||
public function env(Server $server, Site $site): JsonResponse
|
||||
{
|
||||
$this->authorize('view', [$site, $server]);
|
||||
|
||||
$env = $site->getEnv();
|
||||
|
||||
return response()->json([
|
||||
'env' => $env,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
#[Put('/env', name: 'application.update-env')]
|
||||
public function updateEnv(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(UpdateEnv::class)->update($site, $request->input());
|
||||
|
||||
return back()->with('success', '.env file updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SourceControlIsNotConnected
|
||||
*/
|
||||
#[Post('/enable-auto-deployment', name: 'application.enable-auto-deployment')]
|
||||
public function enableAutoDeployment(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
if (! $site->sourceControl) {
|
||||
return back()->with('error', 'Cannot find source control for this site.');
|
||||
}
|
||||
|
||||
$site->enableAutoDeployment();
|
||||
|
||||
return back()->with('success', 'Auto deployment enabled successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SourceControlIsNotConnected
|
||||
* @throws FailedToDestroyGitHook
|
||||
*/
|
||||
#[Post('/disable-auto-deployment', name: 'application.disable-auto-deployment')]
|
||||
public function disableAutoDeployment(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
if (! $site->sourceControl) {
|
||||
return back()->with('error', 'Cannot find source control for this site.');
|
||||
}
|
||||
|
||||
$site->disableAutoDeployment();
|
||||
|
||||
return back()->with('success', 'Auto deployment disabled successfully.');
|
||||
}
|
||||
|
||||
#[Post('/load-balancer', name: 'application.update-load-balancer')]
|
||||
public function updateLoadBalancer(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(UpdateLoadBalancer::class)->update($site, $request->input());
|
||||
|
||||
return back()->with('success', 'Load balancer updated successfully.');
|
||||
}
|
||||
}
|
92
app/Http/Controllers/CommandController.php
Normal file
92
app/Http/Controllers/CommandController.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Site\CreateCommand;
|
||||
use App\Actions\Site\EditCommand;
|
||||
use App\Actions\Site\ExecuteCommand;
|
||||
use App\Http\Resources\CommandExecutionResource;
|
||||
use App\Http\Resources\CommandResource;
|
||||
use App\Models\Command;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Spatie\RouteAttributes\Attributes\Delete;
|
||||
use Spatie\RouteAttributes\Attributes\Get;
|
||||
use Spatie\RouteAttributes\Attributes\Middleware;
|
||||
use Spatie\RouteAttributes\Attributes\Post;
|
||||
use Spatie\RouteAttributes\Attributes\Prefix;
|
||||
use Spatie\RouteAttributes\Attributes\Put;
|
||||
|
||||
#[Prefix('/servers/{server}/sites/{site}/commands')]
|
||||
#[Middleware(['auth', 'has-project'])]
|
||||
class CommandController extends Controller
|
||||
{
|
||||
#[Get('/', name: 'commands')]
|
||||
public function index(Server $server, Site $site): Response
|
||||
{
|
||||
$this->authorize('viewAny', [Command::class, $site, $server]);
|
||||
|
||||
return Inertia::render('commands/index', [
|
||||
'commands' => CommandResource::collection($site->commands()->latest()->simplePaginate(config('web.pagination_size'))),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Post('/', name: 'commands.store')]
|
||||
public function store(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('create', [Command::class, $site, $server]);
|
||||
|
||||
app(CreateCommand::class)->create($site, $request->input());
|
||||
|
||||
return back()
|
||||
->with('success', 'Command created successfully.');
|
||||
}
|
||||
|
||||
#[Get('/{command}', name: 'commands.show')]
|
||||
public function show(Server $server, Site $site, Command $command): Response
|
||||
{
|
||||
$this->authorize('view', [$command, $site, $server]);
|
||||
|
||||
return Inertia::render('commands/show', [
|
||||
'command' => new CommandResource($command),
|
||||
'executions' => CommandExecutionResource::collection($command->executions()->latest()->simplePaginate(config('web.pagination_size'))),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Put('/{command}', name: 'commands.update')]
|
||||
public function update(Request $request, Server $server, Site $site, Command $command): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$command, $site, $server]);
|
||||
|
||||
app(EditCommand::class)->edit($command, $request->input());
|
||||
|
||||
return back()
|
||||
->with('success', 'Command updated successfully.');
|
||||
}
|
||||
|
||||
#[Delete('/{command}', name: 'commands.destroy')]
|
||||
public function destroy(Server $server, Site $site, Command $command): RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', [$command, $site, $server]);
|
||||
|
||||
$command->delete();
|
||||
|
||||
return back()
|
||||
->with('success', 'Command deleted successfully.');
|
||||
}
|
||||
|
||||
#[Post('/{command}/execute', name: 'commands.execute')]
|
||||
public function execute(Request $request, Server $server, Site $site, Command $command): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(ExecuteCommand::class)->execute($command, user(), $request->input());
|
||||
|
||||
return redirect()->route('commands.show', ['server' => $server, 'site' => $site, 'command' => $command])
|
||||
->with('info', 'Command is being executed.');
|
||||
}
|
||||
}
|
56
app/Http/Controllers/RedirectController.php
Normal file
56
app/Http/Controllers/RedirectController.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Redirect\CreateRedirect;
|
||||
use App\Actions\Redirect\DeleteRedirect;
|
||||
use App\Http\Resources\RedirectResource;
|
||||
use App\Models\Redirect;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Spatie\RouteAttributes\Attributes\Delete;
|
||||
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}/redirects')]
|
||||
#[Middleware(['auth', 'has-project'])]
|
||||
class RedirectController extends Controller
|
||||
{
|
||||
#[Get('/', name: 'redirects')]
|
||||
public function index(Server $server, Site $site): Response
|
||||
{
|
||||
$this->authorize('viewAny', [Redirect::class, $site, $server]);
|
||||
|
||||
return Inertia::render('redirects/index', [
|
||||
'redirects' => RedirectResource::collection($site->redirects()->latest()->simplePaginate(config('web.pagination_size'))),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Post('/', name: 'redirects.store')]
|
||||
public function store(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('create', [Redirect::class, $site, $server]);
|
||||
|
||||
app(CreateRedirect::class)->create($site, $request->input());
|
||||
|
||||
return back()
|
||||
->with('info', 'Creating the redirect');
|
||||
}
|
||||
|
||||
#[Delete('/{redirect}', name: 'redirects.destroy')]
|
||||
public function destroy(Server $server, Site $site, Redirect $redirect): RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', [$redirect, $site, $server]);
|
||||
|
||||
app(DeleteRedirect::class)->delete($site, $redirect);
|
||||
|
||||
return back()
|
||||
->with('info', 'Deleting the redirect');
|
||||
}
|
||||
}
|
106
app/Http/Controllers/SSLController.php
Normal file
106
app/Http/Controllers/SSLController.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\SSL\ActivateSSL;
|
||||
use App\Actions\SSL\CreateSSL;
|
||||
use App\Actions\SSL\DeactivateSSL;
|
||||
use App\Actions\SSL\DeleteSSL;
|
||||
use App\Http\Resources\SslResource;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\Ssl;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Spatie\RouteAttributes\Attributes\Delete;
|
||||
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}/ssl')]
|
||||
#[Middleware(['auth', 'has-project'])]
|
||||
class SSLController extends Controller
|
||||
{
|
||||
#[Get('/', name: 'ssls')]
|
||||
public function index(Server $server, Site $site): Response
|
||||
{
|
||||
$this->authorize('viewAny', [Ssl::class, $site, $server]);
|
||||
|
||||
return Inertia::render('ssls/index', [
|
||||
'ssls' => SslResource::collection($site->ssls()->latest()->simplePaginate(config('web.pagination_size'))),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Post('/', name: 'ssls.store')]
|
||||
public function store(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('create', [Ssl::class, $site, $server]);
|
||||
|
||||
app(CreateSSL::class)->create($site, $request->input());
|
||||
|
||||
return back()
|
||||
->with('info', 'Setting up SSL.');
|
||||
}
|
||||
|
||||
#[Delete('/{ssl}', name: 'ssls.destroy')]
|
||||
public function destroy(Server $server, Site $site, Ssl $ssl): RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', [$ssl, $site, $server]);
|
||||
|
||||
app(DeleteSSL::class)->delete($ssl);
|
||||
|
||||
return back()
|
||||
->with('success', 'SSL deleted successfully.');
|
||||
}
|
||||
|
||||
#[Post('/enable-force-ssl', name: 'ssls.enable-force-ssl')]
|
||||
public function enableForceSSL(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
$site->force_ssl = true;
|
||||
$site->save();
|
||||
$site->webserver()->updateVHost($site);
|
||||
|
||||
return back()
|
||||
->with('success', 'Force SSL enabled successfully.');
|
||||
}
|
||||
|
||||
#[Post('/disable-force-ssl', name: 'ssls.disable-force-ssl')]
|
||||
public function disableForceSSL(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
$site->force_ssl = false;
|
||||
$site->save();
|
||||
$site->webserver()->updateVHost($site);
|
||||
|
||||
return back()
|
||||
->with('success', 'Force SSL disabled successfully.');
|
||||
}
|
||||
|
||||
#[Post('/{ssl}/activate', name: 'ssls.activate')]
|
||||
public function activate(Server $server, Site $site, Ssl $ssl): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$ssl, $site, $server]);
|
||||
|
||||
app(ActivateSSL::class)->activate($ssl);
|
||||
|
||||
return back()
|
||||
->with('success', 'SSL activated successfully.');
|
||||
}
|
||||
|
||||
#[Post('/{ssl}/deactivate', name: 'ssls.deactivate')]
|
||||
public function deactivate(Server $server, Site $site, Ssl $ssl): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$ssl, $site, $server]);
|
||||
|
||||
app(DeactivateSSL::class)->deactivate($ssl);
|
||||
|
||||
return back()
|
||||
->with('success', 'SSL deactivated successfully.');
|
||||
}
|
||||
}
|
@ -3,8 +3,6 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Site\CreateSite;
|
||||
use App\Actions\Site\DeleteSite;
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Http\Resources\ServerLogResource;
|
||||
use App\Http\Resources\SiteResource;
|
||||
use App\Models\Server;
|
||||
@ -14,7 +12,6 @@
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Spatie\RouteAttributes\Attributes\Delete;
|
||||
use Spatie\RouteAttributes\Attributes\Get;
|
||||
use Spatie\RouteAttributes\Attributes\Middleware;
|
||||
use Spatie\RouteAttributes\Attributes\Post;
|
||||
@ -43,17 +40,6 @@ public function server(Server $server): Response
|
||||
]);
|
||||
}
|
||||
|
||||
#[Get('/servers/{server}/sites/{site}', name: 'sites.show')]
|
||||
public function show(Server $server, Site $site): Response
|
||||
{
|
||||
$this->authorize('view', [$site, $server]);
|
||||
|
||||
return Inertia::render('sites/show', [
|
||||
'site' => SiteResource::make($site),
|
||||
'logs' => ServerLogResource::collection($site->logs()->latest()->simplePaginate(config('web.pagination_size'), pageName: 'logsPage')),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
@ -64,7 +50,7 @@ public function store(Request $request, Server $server): RedirectResponse
|
||||
|
||||
$site = app(CreateSite::class)->create($server, $request->all());
|
||||
|
||||
return redirect()->route('sites.show', ['server' => $server, 'site' => $site])
|
||||
return redirect()->route('application', ['server' => $server, 'site' => $site])
|
||||
->with('info', 'Installing site, please wait...');
|
||||
}
|
||||
|
||||
@ -79,26 +65,22 @@ public function switch(Server $server, Site $site): RedirectResponse
|
||||
|
||||
if ($previousRoute->hasParameter('site')) {
|
||||
if (count($previousRoute->parameters()) > 2) {
|
||||
return redirect()->route('sites.show', ['server' => $server->id, 'site' => $site->id]);
|
||||
return redirect()->route('application', ['server' => $server->id, 'site' => $site->id]);
|
||||
}
|
||||
|
||||
return redirect()->route($previousRoute->getName(), ['server' => $server, 'site' => $site->id]);
|
||||
}
|
||||
|
||||
return redirect()->route('sites.show', ['server' => $server->id, 'site' => $site->id]);
|
||||
return redirect()->route('application', ['server' => $server->id, 'site' => $site->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
#[Delete('/servers/{server}/sites/{site}', name: 'sites.destroy')]
|
||||
public function destroy(Server $server, Site $site): RedirectResponse
|
||||
#[Get('/servers/{server}/sites/{site}/logs', name: 'sites.logs')]
|
||||
public function logs(Server $server, Site $site): Response
|
||||
{
|
||||
$this->authorize('delete', [$site, $server]);
|
||||
$this->authorize('view', [$site, $server]);
|
||||
|
||||
app(DeleteSite::class)->delete($site);
|
||||
|
||||
return redirect()->route('sites', ['server' => $server])
|
||||
->with('success', 'Site deleted successfully.');
|
||||
return Inertia::render('sites/logs', [
|
||||
'logs' => ServerLogResource::collection($site->logs()->latest()->simplePaginate(config('web.pagination_size'))),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
110
app/Http/Controllers/SiteSettingController.php
Normal file
110
app/Http/Controllers/SiteSettingController.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Site\DeleteSite;
|
||||
use App\Actions\Site\UpdateBranch;
|
||||
use App\Actions\Site\UpdatePHPVersion;
|
||||
use App\Actions\Site\UpdateSourceControl;
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Http\Resources\SourceControlResource;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Spatie\RouteAttributes\Attributes\Delete;
|
||||
use Spatie\RouteAttributes\Attributes\Get;
|
||||
use Spatie\RouteAttributes\Attributes\Middleware;
|
||||
use Spatie\RouteAttributes\Attributes\Patch;
|
||||
use Spatie\RouteAttributes\Attributes\Prefix;
|
||||
use Spatie\RouteAttributes\Attributes\Put;
|
||||
|
||||
#[Prefix('/servers/{server}/sites/{site}/settings')]
|
||||
#[Middleware(['auth', 'has-project'])]
|
||||
class SiteSettingController extends Controller
|
||||
{
|
||||
#[Get('/', name: 'site-settings')]
|
||||
public function index(Server $server, Site $site): Response
|
||||
{
|
||||
return Inertia::render('site-settings/index', [
|
||||
'sourceControl' => $site->sourceControl ? SourceControlResource::make($site->sourceControl) : null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
#[Patch('/branch', name: 'site-settings.update-branch')]
|
||||
public function updateBranch(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(UpdateBranch::class)->update($site, $request->input());
|
||||
|
||||
return back()->with('success', 'Branch updated successfully.');
|
||||
}
|
||||
|
||||
#[Patch('/source-control', name: 'site-settings.update-source-control')]
|
||||
public function updateSourceControl(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(UpdateSourceControl::class)->update($site, $request->input());
|
||||
|
||||
return back()->with('success', 'Source control updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
#[Patch('/php-version', name: 'site-settings.update-php-version')]
|
||||
public function updatePHPVersion(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
app(UpdatePHPVersion::class)->update($site, $request->input());
|
||||
|
||||
return back()->with('success', 'PHP version updated successfully.');
|
||||
}
|
||||
|
||||
#[Get('/vhost', name: 'site-settings.vhost')]
|
||||
public function vhost(Server $server, Site $site): JsonResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
return response()->json([
|
||||
'vhost' => $site->webserver()->getVHost($site),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Put('/vhost', name: 'site-settings.update-vhost')]
|
||||
public function updateVhost(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('update', [$site, $server]);
|
||||
|
||||
$this->validate($request, [
|
||||
'vhost' => 'required|string',
|
||||
]);
|
||||
|
||||
$site->webserver()->updateVHost($site, $request->input('vhost'));
|
||||
|
||||
return back()->with('success', 'VHost updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
#[Delete('/', name: 'site-settings.destroy')]
|
||||
public function destroy(Request $request, Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', [$site, $server]);
|
||||
|
||||
app(DeleteSite::class)->delete($site, $request->input());
|
||||
|
||||
return redirect()->route('sites', ['server' => $server])
|
||||
->with('success', 'Site deleted successfully.');
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ public function index(Server $server): Response
|
||||
]);
|
||||
}
|
||||
|
||||
#[Get('/sites/{site}/workers', name: 'sites.workers')]
|
||||
#[Get('/sites/{site}/workers', name: 'workers.site')]
|
||||
public function site(Server $server, Site $site): Response
|
||||
{
|
||||
$this->authorize('viewAny', [Worker::class, $server, $site]);
|
||||
|
31
app/Http/Resources/CommandExecutionResource.php
Normal file
31
app/Http/Resources/CommandExecutionResource.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\CommandExecution;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin CommandExecution */
|
||||
class CommandExecutionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'command_id' => $this->command_id,
|
||||
'server_id' => $this->server_id,
|
||||
'user_id' => $this->user_id,
|
||||
'server_log_id' => $this->server_log_id,
|
||||
'log' => ServerLogResource::make($this->serverLog),
|
||||
'variables' => $this->variables,
|
||||
'status' => $this->status,
|
||||
'status_color' => CommandExecution::$statusColors[$this->status] ?? 'gray',
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
];
|
||||
}
|
||||
}
|
28
app/Http/Resources/CommandResource.php
Normal file
28
app/Http/Resources/CommandResource.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\Command;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin Command */
|
||||
class CommandResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'server_id' => $this->site->server_id,
|
||||
'site_id' => $this->site_id,
|
||||
'name' => $this->name,
|
||||
'command' => $this->command,
|
||||
'variables' => $this->getVariables(),
|
||||
'updated_at' => $this->updated_at,
|
||||
'created_at' => $this->created_at,
|
||||
];
|
||||
}
|
||||
}
|
32
app/Http/Resources/DeploymentResource.php
Normal file
32
app/Http/Resources/DeploymentResource.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\Deployment;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin Deployment */
|
||||
class DeploymentResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'site_id' => $this->site_id,
|
||||
'deployment_script_id' => $this->deployment_script_id,
|
||||
'log_id' => $this->log_id,
|
||||
'log' => new ServerLogResource($this->log),
|
||||
'commit_id' => $this->commit_id,
|
||||
'commit_id_short' => $this->commit_id_short,
|
||||
'commit_data' => $this->commit_data,
|
||||
'status' => $this->status,
|
||||
'status_color' => Deployment::$statusColors[$this->status] ?? 'gray',
|
||||
'updated_at' => $this->updated_at,
|
||||
'created_at' => $this->created_at,
|
||||
];
|
||||
}
|
||||
}
|
28
app/Http/Resources/LoadBalancerServerResource.php
Normal file
28
app/Http/Resources/LoadBalancerServerResource.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\LoadBalancerServer;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin LoadBalancerServer */
|
||||
class LoadBalancerServerResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'load_balancer_id' => $this->load_balancer_id,
|
||||
'ip' => $this->ip,
|
||||
'port' => $this->port,
|
||||
'weight' => $this->weight,
|
||||
'backup' => $this->backup,
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
];
|
||||
}
|
||||
}
|
@ -16,11 +16,13 @@ public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'server_id' => $this->site->server_id,
|
||||
'site_id' => $this->site_id,
|
||||
'mode' => $this->mode,
|
||||
'from' => $this->from,
|
||||
'to' => $this->to,
|
||||
'mode' => $this->mode,
|
||||
'status' => $this->status,
|
||||
'status_color' => Redirect::$statusColors[$this->status] ?? 'gray',
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
];
|
||||
|
@ -17,6 +17,7 @@ public function toArray(Request $request): array
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'project_id' => $this->project_id,
|
||||
'services' => $this->services()->pluck('name', 'type'),
|
||||
'user_id' => $this->user_id,
|
||||
'provider_id' => $this->provider_id,
|
||||
'name' => $this->name,
|
||||
|
@ -21,18 +21,22 @@ public function toArray(Request $request): array
|
||||
'source_control_id' => $this->source_control_id,
|
||||
'type' => $this->type,
|
||||
'type_data' => $this->type_data,
|
||||
'features' => $this->type()->supportedFeatures(),
|
||||
'domain' => $this->domain,
|
||||
'aliases' => $this->aliases,
|
||||
'web_directory' => $this->web_directory,
|
||||
'webserver' => $this->webserver()->name(),
|
||||
'path' => $this->path,
|
||||
'php_version' => $this->php_version,
|
||||
'repository' => $this->repository,
|
||||
'branch' => $this->branch,
|
||||
'status' => $this->status,
|
||||
'status_color' => Site::$statusColors[$this->status] ?? 'default',
|
||||
'auto_deploy' => $this->isAutoDeployment(),
|
||||
'port' => $this->port,
|
||||
'user' => $this->user,
|
||||
'url' => $this->getUrl(),
|
||||
'force_ssl' => $this->force_ssl,
|
||||
'progress' => $this->progress,
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
|
31
app/Http/Resources/SslResource.php
Normal file
31
app/Http/Resources/SslResource.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\Ssl;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin Ssl */
|
||||
class SslResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'server_id' => $this->site->server_id,
|
||||
'site_id' => $this->site_id,
|
||||
'is_active' => $this->is_active,
|
||||
'type' => $this->type,
|
||||
'status' => $this->status,
|
||||
'log' => $this->log_id ? ServerLogResource::make($this->log) : null,
|
||||
'status_color' => Ssl::$statusColors[$this->status] ?? 'secondary',
|
||||
'expires_at' => $this->expires_at,
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
];
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Database\Factories\CommandFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -22,7 +23,7 @@
|
||||
*/
|
||||
class Command extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\CommandFactory> */
|
||||
/** @use HasFactory<CommandFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Enums\CommandExecutionStatus;
|
||||
use Carbon\Carbon;
|
||||
use Database\Factories\CommandExecutionFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -18,13 +19,13 @@
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Command $command
|
||||
* @property ?ServerLog $serverLog
|
||||
* @property ServerLog $serverLog
|
||||
* @property Server $server
|
||||
* @property ?User $user
|
||||
*/
|
||||
class CommandExecution extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\CommandExecutionFactory> */
|
||||
/** @use HasFactory<CommandExecutionFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\DeploymentStatus;
|
||||
use Database\Factories\DeploymentFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -20,7 +21,7 @@
|
||||
*/
|
||||
class Deployment extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\DeploymentFactory> */
|
||||
/** @use HasFactory<DeploymentFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\DeploymentScriptFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
*/
|
||||
class DeploymentScript extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\DeploymentScriptFactory> */
|
||||
/** @use HasFactory<DeploymentScriptFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected static function boot(): void
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\LoadBalancerServerFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -15,7 +16,7 @@
|
||||
*/
|
||||
class LoadBalancerServer extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\LoadBalancerServerFactory> */
|
||||
/** @use HasFactory<LoadBalancerServerFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Enums\SslStatus;
|
||||
use Carbon\Carbon;
|
||||
use Database\Factories\SslFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
@ -28,7 +29,7 @@
|
||||
*/
|
||||
class Ssl extends AbstractModel
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\SslFactory> */
|
||||
/** @use HasFactory<SslFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\SiteFeature;
|
||||
use App\Models\Command;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
@ -17,7 +16,6 @@ public function viewAny(User $user, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
$site->hasFeature(SiteFeature::COMMANDS) &&
|
||||
$site->isReady();
|
||||
}
|
||||
|
||||
@ -27,7 +25,6 @@ public function view(User $user, Command $command, Site $site, Server $server):
|
||||
$site->server_id === $server->id &&
|
||||
$server->isReady() &&
|
||||
$site->isReady() &&
|
||||
$site->hasFeature(SiteFeature::COMMANDS) &&
|
||||
$command->site_id === $site->id;
|
||||
}
|
||||
|
||||
@ -35,7 +32,6 @@ public function create(User $user, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
$site->hasFeature(SiteFeature::COMMANDS) &&
|
||||
$site->isReady();
|
||||
}
|
||||
|
||||
@ -45,7 +41,6 @@ public function update(User $user, Command $command, Site $site, Server $server)
|
||||
$site->server_id === $server->id &&
|
||||
$server->isReady() &&
|
||||
$site->isReady() &&
|
||||
$site->hasFeature(SiteFeature::COMMANDS) &&
|
||||
$command->site_id === $site->id;
|
||||
}
|
||||
|
||||
@ -55,7 +50,6 @@ public function delete(User $user, Command $command, Site $site, Server $server)
|
||||
$site->server_id === $server->id &&
|
||||
$server->isReady() &&
|
||||
$site->isReady() &&
|
||||
$site->hasFeature(SiteFeature::COMMANDS) &&
|
||||
$command->site_id === $site->id;
|
||||
}
|
||||
}
|
||||
|
@ -2,34 +2,40 @@
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Redirect;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\User;
|
||||
|
||||
class RedirectPolicy
|
||||
{
|
||||
public function view(User $user, Site $site, Server $server): bool
|
||||
public function viewAny(User $user, Site $site, Server $server): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
$site->isReady();
|
||||
}
|
||||
|
||||
return $site->server->project->users->contains($user);
|
||||
public function view(User $user, Redirect $redirect, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $site->server->project->users->contains($user))
|
||||
&& $site->server_id === $server->id
|
||||
&& $site->server->isReady()
|
||||
&& $redirect->site_id === $site->id;
|
||||
}
|
||||
|
||||
public function create(User $user, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $site->server->project->users->contains($user))
|
||||
&& $site->server_id === $server->id
|
||||
&& $site->server->isReady()
|
||||
&& $site->server->webserver();
|
||||
&& $site->server->isReady();
|
||||
}
|
||||
|
||||
public function delete(User $user, Site $site, Server $server): bool
|
||||
public function delete(User $user, Redirect $redirect, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $site->server->project->users->contains($user))
|
||||
&& $site->server_id === $server->id
|
||||
&& $site->server->isReady()
|
||||
&& $site->server->webserver();
|
||||
&& $server->isReady()
|
||||
&& $redirect->site_id === $site->id;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\SiteFeature;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\Ssl;
|
||||
@ -17,7 +16,6 @@ public function viewAny(User $user, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
$site->hasFeature(SiteFeature::SSL) &&
|
||||
$site->isReady();
|
||||
}
|
||||
|
||||
@ -27,7 +25,6 @@ public function view(User $user, Ssl $ssl, Site $site, Server $server): bool
|
||||
$site->server_id === $server->id &&
|
||||
$server->isReady() &&
|
||||
$site->isReady() &&
|
||||
$site->hasFeature(SiteFeature::SSL) &&
|
||||
$ssl->site_id === $site->id;
|
||||
}
|
||||
|
||||
@ -35,18 +32,16 @@ public function create(User $user, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
$site->hasFeature(SiteFeature::SSL) &&
|
||||
$site->isReady();
|
||||
}
|
||||
|
||||
public function update(User $user, Ssl $ssl, Site $site, Server $server): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$site->server_id === $server->id &&
|
||||
$server->isReady() &&
|
||||
$site->isReady() &&
|
||||
$site->hasFeature(SiteFeature::SSL) &&
|
||||
$ssl->site_id === $site->id;
|
||||
$site->server_id === $server->id &&
|
||||
$server->isReady() &&
|
||||
$site->isReady() &&
|
||||
$ssl->site_id === $site->id;
|
||||
}
|
||||
|
||||
public function delete(User $user, Ssl $ssl, Site $site, Server $server): bool
|
||||
@ -55,7 +50,6 @@ public function delete(User $user, Ssl $ssl, Site $site, Server $server): bool
|
||||
$site->server_id === $server->id &&
|
||||
$server->isReady() &&
|
||||
$site->isReady() &&
|
||||
$site->hasFeature(SiteFeature::SSL) &&
|
||||
$ssl->site_id === $site->id;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\SiteFeature;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\User;
|
||||
@ -17,70 +16,37 @@ public function viewAny(User $user, Server $server, ?Site $site = null): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
(
|
||||
! $site instanceof Site ||
|
||||
(
|
||||
$site->hasFeature(SiteFeature::WORKERS) &&
|
||||
$site->isReady()
|
||||
)
|
||||
);
|
||||
$server->processManager();
|
||||
}
|
||||
|
||||
public function view(User $user, Worker $worker, Server $server, ?Site $site = null): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
(
|
||||
! $site instanceof Site ||
|
||||
(
|
||||
$site->server_id === $server->id &&
|
||||
$site->hasFeature(SiteFeature::WORKERS) &&
|
||||
$site->isReady() &&
|
||||
$worker->site_id === $site->id
|
||||
)
|
||||
);
|
||||
$worker->server_id === $server->id &&
|
||||
$server->processManager();
|
||||
}
|
||||
|
||||
public function create(User $user, Server $server, ?Site $site = null): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
(
|
||||
! $site instanceof Site ||
|
||||
(
|
||||
$site->hasFeature(SiteFeature::WORKERS) &&
|
||||
$site->isReady()
|
||||
)
|
||||
);
|
||||
$server->processManager();
|
||||
}
|
||||
|
||||
public function update(User $user, Worker $worker, Server $server, ?Site $site = null): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
(
|
||||
! $site instanceof Site ||
|
||||
(
|
||||
$site->server_id === $server->id &&
|
||||
$site->hasFeature(SiteFeature::WORKERS) &&
|
||||
$site->isReady() &&
|
||||
$worker->site_id === $site->id
|
||||
)
|
||||
);
|
||||
$worker->server_id === $server->id &&
|
||||
$server->processManager();
|
||||
}
|
||||
|
||||
public function delete(User $user, Worker $worker, Server $server, ?Site $site = null): bool
|
||||
{
|
||||
return ($user->isAdmin() || $server->project->users->contains($user)) &&
|
||||
$server->isReady() &&
|
||||
(
|
||||
! $site instanceof Site ||
|
||||
(
|
||||
$site->server_id === $server->id &&
|
||||
$site->hasFeature(SiteFeature::WORKERS) &&
|
||||
$site->isReady() &&
|
||||
$worker->site_id === $site->id
|
||||
)
|
||||
);
|
||||
$worker->server_id === $server->id &&
|
||||
$server->processManager();
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,11 @@
|
||||
|
||||
class Caddy extends AbstractWebserver
|
||||
{
|
||||
public function name(): string
|
||||
{
|
||||
return \App\Enums\Webserver::CADDY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
|
@ -10,6 +10,11 @@
|
||||
|
||||
class Nginx extends AbstractWebserver
|
||||
{
|
||||
public function name(): string
|
||||
{
|
||||
return \App\Enums\Webserver::NGINX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
interface Webserver extends ServiceInterface
|
||||
{
|
||||
public function name(): string;
|
||||
|
||||
public function createVHost(Site $site): void;
|
||||
|
||||
public function updateVHost(Site $site, ?string $vhost = null): void;
|
||||
|
Reference in New Issue
Block a user