2024-02-02 10:50:28 +00:00
< ? php
namespace App\Http\Controllers\Api ;
2024-04-10 13:00:46 +00:00
use App\Actions\Database\StartClickhouse ;
use App\Actions\Database\StartDragonfly ;
use App\Actions\Database\StartKeydb ;
2024-02-02 10:50:28 +00:00
use App\Actions\Database\StartMariadb ;
use App\Actions\Database\StartMongodb ;
use App\Actions\Database\StartMysql ;
use App\Actions\Database\StartPostgresql ;
use App\Actions\Database\StartRedis ;
use App\Actions\Service\StartService ;
use App\Http\Controllers\Controller ;
2024-03-07 11:27:23 +00:00
use App\Models\ApplicationDeploymentQueue ;
use App\Models\Server ;
2024-02-02 10:50:28 +00:00
use App\Models\Tag ;
use Illuminate\Http\Request ;
use Visus\Cuid2\Cuid2 ;
2024-07-01 14:26:50 +00:00
class DeployController extends Controller
2024-02-02 10:50:28 +00:00
{
2024-07-02 10:15:58 +00:00
private function removeSensitiveData ( $deployment )
{
$token = auth () -> user () -> currentAccessToken ();
if ( $token -> can ( 'view:sensitive' )) {
return serializeApiResponse ( $deployment );
}
$deployment -> makeHidden ([
'logs' ,
]);
return serializeApiResponse ( $deployment );
}
2024-03-11 08:42:02 +00:00
public function deployments ( Request $request )
{
2024-07-01 14:26:50 +00:00
$teamId = getTeamIdFromToken ();
2024-03-07 11:27:23 +00:00
if ( is_null ( $teamId )) {
2024-07-01 14:26:50 +00:00
return invalidTokenResponse ();
2024-03-07 11:27:23 +00:00
}
$servers = Server :: whereTeamId ( $teamId ) -> get ();
2024-06-10 20:43:34 +00:00
$deployments_per_server = ApplicationDeploymentQueue :: whereIn ( 'status' , [ 'in_progress' , 'queued' ]) -> whereIn ( 'server_id' , $servers -> pluck ( 'id' )) -> get ([
'id' ,
'application_id' ,
'application_name' ,
'deployment_url' ,
'pull_request_id' ,
'server_name' ,
'server_id' ,
'status' ,
2024-03-07 11:27:23 +00:00
]) -> sortBy ( 'id' ) -> toArray ();
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response () -> json ([
'success' => true ,
'data' => serializeApiResponse ( $deployments_per_server ),
]);
2024-06-21 14:46:13 +00:00
}
public function deployment_by_uuid ( Request $request )
{
2024-07-01 14:26:50 +00:00
$teamId = getTeamIdFromToken ();
2024-06-21 14:46:13 +00:00
if ( is_null ( $teamId )) {
2024-07-01 14:26:50 +00:00
return invalidTokenResponse ();
2024-06-21 14:46:13 +00:00
}
$uuid = $request -> route ( 'uuid' );
if ( ! $uuid ) {
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'UUID is required.' ], 400 );
2024-06-21 14:46:13 +00:00
}
2024-06-26 11:00:36 +00:00
$deployment = ApplicationDeploymentQueue :: where ( 'deployment_uuid' , $uuid ) -> first ();
2024-06-21 14:46:13 +00:00
if ( ! $deployment ) {
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'Deployment not found.' ], 404 );
2024-06-21 14:46:13 +00:00
}
2024-07-01 14:26:50 +00:00
return response () -> json ([
'success' => true ,
2024-07-02 10:15:58 +00:00
'data' => $this -> removeSensitiveData ( $deployment ),
2024-07-01 14:26:50 +00:00
]);
2024-03-07 11:27:23 +00:00
}
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
public function deploy ( Request $request )
{
2024-07-01 14:26:50 +00:00
$teamId = getTeamIdFromToken ();
2024-02-02 10:50:28 +00:00
$uuids = $request -> query -> get ( 'uuid' );
$tags = $request -> query -> get ( 'tag' );
$force = $request -> query -> get ( 'force' ) ? ? false ;
if ( $uuids && $tags ) {
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'You can only use uuid or tag, not both.' , 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook' ], 400 );
2024-02-02 10:50:28 +00:00
}
if ( is_null ( $teamId )) {
2024-07-01 14:26:50 +00:00
return invalidTokenResponse ();
2024-02-02 10:50:28 +00:00
}
if ( $tags ) {
return $this -> by_tags ( $tags , $teamId , $force );
2024-06-10 20:43:34 +00:00
} elseif ( $uuids ) {
2024-02-02 10:50:28 +00:00
return $this -> by_uuids ( $uuids , $teamId , $force );
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'You must provide uuid or tag.' , 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook' ], 400 );
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
private function by_uuids ( string $uuid , int $teamId , bool $force = false )
{
$uuids = explode ( ',' , $uuid );
$uuids = collect ( array_filter ( $uuids ));
if ( count ( $uuids ) === 0 ) {
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'No UUIDs provided.' , 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook' ], 400 );
2024-02-02 10:50:28 +00:00
}
2024-03-07 11:22:18 +00:00
$deployments = collect ();
$payload = collect ();
2024-02-02 10:50:28 +00:00
foreach ( $uuids as $uuid ) {
$resource = getResourceByUuid ( $uuid , $teamId );
if ( $resource ) {
2024-03-07 11:22:18 +00:00
[ 'message' => $return_message , 'deployment_uuid' => $deployment_uuid ] = $this -> deploy_resource ( $resource , $force );
if ( $deployment_uuid ) {
2024-07-01 14:26:50 +00:00
$deployments -> push ([ 'success' => true , 'message' => $return_message , 'resource_uuid' => $uuid , 'deployment_uuid' => $deployment_uuid -> toString ()]);
2024-03-11 08:42:02 +00:00
} else {
2024-07-01 14:26:50 +00:00
$deployments -> push ([ 'success' => true , 'message' => $return_message , 'resource_uuid' => $uuid ]);
2024-03-07 11:22:18 +00:00
}
2024-02-02 10:50:28 +00:00
}
}
2024-03-11 08:42:02 +00:00
if ( $deployments -> count () > 0 ) {
$payload -> put ( 'deployments' , $deployments -> toArray ());
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response () -> json ([
'success' => true ,
'data' => serializeApiResponse ( $payload -> toArray ()),
]);
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'No resources found.' , 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook' ], 404 );
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
public function by_tags ( string $tags , int $team_id , bool $force = false )
{
$tags = explode ( ',' , $tags );
$tags = collect ( array_filter ( $tags ));
if ( count ( $tags ) === 0 ) {
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'No TAGs provided.' , 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook' ], 400 );
2024-02-02 10:50:28 +00:00
}
$message = collect ([]);
2024-03-07 11:22:18 +00:00
$deployments = collect ();
$payload = collect ();
2024-02-02 10:50:28 +00:00
foreach ( $tags as $tag ) {
$found_tag = Tag :: where ([ 'name' => $tag , 'team_id' => $team_id ]) -> first ();
2024-06-10 20:43:34 +00:00
if ( ! $found_tag ) {
2024-03-07 11:35:38 +00:00
// $message->push("Tag {$tag} not found.");
2024-02-02 10:50:28 +00:00
continue ;
}
2024-02-06 06:21:06 +00:00
$applications = $found_tag -> applications () -> get ();
$services = $found_tag -> services () -> get ();
2024-02-03 11:39:07 +00:00
if ( $applications -> count () === 0 && $services -> count () === 0 ) {
2024-02-02 10:50:28 +00:00
$message -> push ( " No resources found for tag { $tag } . " );
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
continue ;
}
2024-02-03 11:39:07 +00:00
foreach ( $applications as $resource ) {
2024-03-07 11:22:18 +00:00
[ 'message' => $return_message , 'deployment_uuid' => $deployment_uuid ] = $this -> deploy_resource ( $resource , $force );
if ( $deployment_uuid ) {
$deployments -> push ([ 'resource_uuid' => $resource -> uuid , 'deployment_uuid' => $deployment_uuid -> toString ()]);
}
2024-02-03 11:39:07 +00:00
$message = $message -> merge ( $return_message );
}
foreach ( $services as $resource ) {
2024-03-07 11:22:18 +00:00
[ 'message' => $return_message ] = $this -> deploy_resource ( $resource , $force );
2024-02-02 10:50:28 +00:00
$message = $message -> merge ( $return_message );
}
}
if ( $message -> count () > 0 ) {
2024-03-07 11:22:18 +00:00
$payload -> put ( 'message' , $message -> toArray ());
if ( $deployments -> count () > 0 ) {
$payload -> put ( 'details' , $deployments -> toArray ());
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return response () -> json ([
'success' => true ,
'data' => serializeApiResponse ( $payload -> toArray ()),
]);
2024-02-02 10:50:28 +00:00
}
2024-07-01 14:26:50 +00:00
return response () -> json ([ 'success' => false , 'message' => 'No resources found with this tag.' , 'docs' => 'https://coolify.io/docs/api-reference/deploy-webhook' ], 404 );
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-03-07 11:22:18 +00:00
public function deploy_resource ( $resource , bool $force = false ) : array
2024-02-02 10:50:28 +00:00
{
2024-03-11 08:42:02 +00:00
$message = null ;
$deployment_uuid = null ;
2024-02-06 06:19:11 +00:00
if ( gettype ( $resource ) !== 'object' ) {
2024-07-01 14:26:50 +00:00
return [ 'success' => false , 'message' => " Resource ( $resource ) not found. " , 'deployment_uuid' => $deployment_uuid ];
2024-02-06 06:19:11 +00:00
}
2024-02-06 06:12:09 +00:00
$type = $resource ? -> getMorphClass ();
2024-02-02 10:50:28 +00:00
if ( $type === 'App\Models\Application' ) {
2024-03-07 11:22:18 +00:00
$deployment_uuid = new Cuid2 ( 7 );
2024-02-02 10:50:28 +00:00
queue_application_deployment (
application : $resource ,
2024-03-07 11:22:18 +00:00
deployment_uuid : $deployment_uuid ,
2024-02-02 10:50:28 +00:00
force_rebuild : $force ,
);
2024-03-11 08:42:02 +00:00
$message = " Application { $resource -> name } deployment queued. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandalonePostgresql' ) {
2024-02-02 10:50:28 +00:00
StartPostgresql :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
2024-03-11 08:42:02 +00:00
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandaloneRedis' ) {
2024-02-02 10:50:28 +00:00
StartRedis :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
2024-03-11 08:42:02 +00:00
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandaloneKeydb' ) {
2024-04-10 13:00:46 +00:00
StartKeydb :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandaloneDragonfly' ) {
2024-04-10 13:00:46 +00:00
StartDragonfly :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandaloneClickhouse' ) {
2024-04-10 13:00:46 +00:00
StartClickhouse :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandaloneMongodb' ) {
2024-02-02 10:50:28 +00:00
StartMongodb :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
2024-03-11 08:42:02 +00:00
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandaloneMysql' ) {
2024-02-02 10:50:28 +00:00
StartMysql :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
2024-03-11 08:42:02 +00:00
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\StandaloneMariadb' ) {
2024-02-02 10:50:28 +00:00
StartMariadb :: run ( $resource );
$resource -> update ([
'started_at' => now (),
]);
2024-03-11 08:42:02 +00:00
$message = " Database { $resource -> name } started. " ;
2024-06-10 20:43:34 +00:00
} elseif ( $type === 'App\Models\Service' ) {
2024-02-02 10:50:28 +00:00
StartService :: run ( $resource );
2024-03-11 08:42:02 +00:00
$message = " Service { $resource -> name } started. It could take a while, be patient. " ;
2024-02-02 10:50:28 +00:00
}
2024-06-10 20:43:34 +00:00
2024-07-01 14:26:50 +00:00
return [ 'success' => true , 'message' => $message , 'deployment_uuid' => $deployment_uuid ];
2024-02-02 10:50:28 +00:00
}
}