mirror of
https://github.com/vitodeploy/vito.git
synced 2025-05-04 07:52:27 +00:00
Compare commits
No commits in common. "1.x" and "1.2.1" have entirely different histories.
.github
README.mdapp
Actions
CronJob
Database
Monitoring
NotificationChannels
PHP
Projects
SSL
Script
Server
ServerProvider
Service
Site
SourceControl
StorageProvider
Tag
User
Console
Enums
CronjobStatus.phpOperatingSystem.phpPHPIniType.phpScriptExecutionStatus.phpServerStatus.phpStorageProvider.phpUserRole.php
Exceptions
Facades
Helpers
Http
Controllers
API
ApplicationController.phpConsoleController.phpCronjobController.phpDatabaseBackupController.phpDatabaseController.phpDatabaseUserController.phpFirewallController.phpMetricController.phpPHPController.phpQueueController.phpSSHKeyController.phpSSLController.phpScriptController.phpSearchController.phpServerController.phpServerLogController.phpServerSettingController.phpServiceController.phpSettings
NotificationChannelController.phpProfileController.phpProjectController.phpSSHKeyController.phpServerProviderController.phpSourceControlController.phpStorageProviderController.phpTagController.phpUserController.php
SiteController.phpSiteLogController.phpSiteSettingController.phpMiddleware
11
.github/ISSUE_TEMPLATE/config.yml
vendored
11
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,11 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Feature request
|
||||
url: https://github.com/vitodeploy/vito/discussions/new?category=ideas
|
||||
about: Share ideas for new features
|
||||
- name: Support
|
||||
url: https://github.com/vitodeploy/vito/discussions/new?category=q-a
|
||||
about: Ask the community for help
|
||||
- name: Discord
|
||||
url: https://discord.gg/uZeeHZZnm5
|
||||
about: Join the community
|
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
To request a feature or suggest an idea please add it to the feedback boards
|
||||
|
||||
https://features.vitodeploy.com/
|
35
.github/workflows/docker-1x.yml
vendored
35
.github/workflows/docker-1x.yml
vendored
@ -1,35 +0,0 @@
|
||||
name: Build and push Docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 1.x
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
docker buildx build . \
|
||||
-f docker/Dockerfile \
|
||||
-t vitodeploy/vito:1.x \
|
||||
--build-arg="RELEASE=0" \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--no-cache \
|
||||
--push
|
35
.github/workflows/docker-release.yml
vendored
35
.github/workflows/docker-release.yml
vendored
@ -1,35 +0,0 @@
|
||||
name: Build and push Docker image
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
docker buildx build . \
|
||||
-f docker/Dockerfile \
|
||||
-t vitodeploy/vito:${{ github.event.release.tag_name }} \
|
||||
-t vitodeploy/vito:latest \
|
||||
--build-arg="RELEASE=0" \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--no-cache \
|
||||
--push
|
@ -1,6 +1,6 @@
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/vitodeploy/vito/assets/61919774/8060fded-58e3-4d58-b58b-5b717b0718e9" alt="VitoDeploy>
|
||||
<img alt="srcshot 2024-02-23 at 16 26 21@2x" src="https://github.com/vitodeploy/vito/assets/61919774/9b3ae8fe-996a-4e10-b42e-74097f8e5512" alt="VitoDeploy>
|
||||
<p align="center">
|
||||
<a href="https://github.com/vitodeploy/vito/actions"><img alt="GitHub Workflow Status" src="https://github.com/vitodeploy/vito/workflows/tests/badge.svg"></a>
|
||||
</p>
|
||||
@ -34,8 +34,9 @@ ## Useful Links
|
||||
- [Documentation](https://vitodeploy.com)
|
||||
- [Install on Server](https://vitodeploy.com/introduction/installation.html#install-on-vps-recommended)
|
||||
- [Install via Docker](https://vitodeploy.com/introduction/installation.html#install-via-docker)
|
||||
- [Roadmap](https://github.com/orgs/vitodeploy/projects/5)
|
||||
- [Video Demo](https://youtu.be/AbmUOBDOc28)
|
||||
- [Feedbacks](https://vitodeploy.featurebase.app)
|
||||
- [Roadmap](https://vitodeploy.featurebase.app/roadmap)
|
||||
- [Video Demo](https://youtu.be/rLRHIyEfON8)
|
||||
- [Discord](https://discord.gg/uZeeHZZnm5)
|
||||
- [Contribution](/CONTRIBUTING.md)
|
||||
- [Security](/SECURITY.md)
|
||||
@ -49,6 +50,8 @@ ## Credits
|
||||
- Alpinejs
|
||||
- HTMX
|
||||
- Vite
|
||||
- Toastr by CodeSeven
|
||||
- Prettier
|
||||
- Postcss
|
||||
- Flowbite
|
||||
- svgrepo.com
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Actions\CronJob;
|
||||
|
||||
use App\Enums\CronjobStatus;
|
||||
use App\Models\CronJob;
|
||||
use App\Models\Server;
|
||||
|
||||
@ -11,9 +10,7 @@ class DeleteCronJob
|
||||
public function delete(Server $server, CronJob $cronJob): void
|
||||
{
|
||||
$user = $cronJob->user;
|
||||
$cronJob->status = CronjobStatus::DELETING;
|
||||
$cronJob->save();
|
||||
$server->cron()->update($cronJob->user, CronJob::crontab($server, $user));
|
||||
$cronJob->delete();
|
||||
$server->cron()->update($cronJob->user, CronJob::crontab($server, $user));
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\CronJob;
|
||||
|
||||
use App\Enums\CronjobStatus;
|
||||
use App\Models\CronJob;
|
||||
use App\Models\Server;
|
||||
|
||||
class DisableCronJob
|
||||
{
|
||||
public function disable(Server $server, CronJob $cronJob): void
|
||||
{
|
||||
$cronJob->status = CronjobStatus::DISABLING;
|
||||
$cronJob->save();
|
||||
|
||||
$server->cron()->update($cronJob->user, CronJob::crontab($server, $cronJob->user));
|
||||
$cronJob->status = CronjobStatus::DISABLED;
|
||||
$cronJob->save();
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\CronJob;
|
||||
|
||||
use App\Enums\CronjobStatus;
|
||||
use App\Models\CronJob;
|
||||
use App\Models\Server;
|
||||
|
||||
class EnableCronJob
|
||||
{
|
||||
public function enable(Server $server, CronJob $cronJob): void
|
||||
{
|
||||
$cronJob->status = CronjobStatus::ENABLING;
|
||||
$cronJob->save();
|
||||
|
||||
$server->cron()->update($cronJob->user, CronJob::crontab($server, $cronJob->user));
|
||||
$cronJob->status = CronjobStatus::READY;
|
||||
$cronJob->save();
|
||||
}
|
||||
}
|
@ -22,9 +22,7 @@ public function create(Server $server, array $input): Database
|
||||
'server_id' => $server->id,
|
||||
'name' => $input['name'],
|
||||
]);
|
||||
/** @var \App\SSH\Services\Database\Database */
|
||||
$databaseHandler = $server->database()->handler();
|
||||
$databaseHandler->create($database->name);
|
||||
$server->database()->handler()->create($database->name);
|
||||
$database->status = DatabaseStatus::READY;
|
||||
$database->save();
|
||||
|
||||
|
@ -1,150 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Monitoring;
|
||||
|
||||
use App\Models\Server;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Database\Query\Expression;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class GetMetrics
|
||||
{
|
||||
public function filter(Server $server, array $input): array
|
||||
{
|
||||
if (isset($input['from']) && isset($input['to']) && $input['from'] === $input['to']) {
|
||||
$input['from'] = Carbon::parse($input['from'])->format('Y-m-d').' 00:00:00';
|
||||
$input['to'] = Carbon::parse($input['to'])->format('Y-m-d').' 23:59:59';
|
||||
}
|
||||
|
||||
$defaultInput = [
|
||||
'period' => '10m',
|
||||
];
|
||||
|
||||
$input = array_merge($defaultInput, $input);
|
||||
|
||||
$this->validate($input);
|
||||
|
||||
return $this->metrics(
|
||||
server: $server,
|
||||
fromDate: $this->getFromDate($input),
|
||||
toDate: $this->getToDate($input),
|
||||
interval: $this->getInterval($input)
|
||||
);
|
||||
}
|
||||
|
||||
private function metrics(
|
||||
Server $server,
|
||||
Carbon $fromDate,
|
||||
Carbon $toDate,
|
||||
?Expression $interval = null
|
||||
): array {
|
||||
$metrics = DB::table('metrics')
|
||||
->where('server_id', $server->id)
|
||||
->whereBetween('created_at', [$fromDate->format('Y-m-d H:i:s'), $toDate->format('Y-m-d H:i:s')])
|
||||
->select(
|
||||
[
|
||||
DB::raw('created_at as date'),
|
||||
DB::raw('ROUND(AVG(load), 2) as load'),
|
||||
DB::raw('ROUND(AVG(memory_total), 2) as memory_total'),
|
||||
DB::raw('ROUND(AVG(memory_used), 2) as memory_used'),
|
||||
DB::raw('ROUND(AVG(memory_free), 2) as memory_free'),
|
||||
DB::raw('ROUND(AVG(disk_total), 2) as disk_total'),
|
||||
DB::raw('ROUND(AVG(disk_used), 2) as disk_used'),
|
||||
DB::raw('ROUND(AVG(disk_free), 2) as disk_free'),
|
||||
$interval,
|
||||
],
|
||||
)
|
||||
->groupByRaw('date_interval')
|
||||
->orderBy('date_interval')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
$item->date = Carbon::parse($item->date)->format('Y-m-d H:i');
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
return [
|
||||
'metrics' => $metrics,
|
||||
];
|
||||
}
|
||||
|
||||
private function getFromDate(array $input): Carbon
|
||||
{
|
||||
if ($input['period'] === 'custom') {
|
||||
return new Carbon($input['from']);
|
||||
}
|
||||
|
||||
return Carbon::parse('-'.convert_time_format($input['period']));
|
||||
}
|
||||
|
||||
private function getToDate(array $input): Carbon
|
||||
{
|
||||
if ($input['period'] === 'custom') {
|
||||
return new Carbon($input['to']);
|
||||
}
|
||||
|
||||
return Carbon::now();
|
||||
}
|
||||
|
||||
private function getInterval(array $input): Expression
|
||||
{
|
||||
if ($input['period'] === 'custom') {
|
||||
$from = new Carbon($input['from']);
|
||||
$to = new Carbon($input['to']);
|
||||
$periodInHours = $from->diffInHours($to);
|
||||
}
|
||||
|
||||
if (! isset($periodInHours)) {
|
||||
$periodInHours = Carbon::parse(
|
||||
convert_time_format($input['period'])
|
||||
)->diffInHours();
|
||||
}
|
||||
|
||||
if (abs($periodInHours) <= 1) {
|
||||
return DB::raw("strftime('%Y-%m-%d %H:%M:00', created_at) as date_interval");
|
||||
}
|
||||
|
||||
if ($periodInHours <= 24) {
|
||||
return DB::raw("strftime('%Y-%m-%d %H:00:00', created_at) as date_interval");
|
||||
}
|
||||
|
||||
if ($periodInHours > 24) {
|
||||
return DB::raw("strftime('%Y-%m-%d 00:00:00', created_at) as date_interval");
|
||||
}
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'period' => [
|
||||
'required',
|
||||
Rule::in([
|
||||
'10m',
|
||||
'30m',
|
||||
'1h',
|
||||
'12h',
|
||||
'1d',
|
||||
'7d',
|
||||
'custom',
|
||||
]),
|
||||
],
|
||||
])->validate();
|
||||
|
||||
if ($input['period'] === 'custom') {
|
||||
Validator::make($input, [
|
||||
'from' => [
|
||||
'required',
|
||||
'date',
|
||||
'before:to',
|
||||
],
|
||||
'to' => [
|
||||
'required',
|
||||
'date',
|
||||
'after:from',
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Monitoring;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateMetricSettings
|
||||
{
|
||||
public function update(Server $server, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$service = $server->monitoring();
|
||||
|
||||
$data = $service->handler()->data();
|
||||
$data['data_retention'] = $input['data_retention'];
|
||||
$service->type_data = $data;
|
||||
$service->save();
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'data_retention' => [
|
||||
'required',
|
||||
Rule::in(config('core.metrics_data_retention')),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ public function add(User $user, array $input): void
|
||||
'user_id' => $user->id,
|
||||
'provider' => $input['provider'],
|
||||
'label' => $input['label'],
|
||||
'project_id' => isset($input['global']) && $input['global'] ? null : $user->current_project_id,
|
||||
]);
|
||||
$this->validateType($channel, $input);
|
||||
$channel->data = $channel->provider()->createData($input);
|
||||
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\NotificationChannels;
|
||||
|
||||
use App\Models\NotificationChannel;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class EditChannel
|
||||
{
|
||||
public function edit(NotificationChannel $notificationChannel, User $user, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$notificationChannel->label = $input['label'];
|
||||
$notificationChannel->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id;
|
||||
|
||||
$notificationChannel->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private function validate(array $input): void
|
||||
{
|
||||
$rules = [
|
||||
'label' => [
|
||||
'required',
|
||||
],
|
||||
];
|
||||
Validator::make($input, $rules)->validate();
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Enums\ServiceStatus;
|
||||
use App\Models\Server;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ChangeDefaultCli
|
||||
@ -13,9 +12,7 @@ public function change(Server $server, array $input): void
|
||||
{
|
||||
$this->validate($server, $input);
|
||||
$service = $server->php($input['version']);
|
||||
/** @var PHP $handler */
|
||||
$handler = $service->handler();
|
||||
$handler->setDefaultCli();
|
||||
$service->handler()->setDefaultCli();
|
||||
$server->defaultService('php')->update(['is_default' => 0]);
|
||||
$service->update(['is_default' => 1]);
|
||||
$service->update(['status' => ServiceStatus::READY]);
|
||||
|
@ -2,11 +2,7 @@
|
||||
|
||||
namespace App\Actions\PHP;
|
||||
|
||||
use App\Enums\PHPIniType;
|
||||
use App\Models\Server;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class GetPHPIni
|
||||
@ -18,10 +14,7 @@ public function getIni(Server $server, array $input): string
|
||||
$php = $server->php($input['version']);
|
||||
|
||||
try {
|
||||
/** @var PHP $handler */
|
||||
$handler = $php->handler();
|
||||
|
||||
return $handler->getPHPIni($input['type']);
|
||||
return $php->handler()->getPHPIni();
|
||||
} catch (\Throwable $e) {
|
||||
throw ValidationException::withMessages(
|
||||
['ini' => $e->getMessage()]
|
||||
@ -31,13 +24,6 @@ public function getIni(Server $server, array $input): string
|
||||
|
||||
public function validate(Server $server, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'type' => [
|
||||
'required',
|
||||
Rule::in([PHPIniType::CLI, PHPIniType::FPM]),
|
||||
],
|
||||
])->validate();
|
||||
|
||||
if (! isset($input['version']) || ! in_array($input['version'], $server->installedPHPVersions())) {
|
||||
throw ValidationException::withMessages(
|
||||
['version' => __('This version is not installed')]
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@ -24,9 +23,7 @@ public function install(Server $server, array $input): Service
|
||||
$service->save();
|
||||
|
||||
dispatch(function () use ($service, $input) {
|
||||
/** @var PHP $handler */
|
||||
$handler = $service->handler();
|
||||
$handler->installExtension($input['extension']);
|
||||
$service->handler()->installExtension($input['extension']);
|
||||
})->catch(function () use ($service, $input) {
|
||||
$service->refresh();
|
||||
$typeData = $service->type_data;
|
||||
|
@ -2,13 +2,10 @@
|
||||
|
||||
namespace App\Actions\PHP;
|
||||
|
||||
use App\Enums\PHPIniType;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Throwable;
|
||||
|
||||
@ -25,19 +22,19 @@ public function update(Server $server, array $input): void
|
||||
|
||||
$tmpName = Str::random(10).strtotime('now');
|
||||
try {
|
||||
/** @var FilesystemAdapter $storageDisk */
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
|
||||
$storageDisk = Storage::disk('local');
|
||||
|
||||
$storageDisk->put($tmpName, $input['ini']);
|
||||
$service->server->ssh('root')->upload(
|
||||
$storageDisk->path($tmpName),
|
||||
sprintf('/etc/php/%s/%s/php.ini', $service->version, $input['type'])
|
||||
"/etc/php/$service->version/cli/php.ini"
|
||||
);
|
||||
$this->deleteTempFile($tmpName);
|
||||
} catch (Throwable) {
|
||||
$this->deleteTempFile($tmpName);
|
||||
throw ValidationException::withMessages([
|
||||
'ini' => __("Couldn't update php.ini (:type) file!", ['type' => $input['type']]),
|
||||
'ini' => __("Couldn't update php.ini file!"),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -59,10 +56,6 @@ public function validate(Server $server, array $input): void
|
||||
'string',
|
||||
],
|
||||
'version' => 'required|string',
|
||||
'type' => [
|
||||
'required',
|
||||
Rule::in([PHPIniType::CLI, PHPIniType::FPM]),
|
||||
],
|
||||
])->validate();
|
||||
|
||||
if (! in_array($input['version'], $server->installedPHPVersions())) {
|
||||
|
@ -10,31 +10,26 @@ class CreateProject
|
||||
{
|
||||
public function create(User $user, array $input): Project
|
||||
{
|
||||
if (isset($input['name'])) {
|
||||
$input['name'] = strtolower($input['name']);
|
||||
}
|
||||
|
||||
$this->validate($input);
|
||||
$this->validate($user, $input);
|
||||
|
||||
$project = new Project([
|
||||
'user_id' => $user->id,
|
||||
'name' => $input['name'],
|
||||
]);
|
||||
|
||||
$project->save();
|
||||
|
||||
$project->users()->attach($user);
|
||||
|
||||
return $project;
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
private function validate(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
'unique:projects,name',
|
||||
'unique:projects,name,NULL,id,user_id,'.$user->id,
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
|
@ -17,16 +17,12 @@ public function delete(User $user, Project $project): void
|
||||
}
|
||||
|
||||
if ($user->current_project_id == $project->id) {
|
||||
throw ValidationException::withMessages([
|
||||
'project' => __('Cannot delete your current project.'),
|
||||
]);
|
||||
/** @var Project $randomProject */
|
||||
$randomProject = $user->projects()->where('id', '!=', $project->id)->first();
|
||||
$user->current_project_id = $randomProject->id;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
/** @var Project $randomProject */
|
||||
$randomProject = $user->projects()->where('project_id', '!=', $project->id)->first();
|
||||
$user->current_project_id = $randomProject->id;
|
||||
$user->save();
|
||||
|
||||
$project->delete();
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,6 @@ class UpdateProject
|
||||
{
|
||||
public function update(Project $project, array $input): Project
|
||||
{
|
||||
if (isset($input['name'])) {
|
||||
$input['name'] = strtolower($input['name']);
|
||||
}
|
||||
|
||||
$this->validate($project, $input);
|
||||
|
||||
$project->name = $input['name'];
|
||||
|
@ -6,7 +6,6 @@
|
||||
use App\Enums\SslType;
|
||||
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;
|
||||
@ -28,23 +27,14 @@ public function create(Site $site, array $input): void
|
||||
'expires_at' => $input['type'] === SslType::LETSENCRYPT ? now()->addMonths(3) : $input['expires_at'],
|
||||
'status' => SslStatus::CREATING,
|
||||
]);
|
||||
$ssl->domains = [$site->domain];
|
||||
if (isset($input['aliases']) && $input['aliases']) {
|
||||
$ssl->domains = array_merge($ssl->domains, $site->aliases);
|
||||
}
|
||||
$ssl->save();
|
||||
|
||||
dispatch(function () use ($site, $ssl) {
|
||||
/** @var Webserver $webserver */
|
||||
$webserver = $site->server->webserver()->handler();
|
||||
$webserver->setupSSL($ssl);
|
||||
$site->server->webserver()->handler()->setupSSL($ssl);
|
||||
$ssl->status = SslStatus::CREATED;
|
||||
$ssl->save();
|
||||
$site->type()->edit();
|
||||
})->catch(function () use ($ssl) {
|
||||
$ssl->status = SslStatus::FAILED;
|
||||
$ssl->save();
|
||||
})->onConnection('ssh');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Script;
|
||||
|
||||
use App\Models\Script;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class CreateScript
|
||||
{
|
||||
public function create(User $user, array $input): Script
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$script = new Script([
|
||||
'user_id' => $user->id,
|
||||
'name' => $input['name'],
|
||||
'content' => $input['content'],
|
||||
]);
|
||||
$script->save();
|
||||
|
||||
return $script;
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'content' => ['required', 'string'],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Script;
|
||||
|
||||
use App\Models\Script;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class EditScript
|
||||
{
|
||||
public function edit(Script $script, array $input): Script
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$script->name = $input['name'];
|
||||
$script->content = $input['content'];
|
||||
$script->save();
|
||||
|
||||
return $script;
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'content' => ['required', 'string'],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Script;
|
||||
|
||||
use App\Enums\ScriptExecutionStatus;
|
||||
use App\Models\Script;
|
||||
use App\Models\ScriptExecution;
|
||||
use App\Models\Server;
|
||||
use App\Models\ServerLog;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class ExecuteScript
|
||||
{
|
||||
public function execute(Script $script, Server $server, array $input): ScriptExecution
|
||||
{
|
||||
$this->validate($server, $input);
|
||||
|
||||
$execution = new ScriptExecution([
|
||||
'script_id' => $script->id,
|
||||
'user' => $input['user'],
|
||||
'variables' => $input['variables'] ?? [],
|
||||
'status' => ScriptExecutionStatus::EXECUTING,
|
||||
]);
|
||||
$execution->save();
|
||||
|
||||
dispatch(function () use ($execution, $server, $script) {
|
||||
$content = $execution->getContent();
|
||||
$log = ServerLog::make($server, 'script-'.$script->id.'-'.strtotime('now'));
|
||||
$log->save();
|
||||
$execution->server_log_id = $log->id;
|
||||
$execution->save();
|
||||
$server->os()->runScript('~/', $content, $log, $execution->user);
|
||||
$execution->status = ScriptExecutionStatus::COMPLETED;
|
||||
$execution->save();
|
||||
})->catch(function () use ($execution) {
|
||||
$execution->status = ScriptExecutionStatus::FAILED;
|
||||
$execution->save();
|
||||
})->onConnection('ssh');
|
||||
|
||||
return $execution;
|
||||
}
|
||||
|
||||
private function validate(Server $server, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'user' => [
|
||||
'required',
|
||||
Rule::in([
|
||||
'root',
|
||||
$server->ssh_user,
|
||||
]),
|
||||
],
|
||||
'variables' => 'array',
|
||||
'variables.*' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Enums\ServerStatus;
|
||||
use App\Facades\Notifier;
|
||||
use App\Models\Server;
|
||||
use App\Notifications\ServerDisconnected;
|
||||
@ -16,12 +15,12 @@ public function check(Server $server): Server
|
||||
try {
|
||||
$server->ssh()->connect();
|
||||
$server->refresh();
|
||||
if (in_array($status, [ServerStatus::DISCONNECTED, ServerStatus::UPDATING])) {
|
||||
$server->status = ServerStatus::READY;
|
||||
if ($status == 'disconnected') {
|
||||
$server->status = 'ready';
|
||||
$server->save();
|
||||
}
|
||||
} catch (Throwable) {
|
||||
$server->status = ServerStatus::DISCONNECTED;
|
||||
$server->status = 'disconnected';
|
||||
$server->save();
|
||||
Notifier::send($server, new ServerDisconnected($server));
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class CreateServerLog
|
||||
{
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function create(Server $server, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$server->logs()->create([
|
||||
'is_remote' => true,
|
||||
'name' => $input['path'],
|
||||
'type' => 'remote',
|
||||
'disk' => 'ssh',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
protected function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'path' => 'required',
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Enums\ServerStatus;
|
||||
use App\Facades\Notifier;
|
||||
use App\Models\Server;
|
||||
use App\Notifications\ServerUpdateFailed;
|
||||
|
||||
class Update
|
||||
{
|
||||
public function update(Server $server): void
|
||||
{
|
||||
$server->status = ServerStatus::UPDATING;
|
||||
$server->save();
|
||||
dispatch(function () use ($server) {
|
||||
$server->os()->upgrade();
|
||||
$server->checkConnection();
|
||||
$server->checkForUpdates();
|
||||
})->catch(function () use ($server) {
|
||||
Notifier::send($server, new ServerUpdateFailed($server));
|
||||
$server->checkConnection();
|
||||
})->onConnection('ssh');
|
||||
}
|
||||
}
|
@ -38,7 +38,6 @@ public function create(User $user, array $input): ServerProvider
|
||||
$serverProvider->profile = $input['name'];
|
||||
$serverProvider->provider = $input['provider'];
|
||||
$serverProvider->credentials = $provider->credentialData($input);
|
||||
$serverProvider->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id;
|
||||
$serverProvider->save();
|
||||
|
||||
return $serverProvider;
|
||||
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\ServerProvider;
|
||||
|
||||
use App\Models\ServerProvider;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class EditServerProvider
|
||||
{
|
||||
public function edit(ServerProvider $serverProvider, User $user, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$serverProvider->profile = $input['name'];
|
||||
$serverProvider->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id;
|
||||
|
||||
$serverProvider->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private function validate(array $input): void
|
||||
{
|
||||
$rules = [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
];
|
||||
Validator::make($input, $rules)->validate();
|
||||
}
|
||||
}
|
@ -8,15 +8,14 @@
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class Install
|
||||
class Create
|
||||
{
|
||||
public function install(Server $server, array $input): Service
|
||||
public function create(Server $server, array $input): Service
|
||||
{
|
||||
$this->validate($server, $input);
|
||||
|
||||
$service = new Service([
|
||||
'server_id' => $server->id,
|
||||
'name' => $input['name'],
|
||||
'name' => $input['type'],
|
||||
'type' => $input['type'],
|
||||
'version' => $input['version'],
|
||||
'status' => ServiceStatus::INSTALLING,
|
||||
@ -28,13 +27,15 @@ public function install(Server $server, array $input): Service
|
||||
|
||||
$service->save();
|
||||
|
||||
$service->handler()->create();
|
||||
|
||||
dispatch(function () use ($service) {
|
||||
$service->handler()->install();
|
||||
$service->status = ServiceStatus::READY;
|
||||
$service->save();
|
||||
})->catch(function () use ($service) {
|
||||
$service->status = ServiceStatus::INSTALLATION_FAILED;
|
||||
$service->save();
|
||||
$service->handler()->delete();
|
||||
$service->delete();
|
||||
})->onConnection('ssh');
|
||||
|
||||
return $service;
|
||||
@ -45,11 +46,8 @@ private function validate(Server $server, array $input): void
|
||||
Validator::make($input, [
|
||||
'type' => [
|
||||
'required',
|
||||
Rule::in(config('core.service_types')),
|
||||
],
|
||||
'name' => [
|
||||
'required',
|
||||
Rule::in(array_keys(config('core.service_types'))),
|
||||
Rule::in(config('core.add_on_services')),
|
||||
Rule::unique('services', 'type')->where('server_id', $server->id),
|
||||
],
|
||||
'version' => 'required',
|
||||
])->validate();
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Service;
|
||||
|
||||
use App\Enums\ServiceStatus;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class Uninstall
|
||||
{
|
||||
public function uninstall(Service $service): void
|
||||
{
|
||||
Validator::make([
|
||||
'service' => $service->id,
|
||||
], $service->handler()->deletionRules())->validate();
|
||||
|
||||
$service->status = ServiceStatus::UNINSTALLING;
|
||||
$service->save();
|
||||
|
||||
dispatch(function () use ($service) {
|
||||
$service->handler()->uninstall();
|
||||
$service->delete();
|
||||
})->catch(function () use ($service) {
|
||||
$service->status = ServiceStatus::FAILED;
|
||||
$service->save();
|
||||
})->onConnection('ssh');
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
class CreateSite
|
||||
{
|
||||
/**
|
||||
* @throws SourceControlIsNotConnected
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function create(Server $server, array $input): Site
|
||||
{
|
||||
@ -33,7 +33,7 @@ public function create(Server $server, array $input): Site
|
||||
'server_id' => $server->id,
|
||||
'type' => $input['type'],
|
||||
'domain' => $input['domain'],
|
||||
'aliases' => $input['aliases'] ?? [],
|
||||
'aliases' => isset($input['alias']) ? [$input['alias']] : [],
|
||||
'path' => '/home/'.$server->getSshUser().'/'.$input['domain'],
|
||||
'status' => SiteStatus::INSTALLING,
|
||||
]);
|
||||
@ -115,7 +115,7 @@ private function validateInputs(Server $server, array $input): void
|
||||
return $query->where('server_id', $server->id);
|
||||
}),
|
||||
],
|
||||
'aliases.*' => [
|
||||
'alias' => [
|
||||
new DomainRule(),
|
||||
],
|
||||
];
|
||||
|
@ -6,7 +6,6 @@
|
||||
use App\Exceptions\DeploymentScriptIsEmptyException;
|
||||
use App\Exceptions\SourceControlIsNotConnected;
|
||||
use App\Models\Deployment;
|
||||
use App\Models\ServerLog;
|
||||
use App\Models\Site;
|
||||
|
||||
class Deploy
|
||||
@ -30,7 +29,7 @@ public function run(Site $site): Deployment
|
||||
'deployment_script_id' => $site->deploymentScript->id,
|
||||
'status' => DeploymentStatus::DEPLOYING,
|
||||
]);
|
||||
$lastCommit = $site->sourceControl()?->provider()?->getLastCommit($site->repository, $site->branch);
|
||||
$lastCommit = $site->sourceControl()->provider()->getLastCommit($site->repository, $site->branch);
|
||||
if ($lastCommit) {
|
||||
$deployment->commit_id = $lastCommit['commit_id'];
|
||||
$deployment->commit_data = $lastCommit['commit_data'];
|
||||
@ -38,19 +37,9 @@ public function run(Site $site): Deployment
|
||||
$deployment->save();
|
||||
|
||||
dispatch(function () use ($site, $deployment) {
|
||||
/** @var ServerLog $log */
|
||||
$log = ServerLog::make($site->server, 'deploy-'.strtotime('now'))
|
||||
->forSite($site);
|
||||
$log->save();
|
||||
$deployment->log_id = $log->id;
|
||||
$deployment->save();
|
||||
$site->server->os()->runScript(
|
||||
path: $site->path,
|
||||
script: $site->deploymentScript->content,
|
||||
serverLog: $log,
|
||||
variables: $site->environmentVariables($deployment)
|
||||
);
|
||||
$log = $site->server->os()->runScript($site->path, $site->deploymentScript->content, $site->id);
|
||||
$deployment->status = DeploymentStatus::FINISHED;
|
||||
$deployment->log_id = $log->id;
|
||||
$deployment->save();
|
||||
})->catch(function () use ($deployment) {
|
||||
$deployment->status = DeploymentStatus::FAILED;
|
||||
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Site;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\ValidationRules\DomainRule;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateAliases
|
||||
{
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$site->aliases = $input['aliases'] ?? [];
|
||||
|
||||
/** @var Webserver $webserver */
|
||||
$webserver = $site->server->webserver()->handler();
|
||||
$webserver->updateVHost($site, ! $site->hasSSL());
|
||||
|
||||
$site->save();
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'aliases.*' => [
|
||||
new DomainRule(),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -2,14 +2,10 @@
|
||||
|
||||
namespace App\Actions\Site;
|
||||
|
||||
use App\Exceptions\SSHUploadFailed;
|
||||
use App\Models\Site;
|
||||
|
||||
class UpdateEnv
|
||||
{
|
||||
/**
|
||||
* @throws SSHUploadFailed
|
||||
*/
|
||||
public function update(Site $site, array $input): void
|
||||
{
|
||||
$site->server->os()->editFile(
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace App\Actions\SourceControl;
|
||||
|
||||
use App\Models\SourceControl;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
@ -11,7 +10,7 @@
|
||||
|
||||
class ConnectSourceControl
|
||||
{
|
||||
public function connect(User $user, array $input): void
|
||||
public function connect(array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
@ -19,7 +18,6 @@ public function connect(User $user, array $input): void
|
||||
'provider' => $input['provider'],
|
||||
'profile' => $input['name'],
|
||||
'url' => Arr::has($input, 'url') ? $input['url'] : null,
|
||||
'project_id' => isset($input['global']) && $input['global'] ? null : $user->current_project_id,
|
||||
]);
|
||||
|
||||
$this->validateProvider($sourceControl, $input);
|
||||
|
@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\SourceControl;
|
||||
|
||||
use App\Models\SourceControl;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class EditSourceControl
|
||||
{
|
||||
public function edit(SourceControl $sourceControl, User $user, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$sourceControl->profile = $input['name'];
|
||||
$sourceControl->url = $input['url'] ?? null;
|
||||
$sourceControl->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id;
|
||||
|
||||
$this->validateProvider($sourceControl, $input);
|
||||
|
||||
$sourceControl->provider_data = $sourceControl->provider()->createData($input);
|
||||
|
||||
if (! $sourceControl->provider()->connect()) {
|
||||
throw ValidationException::withMessages([
|
||||
'token' => __('Cannot connect to :provider or invalid token!', ['provider' => $sourceControl->provider]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
$sourceControl->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private function validate(array $input): void
|
||||
{
|
||||
$rules = [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
];
|
||||
Validator::make($input, $rules)->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private function validateProvider(SourceControl $sourceControl, array $input): void
|
||||
{
|
||||
Validator::make($input, $sourceControl->provider()->createRules($input))->validate();
|
||||
}
|
||||
}
|
@ -21,7 +21,6 @@ public function create(User $user, array $input): void
|
||||
'user_id' => $user->id,
|
||||
'provider' => $input['provider'],
|
||||
'profile' => $input['name'],
|
||||
'project_id' => isset($input['global']) && $input['global'] ? null : $user->current_project_id,
|
||||
]);
|
||||
|
||||
$this->validateProvider($input, $storageProvider->provider()->validationRules());
|
||||
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\StorageProvider;
|
||||
|
||||
use App\Models\StorageProvider;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class EditStorageProvider
|
||||
{
|
||||
public function edit(StorageProvider $storageProvider, User $user, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$storageProvider->profile = $input['name'];
|
||||
$storageProvider->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id;
|
||||
|
||||
$storageProvider->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private function validate(array $input): void
|
||||
{
|
||||
$rules = [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
];
|
||||
Validator::make($input, $rules)->validate();
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Tag;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\Tag;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class AttachTag
|
||||
{
|
||||
public function attach(User $user, array $input): Tag
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
/** @var Server|Site $taggable */
|
||||
$taggable = $input['taggable_type']::findOrFail($input['taggable_id']);
|
||||
|
||||
$tag = Tag::query()->where('name', $input['name'])->first();
|
||||
if ($tag) {
|
||||
if (! $taggable->tags->contains($tag->id)) {
|
||||
$taggable->tags()->attach($tag->id);
|
||||
}
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
$tag = new Tag([
|
||||
'project_id' => $user->currentProject->id,
|
||||
'name' => $input['name'],
|
||||
'color' => config('core.tag_colors')[array_rand(config('core.tag_colors'))],
|
||||
]);
|
||||
$tag->save();
|
||||
|
||||
$taggable->tags()->attach($tag->id);
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
'taggable_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
],
|
||||
'taggable_type' => [
|
||||
'required',
|
||||
Rule::in(config('core.taggable_types')),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Tag;
|
||||
|
||||
use App\Models\Tag;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class CreateTag
|
||||
{
|
||||
public function create(User $user, array $input): Tag
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$tag = Tag::query()
|
||||
->where('project_id', $user->current_project_id)
|
||||
->where('name', $input['name'])
|
||||
->first();
|
||||
if ($tag) {
|
||||
throw ValidationException::withMessages([
|
||||
'name' => ['Tag with this name already exists.'],
|
||||
]);
|
||||
}
|
||||
|
||||
$tag = new Tag([
|
||||
'project_id' => $user->currentProject->id,
|
||||
'name' => $input['name'],
|
||||
'color' => $input['color'],
|
||||
]);
|
||||
$tag->save();
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
'color' => [
|
||||
'required',
|
||||
Rule::in(config('core.tag_colors')),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Tag;
|
||||
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DeleteTag
|
||||
{
|
||||
public function delete(Tag $tag): void
|
||||
{
|
||||
DB::table('taggables')->where('tag_id', $tag->id)->delete();
|
||||
$tag->delete();
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Tag;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class DetachTag
|
||||
{
|
||||
public function detach(Tag $tag, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
/** @var Server|Site $taggable */
|
||||
$taggable = $input['taggable_type']::findOrFail($input['taggable_id']);
|
||||
|
||||
$taggable->tags()->detach($tag->id);
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'taggable_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
],
|
||||
'taggable_type' => [
|
||||
'required',
|
||||
Rule::in(config('core.taggable_types')),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Tag;
|
||||
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class EditTag
|
||||
{
|
||||
public function edit(Tag $tag, array $input): void
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
$tag->name = $input['name'];
|
||||
$tag->color = $input['color'];
|
||||
|
||||
$tag->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private function validate(array $input): void
|
||||
{
|
||||
$rules = [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
'color' => [
|
||||
'required',
|
||||
Rule::in(config('core.tag_colors')),
|
||||
],
|
||||
];
|
||||
Validator::make($input, $rules)->validate();
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\User;
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CreateUser
|
||||
{
|
||||
public function create(array $input): User
|
||||
{
|
||||
$this->validate($input);
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::query()->create([
|
||||
'name' => $input['name'],
|
||||
'email' => $input['email'],
|
||||
'role' => $input['role'],
|
||||
'password' => bcrypt($input['password']),
|
||||
'timezone' => 'UTC',
|
||||
]);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
private function validate(array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => 'required|string|max:255',
|
||||
'email' => 'required|email|unique:users,email',
|
||||
'password' => 'required|string|min:8',
|
||||
'role' => [
|
||||
'required',
|
||||
Rule::in([UserRole::ADMIN, UserRole::USER]),
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\User;
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateUser
|
||||
{
|
||||
public function update(User $user, array $input): void
|
||||
{
|
||||
$this->validate($user, $input);
|
||||
|
||||
$user->name = $input['name'];
|
||||
$user->email = $input['email'];
|
||||
$user->timezone = $input['timezone'];
|
||||
$user->role = $input['role'];
|
||||
|
||||
if (isset($input['password']) && $input['password'] !== null) {
|
||||
$user->password = bcrypt($input['password']);
|
||||
}
|
||||
|
||||
$user->save();
|
||||
}
|
||||
|
||||
private function validate(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
|
||||
'timezone' => [
|
||||
'required',
|
||||
Rule::in(timezone_identifiers_list()),
|
||||
],
|
||||
'role' => [
|
||||
'required',
|
||||
Rule::in([UserRole::ADMIN, UserRole::USER]),
|
||||
function ($attribute, $value, $fail) use ($user) {
|
||||
if ($user->is(auth()->user()) && $value !== $user->role) {
|
||||
$fail('You cannot change your own role');
|
||||
}
|
||||
},
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
class CreateUserCommand extends Command
|
||||
{
|
||||
protected $signature = 'user:create {name} {email} {password} {--role=admin}';
|
||||
protected $signature = 'user:create {name} {email} {password}';
|
||||
|
||||
protected $description = 'Create a new user';
|
||||
|
||||
@ -25,7 +25,6 @@ public function handle(): void
|
||||
'name' => $this->argument('name'),
|
||||
'email' => $this->argument('email'),
|
||||
'password' => bcrypt($this->argument('password')),
|
||||
'role' => $this->option('role'),
|
||||
]);
|
||||
|
||||
$this->info('User created!');
|
||||
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Service;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class DeleteOlderMetricsCommand extends Command
|
||||
{
|
||||
protected $signature = 'metrics:delete-older-metrics';
|
||||
|
||||
protected $description = 'Delete older metrics from database';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
Service::query()->where('type', 'monitoring')->chunk(100, function ($services) {
|
||||
$services->each(function ($service) {
|
||||
$this->info("Deleting older metrics for service {$service->server->name}");
|
||||
$service
|
||||
->server
|
||||
->metrics()
|
||||
->where('created_at', '<', now()->subDays($service->handler()->data()['data_retention']))
|
||||
->delete();
|
||||
$this->info('Metrics deleted');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class GetMetricsCommand extends Command
|
||||
{
|
||||
protected $signature = 'metrics:get';
|
||||
|
||||
protected $description = 'Get server metrics';
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$checkedMetrics = 0;
|
||||
Server::query()->whereHas('services', function (Builder $query) {
|
||||
$query->where('type', 'monitoring')
|
||||
->where('name', 'remote-monitor');
|
||||
})->chunk(10, function ($servers) use (&$checkedMetrics) {
|
||||
/** @var Server $server */
|
||||
foreach ($servers as $server) {
|
||||
$info = $server->os()->resourceInfo();
|
||||
$server->metrics()->create(array_merge($info, ['server_id' => $server->id]));
|
||||
$checkedMetrics++;
|
||||
}
|
||||
});
|
||||
$this->info("Checked $checkedMetrics metrics");
|
||||
}
|
||||
}
|
@ -16,8 +16,6 @@ protected function schedule(Schedule $schedule): void
|
||||
$schedule->command('backups:run "0 0 * * *"')->daily();
|
||||
$schedule->command('backups:run "0 0 * * 0"')->weekly();
|
||||
$schedule->command('backups:run "0 0 1 * *"')->monthly();
|
||||
$schedule->command('metrics:delete-older-metrics')->daily();
|
||||
$schedule->command('metrics:get')->everyMinute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,10 +9,4 @@ final class CronjobStatus
|
||||
const READY = 'ready';
|
||||
|
||||
const DELETING = 'deleting';
|
||||
|
||||
const ENABLING = 'enabling';
|
||||
|
||||
const DISABLING = 'disabling';
|
||||
|
||||
const DISABLED = 'disabled';
|
||||
}
|
||||
|
@ -9,6 +9,4 @@ final class OperatingSystem
|
||||
const UBUNTU20 = 'ubuntu_20';
|
||||
|
||||
const UBUNTU22 = 'ubuntu_22';
|
||||
|
||||
const UBUNTU24 = 'ubuntu_24';
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
final class PHPIniType
|
||||
{
|
||||
const CLI = 'cli';
|
||||
|
||||
const FPM = 'fpm';
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
final class ScriptExecutionStatus
|
||||
{
|
||||
const EXECUTING = 'executing';
|
||||
|
||||
const COMPLETED = 'completed';
|
||||
|
||||
const FAILED = 'failed';
|
||||
}
|
@ -11,6 +11,4 @@ final class ServerStatus
|
||||
const INSTALLATION_FAILED = 'installation_failed';
|
||||
|
||||
const DISCONNECTED = 'disconnected';
|
||||
|
||||
const UPDATING = 'updating';
|
||||
}
|
||||
|
@ -7,10 +7,4 @@ final class StorageProvider
|
||||
const DROPBOX = 'dropbox';
|
||||
|
||||
const FTP = 'ftp';
|
||||
|
||||
const LOCAL = 'local';
|
||||
|
||||
const S3 = 's3';
|
||||
|
||||
const WASABI = 'wasabi';
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
final class UserRole
|
||||
{
|
||||
const USER = 'user';
|
||||
|
||||
const ADMIN = 'admin';
|
||||
}
|
@ -4,4 +4,6 @@
|
||||
|
||||
use Exception;
|
||||
|
||||
class DeploymentScriptIsEmptyException extends Exception {}
|
||||
class DeploymentScriptIsEmptyException extends Exception
|
||||
{
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
class SSHUploadFailed extends SSHError
|
||||
{
|
||||
//
|
||||
}
|
@ -4,4 +4,6 @@
|
||||
|
||||
use Exception;
|
||||
|
||||
class SourceControlIsNotConnected extends Exception {}
|
||||
class SourceControlIsNotConnected extends Exception
|
||||
{
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facades;
|
||||
|
||||
use App\Support\Testing\FTPFake;
|
||||
use FTP\Connection;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @method static bool|Connection connect(string $host, string $port, bool $ssl = false)
|
||||
* @method static bool login(string $username, string $password, bool|Connection $connection)
|
||||
* @method static void close(bool|Connection $connection)
|
||||
* @method static bool passive(bool|Connection $connection, bool $passive)
|
||||
* @method static bool delete(bool|Connection $connection, string $path)
|
||||
* @method static void assertConnected(string $host)
|
||||
*/
|
||||
class FTP extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor(): string
|
||||
{
|
||||
return 'ftp';
|
||||
}
|
||||
|
||||
public static function fake(): FTPFake
|
||||
{
|
||||
static::swap($fake = new FTPFake());
|
||||
|
||||
return $fake;
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
namespace App\Facades;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\ServerLog;
|
||||
use App\Support\Testing\SSHFake;
|
||||
use Illuminate\Support\Facades\Facade as FacadeAlias;
|
||||
|
||||
@ -11,13 +10,11 @@
|
||||
* Class SSH
|
||||
*
|
||||
* @method static init(Server $server, string $asUser = null)
|
||||
* @method static setLog(?ServerLog $log)
|
||||
* @method static setLog(string $logType, int $siteId = null)
|
||||
* @method static connect()
|
||||
* @method static string exec(string $command, string $log = '', int $siteId = null, ?bool $stream = false)
|
||||
* @method static string assertExecuted(array|string $commands)
|
||||
* @method static string assertExecutedContains(string $command)
|
||||
* @method static string assertFileUploaded(string $toPath, ?string $content = null)
|
||||
* @method static string getUploadedLocalPath()
|
||||
* @method static disconnect()
|
||||
*/
|
||||
class SSH extends FacadeAlias
|
||||
|
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use FTP\Connection;
|
||||
|
||||
class FTP
|
||||
{
|
||||
public function connect(string $host, string $port, bool $ssl = false): bool|Connection
|
||||
{
|
||||
if ($ssl) {
|
||||
return ftp_ssl_connect($host, $port, 5);
|
||||
}
|
||||
|
||||
return ftp_connect($host, $port, 5);
|
||||
}
|
||||
|
||||
public function login(string $username, string $password, bool|Connection $connection): bool
|
||||
{
|
||||
return ftp_login($connection, $username, $password);
|
||||
}
|
||||
|
||||
public function close(bool|Connection $connection): void
|
||||
{
|
||||
ftp_close($connection);
|
||||
}
|
||||
|
||||
public function passive(bool|Connection $connection, bool $passive): bool
|
||||
{
|
||||
return ftp_pasv($connection, $passive);
|
||||
}
|
||||
|
||||
public function delete(bool|Connection $connection, string $path): bool
|
||||
{
|
||||
return ftp_delete($connection, $path);
|
||||
}
|
||||
}
|
@ -50,9 +50,14 @@ public function init(Server $server, ?string $asUser = null): self
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLog(ServerLog $log): self
|
||||
public function setLog(string $logType, $siteId = null): self
|
||||
{
|
||||
$this->log = $log;
|
||||
$this->log = $this->server->logs()->create([
|
||||
'site_id' => $siteId,
|
||||
'name' => $this->server->id.'-'.strtotime('now').'-'.$logType.'.log',
|
||||
'type' => $logType,
|
||||
'disk' => config('core.logs_disk'),
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -93,12 +98,10 @@ public function connect(bool $sftp = false): void
|
||||
*/
|
||||
public function exec(string $command, string $log = '', ?int $siteId = null, ?bool $stream = false): string
|
||||
{
|
||||
if (! $this->log && $log) {
|
||||
$this->log = ServerLog::make($this->server, $log);
|
||||
if ($siteId) {
|
||||
$this->log->forSite($siteId);
|
||||
}
|
||||
$this->log->save();
|
||||
if ($log) {
|
||||
$this->setLog($log, $siteId);
|
||||
} else {
|
||||
$this->log = null;
|
||||
}
|
||||
|
||||
try {
|
||||
@ -129,8 +132,8 @@ public function exec(string $command, string $log = '', ?int $siteId = null, ?bo
|
||||
|
||||
$this->log?->write($output);
|
||||
|
||||
if ($this->connection->getExitStatus() !== 0 || Str::contains($output, 'VITO_SSH_ERROR')) {
|
||||
throw new SSHCommandError('SSH command failed with an error', $this->connection->getExitStatus());
|
||||
if (Str::contains($output, 'VITO_SSH_ERROR')) {
|
||||
throw new SSHCommandError('SSH command failed with an error');
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AgentController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request, Server $server, int $id): JsonResponse
|
||||
{
|
||||
$validated = $this->validate($request, [
|
||||
'load' => 'required|numeric',
|
||||
'memory_total' => 'required|numeric',
|
||||
'memory_used' => 'required|numeric',
|
||||
'memory_free' => 'required|numeric',
|
||||
'disk_total' => 'required|numeric',
|
||||
'disk_used' => 'required|numeric',
|
||||
'disk_free' => 'required|numeric',
|
||||
]);
|
||||
|
||||
/** @var Service $service */
|
||||
$service = $server->services()->findOrFail($id);
|
||||
|
||||
if ($request->header('secret') !== $service->handler()->data()['secret']) {
|
||||
return response()->json(['error' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
$server->metrics()->create(array_merge($validated, ['server_id' => $server->id]));
|
||||
|
||||
return response()->json();
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
use App\Exceptions\RepositoryNotFound;
|
||||
use App\Exceptions\RepositoryPermissionDenied;
|
||||
use App\Exceptions\SourceControlIsNotConnected;
|
||||
use App\Exceptions\SSHUploadFailed;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\Deployment;
|
||||
@ -23,8 +22,6 @@ class ApplicationController extends Controller
|
||||
{
|
||||
public function deploy(Server $server, Site $site): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
try {
|
||||
app(Deploy::class)->run($site);
|
||||
|
||||
@ -44,15 +41,11 @@ public function deploy(Server $server, Site $site): HtmxResponse
|
||||
|
||||
public function showDeploymentLog(Server $server, Site $site, Deployment $deployment): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return back()->with('content', $deployment->log?->getContent());
|
||||
}
|
||||
|
||||
public function updateDeploymentScript(Server $server, Site $site, Request $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(UpdateDeploymentScript::class)->update($site, $request->input());
|
||||
|
||||
Toast::success('Deployment script updated!');
|
||||
@ -62,8 +55,6 @@ public function updateDeploymentScript(Server $server, Site $site, Request $requ
|
||||
|
||||
public function updateBranch(Server $server, Site $site, Request $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(UpdateBranch::class)->update($site, $request->input());
|
||||
|
||||
Toast::success('Branch updated!');
|
||||
@ -73,29 +64,20 @@ public function updateBranch(Server $server, Site $site, Request $request): Redi
|
||||
|
||||
public function getEnv(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return back()->with('env', $site->getEnv());
|
||||
}
|
||||
|
||||
public function updateEnv(Server $server, Site $site, Request $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
app(UpdateEnv::class)->update($site, $request->input());
|
||||
|
||||
try {
|
||||
app(UpdateEnv::class)->update($site, $request->input());
|
||||
Toast::success('Env updated!');
|
||||
} catch (SSHUploadFailed) {
|
||||
Toast::error('Failed to update .env file!');
|
||||
}
|
||||
Toast::success('Env updated!');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function enableAutoDeployment(Server $server, Site $site): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
if (! $site->isAutoDeployment()) {
|
||||
try {
|
||||
$site->enableAutoDeployment();
|
||||
@ -119,8 +101,6 @@ public function enableAutoDeployment(Server $server, Site $site): HtmxResponse
|
||||
|
||||
public function disableAutoDeployment(Server $server, Site $site): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
if ($site->isAutoDeployment()) {
|
||||
try {
|
||||
$site->disableAutoDeployment();
|
||||
|
@ -11,8 +11,6 @@ class ConsoleController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('console.index', [
|
||||
'server' => $server,
|
||||
]);
|
||||
@ -20,8 +18,6 @@ public function index(Server $server): View
|
||||
|
||||
public function run(Server $server, Request $request)
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$this->validate($request, [
|
||||
'user' => [
|
||||
'required',
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
use App\Actions\CronJob\CreateCronJob;
|
||||
use App\Actions\CronJob\DeleteCronJob;
|
||||
use App\Actions\CronJob\DisableCronJob;
|
||||
use App\Actions\CronJob\EnableCronJob;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\CronJob;
|
||||
@ -18,8 +16,6 @@ class CronjobController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('cronjobs.index', [
|
||||
'server' => $server,
|
||||
'cronjobs' => $server->cronJobs,
|
||||
@ -28,8 +24,6 @@ public function index(Server $server): View
|
||||
|
||||
public function store(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(CreateCronJob::class)->create($server, $request->input());
|
||||
|
||||
Toast::success('Cronjob created successfully.');
|
||||
@ -39,34 +33,10 @@ public function store(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function destroy(Server $server, CronJob $cronJob): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteCronJob::class)->delete($server, $cronJob);
|
||||
|
||||
Toast::success('Cronjob deleted successfully.');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function enable(Server $server, CronJob $cronJob): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(EnableCronJob::class)->enable($server, $cronJob);
|
||||
|
||||
Toast::success('Cronjob enabled successfully.');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function disable(Server $server, CronJob $cronJob): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DisableCronJob::class)->disable($server, $cronJob);
|
||||
|
||||
Toast::success('Cronjob disabled successfully.');
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ class DatabaseBackupController extends Controller
|
||||
{
|
||||
public function show(Server $server, Backup $backup): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('databases.backups', [
|
||||
'server' => $server,
|
||||
'databases' => $server->databases,
|
||||
@ -30,8 +28,6 @@ public function show(Server $server, Backup $backup): View
|
||||
|
||||
public function run(Server $server, Backup $backup): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(RunBackup::class)->run($backup);
|
||||
|
||||
Toast::success('Backup is running.');
|
||||
@ -41,8 +37,6 @@ public function run(Server $server, Backup $backup): RedirectResponse
|
||||
|
||||
public function store(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(CreateBackup::class)->create('database', $server, $request->input());
|
||||
|
||||
Toast::success('Backup created successfully.');
|
||||
@ -52,8 +46,6 @@ public function store(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function destroy(Server $server, Backup $backup): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$backup->delete();
|
||||
|
||||
Toast::success('Backup deleted successfully.');
|
||||
@ -63,8 +55,6 @@ public function destroy(Server $server, Backup $backup): RedirectResponse
|
||||
|
||||
public function restore(Server $server, Backup $backup, BackupFile $backupFile, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(RestoreBackup::class)->restore($backupFile, $request->input());
|
||||
|
||||
Toast::success('Backup restored successfully.');
|
||||
@ -74,17 +64,8 @@ public function restore(Server $server, Backup $backup, BackupFile $backupFile,
|
||||
|
||||
public function destroyFile(Server $server, Backup $backup, BackupFile $backupFile): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$backupFile->delete();
|
||||
|
||||
$backupFile
|
||||
->backup
|
||||
->storage
|
||||
->provider()
|
||||
->ssh($server)
|
||||
->delete($backupFile->storagePath());
|
||||
|
||||
Toast::success('Backup file deleted successfully.');
|
||||
|
||||
return back();
|
||||
|
@ -17,8 +17,6 @@ class DatabaseController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('databases.index', [
|
||||
'server' => $server,
|
||||
'databases' => $server->databases,
|
||||
@ -29,8 +27,6 @@ public function index(Server $server): View
|
||||
|
||||
public function store(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$database = app(CreateDatabase::class)->create($server, $request->input());
|
||||
|
||||
if ($request->input('user')) {
|
||||
@ -44,8 +40,6 @@ public function store(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function destroy(Server $server, Database $database): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteDatabase::class)->delete($server, $database);
|
||||
|
||||
Toast::success('Database deleted successfully.');
|
||||
|
@ -16,8 +16,6 @@ class DatabaseUserController extends Controller
|
||||
{
|
||||
public function store(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$database = app(CreateDatabaseUser::class)->create($server, $request->input());
|
||||
|
||||
if ($request->input('user')) {
|
||||
@ -31,8 +29,6 @@ public function store(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function destroy(Server $server, DatabaseUser $databaseUser): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteDatabaseUser::class)->delete($server, $databaseUser);
|
||||
|
||||
Toast::success('User deleted successfully.');
|
||||
@ -42,8 +38,6 @@ public function destroy(Server $server, DatabaseUser $databaseUser): RedirectRes
|
||||
|
||||
public function password(Server $server, DatabaseUser $databaseUser): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return back()->with([
|
||||
'password' => $databaseUser->password,
|
||||
]);
|
||||
@ -51,8 +45,6 @@ public function password(Server $server, DatabaseUser $databaseUser): RedirectRe
|
||||
|
||||
public function link(Server $server, DatabaseUser $databaseUser, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(LinkUser::class)->link($databaseUser, $request->input());
|
||||
|
||||
Toast::success('Database linked successfully.');
|
||||
|
@ -16,8 +16,6 @@ class FirewallController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('firewall.index', [
|
||||
'server' => $server,
|
||||
'rules' => $server->firewallRules,
|
||||
@ -26,8 +24,6 @@ public function index(Server $server): View
|
||||
|
||||
public function store(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(CreateRule::class)->create($server, $request->input());
|
||||
|
||||
Toast::success('Firewall rule created!');
|
||||
@ -37,8 +33,6 @@ public function store(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function destroy(Server $server, FirewallRule $firewallRule): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteRule::class)->delete($server, $firewallRule);
|
||||
|
||||
Toast::success('Firewall rule deleted!');
|
||||
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Monitoring\GetMetrics;
|
||||
use App\Actions\Monitoring\UpdateMetricSettings;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class MetricController extends Controller
|
||||
{
|
||||
public function index(Server $server, Request $request): View|RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$this->checkIfMonitoringServiceInstalled($server);
|
||||
|
||||
return view('metrics.index', [
|
||||
'server' => $server,
|
||||
'data' => app(GetMetrics::class)->filter($server, $request->input()),
|
||||
'lastMetric' => $server->metrics()->latest()->first(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function settings(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$this->checkIfMonitoringServiceInstalled($server);
|
||||
|
||||
app(UpdateMetricSettings::class)->update($server, $request->input());
|
||||
|
||||
Toast::success('Metric settings updated successfully');
|
||||
|
||||
return htmx()->back();
|
||||
}
|
||||
|
||||
private function checkIfMonitoringServiceInstalled(Server $server): void
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
if (! $server->monitoring()) {
|
||||
abort(404, 'Monitoring service is not installed on this server');
|
||||
}
|
||||
}
|
||||
}
|
@ -20,8 +20,6 @@ class PHPController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('php.index', [
|
||||
'server' => $server,
|
||||
'phps' => $server->services()->where('type', 'php')->get(),
|
||||
@ -31,8 +29,6 @@ public function index(Server $server): View
|
||||
|
||||
public function install(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
try {
|
||||
app(InstallNewPHP::class)->install($server, $request->input());
|
||||
|
||||
@ -46,8 +42,6 @@ public function install(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function installExtension(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(InstallPHPExtension::class)->install($server, $request->input());
|
||||
|
||||
Toast::success('PHP extension is being installed! Check the logs');
|
||||
@ -57,8 +51,6 @@ public function installExtension(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function defaultCli(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(ChangeDefaultCli::class)->change($server, $request->input());
|
||||
|
||||
Toast::success('Default PHP CLI is being changed!');
|
||||
@ -68,8 +60,6 @@ public function defaultCli(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function getIni(Server $server, Request $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$ini = app(GetPHPIni::class)->getIni($server, $request->input());
|
||||
|
||||
return back()->with('ini', $ini);
|
||||
@ -77,11 +67,9 @@ public function getIni(Server $server, Request $request): RedirectResponse
|
||||
|
||||
public function updateIni(Server $server, Request $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(UpdatePHPIni::class)->update($server, $request->input());
|
||||
|
||||
Toast::success(__('PHP ini (:type) updated!', ['type' => $request->input('type')]));
|
||||
Toast::success('PHP ini updated!');
|
||||
|
||||
return back()->with([
|
||||
'ini' => $request->input('ini'),
|
||||
@ -90,8 +78,6 @@ public function updateIni(Server $server, Request $request): RedirectResponse
|
||||
|
||||
public function uninstall(Server $server, Request $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(UninstallPHP::class)->uninstall($server, $request->input());
|
||||
|
||||
Toast::success('PHP is being uninstalled!');
|
||||
|
@ -19,8 +19,6 @@ class QueueController extends Controller
|
||||
{
|
||||
public function index(Server $server, Site $site): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('queues.index', [
|
||||
'server' => $server,
|
||||
'site' => $site,
|
||||
@ -30,8 +28,6 @@ public function index(Server $server, Site $site): View
|
||||
|
||||
public function store(Server $server, Site $site, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(CreateQueue::class)->create($site, $request->input());
|
||||
|
||||
Toast::success('Queue is being created.');
|
||||
@ -41,8 +37,6 @@ public function store(Server $server, Site $site, Request $request): HtmxRespons
|
||||
|
||||
public function action(Server $server, Site $site, Queue $queue, string $action): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(ManageQueue::class)->{$action}($queue);
|
||||
|
||||
Toast::success('Queue is about to '.$action);
|
||||
@ -52,8 +46,6 @@ public function action(Server $server, Site $site, Queue $queue, string $action)
|
||||
|
||||
public function destroy(Server $server, Site $site, Queue $queue): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteQueue::class)->delete($queue);
|
||||
|
||||
Toast::success('Queue is being deleted.');
|
||||
@ -63,8 +55,6 @@ public function destroy(Server $server, Site $site, Queue $queue): RedirectRespo
|
||||
|
||||
public function logs(Server $server, Site $site, Queue $queue): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return back()->with('content', app(GetQueueLogs::class)->getLogs($queue));
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,6 @@ class SSHKeyController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('server-ssh-keys.index', [
|
||||
'server' => $server,
|
||||
'keys' => $server->sshKeys,
|
||||
@ -27,9 +25,7 @@ public function index(Server $server): View
|
||||
|
||||
public function store(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
/** @var SshKey $key */
|
||||
/** @var \App\Models\SshKey $key */
|
||||
$key = app(CreateSshKey::class)->create(
|
||||
$request->user(),
|
||||
$request->input()
|
||||
@ -42,8 +38,6 @@ public function store(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function destroy(Server $server, SshKey $sshKey): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteKeyFromServer::class)->delete($server, $sshKey);
|
||||
|
||||
Toast::success('SSH Key has been deleted.');
|
||||
@ -53,8 +47,6 @@ public function destroy(Server $server, SshKey $sshKey): RedirectResponse
|
||||
|
||||
public function deploy(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeployKeyToServer::class)->deploy(
|
||||
$request->user(),
|
||||
$server,
|
||||
|
@ -17,8 +17,6 @@ class SSLController extends Controller
|
||||
{
|
||||
public function index(Server $server, Site $site): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('ssls.index', [
|
||||
'server' => $server,
|
||||
'site' => $site,
|
||||
@ -28,8 +26,6 @@ public function index(Server $server, Site $site): View
|
||||
|
||||
public function store(Server $server, Site $site, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(CreateSSL::class)->create($site, $request->input());
|
||||
|
||||
Toast::success('SSL certificate is being created.');
|
||||
@ -39,8 +35,6 @@ public function store(Server $server, Site $site, Request $request): HtmxRespons
|
||||
|
||||
public function destroy(Server $server, Site $site, Ssl $ssl): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteSSL::class)->delete($ssl);
|
||||
|
||||
Toast::success('SSL certificate has been deleted.');
|
||||
|
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Script\CreateScript;
|
||||
use App\Actions\Script\EditScript;
|
||||
use App\Actions\Script\ExecuteScript;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\Script;
|
||||
use App\Models\ScriptExecution;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ScriptController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$this->authorize('viewAny', Script::class);
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$data = [
|
||||
'scripts' => $user->scripts,
|
||||
];
|
||||
|
||||
if ($request->has('edit')) {
|
||||
$data['editScript'] = $user->scripts()->findOrFail($request->input('edit'));
|
||||
}
|
||||
|
||||
if ($request->has('execute')) {
|
||||
$data['executeScript'] = $user->scripts()->findOrFail($request->input('execute'));
|
||||
}
|
||||
|
||||
return view('scripts.index', $data);
|
||||
}
|
||||
|
||||
public function show(Script $script): View
|
||||
{
|
||||
$this->authorize('view', $script);
|
||||
|
||||
return view('scripts.show', [
|
||||
'script' => $script,
|
||||
'executions' => $script->executions()->latest()->paginate(20),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('create', Script::class);
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
app(CreateScript::class)->create($user, $request->input());
|
||||
|
||||
Toast::success('Script created.');
|
||||
|
||||
return htmx()->redirect(route('scripts.index'));
|
||||
}
|
||||
|
||||
public function edit(Request $request, Script $script): HtmxResponse
|
||||
{
|
||||
$this->authorize('update', $script);
|
||||
|
||||
app(EditScript::class)->edit($script, $request->input());
|
||||
|
||||
Toast::success('Script updated.');
|
||||
|
||||
return htmx()->redirect(route('scripts.index'));
|
||||
}
|
||||
|
||||
public function execute(Script $script, Request $request): HtmxResponse
|
||||
{
|
||||
$this->validate($request, [
|
||||
'server' => 'required|exists:servers,id',
|
||||
]);
|
||||
|
||||
$server = Server::findOrFail($request->input('server'));
|
||||
|
||||
$this->authorize('execute', [$script, $server]);
|
||||
|
||||
app(ExecuteScript::class)->execute($script, $server, $request->input());
|
||||
|
||||
Toast::success('Executing the script...');
|
||||
|
||||
return htmx()->redirect(route('scripts.show', $script));
|
||||
}
|
||||
|
||||
public function delete(Script $script): RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', $script);
|
||||
|
||||
$script->delete();
|
||||
|
||||
Toast::success('Script deleted.');
|
||||
|
||||
return redirect()->route('scripts.index');
|
||||
}
|
||||
|
||||
public function log(Script $script, ScriptExecution $execution): RedirectResponse
|
||||
{
|
||||
$this->authorize('view', $script);
|
||||
|
||||
return back()->with('content', $execution->serverLog?->getContent());
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@ -24,22 +23,10 @@ public function search(Request $request): JsonResponse
|
||||
$query->where('name', 'like', '%'.$request->input('q').'%')
|
||||
->orWhere('ip', 'like', '%'.$request->input('q').'%');
|
||||
})
|
||||
->whereHas('project', function (Builder $projectQuery) {
|
||||
$projectQuery->whereHas('users', function (Builder $userQuery) {
|
||||
$userQuery->where('user_id', auth()->user()->id);
|
||||
});
|
||||
})
|
||||
->get();
|
||||
|
||||
$sites = Site::query()
|
||||
->where('domain', 'like', '%'.$request->input('q').'%')
|
||||
->whereHas('server', function (Builder $serverQuery) {
|
||||
$serverQuery->whereHas('project', function (Builder $projectQuery) {
|
||||
$projectQuery->whereHas('users', function (Builder $userQuery) {
|
||||
$userQuery->where('user_id', auth()->user()->id);
|
||||
});
|
||||
});
|
||||
})
|
||||
->get();
|
||||
|
||||
$result = [];
|
||||
|
@ -19,9 +19,6 @@ public function index(): View
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->authorize('viewAny', [Server::class, $user->currentProject]);
|
||||
|
||||
$servers = $user->currentProject->servers()->orderByDesc('created_at')->get();
|
||||
|
||||
return view('servers.index', compact('servers'));
|
||||
@ -29,15 +26,8 @@ public function index(): View
|
||||
|
||||
public function create(Request $request): View
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->authorize('create', [Server::class, $user->currentProject]);
|
||||
|
||||
$provider = $request->query('provider', old('provider', \App\Enums\ServerProvider::CUSTOM));
|
||||
$serverProviders = ServerProvider::getByProjectId(auth()->user()->current_project_id)
|
||||
->where('provider', $provider)
|
||||
->get();
|
||||
$serverProviders = ServerProvider::query()->where('provider', $provider)->get();
|
||||
|
||||
return view('servers.create', [
|
||||
'serverProviders' => $serverProviders,
|
||||
@ -50,13 +40,8 @@ public function create(Request $request): View
|
||||
*/
|
||||
public function store(Request $request): HtmxResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->authorize('create', [Server::class, $user->currentProject]);
|
||||
|
||||
$server = app(CreateServer::class)->create(
|
||||
$user,
|
||||
$request->user(),
|
||||
$request->input()
|
||||
);
|
||||
|
||||
@ -67,17 +52,14 @@ public function store(Request $request): HtmxResponse
|
||||
|
||||
public function show(Server $server): View
|
||||
{
|
||||
$this->authorize('view', $server);
|
||||
|
||||
return view('servers.show', [
|
||||
'server' => $server,
|
||||
'logs' => $server->logs()->latest()->limit(10)->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete(Server $server): RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', $server);
|
||||
|
||||
$server->delete();
|
||||
|
||||
Toast::success('Server deleted successfully.');
|
||||
|
@ -2,30 +2,22 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Server\CreateServerLog;
|
||||
use App\Facades\Toast;
|
||||
use App\Models\Server;
|
||||
use App\Models\ServerLog;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ServerLogController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('server-logs.index', [
|
||||
'server' => $server,
|
||||
'pageTitle' => __('Vito Logs'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Server $server, ServerLog $serverLog): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
if ($server->id != $serverLog->server_id) {
|
||||
abort(404);
|
||||
}
|
||||
@ -34,37 +26,4 @@ public function show(Server $server, ServerLog $serverLog): RedirectResponse
|
||||
'content' => $serverLog->getContent(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function remote(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('server-logs.remote-logs', [
|
||||
'server' => $server,
|
||||
'remote' => true,
|
||||
'pageTitle' => __('Remote Logs'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Server $server, Request $request): \App\Helpers\HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(CreateServerLog::class)->create($server, $request->input());
|
||||
|
||||
Toast::success('Log added successfully.');
|
||||
|
||||
return htmx()->redirect(route('servers.logs.remote', ['server' => $server]));
|
||||
}
|
||||
|
||||
public function destroy(Server $server, ServerLog $serverLog): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$serverLog->delete();
|
||||
|
||||
Toast::success('Remote log deleted successfully.');
|
||||
|
||||
return redirect()->route('servers.logs.remote', ['server' => $server]);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Actions\Server\EditServer;
|
||||
use App\Actions\Server\RebootServer;
|
||||
use App\Actions\Server\Update;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\Server;
|
||||
@ -16,15 +15,11 @@ class ServerSettingController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('server-settings.index', compact('server'));
|
||||
}
|
||||
|
||||
public function checkConnection(Server $server): RedirectResponse|HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$oldStatus = $server->status;
|
||||
|
||||
$server = $server->checkConnection();
|
||||
@ -46,8 +41,6 @@ public function checkConnection(Server $server): RedirectResponse|HtmxResponse
|
||||
|
||||
public function reboot(Server $server): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(RebootServer::class)->reboot($server);
|
||||
|
||||
Toast::info('Server is rebooting.');
|
||||
@ -57,32 +50,10 @@ public function reboot(Server $server): HtmxResponse
|
||||
|
||||
public function edit(Request $request, Server $server): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(EditServer::class)->edit($server, $request->input());
|
||||
|
||||
Toast::success('Server updated.');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function checkUpdates(Server $server): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$server->checkForUpdates();
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function update(Server $server): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(Update::class)->update($server);
|
||||
|
||||
Toast::info('Updating server. This may take a few minutes.');
|
||||
|
||||
return htmx()->back();
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Service\Install;
|
||||
use App\Actions\Service\Uninstall;
|
||||
use App\Actions\Service\Create;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\Server;
|
||||
@ -16,8 +15,6 @@ class ServiceController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('services.index', [
|
||||
'server' => $server,
|
||||
'services' => $server->services,
|
||||
@ -26,8 +23,6 @@ public function index(Server $server): View
|
||||
|
||||
public function start(Server $server, Service $service): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$service->start();
|
||||
|
||||
Toast::success('Service is being started!');
|
||||
@ -37,8 +32,6 @@ public function start(Server $server, Service $service): RedirectResponse
|
||||
|
||||
public function stop(Server $server, Service $service): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$service->stop();
|
||||
|
||||
Toast::success('Service is being stopped!');
|
||||
@ -48,8 +41,6 @@ public function stop(Server $server, Service $service): RedirectResponse
|
||||
|
||||
public function restart(Server $server, Service $service): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$service->restart();
|
||||
|
||||
Toast::success('Service is being restarted!');
|
||||
@ -59,8 +50,6 @@ public function restart(Server $server, Service $service): RedirectResponse
|
||||
|
||||
public function enable(Server $server, Service $service): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$service->enable();
|
||||
|
||||
Toast::success('Service is being enabled!');
|
||||
@ -70,8 +59,6 @@ public function enable(Server $server, Service $service): RedirectResponse
|
||||
|
||||
public function disable(Server $server, Service $service): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$service->disable();
|
||||
|
||||
Toast::success('Service is being disabled!');
|
||||
@ -81,20 +68,7 @@ public function disable(Server $server, Service $service): RedirectResponse
|
||||
|
||||
public function install(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(Install::class)->install($server, $request->input());
|
||||
|
||||
Toast::success('Service is being installed!');
|
||||
|
||||
return htmx()->back();
|
||||
}
|
||||
|
||||
public function uninstall(Server $server, Service $service): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(Uninstall::class)->uninstall($service);
|
||||
app(Create::class)->create($server, $request->input());
|
||||
|
||||
Toast::success('Service is being uninstalled!');
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Actions\NotificationChannels\AddChannel;
|
||||
use App\Actions\NotificationChannels\EditChannel;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
@ -14,17 +13,11 @@
|
||||
|
||||
class NotificationChannelController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
public function index(): View
|
||||
{
|
||||
$data = [
|
||||
'channels' => NotificationChannel::getByProjectId(auth()->user()->current_project_id)->get(),
|
||||
];
|
||||
|
||||
if ($request->has('edit')) {
|
||||
$data['editChannel'] = NotificationChannel::find($request->input('edit'));
|
||||
}
|
||||
|
||||
return view('settings.notification-channels.index', $data);
|
||||
return view('settings.notification-channels.index', [
|
||||
'channels' => NotificationChannel::query()->latest()->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function add(Request $request): HtmxResponse
|
||||
@ -36,20 +29,7 @@ public function add(Request $request): HtmxResponse
|
||||
|
||||
Toast::success('Channel added successfully');
|
||||
|
||||
return htmx()->redirect(route('settings.notification-channels'));
|
||||
}
|
||||
|
||||
public function update(NotificationChannel $notificationChannel, Request $request): HtmxResponse
|
||||
{
|
||||
app(EditChannel::class)->edit(
|
||||
$notificationChannel,
|
||||
$request->user(),
|
||||
$request->input(),
|
||||
);
|
||||
|
||||
Toast::success('Channel updated.');
|
||||
|
||||
return htmx()->redirect(route('settings.notification-channels'));
|
||||
return htmx()->redirect(route('notification-channels'));
|
||||
}
|
||||
|
||||
public function delete(int $id): RedirectResponse
|
||||
@ -60,6 +40,6 @@ public function delete(int $id): RedirectResponse
|
||||
|
||||
Toast::success('Channel deleted successfully');
|
||||
|
||||
return redirect()->route('settings.notification-channels');
|
||||
return redirect()->route('notification-channels');
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Actions\User\UpdateUserPassword;
|
||||
use App\Actions\User\UpdateUserProfileInformation;
|
||||
use App\Facades\Toast;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@ -13,7 +14,7 @@ class ProfileController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
{
|
||||
return view('profile.index');
|
||||
return view('settings.profile.index');
|
||||
}
|
||||
|
||||
public function info(Request $request): RedirectResponse
|
@ -19,42 +19,40 @@ class ProjectController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
{
|
||||
$this->authorize('viewAny', Project::class);
|
||||
|
||||
return view('settings.projects.index', [
|
||||
'projects' => Project::all(),
|
||||
'projects' => auth()->user()->projects,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('create', Project::class);
|
||||
|
||||
app(CreateProject::class)->create($request->user(), $request->input());
|
||||
|
||||
Toast::success('Project created.');
|
||||
|
||||
return htmx()->redirect(route('settings.projects'));
|
||||
return htmx()->redirect(route('projects'));
|
||||
}
|
||||
|
||||
public function update(Request $request, Project $project): HtmxResponse
|
||||
{
|
||||
$this->authorize('update', $project);
|
||||
/** @var Project $project */
|
||||
$project = $request->user()->projects()->findOrFail($project->id);
|
||||
|
||||
app(UpdateProject::class)->update($project, $request->input());
|
||||
|
||||
Toast::success('Project updated.');
|
||||
|
||||
return htmx()->redirect(route('settings.projects'));
|
||||
return htmx()->redirect(route('projects'));
|
||||
}
|
||||
|
||||
public function delete(Project $project): RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', $project);
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var Project $project */
|
||||
$project = $user->projects()->findOrFail($project->id);
|
||||
|
||||
try {
|
||||
app(DeleteProject::class)->delete($user, $project);
|
||||
} catch (ValidationException $e) {
|
||||
@ -68,7 +66,7 @@ public function delete(Project $project): RedirectResponse
|
||||
return back();
|
||||
}
|
||||
|
||||
public function switch(Request $request, $projectId): RedirectResponse
|
||||
public function switch($projectId): RedirectResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
@ -76,16 +74,9 @@ public function switch(Request $request, $projectId): RedirectResponse
|
||||
/** @var Project $project */
|
||||
$project = $user->projects()->findOrFail($projectId);
|
||||
|
||||
$this->authorize('view', $project);
|
||||
|
||||
$user->current_project_id = $project->id;
|
||||
$user->save();
|
||||
|
||||
// check if the referer is settings/*
|
||||
if (str_contains($request->headers->get('referer'), 'settings')) {
|
||||
return redirect()->to($request->headers->get('referer'));
|
||||
}
|
||||
|
||||
return redirect()->route('servers');
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public function add(Request $request): HtmxResponse
|
||||
|
||||
Toast::success('SSH Key added');
|
||||
|
||||
return htmx()->redirect(route('settings.ssh-keys'));
|
||||
return htmx()->redirect(route('ssh-keys'));
|
||||
}
|
||||
|
||||
public function delete(int $id): RedirectResponse
|
||||
@ -40,6 +40,6 @@ public function delete(int $id): RedirectResponse
|
||||
|
||||
Toast::success('SSH Key deleted');
|
||||
|
||||
return redirect()->route('settings.ssh-keys');
|
||||
return redirect()->route('ssh-keys');
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Actions\ServerProvider\CreateServerProvider;
|
||||
use App\Actions\ServerProvider\DeleteServerProvider;
|
||||
use App\Actions\ServerProvider\EditServerProvider;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
@ -15,17 +14,11 @@
|
||||
|
||||
class ServerProviderController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
public function index(): View
|
||||
{
|
||||
$data = [
|
||||
'providers' => ServerProvider::getByProjectId(auth()->user()->current_project_id)->get(),
|
||||
];
|
||||
|
||||
if ($request->has('edit')) {
|
||||
$data['editProvider'] = ServerProvider::find($request->input('edit'));
|
||||
}
|
||||
|
||||
return view('settings.server-providers.index', $data);
|
||||
return view('settings.server-providers.index', [
|
||||
'providers' => auth()->user()->serverProviders,
|
||||
]);
|
||||
}
|
||||
|
||||
public function connect(Request $request): HtmxResponse
|
||||
@ -37,20 +30,7 @@ public function connect(Request $request): HtmxResponse
|
||||
|
||||
Toast::success('Server provider connected.');
|
||||
|
||||
return htmx()->redirect(route('settings.server-providers'));
|
||||
}
|
||||
|
||||
public function update(ServerProvider $serverProvider, Request $request): HtmxResponse
|
||||
{
|
||||
app(EditServerProvider::class)->edit(
|
||||
$serverProvider,
|
||||
$request->user(),
|
||||
$request->input(),
|
||||
);
|
||||
|
||||
Toast::success('Provider updated.');
|
||||
|
||||
return htmx()->redirect(route('settings.server-providers'));
|
||||
return htmx()->redirect(route('server-providers'));
|
||||
}
|
||||
|
||||
public function delete(ServerProvider $serverProvider): RedirectResponse
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Actions\SourceControl\ConnectSourceControl;
|
||||
use App\Actions\SourceControl\DeleteSourceControl;
|
||||
use App\Actions\SourceControl\EditSourceControl;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
@ -15,42 +14,22 @@
|
||||
|
||||
class SourceControlController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
public function index(): View
|
||||
{
|
||||
$data = [
|
||||
'sourceControls' => SourceControl::getByProjectId(auth()->user()->current_project_id)->get(),
|
||||
];
|
||||
|
||||
if ($request->has('edit')) {
|
||||
$data['editSourceControl'] = SourceControl::find($request->input('edit'));
|
||||
}
|
||||
|
||||
return view('settings.source-controls.index', $data);
|
||||
return view('settings.source-controls.index', [
|
||||
'sourceControls' => SourceControl::query()->orderByDesc('id')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function connect(Request $request): HtmxResponse
|
||||
{
|
||||
app(ConnectSourceControl::class)->connect(
|
||||
$request->user(),
|
||||
$request->input(),
|
||||
);
|
||||
|
||||
Toast::success('Source control connected.');
|
||||
|
||||
return htmx()->redirect(route('settings.source-controls'));
|
||||
}
|
||||
|
||||
public function update(SourceControl $sourceControl, Request $request): HtmxResponse
|
||||
{
|
||||
app(EditSourceControl::class)->edit(
|
||||
$sourceControl,
|
||||
$request->user(),
|
||||
$request->input(),
|
||||
);
|
||||
|
||||
Toast::success('Source control updated.');
|
||||
|
||||
return htmx()->redirect(route('settings.source-controls'));
|
||||
return htmx()->redirect(route('source-controls'));
|
||||
}
|
||||
|
||||
public function delete(SourceControl $sourceControl): RedirectResponse
|
||||
@ -65,6 +44,6 @@ public function delete(SourceControl $sourceControl): RedirectResponse
|
||||
|
||||
Toast::success('Source control deleted.');
|
||||
|
||||
return redirect()->route('settings.source-controls');
|
||||
return redirect()->route('source-controls');
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Actions\StorageProvider\CreateStorageProvider;
|
||||
use App\Actions\StorageProvider\DeleteStorageProvider;
|
||||
use App\Actions\StorageProvider\EditStorageProvider;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
@ -15,17 +14,11 @@
|
||||
|
||||
class StorageProviderController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
public function index(): View
|
||||
{
|
||||
$data = [
|
||||
'providers' => StorageProvider::getByProjectId(auth()->user()->current_project_id)->get(),
|
||||
];
|
||||
|
||||
if ($request->has('edit')) {
|
||||
$data['editProvider'] = StorageProvider::find($request->input('edit'));
|
||||
}
|
||||
|
||||
return view('settings.storage-providers.index', $data);
|
||||
return view('settings.storage-providers.index', [
|
||||
'providers' => auth()->user()->storageProviders,
|
||||
]);
|
||||
}
|
||||
|
||||
public function connect(Request $request): HtmxResponse
|
||||
@ -37,20 +30,7 @@ public function connect(Request $request): HtmxResponse
|
||||
|
||||
Toast::success('Storage provider connected.');
|
||||
|
||||
return htmx()->redirect(route('settings.storage-providers'));
|
||||
}
|
||||
|
||||
public function update(StorageProvider $storageProvider, Request $request): HtmxResponse
|
||||
{
|
||||
app(EditStorageProvider::class)->edit(
|
||||
$storageProvider,
|
||||
$request->user(),
|
||||
$request->input(),
|
||||
);
|
||||
|
||||
Toast::success('Provider updated.');
|
||||
|
||||
return htmx()->redirect(route('settings.storage-providers'));
|
||||
return htmx()->redirect(route('storage-providers'));
|
||||
}
|
||||
|
||||
public function delete(StorageProvider $storageProvider): RedirectResponse
|
||||
|
@ -1,90 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Actions\Tag\AttachTag;
|
||||
use App\Actions\Tag\CreateTag;
|
||||
use App\Actions\Tag\DeleteTag;
|
||||
use App\Actions\Tag\DetachTag;
|
||||
use App\Actions\Tag\EditTag;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Tag;
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$data = [
|
||||
'tags' => Tag::getByProjectId(auth()->user()->current_project_id)->get(),
|
||||
];
|
||||
|
||||
if ($request->has('edit')) {
|
||||
$data['editTag'] = Tag::find($request->input('edit'));
|
||||
}
|
||||
|
||||
return view('settings.tags.index', $data);
|
||||
}
|
||||
|
||||
public function create(Request $request): HtmxResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $request->user();
|
||||
|
||||
app(CreateTag::class)->create(
|
||||
$user,
|
||||
$request->input(),
|
||||
);
|
||||
|
||||
Toast::success('Tag created.');
|
||||
|
||||
return htmx()->redirect(route('settings.tags'));
|
||||
}
|
||||
|
||||
public function update(Tag $tag, Request $request): HtmxResponse
|
||||
{
|
||||
app(EditTag::class)->edit(
|
||||
$tag,
|
||||
$request->input(),
|
||||
);
|
||||
|
||||
Toast::success('Tag updated.');
|
||||
|
||||
return htmx()->redirect(route('settings.tags'));
|
||||
}
|
||||
|
||||
public function attach(Request $request): RedirectResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $request->user();
|
||||
|
||||
app(AttachTag::class)->attach($user, $request->input());
|
||||
|
||||
return back()->with([
|
||||
'status' => 'tag-created',
|
||||
]);
|
||||
}
|
||||
|
||||
public function detach(Request $request, Tag $tag): RedirectResponse
|
||||
{
|
||||
app(DetachTag::class)->detach($tag, $request->input());
|
||||
|
||||
return back()->with([
|
||||
'status' => 'tag-detached',
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete(Tag $tag): RedirectResponse
|
||||
{
|
||||
app(DeleteTag::class)->delete($tag);
|
||||
|
||||
Toast::success('Tag deleted.');
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Actions\User\CreateUser;
|
||||
use App\Actions\User\UpdateUser;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Project;
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
{
|
||||
$users = User::query()->paginate(20);
|
||||
|
||||
return view('settings.users.index', compact('users'));
|
||||
}
|
||||
|
||||
public function store(Request $request): HtmxResponse
|
||||
{
|
||||
$user = app(CreateUser::class)->create($request->input());
|
||||
|
||||
return htmx()->redirect(route('settings.users.show', $user));
|
||||
}
|
||||
|
||||
public function show(User $user): View
|
||||
{
|
||||
return view('settings.users.show', [
|
||||
'user' => $user,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(User $user, Request $request): RedirectResponse
|
||||
{
|
||||
app(UpdateUser::class)->update($user, $request->input());
|
||||
|
||||
Toast::success('User updated successfully');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function updateProjects(User $user, Request $request): HtmxResponse
|
||||
{
|
||||
$this->validate($request, [
|
||||
'projects.*' => [
|
||||
'required',
|
||||
Rule::exists('projects', 'id'),
|
||||
],
|
||||
]);
|
||||
|
||||
$user->projects()->sync($request->projects);
|
||||
|
||||
if ($user->currentProject && ! $user->projects->contains($user->currentProject)) {
|
||||
$user->current_project_id = null;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
/** @var Project $firstProject */
|
||||
$firstProject = $user->projects->first();
|
||||
if (! $user->currentProject && $firstProject) {
|
||||
$user->current_project_id = $firstProject->id;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
Toast::success('Projects updated successfully');
|
||||
|
||||
return htmx()->redirect(route('settings.users.show', $user));
|
||||
}
|
||||
|
||||
public function destroy(User $user): RedirectResponse
|
||||
{
|
||||
if ($user->is(request()->user())) {
|
||||
Toast::error('You cannot delete your own account');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
$user->delete();
|
||||
|
||||
Toast::success('User deleted successfully');
|
||||
|
||||
return redirect()->route('settings.users.index');
|
||||
}
|
||||
}
|
@ -19,8 +19,6 @@ class SiteController extends Controller
|
||||
{
|
||||
public function index(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('sites.index', [
|
||||
'server' => $server,
|
||||
'sites' => $server->sites()->orderByDesc('id')->get(),
|
||||
@ -29,8 +27,6 @@ public function index(Server $server): View
|
||||
|
||||
public function store(Server $server, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$site = app(CreateSite::class)->create($server, $request->input());
|
||||
|
||||
Toast::success('Site created');
|
||||
@ -40,8 +36,6 @@ public function store(Server $server, Request $request): HtmxResponse
|
||||
|
||||
public function create(Server $server): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('sites.create', [
|
||||
'server' => $server,
|
||||
'type' => old('type', request()->query('type', SiteType::LARAVEL)),
|
||||
@ -51,8 +45,6 @@ public function create(Server $server): View
|
||||
|
||||
public function show(Server $server, Site $site, Request $request): View|RedirectResponse|HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
if (in_array($site->status, [SiteStatus::INSTALLING, SiteStatus::INSTALLATION_FAILED])) {
|
||||
if ($request->hasHeader('HX-Request')) {
|
||||
return htmx()->redirect(route('servers.sites.installing', [$server, $site]));
|
||||
@ -69,8 +61,6 @@ public function show(Server $server, Site $site, Request $request): View|Redirec
|
||||
|
||||
public function installing(Server $server, Site $site, Request $request): View|RedirectResponse|HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
if (! in_array($site->status, [SiteStatus::INSTALLING, SiteStatus::INSTALLATION_FAILED])) {
|
||||
if ($request->hasHeader('HX-Request')) {
|
||||
return htmx()->redirect(route('servers.sites.show', [$server, $site]));
|
||||
@ -87,8 +77,6 @@ public function installing(Server $server, Site $site, Request $request): View|R
|
||||
|
||||
public function destroy(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DeleteSite::class)->delete($site);
|
||||
|
||||
Toast::success('Site is being deleted');
|
||||
|
@ -10,12 +10,9 @@ class SiteLogController extends Controller
|
||||
{
|
||||
public function index(Server $server, Site $site): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('site-logs.index', [
|
||||
'server' => $server,
|
||||
'site' => $site,
|
||||
'pageTitle' => __('Vito Logs'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Site\UpdateAliases;
|
||||
use App\Actions\Site\UpdateSourceControl;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@ -19,8 +17,6 @@ class SiteSettingController extends Controller
|
||||
{
|
||||
public function index(Server $server, Site $site): View
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
return view('site-settings.index', [
|
||||
'server' => $server,
|
||||
'site' => $site,
|
||||
@ -29,26 +25,17 @@ public function index(Server $server, Site $site): View
|
||||
|
||||
public function getVhost(Server $server, Site $site): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
/** @var Webserver $handler */
|
||||
$handler = $server->webserver()->handler();
|
||||
|
||||
return back()->with('vhost', $handler->getVHost($site));
|
||||
return back()->with('vhost', $server->webserver()->handler()->getVHost($site));
|
||||
}
|
||||
|
||||
public function updateVhost(Server $server, Site $site, Request $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$this->validate($request, [
|
||||
'vhost' => 'required|string',
|
||||
]);
|
||||
|
||||
try {
|
||||
/** @var Webserver $handler */
|
||||
$handler = $server->webserver()->handler();
|
||||
$handler->updateVHost($site, false, $request->input('vhost'));
|
||||
$server->webserver()->handler()->updateVHost($site, false, $request->input('vhost'));
|
||||
|
||||
Toast::success('VHost updated successfully!');
|
||||
} catch (Throwable $e) {
|
||||
@ -60,8 +47,6 @@ public function updateVhost(Server $server, Site $site, Request $request): Redir
|
||||
|
||||
public function updatePHPVersion(Server $server, Site $site, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
$this->validate($request, [
|
||||
'version' => [
|
||||
'required',
|
||||
@ -82,23 +67,10 @@ public function updatePHPVersion(Server $server, Site $site, Request $request):
|
||||
|
||||
public function updateSourceControl(Server $server, Site $site, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(UpdateSourceControl::class)->update($site, $request->input());
|
||||
$site = app(UpdateSourceControl::class)->update($site, $request->input());
|
||||
|
||||
Toast::success('Source control updated successfully!');
|
||||
|
||||
return htmx()->back();
|
||||
}
|
||||
|
||||
public function updateAliases(Server $server, Site $site, Request $request): HtmxResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(UpdateAliases::class)->update($site, $request->input());
|
||||
|
||||
Toast::success('Aliases updated successfully!');
|
||||
|
||||
return htmx()->back();
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,5 @@ class Kernel extends HttpKernel
|
||||
'server-is-ready' => ServerIsReadyMiddleware::class,
|
||||
'handle-ssh-errors' => HandleSSHErrors::class,
|
||||
'select-current-project' => SelectCurrentProject::class,
|
||||
'is-admin' => \App\Http\Middleware\IsAdmin::class,
|
||||
'must-have-current-project' => \App\Http\Middleware\MustHaveCurrentProject::class,
|
||||
];
|
||||
}
|
||||
|
@ -14,17 +14,17 @@ class HandleSSHErrors
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$res = $next($request);
|
||||
// if ($res instanceof Response && $res->exception) {
|
||||
// if ($res->exception instanceof SSHConnectionError || $res->exception instanceof SSHCommandError) {
|
||||
// Toast::error($res->exception->getMessage());
|
||||
if ($res instanceof Response && $res->exception) {
|
||||
if ($res->exception instanceof SSHConnectionError || $res->exception instanceof SSHCommandError) {
|
||||
Toast::error($res->exception->getMessage());
|
||||
|
||||
// if ($request->hasHeader('HX-Request')) {
|
||||
// return htmx()->back();
|
||||
// }
|
||||
if ($request->hasHeader('HX-Request')) {
|
||||
return htmx()->back();
|
||||
}
|
||||
|
||||
// return back();
|
||||
// }
|
||||
// }
|
||||
return back();
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class IsAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (auth()->user()->role !== UserRole::ADMIN) {
|
||||
abort(403, 'You are not authorized to access this page.');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Facades\Toast;
|
||||
use App\Models\User;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class MustHaveCurrentProject
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $request->user();
|
||||
|
||||
if (! $user->currentProject) {
|
||||
Toast::warning('Please select a project to continue');
|
||||
|
||||
return redirect()->route('profile');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ public function handle(Request $request, Closure $next): Response
|
||||
/** @var User $user */
|
||||
$user = $request->user();
|
||||
|
||||
if ($server->project_id != $user->current_project_id && $user->can('view', $server)) {
|
||||
if ($server->project_id != $user->current_project_id) {
|
||||
$user->current_project_id = $server->project_id;
|
||||
$user->save();
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user