2023-10-20 10:34:53 +00:00
< ? php
2023-12-07 18:06:32 +00:00
namespace App\Livewire\Project ;
2023-10-20 10:34:53 +00:00
use App\Models\Environment ;
use App\Models\Project ;
use App\Models\Server ;
use Livewire\Component ;
use Visus\Cuid2\Cuid2 ;
2024-01-07 15:23:41 +00:00
class CloneMe extends Component
2023-10-20 10:34:53 +00:00
{
public string $project_uuid ;
2024-06-10 20:43:34 +00:00
2024-11-22 15:03:20 +00:00
public string $environment_uuid ;
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public int $project_id ;
public Project $project ;
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public $environments ;
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public $servers ;
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public ? Environment $environment = null ;
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public ? int $selectedServer = null ;
2024-06-10 20:43:34 +00:00
2023-12-13 13:22:23 +00:00
public ? int $selectedDestination = null ;
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public ? Server $server = null ;
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public $resources = [];
2024-06-10 20:43:34 +00:00
2024-02-04 15:54:12 +00:00
public string $newName = '' ;
2023-10-20 10:34:53 +00:00
protected $messages = [
'selectedServer' => 'Please select a server.' ,
2023-12-13 13:22:23 +00:00
'selectedDestination' => 'Please select a server & destination.' ,
2024-02-04 15:54:12 +00:00
'newName' => 'Please enter a name for the new project or environment.' ,
2023-10-20 10:34:53 +00:00
];
2024-06-10 20:43:34 +00:00
2023-10-20 10:34:53 +00:00
public function mount ( $project_uuid )
{
$this -> project_uuid = $project_uuid ;
2025-01-07 14:31:43 +00:00
$this -> project = Project :: where ( 'uuid' , $project_uuid ) -> firstOrFail ();
2024-11-22 15:03:20 +00:00
$this -> environment = $this -> project -> environments -> where ( 'uuid' , $this -> environment_uuid ) -> first ();
2023-10-20 10:34:53 +00:00
$this -> project_id = $this -> project -> id ;
$this -> servers = currentTeam () -> servers ;
2025-01-07 14:31:43 +00:00
$this -> newName = str ( $this -> project -> name . '-clone-' . ( string ) new Cuid2 ) -> slug ();
2023-10-20 10:34:53 +00:00
}
public function render ()
{
2024-01-07 15:23:41 +00:00
return view ( 'livewire.project.clone-me' );
2023-10-20 10:34:53 +00:00
}
2023-12-13 13:22:23 +00:00
public function selectServer ( $server_id , $destination_id )
2023-10-20 10:34:53 +00:00
{
2024-02-04 15:54:12 +00:00
if ( $server_id == $this -> selectedServer && $destination_id == $this -> selectedDestination ) {
$this -> selectedServer = null ;
$this -> selectedDestination = null ;
$this -> server = null ;
2024-06-10 20:43:34 +00:00
2024-02-04 15:54:12 +00:00
return ;
}
2023-10-20 10:34:53 +00:00
$this -> selectedServer = $server_id ;
2023-12-13 13:22:23 +00:00
$this -> selectedDestination = $destination_id ;
2023-10-20 10:34:53 +00:00
$this -> server = $this -> servers -> where ( 'id' , $server_id ) -> first ();
}
2024-02-04 15:54:12 +00:00
public function clone ( string $type )
2023-10-20 10:34:53 +00:00
{
try {
$this -> validate ([
2023-12-13 13:22:23 +00:00
'selectedDestination' => 'required' ,
2024-02-04 15:54:12 +00:00
'newName' => 'required' ,
2023-10-20 10:34:53 +00:00
]);
2024-02-04 15:54:12 +00:00
if ( $type === 'project' ) {
2025-01-07 14:31:43 +00:00
$foundProject = Project :: where ( 'name' , $this -> newName ) -> first ();
2024-02-04 15:54:12 +00:00
if ( $foundProject ) {
2025-01-07 14:31:43 +00:00
throw new \Exception ( 'Project with the same name already exists.' );
2024-02-04 15:54:12 +00:00
}
2025-01-07 14:31:43 +00:00
$project = Project :: create ([
2024-02-04 15:54:12 +00:00
'name' => $this -> newName ,
'team_id' => currentTeam () -> id ,
2024-06-10 20:43:34 +00:00
'description' => $this -> project -> description . ' (clone)' ,
2024-02-04 15:54:12 +00:00
]);
if ( $this -> environment -> name !== 'production' ) {
$project -> environments () -> create ([
'name' => $this -> environment -> name ,
2024-11-22 15:03:20 +00:00
'uuid' => ( string ) new Cuid2 ,
2024-02-04 15:54:12 +00:00
]);
}
$environment = $project -> environments -> where ( 'name' , $this -> environment -> name ) -> first ();
} else {
$foundEnv = $this -> project -> environments () -> where ( 'name' , $this -> newName ) -> first ();
if ( $foundEnv ) {
2025-01-07 14:31:43 +00:00
throw new \Exception ( 'Environment with the same name already exists.' );
2024-02-04 15:54:12 +00:00
}
$project = $this -> project ;
$environment = $this -> project -> environments () -> create ([
'name' => $this -> newName ,
2024-11-22 15:03:20 +00:00
'uuid' => ( string ) new Cuid2 ,
2023-10-20 10:34:53 +00:00
]);
}
$applications = $this -> environment -> applications ;
$databases = $this -> environment -> databases ();
$services = $this -> environment -> services ;
foreach ( $applications as $application ) {
2024-07-25 11:31:59 +00:00
$uuid = ( string ) new Cuid2 ;
2025-01-07 16:18:04 +00:00
$newApplication = $application -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
'additional_servers_count' ,
'additional_networks_count' ,
]) -> fill ([
2023-10-20 10:34:53 +00:00
'uuid' => $uuid ,
2025-01-08 15:26:02 +00:00
'fqdn' => generateFqdn ( $this -> server , $uuid ), // this also needs a condition
2023-10-20 10:34:53 +00:00
'status' => 'exited' ,
2024-02-04 15:54:12 +00:00
'environment_id' => $environment -> id ,
2023-12-13 13:22:23 +00:00
'destination_id' => $this -> selectedDestination ,
2023-10-20 10:34:53 +00:00
]);
$newApplication -> save ();
2025-01-07 19:27:54 +00:00
2025-01-08 15:26:02 +00:00
if ( $newApplication -> destination -> server -> proxyType () !== 'NONE' || ! $newApplication -> application_settings -> is_container_label_readonly_enabled ) { // fix after switching this logic up
$customLabels = str ( implode ( '|coolify|' , generateLabelsApplication ( $newApplication ))) -> replace ( '|coolify|' , " \n " );
$newApplication -> custom_labels = base64_encode ( $customLabels );
$newApplication -> save ();
}
$newApplication -> settings () -> delete ();
2025-01-07 19:27:54 +00:00
$applicationSettings = $application -> settings ;
if ( $applicationSettings ) {
$newApplicationSettings = $applicationSettings -> replicate ([
2025-01-07 16:18:04 +00:00
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
2025-01-07 19:27:54 +00:00
'application_id' => $newApplication -> id ,
2023-10-20 10:34:53 +00:00
]);
2025-01-07 19:27:54 +00:00
$newApplicationSettings -> save ();
2023-10-20 10:34:53 +00:00
}
2025-01-07 19:27:54 +00:00
$tags = $application -> tags ;
foreach ( $tags as $tag ) {
$newApplication -> tags () -> attach ( $tag -> id );
}
$scheduledTasks = $application -> scheduled_tasks () -> get ();
foreach ( $scheduledTasks as $task ) {
$newTask = $task -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'uuid' => ( string ) new Cuid2 ,
'application_id' => $newApplication -> id ,
'team_id' => currentTeam () -> id ,
]);
$newTask -> save ();
}
$applicationPreviews = $application -> previews () -> get ();
foreach ( $applicationPreviews as $preview ) {
$newPreview = $preview -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'application_id' => $newApplication -> id ,
'status' => 'exited' ,
]);
$newPreview -> save ();
}
2023-10-20 10:34:53 +00:00
$persistentVolumes = $application -> persistentStorages () -> get ();
2025-01-07 14:31:43 +00:00
foreach ( $persistentVolumes as $volume ) {
2025-01-07 16:18:04 +00:00
$newPersistentVolume = $volume -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
2025-01-07 14:31:43 +00:00
'name' => $newApplication -> uuid . '-' . str ( $volume -> name ) -> afterLast ( '-' ),
2023-10-20 10:34:53 +00:00
'resource_id' => $newApplication -> id ,
]);
$newPersistentVolume -> save ();
}
2025-01-07 19:27:54 +00:00
$fileStorages = $application -> fileStorages () -> get ();
foreach ( $fileStorages as $storage ) {
$newStorage = $storage -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'resource_id' => $newApplication -> id ,
]);
$newStorage -> save ();
}
$environmentVaribles = $application -> environment_variables () -> get ();
foreach ( $environmentVaribles as $environmentVarible ) {
$newEnvironmentVariable = $environmentVarible -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'resourceable_id' => $newApplication -> id ,
]);
$newEnvironmentVariable -> save ();
}
2023-10-20 10:34:53 +00:00
}
2025-01-07 19:27:54 +00:00
2023-10-20 10:34:53 +00:00
foreach ( $databases as $database ) {
2024-07-25 11:31:59 +00:00
$uuid = ( string ) new Cuid2 ;
2025-01-07 16:18:04 +00:00
$newDatabase = $database -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
2023-10-20 10:34:53 +00:00
'uuid' => $uuid ,
2023-11-07 11:11:47 +00:00
'status' => 'exited' ,
2023-11-08 08:07:30 +00:00
'started_at' => null ,
2024-02-04 15:54:12 +00:00
'environment_id' => $environment -> id ,
2023-12-13 13:22:23 +00:00
'destination_id' => $this -> selectedDestination ,
2023-10-20 10:34:53 +00:00
]);
$newDatabase -> save ();
2025-01-08 15:26:02 +00:00
$tags = $database -> tags ;
foreach ( $tags as $tag ) {
$newDatabase -> tags () -> attach ( $tag -> id );
}
$newDatabase -> persistentStorages () -> delete ();
$persistentVolumes = $database -> persistentStorages () -> get ();
foreach ( $persistentVolumes as $volume ) {
$originalName = $volume -> name ;
$newName = '' ;
if ( str_starts_with ( $originalName , 'postgres-data-' )) {
$newName = 'postgres-data-' . $newDatabase -> uuid ;
} else {
$newName = str ( $originalName )
-> replaceFirst ( $database -> uuid , $newDatabase -> uuid )
-> toString ();
}
$newPersistentVolume = $volume -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'name' => $newName ,
'resource_id' => $newDatabase -> id ,
]);
$newPersistentVolume -> save ();
}
$fileStorages = $database -> fileStorages () -> get ();
foreach ( $fileStorages as $storage ) {
$newStorage = $storage -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'resource_id' => $newDatabase -> id ,
]);
$newStorage -> save ();
}
$scheduledBackups = $database -> scheduledBackups () -> get ();
foreach ( $scheduledBackups as $backup ) {
$uuid = ( string ) new Cuid2 ;
$newBackup = $backup -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'uuid' => $uuid ,
'database_id' => $newDatabase -> id ,
'database_type' => $newDatabase -> getMorphClass (),
'team_id' => currentTeam () -> id ,
]);
$newBackup -> save ();
}
2023-10-20 10:34:53 +00:00
$environmentVaribles = $database -> environment_variables () -> get ();
foreach ( $environmentVaribles as $environmentVarible ) {
$payload = [];
2024-12-17 09:38:32 +00:00
$payload [ 'resourceable_id' ] = $newDatabase -> id ;
$payload [ 'resourceable_type' ] = $newDatabase -> getMorphClass ();
2025-01-07 16:18:04 +00:00
$newEnvironmentVariable = $environmentVarible -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ( $payload );
2023-10-20 10:34:53 +00:00
$newEnvironmentVariable -> save ();
}
}
2025-01-08 15:26:02 +00:00
2023-10-20 10:34:53 +00:00
foreach ( $services as $service ) {
2024-07-25 11:31:59 +00:00
$uuid = ( string ) new Cuid2 ;
2025-01-07 16:18:04 +00:00
$newService = $service -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
2023-10-20 10:34:53 +00:00
'uuid' => $uuid ,
2024-02-04 15:54:12 +00:00
'environment_id' => $environment -> id ,
2023-12-13 13:22:23 +00:00
'destination_id' => $this -> selectedDestination ,
2023-10-20 10:34:53 +00:00
]);
$newService -> save ();
2025-01-08 15:26:02 +00:00
$tags = $service -> tags ;
foreach ( $tags as $tag ) {
$newService -> tags () -> attach ( $tag -> id );
}
$scheduledTasks = $service -> scheduled_tasks () -> get ();
foreach ( $scheduledTasks as $task ) {
$newTask = $task -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'uuid' => ( string ) new Cuid2 ,
'service_id' => $newService -> id ,
'team_id' => currentTeam () -> id ,
]);
$newTask -> save ();
}
$environmentVariables = $service -> environment_variables () -> get ();
foreach ( $environmentVariables as $environmentVariable ) {
$newEnvironmentVariable = $environmentVariable -> replicate ([
'id' ,
'created_at' ,
'updated_at' ,
]) -> fill ([
'resourceable_id' => $newService -> id ,
'resourceable_type' => $newService -> getMorphClass (),
]);
$newEnvironmentVariable -> save ();
}
2023-11-07 11:11:47 +00:00
foreach ( $newService -> applications () as $application ) {
$application -> update ([
'status' => 'exited' ,
]);
}
2025-01-08 15:26:02 +00:00
2023-11-07 11:11:47 +00:00
foreach ( $newService -> databases () as $database ) {
$database -> update ([
'status' => 'exited' ,
]);
}
2025-01-08 15:26:02 +00:00
2023-10-20 10:34:53 +00:00
$newService -> parse ();
}
2024-06-10 20:43:34 +00:00
2025-01-07 14:31:43 +00:00
} catch ( \Exception $e ) {
2025-01-08 15:26:02 +00:00
handleError ( $e , $this );
return ;
} finally {
if ( ! isset ( $e )) {
return redirect () -> route ( 'project.resource.index' , [
'project_uuid' => $project -> uuid ,
'environment_uuid' => $environment -> uuid ,
]);
}
2023-10-20 10:34:53 +00:00
}
}
}