feat: initial api endpoints
feat: server resources are now looks better
This commit is contained in:
parent
3539e4dce9
commit
b8708f086e
@ -18,8 +18,7 @@ class Deploy extends Controller
|
|||||||
{
|
{
|
||||||
public function deploy(Request $request)
|
public function deploy(Request $request)
|
||||||
{
|
{
|
||||||
$token = auth()->user()->currentAccessToken();
|
$teamId = get_team_id_from_token();
|
||||||
$teamId = data_get($token, 'team_id');
|
|
||||||
$uuids = $request->query->get('uuid');
|
$uuids = $request->query->get('uuid');
|
||||||
$tags = $request->query->get('tag');
|
$tags = $request->query->get('tag');
|
||||||
$force = $request->query->get('force') ?? false;
|
$force = $request->query->get('force') ?? false;
|
||||||
|
39
app/Http/Controllers/Api/Project.php
Normal file
39
app/Http/Controllers/Api/Project.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Project as ModelsProject;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class Project extends Controller
|
||||||
|
{
|
||||||
|
public function projects(Request $request)
|
||||||
|
{
|
||||||
|
$teamId = get_team_id_from_token();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400);
|
||||||
|
}
|
||||||
|
$projects = ModelsProject::whereTeamId($teamId)->select('id', 'name', 'uuid')->get();
|
||||||
|
return response()->json($projects);
|
||||||
|
}
|
||||||
|
public function project_by_uuid(Request $request)
|
||||||
|
{
|
||||||
|
$teamId = get_team_id_from_token();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400);
|
||||||
|
}
|
||||||
|
$project = ModelsProject::whereTeamId($teamId)->whereUuid(request()->uuid)->first()->load(['environments']);
|
||||||
|
return response()->json($project);
|
||||||
|
}
|
||||||
|
public function environment_details(Request $request)
|
||||||
|
{
|
||||||
|
$teamId = get_team_id_from_token();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400);
|
||||||
|
}
|
||||||
|
$project = ModelsProject::whereTeamId($teamId)->whereUuid(request()->uuid)->first();
|
||||||
|
$environment = $project->environments()->whereName(request()->environment_name)->first()->load(['applications', 'postgresqls', 'redis', 'mongodbs', 'mysqls', 'mariadbs', 'services']);
|
||||||
|
return response()->json($environment);
|
||||||
|
}
|
||||||
|
}
|
54
app/Http/Controllers/Api/Server.php
Normal file
54
app/Http/Controllers/Api/Server.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Server as ModelsServer;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class Server extends Controller
|
||||||
|
{
|
||||||
|
public function servers(Request $request)
|
||||||
|
{
|
||||||
|
$teamId = get_team_id_from_token();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400);
|
||||||
|
}
|
||||||
|
$servers = ModelsServer::whereTeamId($teamId)->select('id', 'name', 'uuid', 'ip', 'user', 'port')->get()->load(['settings'])->map(function ($server) {
|
||||||
|
$server['is_reachable'] = $server->settings->is_reachable;
|
||||||
|
$server['is_usable'] = $server->settings->is_usable;
|
||||||
|
return $server;
|
||||||
|
});
|
||||||
|
ray($servers);
|
||||||
|
return response()->json($servers);
|
||||||
|
}
|
||||||
|
public function server_by_uuid(Request $request)
|
||||||
|
{
|
||||||
|
$teamId = get_team_id_from_token();
|
||||||
|
if (is_null($teamId)) {
|
||||||
|
return response()->json(['error' => 'Invalid token.', 'docs' => 'https://coolify.io/docs/api/authentication'], 400);
|
||||||
|
}
|
||||||
|
$server = ModelsServer::whereTeamId($teamId)->whereUuid(request()->uuid)->first();
|
||||||
|
if (is_null($server)) {
|
||||||
|
return response()->json(['error' => 'Server not found.'], 404);
|
||||||
|
}
|
||||||
|
$server->load(['settings']);
|
||||||
|
$server['resources'] = $server->definedResources()->map(function ($resource) {
|
||||||
|
$payload = [
|
||||||
|
'id' => $resource->id,
|
||||||
|
'uuid' => $resource->uuid,
|
||||||
|
'name' => $resource->name,
|
||||||
|
'type' => $resource->type(),
|
||||||
|
'created_at' => $resource->created_at,
|
||||||
|
'updated_at' => $resource->updated_at,
|
||||||
|
];
|
||||||
|
if ($resource->type() === 'service') {
|
||||||
|
$payload['status'] = $resource->status();
|
||||||
|
} else {
|
||||||
|
$payload['status'] = $resource->status;
|
||||||
|
}
|
||||||
|
return $payload;
|
||||||
|
});
|
||||||
|
return response()->json($server);
|
||||||
|
}
|
||||||
|
}
|
@ -104,7 +104,7 @@ public function mount()
|
|||||||
'environment_name' => data_get($service, 'environment.name'),
|
'environment_name' => data_get($service, 'environment.name'),
|
||||||
'service_uuid' => data_get($service, 'uuid')
|
'service_uuid' => data_get($service, 'uuid')
|
||||||
]);
|
]);
|
||||||
$service->status = serviceStatus($service);
|
$service->status = $service->status();
|
||||||
}
|
}
|
||||||
return $service;
|
return $service;
|
||||||
});
|
});
|
||||||
|
30
app/Livewire/Server/Resources.php
Normal file
30
app/Livewire/Server/Resources.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Server;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Resources extends Component
|
||||||
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
public ?Server $server = null;
|
||||||
|
public $parameters = [];
|
||||||
|
|
||||||
|
public function mount() {
|
||||||
|
$this->parameters = get_route_parameters();
|
||||||
|
try {
|
||||||
|
$this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
|
||||||
|
if (is_null($this->server)) {
|
||||||
|
return redirect()->route('server.index');
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.server.resources');
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,6 @@ public function applications()
|
|||||||
{
|
{
|
||||||
return $this->hasMany(Application::class);
|
return $this->hasMany(Application::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postgresqls()
|
public function postgresqls()
|
||||||
{
|
{
|
||||||
return $this->hasMany(StandalonePostgresql::class);
|
return $this->hasMany(StandalonePostgresql::class);
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
|
|
||||||
class ProjectSetting extends Model
|
class ProjectSetting extends Model
|
||||||
{
|
{
|
||||||
protected $fillable = [
|
protected $guarded = [];
|
||||||
'project_id'
|
|
||||||
];
|
public function project()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Project::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,6 +245,8 @@ public function databases()
|
|||||||
$mysqls = data_get($standaloneDocker, 'mysqls', collect([]));
|
$mysqls = data_get($standaloneDocker, 'mysqls', collect([]));
|
||||||
$mariadbs = data_get($standaloneDocker, 'mariadbs', collect([]));
|
$mariadbs = data_get($standaloneDocker, 'mariadbs', collect([]));
|
||||||
return $postgresqls->concat($redis)->concat($mongodbs)->concat($mysqls)->concat($mariadbs);
|
return $postgresqls->concat($redis)->concat($mongodbs)->concat($mysqls)->concat($mariadbs);
|
||||||
|
})->filter(function ($item) {
|
||||||
|
return data_get($item,'name') === 'coolify-db';
|
||||||
})->flatten();
|
})->flatten();
|
||||||
}
|
}
|
||||||
public function applications()
|
public function applications()
|
||||||
|
@ -28,6 +28,48 @@ public function tags()
|
|||||||
{
|
{
|
||||||
return $this->morphToMany(Tag::class, 'taggable');
|
return $this->morphToMany(Tag::class, 'taggable');
|
||||||
}
|
}
|
||||||
|
public function status() {
|
||||||
|
$foundRunning = false;
|
||||||
|
$isDegraded = false;
|
||||||
|
$foundRestaring = false;
|
||||||
|
$applications = $this->applications;
|
||||||
|
$databases = $this->databases;
|
||||||
|
foreach ($applications as $application) {
|
||||||
|
if ($application->exclude_from_status) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Str::of($application->status)->startsWith('running')) {
|
||||||
|
$foundRunning = true;
|
||||||
|
} else if (Str::of($application->status)->startsWith('restarting')) {
|
||||||
|
$foundRestaring = true;
|
||||||
|
} else {
|
||||||
|
$isDegraded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($databases as $database) {
|
||||||
|
if ($database->exclude_from_status) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Str::of($database->status)->startsWith('running')) {
|
||||||
|
$foundRunning = true;
|
||||||
|
} else if (Str::of($database->status)->startsWith('restarting')) {
|
||||||
|
$foundRestaring = true;
|
||||||
|
} else {
|
||||||
|
$isDegraded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($foundRestaring) {
|
||||||
|
return 'degraded';
|
||||||
|
}
|
||||||
|
if ($foundRunning && !$isDegraded) {
|
||||||
|
return 'running';
|
||||||
|
} else if ($foundRunning && $isDegraded) {
|
||||||
|
return 'degraded';
|
||||||
|
} else if (!$foundRunning && !$isDegraded) {
|
||||||
|
return 'exited';
|
||||||
|
}
|
||||||
|
return 'exited';
|
||||||
|
}
|
||||||
public function extraFields()
|
public function extraFields()
|
||||||
{
|
{
|
||||||
$fields = collect([]);
|
$fields = collect([]);
|
||||||
|
@ -82,6 +82,9 @@ public function tags()
|
|||||||
{
|
{
|
||||||
return $this->morphToMany(Tag::class, 'taggable');
|
return $this->morphToMany(Tag::class, 'taggable');
|
||||||
}
|
}
|
||||||
|
public function project() {
|
||||||
|
return data_get($this, 'environment.project');
|
||||||
|
}
|
||||||
public function team()
|
public function team()
|
||||||
{
|
{
|
||||||
return data_get($this, 'environment.project.team');
|
return data_get($this, 'environment.project.team');
|
||||||
|
@ -85,6 +85,9 @@ public function tags()
|
|||||||
{
|
{
|
||||||
return $this->morphToMany(Tag::class, 'taggable');
|
return $this->morphToMany(Tag::class, 'taggable');
|
||||||
}
|
}
|
||||||
|
public function project() {
|
||||||
|
return data_get($this, 'environment.project');
|
||||||
|
}
|
||||||
public function team()
|
public function team()
|
||||||
{
|
{
|
||||||
return data_get($this, 'environment.project.team');
|
return data_get($this, 'environment.project.team');
|
||||||
|
@ -82,6 +82,9 @@ public function tags()
|
|||||||
{
|
{
|
||||||
return $this->morphToMany(Tag::class, 'taggable');
|
return $this->morphToMany(Tag::class, 'taggable');
|
||||||
}
|
}
|
||||||
|
public function project() {
|
||||||
|
return data_get($this, 'environment.project');
|
||||||
|
}
|
||||||
public function team()
|
public function team()
|
||||||
{
|
{
|
||||||
return data_get($this, 'environment.project.team');
|
return data_get($this, 'environment.project.team');
|
||||||
|
@ -82,6 +82,10 @@ public function tags()
|
|||||||
{
|
{
|
||||||
return $this->morphToMany(Tag::class, 'taggable');
|
return $this->morphToMany(Tag::class, 'taggable');
|
||||||
}
|
}
|
||||||
|
public function project()
|
||||||
|
{
|
||||||
|
return data_get($this, 'environment.project');
|
||||||
|
}
|
||||||
public function link()
|
public function link()
|
||||||
{
|
{
|
||||||
if (data_get($this, 'environment.project.uuid')) {
|
if (data_get($this, 'environment.project.uuid')) {
|
||||||
|
@ -77,6 +77,10 @@ public function tags()
|
|||||||
{
|
{
|
||||||
return $this->morphToMany(Tag::class, 'taggable');
|
return $this->morphToMany(Tag::class, 'taggable');
|
||||||
}
|
}
|
||||||
|
public function project()
|
||||||
|
{
|
||||||
|
return data_get($this, 'environment.project');
|
||||||
|
}
|
||||||
public function team()
|
public function team()
|
||||||
{
|
{
|
||||||
return data_get($this, 'environment.project.team');
|
return data_get($this, 'environment.project.team');
|
||||||
|
@ -16,7 +16,7 @@ public function __construct(
|
|||||||
public Service $service,
|
public Service $service,
|
||||||
public string $complexStatus = 'exited',
|
public string $complexStatus = 'exited',
|
||||||
) {
|
) {
|
||||||
$this->complexStatus = serviceStatus($service);
|
$this->complexStatus = $service->status();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
7
bootstrap/helpers/api.php
Normal file
7
bootstrap/helpers/api.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function get_team_id_from_token()
|
||||||
|
{
|
||||||
|
$token = auth()->user()->currentAccessToken();
|
||||||
|
return data_get($token, 'team_id');
|
||||||
|
}
|
@ -21,49 +21,6 @@ function replaceVariables($variable)
|
|||||||
return $variable->replaceFirst('$', '')->replaceFirst('{', '')->replaceLast('}', '');
|
return $variable->replaceFirst('$', '')->replaceFirst('{', '')->replaceLast('}', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function serviceStatus(Service $service)
|
|
||||||
{
|
|
||||||
$foundRunning = false;
|
|
||||||
$isDegraded = false;
|
|
||||||
$foundRestaring = false;
|
|
||||||
$applications = $service->applications;
|
|
||||||
$databases = $service->databases;
|
|
||||||
foreach ($applications as $application) {
|
|
||||||
if ($application->exclude_from_status) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Str::of($application->status)->startsWith('running')) {
|
|
||||||
$foundRunning = true;
|
|
||||||
} else if (Str::of($application->status)->startsWith('restarting')) {
|
|
||||||
$foundRestaring = true;
|
|
||||||
} else {
|
|
||||||
$isDegraded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach ($databases as $database) {
|
|
||||||
if ($database->exclude_from_status) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Str::of($database->status)->startsWith('running')) {
|
|
||||||
$foundRunning = true;
|
|
||||||
} else if (Str::of($database->status)->startsWith('restarting')) {
|
|
||||||
$foundRestaring = true;
|
|
||||||
} else {
|
|
||||||
$isDegraded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($foundRestaring) {
|
|
||||||
return 'degraded';
|
|
||||||
}
|
|
||||||
if ($foundRunning && !$isDegraded) {
|
|
||||||
return 'running';
|
|
||||||
} else if ($foundRunning && $isDegraded) {
|
|
||||||
return 'degraded';
|
|
||||||
} else if (!$foundRunning && !$isDegraded) {
|
|
||||||
return 'exited';
|
|
||||||
}
|
|
||||||
return 'exited';
|
|
||||||
}
|
|
||||||
function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase $oneService, bool $isInit = false)
|
function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase $oneService, bool $isInit = false)
|
||||||
{
|
{
|
||||||
// TODO: make this async
|
// TODO: make this async
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
]) }}">
|
]) }}">
|
||||||
<button>General</button>
|
<button>General</button>
|
||||||
</a>
|
</a>
|
||||||
|
<a class="{{ request()->routeIs('server.resources') ? 'text-white' : '' }}"
|
||||||
|
href="{{ route('server.resources', [
|
||||||
|
'server_uuid' => data_get($parameters, 'server_uuid'),
|
||||||
|
]) }}">
|
||||||
|
<button>Resources</button>
|
||||||
|
</a>
|
||||||
<a class="{{ request()->routeIs('server.private-key') ? 'text-white' : '' }}"
|
<a class="{{ request()->routeIs('server.private-key') ? 'text-white' : '' }}"
|
||||||
href="{{ route('server.private-key', [
|
href="{{ route('server.private-key', [
|
||||||
'server_uuid' => data_get($parameters, 'server_uuid'),
|
'server_uuid' => data_get($parameters, 'server_uuid'),
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<x-services.links />
|
<x-services.links />
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
@if (serviceStatus($service) === 'degraded')
|
@if ($service->status() === 'degraded')
|
||||||
<button wire:click='deploy' onclick="startService.showModal()"
|
<button wire:click='deploy' onclick="startService.showModal()"
|
||||||
class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||||
<svg class="w-5 h-5 text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-5 h-5 text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
@ -26,7 +26,7 @@ class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400"
|
|||||||
Stop
|
Stop
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
@if (serviceStatus($service) === 'running')
|
@if ($service->status() === 'running')
|
||||||
<button wire:click='restart' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
<button wire:click='restart' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||||
<svg class="w-5 h-5 text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-5 h-5 text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||||
@ -47,7 +47,7 @@ class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400"
|
|||||||
Stop
|
Stop
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
@if (serviceStatus($service) === 'exited')
|
@if ($service->status() === 'exited')
|
||||||
<button wire:click='stop(true)'
|
<button wire:click='stop(true)'
|
||||||
class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||||
<svg class="w-5 h-5 " viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-5 h-5 " viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
@props(['status', 'showRefreshButton' => true])
|
||||||
@if (str($status)->startsWith('running'))
|
@if (str($status)->startsWith('running'))
|
||||||
<x-status.running :status="$status" />
|
<x-status.running :status="$status" />
|
||||||
@elseif(str($status)->startsWith('restarting') || str($status)->startsWith('starting') || str($status)->startsWith('degraded'))
|
@elseif(str($status)->startsWith('restarting') ||
|
||||||
|
str($status)->startsWith('starting') ||
|
||||||
|
str($status)->startsWith('degraded'))
|
||||||
<x-status.restarting :status="$status" />
|
<x-status.restarting :status="$status" />
|
||||||
@else
|
@else
|
||||||
<x-status.stopped :status="$status" />
|
<x-status.stopped :status="$status"/>
|
||||||
@endif
|
@endif
|
||||||
@if (!str($status)->contains('exited'))
|
|
||||||
|
@if (!str($status)->contains('exited') && $showRefreshButton)
|
||||||
<button title="Refresh Status" wire:click='check_status(true)' class="mx-1 hover:fill-white fill-warning">
|
<button title="Refresh Status" wire:click='check_status(true)' class="mx-1 hover:fill-white fill-warning">
|
||||||
<svg class="w-4 h-4" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-4 h-4" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
|
@ -22,37 +22,33 @@
|
|||||||
@endif
|
@endif
|
||||||
@if ($resource->link())
|
@if ($resource->link())
|
||||||
<a class="flex gap-2 p-1 hover:bg-coolgray-100 hover:no-underline" href="{{ $resource->link() }}">
|
<a class="flex gap-2 p-1 hover:bg-coolgray-100 hover:no-underline" href="{{ $resource->link() }}">
|
||||||
<div class="w-64">{{ str($resource->type())->headline() }}</div>
|
<div class="w-40">
|
||||||
<div>{{ $resource->name }}</div>
|
@if ($resource->type() === 'service')
|
||||||
|
<x-status.services :service="$resource" />
|
||||||
|
@else
|
||||||
|
<x-status.index :status="$resource->status" :showRefreshButton="false" :showIcon="false" />
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div>{{ $resource->name }}<span
|
||||||
|
class="px-2 text-xs">({{ str($resource->type())->headline() }})</span></div>
|
||||||
</a>
|
</a>
|
||||||
@else
|
@else
|
||||||
<div class="flex gap-2 p-1 hover:bg-coolgray-100 hover:no-underline">
|
<div class="flex gap-2 p-1 hover:bg-coolgray-100 hover:no-underline">
|
||||||
<div class="w-64">{{ str($resource->type())->headline() }}</div>
|
<div class="w-40">
|
||||||
<div>{{ $resource->name }}</div>
|
@if ($resource->type() === 'service')
|
||||||
|
<x-status.services :service="$resource" />
|
||||||
|
@else
|
||||||
|
<x-status.index :status="$resource->status" :showRefreshButton="false" :showIcon="false" />
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div>{{ $resource->name }}<span
|
||||||
|
class="px-2 text-xs">({{ str($resource->type())->headline() }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@empty
|
@empty
|
||||||
@endforelse
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<div class="flex flex-col">
|
|
||||||
@forelse ($server->definedResources() as $resource)
|
|
||||||
@if ($loop->first)
|
|
||||||
<h3 class="pt-4">Resources</h3>
|
|
||||||
@endif
|
|
||||||
@if ($resource->link())
|
|
||||||
<a class="flex gap-2 p-1 hover:bg-coolgray-100 hover:no-underline" href="{{ $resource->link() }}">
|
|
||||||
<div class="w-64">{{ str($resource->type())->headline() }}</div>
|
|
||||||
<div>{{ $resource->name }}</div>
|
|
||||||
</a>
|
|
||||||
@else
|
|
||||||
<div class="flex gap-2 p-1 hover:bg-coolgray-100 hover:no-underline">
|
|
||||||
<div class="w-64">{{ str($resource->type())->headline() }}</div>
|
|
||||||
<div>{{ $resource->name }}</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@empty
|
|
||||||
@endforelse
|
|
||||||
</div>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
46
resources/views/livewire/server/resources.blade.php
Normal file
46
resources/views/livewire/server/resources.blade.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<div>
|
||||||
|
<x-server.navbar :server="$server" :parameters="$parameters" />
|
||||||
|
<h2>Resources</h2>
|
||||||
|
<div class="pb-4 title">Here you can find all resources for this server.</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<div class="inline-block min-w-full">
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<table class="min-w-full divide-y divide-coolgray-400">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-neutral-500">
|
||||||
|
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Project Name</th>
|
||||||
|
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Name</th>
|
||||||
|
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Type</th>
|
||||||
|
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-coolgray-400">
|
||||||
|
@forelse ($server->definedResources()->sortBy('name',SORT_NATURAL) as $resource)
|
||||||
|
<tr class="text-white bg-coolblack hover:bg-coolgray-100">
|
||||||
|
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||||
|
{{ data_get($resource->project(), 'name') }}
|
||||||
|
</td>
|
||||||
|
<td class="px-5 py-4 text-sm whitespace-nowrap"> <a class=""
|
||||||
|
href="{{ $resource->link() }}">{{ $resource->name }} </a></td>
|
||||||
|
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||||
|
{{ str($resource->type())->headline() }}</td>
|
||||||
|
<td class="px-5 py-4 text-sm font-medium whitespace-nowrap">
|
||||||
|
@if ($resource->type() === 'service')
|
||||||
|
<x-status.services :service="$resource" />
|
||||||
|
@else
|
||||||
|
<x-status.index :status="$resource->status" :showRefreshButton="false" />
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,36 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
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\Api\Deploy;
|
use App\Http\Controllers\Api\Deploy;
|
||||||
use App\Models\ApplicationDeploymentQueue;
|
use App\Http\Controllers\Api\Project;
|
||||||
use App\Models\Tag;
|
use App\Http\Controllers\Api\Server;
|
||||||
use App\Models\User;
|
|
||||||
use App\Providers\RouteServiceProvider;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Visus\Cuid2\Cuid2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| API Routes
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Here is where you can register API routes for your application. These
|
|
||||||
| routes are loaded by the RouteServiceProvider and all of them will
|
|
||||||
| be assigned to the "api" middleware group. Make something great!
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
$middlewares = ['auth:sanctum'];
|
|
||||||
if (isDev()) {
|
|
||||||
$middlewares = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
Route::get('/health', function () {
|
Route::get('/health', function () {
|
||||||
return 'OK';
|
return 'OK';
|
||||||
@ -45,44 +20,41 @@
|
|||||||
}
|
}
|
||||||
return response()->json(['message' => 'Feedback sent.'], 200);
|
return response()->json(['message' => 'Feedback sent.'], 200);
|
||||||
});
|
});
|
||||||
// Route::group([
|
|
||||||
// 'middleware' => $middlewares,
|
|
||||||
// 'prefix' => 'v1'
|
|
||||||
// ], function () {
|
|
||||||
// Route::get('/deployments', function () {
|
|
||||||
// return ApplicationDeploymentQueue::whereIn("status", ["in_progress", "queued"])->get([
|
|
||||||
// "id",
|
|
||||||
// "server_id",
|
|
||||||
// "status"
|
|
||||||
// ])->groupBy("server_id")->map(function ($item) {
|
|
||||||
// return $item;
|
|
||||||
// })->toArray();
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
Route::group([
|
Route::group([
|
||||||
'middleware' => ['auth:sanctum'],
|
'middleware' => ['auth:sanctum'],
|
||||||
'prefix' => 'v1'
|
'prefix' => 'v1'
|
||||||
], function () {
|
], function () {
|
||||||
|
Route::get('/version', function () {
|
||||||
|
return response(config('version'));
|
||||||
|
});
|
||||||
Route::get('/deploy', [Deploy::class, 'deploy']);
|
Route::get('/deploy', [Deploy::class, 'deploy']);
|
||||||
|
Route::get('/servers', [Server::class, 'servers']);
|
||||||
|
Route::get('/server/{uuid}', [Server::class, 'server_by_uuid']);
|
||||||
|
Route::get('/projects', [Project::class, 'projects']);
|
||||||
|
Route::get('/project/{uuid}', [Project::class, 'project_by_uuid']);
|
||||||
|
Route::get('/project/{uuid}/{environment_name}', [Project::class, 'environment_details']);
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::middleware(['throttle:5'])->group(function () {
|
Route::get('/{any}', function () {
|
||||||
Route::get('/unsubscribe/{token}', function () {
|
return response()->json(['error' => 'Not found.'], 404);
|
||||||
try {
|
})->where('any', '.*');
|
||||||
$token = request()->token;
|
|
||||||
$email = decrypt($token);
|
// Route::middleware(['throttle:5'])->group(function () {
|
||||||
if (!User::whereEmail($email)->exists()) {
|
// Route::get('/unsubscribe/{token}', function () {
|
||||||
return redirect(RouteServiceProvider::HOME);
|
// try {
|
||||||
}
|
// $token = request()->token;
|
||||||
if (User::whereEmail($email)->first()->marketing_emails === false) {
|
// $email = decrypt($token);
|
||||||
return 'You have already unsubscribed from marketing emails.';
|
// if (!User::whereEmail($email)->exists()) {
|
||||||
}
|
// return redirect(RouteServiceProvider::HOME);
|
||||||
User::whereEmail($email)->update(['marketing_emails' => false]);
|
// }
|
||||||
return 'You have been unsubscribed from marketing emails.';
|
// if (User::whereEmail($email)->first()->marketing_emails === false) {
|
||||||
} catch (\Throwable $e) {
|
// return 'You have already unsubscribed from marketing emails.';
|
||||||
return 'Something went wrong. Please try again or contact support.';
|
// }
|
||||||
}
|
// User::whereEmail($email)->update(['marketing_emails' => false]);
|
||||||
})->name('unsubscribe.marketing.emails');
|
// return 'You have been unsubscribed from marketing emails.';
|
||||||
});
|
// } catch (\Throwable $e) {
|
||||||
|
// return 'Something went wrong. Please try again or contact support.';
|
||||||
|
// }
|
||||||
|
// })->name('unsubscribe.marketing.emails');
|
||||||
|
// });
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\Api\Server as ApiServer;
|
||||||
use App\Models\GitlabApp;
|
use App\Models\GitlabApp;
|
||||||
use App\Models\PrivateKey;
|
use App\Models\PrivateKey;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
@ -61,12 +62,13 @@
|
|||||||
use App\Livewire\Server\Index as ServerIndex;
|
use App\Livewire\Server\Index as ServerIndex;
|
||||||
use App\Livewire\Server\Create as ServerCreate;
|
use App\Livewire\Server\Create as ServerCreate;
|
||||||
use App\Livewire\Server\Show as ServerShow;
|
use App\Livewire\Server\Show as ServerShow;
|
||||||
|
use App\Livewire\Server\Resources as ResourcesShow;
|
||||||
|
|
||||||
use App\Livewire\Server\Destination\Show as DestinationShow;
|
use App\Livewire\Server\Destination\Show as DestinationShow;
|
||||||
use App\Livewire\Server\LogDrains;
|
use App\Livewire\Server\LogDrains;
|
||||||
use App\Livewire\Server\PrivateKey\Show as PrivateKeyShow;
|
use App\Livewire\Server\PrivateKey\Show as PrivateKeyShow;
|
||||||
use App\Livewire\Server\Proxy\Show as ProxyShow;
|
use App\Livewire\Server\Proxy\Show as ProxyShow;
|
||||||
use App\Livewire\Server\Proxy\Logs as ProxyLogs;
|
use App\Livewire\Server\Proxy\Logs as ProxyLogs;
|
||||||
|
|
||||||
use App\Livewire\Source\Github\Change as GitHubChange;
|
use App\Livewire\Source\Github\Change as GitHubChange;
|
||||||
use App\Livewire\Subscription\Index as SubscriptionIndex;
|
use App\Livewire\Subscription\Index as SubscriptionIndex;
|
||||||
|
|
||||||
@ -173,6 +175,7 @@
|
|||||||
|
|
||||||
Route::prefix('server/{server_uuid}')->group(function () {
|
Route::prefix('server/{server_uuid}')->group(function () {
|
||||||
Route::get('/', ServerShow::class)->name('server.show');
|
Route::get('/', ServerShow::class)->name('server.show');
|
||||||
|
Route::get('/resources', ResourcesShow::class)->name('server.resources');
|
||||||
Route::get('/proxy', ProxyShow::class)->name('server.proxy');
|
Route::get('/proxy', ProxyShow::class)->name('server.proxy');
|
||||||
Route::get('/proxy/logs', ProxyLogs::class)->name('server.proxy.logs');
|
Route::get('/proxy/logs', ProxyLogs::class)->name('server.proxy.logs');
|
||||||
Route::get('/private-key', PrivateKeyShow::class)->name('server.private-key');
|
Route::get('/private-key', PrivateKeyShow::class)->name('server.private-key');
|
||||||
|
Loading…
Reference in New Issue
Block a user