feat(server): allow force deletion of servers with resources (#8962)
This commit is contained in:
commit
cde0bebfd4
6 changed files with 54 additions and 6 deletions
|
|
@ -7,6 +7,7 @@
|
|||
use App\Enums\ProxyStatus;
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Jobs\DeleteResourceJob;
|
||||
use App\Models\Application;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
|
|
@ -758,12 +759,22 @@ public function delete_server(Request $request)
|
|||
if (! $server) {
|
||||
return response()->json(['message' => 'Server not found.'], 404);
|
||||
}
|
||||
if ($server->definedResources()->count() > 0) {
|
||||
return response()->json(['message' => 'Server has resources, so you need to delete them before.'], 400);
|
||||
|
||||
$force = filter_var($request->query('force', false), FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if ($server->definedResources()->count() > 0 && ! $force) {
|
||||
return response()->json(['message' => 'Server has resources. Use ?force=true to delete all resources and the server, or delete resources manually first.'], 400);
|
||||
}
|
||||
if ($server->isLocalhost()) {
|
||||
return response()->json(['message' => 'Local server cannot be deleted.'], 400);
|
||||
}
|
||||
|
||||
if ($force) {
|
||||
foreach ($server->definedResources() as $resource) {
|
||||
DeleteResourceJob::dispatch($resource);
|
||||
}
|
||||
}
|
||||
|
||||
$server->delete();
|
||||
DeleteServer::dispatch(
|
||||
$server->id,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Livewire\Server;
|
||||
|
||||
use App\Actions\Server\DeleteServer;
|
||||
use App\Jobs\DeleteResourceJob;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
|
@ -15,6 +16,8 @@ class Delete extends Component
|
|||
|
||||
public bool $delete_from_hetzner = false;
|
||||
|
||||
public bool $force_delete_resources = false;
|
||||
|
||||
public function mount(string $server_uuid)
|
||||
{
|
||||
try {
|
||||
|
|
@ -32,15 +35,22 @@ public function delete($password, $selectedActions = [])
|
|||
|
||||
if (! empty($selectedActions)) {
|
||||
$this->delete_from_hetzner = in_array('delete_from_hetzner', $selectedActions);
|
||||
$this->force_delete_resources = in_array('force_delete_resources', $selectedActions);
|
||||
}
|
||||
try {
|
||||
$this->authorize('delete', $this->server);
|
||||
if ($this->server->hasDefinedResources()) {
|
||||
$this->dispatch('error', 'Server has defined resources. Please delete them first.');
|
||||
if ($this->server->hasDefinedResources() && ! $this->force_delete_resources) {
|
||||
$this->dispatch('error', 'Server has defined resources. Please delete them first or select "Delete all resources".');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->force_delete_resources) {
|
||||
foreach ($this->server->definedResources() as $resource) {
|
||||
DeleteResourceJob::dispatch($resource);
|
||||
}
|
||||
}
|
||||
|
||||
$this->server->delete();
|
||||
DeleteServer::dispatch(
|
||||
$this->server->id,
|
||||
|
|
@ -60,6 +70,15 @@ public function render()
|
|||
{
|
||||
$checkboxes = [];
|
||||
|
||||
if ($this->server->hasDefinedResources()) {
|
||||
$resourceCount = $this->server->definedResources()->count();
|
||||
$checkboxes[] = [
|
||||
'id' => 'force_delete_resources',
|
||||
'label' => "Delete all resources ({$resourceCount} total)",
|
||||
'default_warning' => 'Server cannot be deleted while it has resources.',
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->server->hetzner_server_id) {
|
||||
$checkboxes[] = [
|
||||
'id' => 'delete_from_hetzner',
|
||||
|
|
|
|||
10
openapi.json
10
openapi.json
|
|
@ -9685,6 +9685,11 @@
|
|||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Force domain override even if conflicts are detected."
|
||||
},
|
||||
"is_container_label_escape_enabled": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Escape special characters in labels. By default, $ (and other chars) is escaped. If you want to use env variables inside the labels, turn this off."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
|
@ -10011,6 +10016,11 @@
|
|||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Force domain override even if conflicts are detected."
|
||||
},
|
||||
"is_container_label_escape_enabled": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Escape special characters in labels. By default, $ (and other chars) is escaped. If you want to use env variables inside the labels, turn this off."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
|
|
|||
|
|
@ -6152,6 +6152,10 @@ paths:
|
|||
type: boolean
|
||||
default: false
|
||||
description: 'Force domain override even if conflicts are detected.'
|
||||
is_container_label_escape_enabled:
|
||||
type: boolean
|
||||
default: true
|
||||
description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. If you want to use env variables inside the labels, turn this off.'
|
||||
type: object
|
||||
responses:
|
||||
'201':
|
||||
|
|
@ -6337,6 +6341,10 @@ paths:
|
|||
type: boolean
|
||||
default: false
|
||||
description: 'Force domain override even if conflicts are detected.'
|
||||
is_container_label_escape_enabled:
|
||||
type: boolean
|
||||
default: true
|
||||
description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. If you want to use env variables inside the labels, turn this off.'
|
||||
type: object
|
||||
responses:
|
||||
'200':
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
back!
|
||||
</div>
|
||||
@if ($server->definedResources()->count() > 0)
|
||||
<div class="pb-2 text-red-500">You need to delete all resources before deleting this server.</div>
|
||||
<div class="pb-2 text-red-500">This server has resources. You can force delete all resources by checking the option below.</div>
|
||||
@endif
|
||||
|
||||
<x-modal-confirmation title="Confirm Server Deletion?" isErrorButton buttonTitle="Delete"
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class="mx-1 dark:hover:fill-white fill-black dark:fill-warning">
|
|||
<div class="subtitle">{{ data_get($server, 'name') }}</div>
|
||||
<div class="navbar-main">
|
||||
<nav
|
||||
class="flex items-center gap-4 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap pt-2">
|
||||
class="flex items-center gap-6 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap pt-2">
|
||||
<a class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}" href="{{ route('server.show', [
|
||||
'server_uuid' => data_get($server, 'uuid'),
|
||||
]) }}" {{ wireNavigate() }}>
|
||||
|
|
|
|||
Loading…
Reference in a new issue