feat: clone any resource
This commit is contained in:
parent
2edf71a0dd
commit
abcc004953
@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire\Project\Shared;
|
|
||||||
|
|
||||||
use App\Models\Environment;
|
|
||||||
use App\Models\Project;
|
|
||||||
use Livewire\Component;
|
|
||||||
use Visus\Cuid2\Cuid2;
|
|
||||||
|
|
||||||
class MoveResource extends Component
|
|
||||||
{
|
|
||||||
public $resource;
|
|
||||||
public $projectUuid;
|
|
||||||
public $environmentName;
|
|
||||||
public $projects;
|
|
||||||
|
|
||||||
public function mount()
|
|
||||||
{
|
|
||||||
$parameters = get_route_parameters();
|
|
||||||
$this->projectUuid = $parameters['project_uuid'];
|
|
||||||
$this->environmentName = $parameters['environment_name'];
|
|
||||||
$this->projects = Project::ownedByCurrentTeam()->get();
|
|
||||||
}
|
|
||||||
public function moveTo($environment_id)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$new_environment = Environment::findOrFail($environment_id);
|
|
||||||
$this->resource->update([
|
|
||||||
'environment_id' => $environment_id
|
|
||||||
]);
|
|
||||||
if ($this->resource->type() === 'application') {
|
|
||||||
return redirect()->route('project.application.configuration', [
|
|
||||||
'project_uuid' => $new_environment->project->uuid,
|
|
||||||
'environment_name' => $new_environment->name,
|
|
||||||
'application_uuid' => $this->resource->uuid,
|
|
||||||
]);
|
|
||||||
} else if (str($this->resource->type())->startsWith('standalone-')) {
|
|
||||||
return redirect()->route('project.database.configuration', [
|
|
||||||
'project_uuid' => $new_environment->project->uuid,
|
|
||||||
'environment_name' => $new_environment->name,
|
|
||||||
'database_uuid' => $this->resource->uuid,
|
|
||||||
]);
|
|
||||||
} else if ($this->resource->type() === 'service') {
|
|
||||||
return redirect()->route('project.service.configuration', [
|
|
||||||
'project_uuid' => $new_environment->project->uuid,
|
|
||||||
'environment_name' => $new_environment->name,
|
|
||||||
'service_uuid' => $this->resource->uuid,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
return handleError($e, $this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
return view('livewire.project.shared.move-resource');
|
|
||||||
}
|
|
||||||
}
|
|
173
app/Livewire/Project/Shared/ResourceOperations.php
Normal file
173
app/Livewire/Project/Shared/ResourceOperations.php
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Project\Shared;
|
||||||
|
|
||||||
|
use App\Models\Environment;
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Models\StandaloneDocker;
|
||||||
|
use App\Models\SwarmDocker;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
|
class ResourceOperations extends Component
|
||||||
|
{
|
||||||
|
public $resource;
|
||||||
|
public $projectUuid;
|
||||||
|
public $environmentName;
|
||||||
|
public $projects;
|
||||||
|
public $servers;
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$parameters = get_route_parameters();
|
||||||
|
$this->projectUuid = $parameters['project_uuid'];
|
||||||
|
$this->environmentName = $parameters['environment_name'];
|
||||||
|
$this->projects = Project::ownedByCurrentTeam()->get();
|
||||||
|
$this->servers = currentTeam()->servers;
|
||||||
|
}
|
||||||
|
public function cloneTo($destination_id)
|
||||||
|
{
|
||||||
|
$new_destination = StandaloneDocker::find($destination_id);
|
||||||
|
if (!$new_destination) {
|
||||||
|
$new_destination = SwarmDocker::find($destination_id);
|
||||||
|
}
|
||||||
|
if (!$new_destination) {
|
||||||
|
return $this->addError('destination_id', 'Destination not found.');
|
||||||
|
}
|
||||||
|
$uuid = (string)new Cuid2(7);
|
||||||
|
$server = $new_destination->server;
|
||||||
|
if ($this->resource->getMorphClass() === 'App\Models\Application') {
|
||||||
|
$new_resource = $this->resource->replicate()->fill([
|
||||||
|
'uuid' => $uuid,
|
||||||
|
'name' => $this->resource->name . '-clone-' . $uuid,
|
||||||
|
'fqdn' => generateFqdn($server, $uuid),
|
||||||
|
'status' => 'exited',
|
||||||
|
'destination_id' => $new_destination->id,
|
||||||
|
]);
|
||||||
|
$new_resource->save();
|
||||||
|
$environmentVaribles = $this->resource->environment_variables()->get();
|
||||||
|
foreach ($environmentVaribles as $environmentVarible) {
|
||||||
|
$newEnvironmentVariable = $environmentVarible->replicate()->fill([
|
||||||
|
'application_id' => $new_resource->id,
|
||||||
|
]);
|
||||||
|
$newEnvironmentVariable->save();
|
||||||
|
}
|
||||||
|
$persistentVolumes = $this->resource->persistentStorages()->get();
|
||||||
|
foreach ($persistentVolumes as $volume) {
|
||||||
|
$newPersistentVolume = $volume->replicate()->fill([
|
||||||
|
'name' => $new_resource->uuid . '-' . str($volume->name)->afterLast('-'),
|
||||||
|
'resource_id' => $new_resource->id,
|
||||||
|
]);
|
||||||
|
$newPersistentVolume->save();
|
||||||
|
}
|
||||||
|
$route = route('project.application.configuration', [
|
||||||
|
'project_uuid' => $this->projectUuid,
|
||||||
|
'environment_name' => $this->environmentName,
|
||||||
|
'application_uuid' => $new_resource->uuid,
|
||||||
|
]) . "#resource-operations";
|
||||||
|
return redirect()->to($route);
|
||||||
|
} else if (
|
||||||
|
$this->resource->getMorphClass() === 'App\Models\StandalonePostgresql' ||
|
||||||
|
$this->resource->getMorphClass() === 'App\Models\StandaloneMongodb' ||
|
||||||
|
$this->resource->getMorphClass() === 'App\Models\StandaloneMysql' ||
|
||||||
|
$this->resource->getMorphClass() === 'App\Models\StandaloneMariadb' ||
|
||||||
|
$this->resource->getMorphClass() === 'App\Models\StandaloneRedis'
|
||||||
|
) {
|
||||||
|
$uuid = (string)new Cuid2(7);
|
||||||
|
$new_resource = $this->resource->replicate()->fill([
|
||||||
|
'uuid' => $uuid,
|
||||||
|
'name' => $this->resource->name . '-clone-' . $uuid,
|
||||||
|
'status' => 'exited',
|
||||||
|
'started_at' => null,
|
||||||
|
'destination_id' => $new_destination->id,
|
||||||
|
]);
|
||||||
|
$new_resource->save();
|
||||||
|
$environmentVaribles = $this->resource->environment_variables()->get();
|
||||||
|
foreach ($environmentVaribles as $environmentVarible) {
|
||||||
|
$payload = [];
|
||||||
|
if ($this->resource->type() === 'standalone-postgresql') {
|
||||||
|
$payload['standalone_postgresql_id'] = $new_resource->id;
|
||||||
|
} else if ($this->resource->type() === 'standalone-redis') {
|
||||||
|
$payload['standalone_redis_id'] = $new_resource->id;
|
||||||
|
} else if ($this->resource->type() === 'standalone-mongodb') {
|
||||||
|
$payload['standalone_mongodb_id'] = $new_resource->id;
|
||||||
|
} else if ($this->resource->type() === 'standalone-mysql') {
|
||||||
|
$payload['standalone_mysql_id'] = $new_resource->id;
|
||||||
|
} else if ($this->resource->type() === 'standalone-mariadb') {
|
||||||
|
$payload['standalone_mariadb_id'] = $new_resource->id;
|
||||||
|
}
|
||||||
|
$newEnvironmentVariable = $environmentVarible->replicate()->fill($payload);
|
||||||
|
$newEnvironmentVariable->save();
|
||||||
|
}
|
||||||
|
$route = route('project.database.configuration', [
|
||||||
|
'project_uuid' => $this->projectUuid,
|
||||||
|
'environment_name' => $this->environmentName,
|
||||||
|
'database_uuid' => $new_resource->uuid,
|
||||||
|
]) . "#resource-operations";
|
||||||
|
return redirect()->to($route);
|
||||||
|
} else if ($this->resource->type() === 'service') {
|
||||||
|
$uuid = (string)new Cuid2(7);
|
||||||
|
$new_resource = $this->resource->replicate()->fill([
|
||||||
|
'uuid' => $uuid,
|
||||||
|
'name' => $this->resource->name . '-clone-' . $uuid,
|
||||||
|
'destination_id' => $new_destination->id,
|
||||||
|
]);
|
||||||
|
$new_resource->save();
|
||||||
|
foreach ($new_resource->applications() as $application) {
|
||||||
|
$application->update([
|
||||||
|
'status' => 'exited',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
foreach ($new_resource->databases() as $database) {
|
||||||
|
$database->update([
|
||||||
|
'status' => 'exited',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$new_resource->parse();
|
||||||
|
$route = route('project.service.configuration', [
|
||||||
|
'project_uuid' => $this->projectUuid,
|
||||||
|
'environment_name' => $this->environmentName,
|
||||||
|
'service_uuid' => $new_resource->uuid,
|
||||||
|
]) . "#resource-operations";
|
||||||
|
return redirect()->to($route);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
public function moveTo($environment_id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$new_environment = Environment::findOrFail($environment_id);
|
||||||
|
$this->resource->update([
|
||||||
|
'environment_id' => $environment_id
|
||||||
|
]);
|
||||||
|
if ($this->resource->type() === 'application') {
|
||||||
|
$route = route('project.application.configuration', [
|
||||||
|
'project_uuid' => $new_environment->project->uuid,
|
||||||
|
'environment_name' => $new_environment->name,
|
||||||
|
'application_uuid' => $this->resource->uuid,
|
||||||
|
]) . "#resource-operations";
|
||||||
|
return redirect()->to($route);
|
||||||
|
} else if (str($this->resource->type())->startsWith('standalone-')) {
|
||||||
|
$route = route('project.database.configuration', [
|
||||||
|
'project_uuid' => $new_environment->project->uuid,
|
||||||
|
'environment_name' => $new_environment->name,
|
||||||
|
'database_uuid' => $this->resource->uuid,
|
||||||
|
]) . "#resource-operations";
|
||||||
|
return redirect()->to($route);
|
||||||
|
} else if ($this->resource->type() === 'service') {
|
||||||
|
$route = route('project.service.configuration', [
|
||||||
|
'project_uuid' => $new_environment->project->uuid,
|
||||||
|
'environment_name' => $new_environment->name,
|
||||||
|
'service_uuid' => $this->resource->uuid,
|
||||||
|
]) . "#resource-operations";
|
||||||
|
return redirect()->to($route);
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.project.shared.resource-operations');
|
||||||
|
}
|
||||||
|
}
|
@ -59,8 +59,9 @@
|
|||||||
href="#">Resource Limits
|
href="#">Resource Limits
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
<a :class="activeTab === 'move' && 'text-white'"
|
<a :class="activeTab === 'resource-operations' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'move'; window.location.hash = 'move'" href="#">Move Resource
|
@click.prevent="activeTab = 'resource-operations'; window.location.hash = 'resource-operations'"
|
||||||
|
href="#">Resource Operations
|
||||||
</a>
|
</a>
|
||||||
<a :class="activeTab === 'danger' && 'text-white'"
|
<a :class="activeTab === 'danger' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'danger'; window.location.hash = 'danger'" href="#">Danger Zone
|
@click.prevent="activeTab = 'danger'; window.location.hash = 'danger'" href="#">Danger Zone
|
||||||
@ -108,8 +109,8 @@
|
|||||||
<div x-cloak x-show="activeTab === 'scheduled-tasks'">
|
<div x-cloak x-show="activeTab === 'scheduled-tasks'">
|
||||||
<livewire:project.shared.scheduled-task.all :resource="$application" />
|
<livewire:project.shared.scheduled-task.all :resource="$application" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'move'">
|
<div x-cloak x-show="activeTab === 'resource-operations'">
|
||||||
<livewire:project.shared.move-resource :resource="$application" />
|
<livewire:project.shared.resource-operations :resource="$application" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'danger'">
|
<div x-cloak x-show="activeTab === 'danger'">
|
||||||
<livewire:project.shared.danger :resource="$application" />
|
<livewire:project.shared.danger :resource="$application" />
|
||||||
|
@ -44,8 +44,9 @@
|
|||||||
window.location.hash = 'resource-limits'"
|
window.location.hash = 'resource-limits'"
|
||||||
href="#">Resource Limits
|
href="#">Resource Limits
|
||||||
</a>
|
</a>
|
||||||
<a :class="activeTab === 'move' && 'text-white'"
|
<a :class="activeTab === 'resource-operations' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'move'; window.location.hash = 'move'" href="#">Move Resource
|
@click.prevent="activeTab = 'resource-operations'; window.location.hash = 'resource-operations'"
|
||||||
|
href="#">Resource Operations
|
||||||
</a>
|
</a>
|
||||||
<a :class="activeTab === 'danger' && 'text-white'"
|
<a :class="activeTab === 'danger' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'danger';
|
@click.prevent="activeTab = 'danger';
|
||||||
@ -85,8 +86,8 @@
|
|||||||
<div x-cloak x-show="activeTab === 'import'">
|
<div x-cloak x-show="activeTab === 'import'">
|
||||||
<livewire:project.database.import :resource="$database" />
|
<livewire:project.database.import :resource="$database" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'move'">
|
<div x-cloak x-show="activeTab === 'resource-operations'">
|
||||||
<livewire:project.shared.move-resource :resource="$database" />
|
<livewire:project.shared.resource-operations :resource="$database" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'danger'">
|
<div x-cloak x-show="activeTab === 'danger'">
|
||||||
<livewire:project.shared.danger :resource="$database" />
|
<livewire:project.shared.danger :resource="$database" />
|
||||||
|
@ -26,9 +26,10 @@
|
|||||||
<a :class="activeTab === 'webhooks' && 'text-white'"
|
<a :class="activeTab === 'webhooks' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'webhooks'; window.location.hash = 'webhooks'" href="#">Webhooks
|
@click.prevent="activeTab = 'webhooks'; window.location.hash = 'webhooks'" href="#">Webhooks
|
||||||
</a>
|
</a>
|
||||||
<a :class="activeTab === 'move' && 'text-white'"
|
<a :class="activeTab === 'resource-operations' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'move'; window.location.hash = 'move'" href="#">Move Resource
|
@click.prevent="activeTab = 'resource-operations'; window.location.hash = 'resource-operations'"
|
||||||
</a>
|
href="#">Resource Operations
|
||||||
|
</a>
|
||||||
<a :class="activeTab === 'danger' && 'text-white'"
|
<a :class="activeTab === 'danger' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'danger';
|
@click.prevent="activeTab = 'danger';
|
||||||
window.location.hash = 'danger'"
|
window.location.hash = 'danger'"
|
||||||
@ -160,8 +161,8 @@
|
|||||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||||
<livewire:project.shared.environment-variable.all :resource="$service" />
|
<livewire:project.shared.environment-variable.all :resource="$service" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'move'">
|
<div x-cloak x-show="activeTab === 'resource-operations'">
|
||||||
<livewire:project.shared.move-resource :resource="$service" />
|
<livewire:project.shared.resource-operations :resource="$service" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'danger'">
|
<div x-cloak x-show="activeTab === 'danger'">
|
||||||
<livewire:project.shared.danger :resource="$service" />
|
<livewire:project.shared.danger :resource="$service" />
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
<div>
|
|
||||||
<h2>Move Resource</h2>
|
|
||||||
<div class="pb-4">You can easily move this resource to another project.</div>
|
|
||||||
<div>
|
|
||||||
<div class="pb-8">
|
|
||||||
This resource is currently in the <span
|
|
||||||
class="font-bold text-warning">{{ $resource->environment->project->name }} /
|
|
||||||
{{ $resource->environment->name }}</span> environment.
|
|
||||||
</div>
|
|
||||||
<div class="grid grid-flow-col grid-rows-2 gap-4">
|
|
||||||
@forelse ($projects as $project)
|
|
||||||
<div class="grid grid-flow-col grid-rows-2 gap-4">
|
|
||||||
@foreach ($project->environments as $environment)
|
|
||||||
<div class="flex flex-col gap-2 box" wire:click="moveTo('{{ data_get($environment, 'id') }}')">
|
|
||||||
<div class="font-bold text-white">{{ $project->name }}</div>
|
|
||||||
<div><span class="text-warning">{{ $environment->name }}</span> environment</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
@empty
|
|
||||||
<div>No projects found to move to</div>
|
|
||||||
@endforelse
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -0,0 +1,46 @@
|
|||||||
|
<div>
|
||||||
|
<h2>Resource Operations</h2>
|
||||||
|
<div class="pb-4">You can easily make different kind of operations on this resource.</div>
|
||||||
|
<h4>Clone</h4>
|
||||||
|
<div class="pb-8">
|
||||||
|
<div class="pb-8">
|
||||||
|
Clone this resource to another project / environment.
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
@foreach ($servers->sortBy('id') as $server)
|
||||||
|
<div>
|
||||||
|
<div class="grid grid-cols-1 gap-2 pb-4 lg:grid-cols-4">
|
||||||
|
@foreach ($server->destinations() as $destination)
|
||||||
|
<div class="flex flex-col gap-2 box" wire:click="cloneTo('{{ data_get($destination, 'id') }}')">
|
||||||
|
<div class="font-bold text-white">{{ $server->name }}</div>
|
||||||
|
<div>{{ $destination->name }}</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4>Move</h4>
|
||||||
|
<div>
|
||||||
|
<div class="pb-8">
|
||||||
|
This resource is currently in the <span
|
||||||
|
class="font-bold text-warning">{{ $resource->environment->project->name }} /
|
||||||
|
{{ $resource->environment->name }}</span> environment.
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-4">
|
||||||
|
@forelse ($projects as $project)
|
||||||
|
<div class="flex flex-row flex-wrap gap-2">
|
||||||
|
@foreach ($project->environments as $environment)
|
||||||
|
<div class="flex flex-col gap-2 box" wire:click="moveTo('{{ data_get($environment, 'id') }}')">
|
||||||
|
<div class="font-bold text-white">{{ $project->name }}</div>
|
||||||
|
<div><span class="text-warning">{{ $environment->name }}</span> environment</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@empty
|
||||||
|
<div>No projects found to move to</div>
|
||||||
|
@endforelse
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user