fix: force enable/disable server in case ultimate package quantity decreases
This commit is contained in:
		@@ -14,7 +14,7 @@ use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Collection;
 | 
			
		||||
use Visus\Cuid2\Cuid2;
 | 
			
		||||
 | 
			
		||||
class Deploy extends Controller
 | 
			
		||||
class APIDeploy extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function deploy(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\Project as ModelsProject;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
class Project extends Controller
 | 
			
		||||
class APIProject extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function projects(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\Server as ModelsServer;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
 | 
			
		||||
class Server extends Controller
 | 
			
		||||
class APIServer extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function servers(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1675,7 +1675,6 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->next(ApplicationDeploymentStatus::FAILED->value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,8 @@
 | 
			
		||||
namespace App\Jobs;
 | 
			
		||||
 | 
			
		||||
use App\Models\Team;
 | 
			
		||||
use App\Notifications\Server\DisabledDueToOverflow;
 | 
			
		||||
use App\Notifications\Server\ForceDisabled;
 | 
			
		||||
use App\Notifications\Server\ForceEnabled;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
@@ -12,7 +13,7 @@ use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
 | 
			
		||||
class ServerOverflowJob implements ShouldQueue, ShouldBeEncrypted
 | 
			
		||||
class ServerLimitCheckJob implements ShouldQueue, ShouldBeEncrypted
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
			
		||||
 | 
			
		||||
@@ -37,26 +38,31 @@ class ServerOverflowJob implements ShouldQueue, ShouldBeEncrypted
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            ray('ServerOverflowJob');
 | 
			
		||||
            $servers = $this->team->servers;
 | 
			
		||||
            $servers_count = $servers->count();
 | 
			
		||||
            $limit = $this->team->limits['serverLimit'];
 | 
			
		||||
            $number_of_servers_to_disable = $servers_count - $limit;
 | 
			
		||||
            ray($number_of_servers_to_disable, $servers_count, $limit);
 | 
			
		||||
            ray('ServerLimitCheckJob', $this->team->uuid, $servers_count, $limit, $number_of_servers_to_disable);
 | 
			
		||||
            if ($number_of_servers_to_disable > 0) {
 | 
			
		||||
                ray('Disabling servers');
 | 
			
		||||
                $servers = $servers->sortBy('created_at');
 | 
			
		||||
                $servers = $servers->sortbyDesc('created_at');
 | 
			
		||||
                $servers_to_disable = $servers->take($number_of_servers_to_disable);
 | 
			
		||||
                $servers_to_disable->each(function ($server) {
 | 
			
		||||
                    $server->disableServerDueToOverflow();
 | 
			
		||||
                    $this->team->notify(new DisabledDueToOverflow($server));
 | 
			
		||||
                    $server->forceDisableServer();
 | 
			
		||||
                    $this->team->notify(new ForceDisabled($server));
 | 
			
		||||
                });
 | 
			
		||||
            } else if ($number_of_servers_to_disable === 0) {
 | 
			
		||||
                $servers->each(function ($server) {
 | 
			
		||||
                    if ($server->isForceDisabled()) {
 | 
			
		||||
                        $server->forceEnableServer();
 | 
			
		||||
                        $this->team->notify(new ForceEnabled($server));
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            send_internal_notification('ServerOverflowJob failed with: ' . $e->getMessage());
 | 
			
		||||
            send_internal_notification('ServerLimitCheckJob failed with: ' . $e->getMessage());
 | 
			
		||||
            ray($e->getMessage());
 | 
			
		||||
            return handleError($e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
namespace App\Livewire\Admin;
 | 
			
		||||
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use Illuminate\Support\Facades\Crypt;
 | 
			
		||||
use Livewire\Component;
 | 
			
		||||
 | 
			
		||||
@@ -27,6 +28,7 @@ class Index extends Component
 | 
			
		||||
        auth()->login($user);
 | 
			
		||||
 | 
			
		||||
        if ($user_id === 0) {
 | 
			
		||||
            Cache::forget('team:0');
 | 
			
		||||
            session()->forget('adminToken');
 | 
			
		||||
        } else {
 | 
			
		||||
            $token_payload = [
 | 
			
		||||
@@ -35,6 +37,7 @@ class Index extends Component
 | 
			
		||||
            $token = Crypt::encrypt($token_payload);
 | 
			
		||||
            session(['adminToken' => $token]);
 | 
			
		||||
        }
 | 
			
		||||
        session()->regenerate();
 | 
			
		||||
        return refreshSession();
 | 
			
		||||
    }
 | 
			
		||||
    public function render()
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Livewire\Tags;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Api\Deploy;
 | 
			
		||||
use App\Http\Controllers\Api\APIDeploy as Deploy;
 | 
			
		||||
use App\Models\ApplicationDeploymentQueue;
 | 
			
		||||
use App\Models\Tag;
 | 
			
		||||
use Livewire\Component;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ use App\Notifications\Server\Unreachable;
 | 
			
		||||
use Illuminate\Database\Eloquent\Builder;
 | 
			
		||||
use Illuminate\Database\Eloquent\Casts\Attribute;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Storage;
 | 
			
		||||
use Spatie\SchemalessAttributes\Casts\SchemalessAttributes;
 | 
			
		||||
use Spatie\SchemalessAttributes\SchemalessAttributesTrait;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
@@ -69,7 +70,7 @@ class Server extends BaseModel
 | 
			
		||||
 | 
			
		||||
    static public function isUsable()
 | 
			
		||||
    {
 | 
			
		||||
        return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_swarm_worker', false)->whereRelation('settings', 'is_build_server', false);
 | 
			
		||||
        return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_swarm_worker', false)->whereRelation('settings', 'is_build_server', false)->whereRelation('settings', 'force_disabled', false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static public function destinationsByServer(string $server_id)
 | 
			
		||||
@@ -149,13 +150,31 @@ class Server extends BaseModel
 | 
			
		||||
            ray('skipping 1.2.3.4');
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if ($this->settings->force_disabled === true) {
 | 
			
		||||
            ray('force_disabled');
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    public function disableServerDueToOverflow() {
 | 
			
		||||
    public function isForceDisabled()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->settings->force_disabled;
 | 
			
		||||
    }
 | 
			
		||||
    public function forceEnableServer()
 | 
			
		||||
    {
 | 
			
		||||
        $this->settings->update([
 | 
			
		||||
            'disabled_by_overflow' => true,
 | 
			
		||||
            'force_disabled' => false,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
    public function forceDisableServer()
 | 
			
		||||
    {
 | 
			
		||||
        $this->settings->update([
 | 
			
		||||
            'force_disabled' => true,
 | 
			
		||||
        ]);
 | 
			
		||||
        $sshKeyFileLocation = "id.root@{$this->uuid}";
 | 
			
		||||
        Storage::disk('ssh-keys')->delete($sshKeyFileLocation);
 | 
			
		||||
        Storage::disk('ssh-mux')->delete($this->muxFilename());
 | 
			
		||||
    }
 | 
			
		||||
    public function isServerReady(int $tries = 3)
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->skipServer()) {
 | 
			
		||||
@@ -379,7 +398,7 @@ class Server extends BaseModel
 | 
			
		||||
    }
 | 
			
		||||
    public function isFunctional()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->settings->is_reachable && $this->settings->is_usable;
 | 
			
		||||
        return $this->settings->is_reachable && $this->settings->is_usable && !$this->settings->force_disabled;
 | 
			
		||||
    }
 | 
			
		||||
    public function isLogDrainEnabled()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Notifications\Messages\MailMessage;
 | 
			
		||||
use Illuminate\Notifications\Notification;
 | 
			
		||||
 | 
			
		||||
class DisabledDueToOverflow extends Notification implements ShouldQueue
 | 
			
		||||
class ForceDisabled extends Notification implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Queueable;
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +43,7 @@ class DisabledDueToOverflow extends Notification implements ShouldQueue
 | 
			
		||||
    {
 | 
			
		||||
        $mail = new MailMessage();
 | 
			
		||||
        $mail->subject("Coolify: Server ({$this->server->name}) disabled because it is not paid!");
 | 
			
		||||
        $mail->view('emails.server-disabled-due-to-overflow', [
 | 
			
		||||
        $mail->view('emails.server-force-disabled', [
 | 
			
		||||
            'name' => $this->server->name,
 | 
			
		||||
        ]);
 | 
			
		||||
        return $mail;
 | 
			
		||||
							
								
								
									
										63
									
								
								app/Notifications/Server/ForceEnabled.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								app/Notifications/Server/ForceEnabled.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Notifications\Server;
 | 
			
		||||
 | 
			
		||||
use App\Models\Server;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use App\Notifications\Channels\DiscordChannel;
 | 
			
		||||
use App\Notifications\Channels\EmailChannel;
 | 
			
		||||
use App\Notifications\Channels\TelegramChannel;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Notifications\Messages\MailMessage;
 | 
			
		||||
use Illuminate\Notifications\Notification;
 | 
			
		||||
 | 
			
		||||
class ForceEnabled extends Notification implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Queueable;
 | 
			
		||||
 | 
			
		||||
    public $tries = 1;
 | 
			
		||||
    public function __construct(public Server $server)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function via(object $notifiable): array
 | 
			
		||||
    {
 | 
			
		||||
        $channels = [];
 | 
			
		||||
        $isEmailEnabled = isEmailEnabled($notifiable);
 | 
			
		||||
        $isDiscordEnabled = data_get($notifiable, 'discord_enabled');
 | 
			
		||||
        $isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
 | 
			
		||||
 | 
			
		||||
        if ($isDiscordEnabled) {
 | 
			
		||||
            $channels[] = DiscordChannel::class;
 | 
			
		||||
        }
 | 
			
		||||
        if ($isEmailEnabled) {
 | 
			
		||||
            $channels[] = EmailChannel::class;
 | 
			
		||||
        }
 | 
			
		||||
        if ($isTelegramEnabled) {
 | 
			
		||||
            $channels[] = TelegramChannel::class;
 | 
			
		||||
        }
 | 
			
		||||
        return $channels;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function toMail(): MailMessage
 | 
			
		||||
    {
 | 
			
		||||
        $mail = new MailMessage();
 | 
			
		||||
        $mail->subject("Coolify: Server ({$this->server->name}) enabled again!");
 | 
			
		||||
        $mail->view('emails.server-force-enabled', [
 | 
			
		||||
            'name' => $this->server->name,
 | 
			
		||||
        ]);
 | 
			
		||||
        return $mail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function toDiscord(): string
 | 
			
		||||
    {
 | 
			
		||||
        $message = "Coolify: Server ({$this->server->name}) enabled again!";
 | 
			
		||||
        return $message;
 | 
			
		||||
    }
 | 
			
		||||
    public function toTelegram(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            "message" => "Coolify: Server ({$this->server->name}) enabled again!"
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -24,6 +24,12 @@ trait ExecuteRemoteCommand
 | 
			
		||||
        if ($this->server instanceof Server === false) {
 | 
			
		||||
            throw new \RuntimeException('Server is not set or is not an instance of Server model');
 | 
			
		||||
        }
 | 
			
		||||
        if ($this->server->settings->force_disabled) {
 | 
			
		||||
            $this->application_deployment_queue->update([
 | 
			
		||||
                'status' => ApplicationDeploymentStatus::FAILED->value,
 | 
			
		||||
            ]);
 | 
			
		||||
            throw new \RuntimeException('Server is disabled');
 | 
			
		||||
        }
 | 
			
		||||
        $commandsText->each(function ($single_command) {
 | 
			
		||||
            $command = data_get($single_command, 'command') ?? $single_command[0] ?? null;
 | 
			
		||||
            if ($command === null) {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ return new class extends Migration
 | 
			
		||||
    public function up(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::table('server_settings', function (Blueprint $table) {
 | 
			
		||||
            $table->boolean('disabled_by_overflow')->default(false);
 | 
			
		||||
            $table->boolean('force_disabled')->default(false);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +22,7 @@ return new class extends Migration
 | 
			
		||||
    public function down(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::table('server_settings', function (Blueprint $table) {
 | 
			
		||||
            $table->dropColumn('disabled_by_overflow');
 | 
			
		||||
            $table->dropColumn('force_disabled');
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@@ -1,24 +1,18 @@
 | 
			
		||||
<div>
 | 
			
		||||
    @if ($server->isFunctional())
 | 
			
		||||
        <div class="flex h-full pr-4">
 | 
			
		||||
            <div class="flex flex-col w-48 gap-4 min-w-fit">
 | 
			
		||||
                <a class="{{ request()->routeIs('server.proxy') ? 'text-white' : '' }}"
 | 
			
		||||
                    href="{{ route('server.proxy', $parameters) }}">
 | 
			
		||||
                    <button>Configuration</button>
 | 
			
		||||
                </a>
 | 
			
		||||
                @if (data_get($server, 'proxy.type') !== 'NONE')
 | 
			
		||||
                    <a class="{{ request()->routeIs('server.proxy.dynamic-confs') ? 'text-white' : '' }}"
 | 
			
		||||
                        href="{{ route('server.proxy.dynamic-confs', $parameters) }}">
 | 
			
		||||
                        <button>Dynamic Configurations</button>
 | 
			
		||||
                    </a>
 | 
			
		||||
                    <a class="{{ request()->routeIs('server.proxy.logs') ? 'text-white' : '' }}"
 | 
			
		||||
                        href="{{ route('server.proxy.logs', $parameters) }}">
 | 
			
		||||
                        <button>Logs</button>
 | 
			
		||||
                    </a>
 | 
			
		||||
                @endif
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    @else
 | 
			
		||||
        <div>Server is not validated. Validate first.</div>
 | 
			
		||||
    @endif
 | 
			
		||||
<div class="flex h-full pr-4">
 | 
			
		||||
    <div class="flex flex-col w-48 gap-4 min-w-fit">
 | 
			
		||||
        <a class="{{ request()->routeIs('server.proxy') ? 'text-white' : '' }}"
 | 
			
		||||
            href="{{ route('server.proxy', $parameters) }}">
 | 
			
		||||
            <button>Configuration</button>
 | 
			
		||||
        </a>
 | 
			
		||||
        @if (data_get($server, 'proxy.type') !== 'NONE')
 | 
			
		||||
            <a class="{{ request()->routeIs('server.proxy.dynamic-confs') ? 'text-white' : '' }}"
 | 
			
		||||
                href="{{ route('server.proxy.dynamic-confs', $parameters) }}">
 | 
			
		||||
                <button>Dynamic Configurations</button>
 | 
			
		||||
            </a>
 | 
			
		||||
            <a class="{{ request()->routeIs('server.proxy.logs') ? 'text-white' : '' }}"
 | 
			
		||||
                href="{{ route('server.proxy.logs', $parameters) }}">
 | 
			
		||||
                <button>Logs</button>
 | 
			
		||||
            </a>
 | 
			
		||||
        @endif
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								resources/views/emails/server-force-enabled.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								resources/views/emails/server-force-enabled.blade.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
<x-emails.layout>
 | 
			
		||||
Your server ({{ $name }}) is enabled again!
 | 
			
		||||
</x-emails.layout>
 | 
			
		||||
@@ -12,8 +12,12 @@
 | 
			
		||||
        </div>
 | 
			
		||||
    @endif
 | 
			
		||||
    @if (currentTeam()->serverOverflow())
 | 
			
		||||
    <x-banner :closable=false>
 | 
			
		||||
            <div><span class="font-bold text-red-500">WARNING:</span> The number of active servers exceeds the limit covered by your payment. If not resolved, some of your servers <span class="font-bold text-red-500">will be deactivated</span> in the next billing cycle. Visit <a href="{{route('subscription.show')}}" class="text-white underline">/subscription</a> to update your subscription.</div>
 | 
			
		||||
    </x-banner>
 | 
			
		||||
        <x-banner :closable=false>
 | 
			
		||||
            <div><span class="font-bold text-red-500">WARNING:</span> The number of active servers exceeds the limit
 | 
			
		||||
                covered by your payment. If not resolved, some of your servers <span class="font-bold text-red-500">will
 | 
			
		||||
                    be deactivated</span>. Visit <a href="{{ route('subscription.show') }}"
 | 
			
		||||
                    class="text-white underline">/subscription</a> to update your subscription or remove some servers.
 | 
			
		||||
            </div>
 | 
			
		||||
        </x-banner>
 | 
			
		||||
    @endif
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,10 +7,10 @@
 | 
			
		||||
            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>
 | 
			
		||||
            <x-new-modal disabled isErrorButton buttonTitle="Delete">
 | 
			
		||||
                This server will be deleted. It is not reversible. <br>Please think again.
 | 
			
		||||
            </x-new-modal>
 | 
			
		||||
            <div>You need to delete all resources before deleting this server.</div>
 | 
			
		||||
        @else
 | 
			
		||||
            <x-new-modal isErrorButton buttonTitle="Delete">
 | 
			
		||||
                This server will be deleted. It is not reversible. <br>Please think again.
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,10 @@
 | 
			
		||||
                Validate Server
 | 
			
		||||
            </x-forms.button>
 | 
			
		||||
        @endif
 | 
			
		||||
        @if ($server->isForceDisabled() && isCloud())
 | 
			
		||||
            <div class="pt-4 font-bold text-red-500">The system has disabled the server because you have exceeded the
 | 
			
		||||
                number of servers for which you have paid.</div>
 | 
			
		||||
        @endif
 | 
			
		||||
        <div class="flex flex-col gap-2 pt-4">
 | 
			
		||||
            <div class="flex flex-col w-full gap-2 lg:flex-row">
 | 
			
		||||
                <x-forms.input id="server.name" label="Name" required />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,18 @@
 | 
			
		||||
<div>
 | 
			
		||||
    <div class="flex items-start gap-2">
 | 
			
		||||
        <h1>Servers</h1>
 | 
			
		||||
        <a  class="text-white hover:no-underline" href="{{ route('server.create') }}">
 | 
			
		||||
        <a class="text-white hover:no-underline" href="{{ route('server.create') }}">
 | 
			
		||||
            <x-forms.button class="btn">+ Add</x-forms.button>
 | 
			
		||||
        </a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="subtitle ">All Servers</div>
 | 
			
		||||
    <div class="grid gap-2 lg:grid-cols-2">
 | 
			
		||||
        @forelse ($servers as $server)
 | 
			
		||||
            <a  href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
 | 
			
		||||
            <a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
 | 
			
		||||
                @class([
 | 
			
		||||
                    'gap-2 border cursor-pointer box group',
 | 
			
		||||
                    'border-transparent' => $server->settings->is_reachable,
 | 
			
		||||
                    'border-red-500' => !$server->settings->is_reachable,
 | 
			
		||||
                    'border-transparent' => $server->settings->is_reachable && $server->settings->is_usable && !$server->settings->force_disabled,
 | 
			
		||||
                    'border-red-500' => !$server->settings->is_reachable || $server->settings->force_disabled,
 | 
			
		||||
                ])>
 | 
			
		||||
                <div class="flex flex-col mx-6">
 | 
			
		||||
                    <div class="font-bold text-white">
 | 
			
		||||
@@ -30,6 +30,9 @@
 | 
			
		||||
                        @if (!$server->settings->is_usable)
 | 
			
		||||
                            <span>Not usable by Coolify</span>
 | 
			
		||||
                        @endif
 | 
			
		||||
                        @if ($server->settings->force_disabled)
 | 
			
		||||
                            <span>Disabled by the system</span>
 | 
			
		||||
                        @endif
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="flex-1"></div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<div>
 | 
			
		||||
    <x-server.navbar :server="$server" :parameters="$parameters" />
 | 
			
		||||
    <x-server.sidebar :server="$server" :parameters="$parameters" />
 | 
			
		||||
    <div class="flex gap-2">
 | 
			
		||||
        <x-server.sidebar :server="$server" :parameters="$parameters" />
 | 
			
		||||
        <div class="w-full">
 | 
			
		||||
            @if ($server->isFunctional())
 | 
			
		||||
                <div class="flex gap-2">
 | 
			
		||||
@@ -48,7 +48,6 @@
 | 
			
		||||
                        <div wire:loading.remove> No dynamic configurations found.</div>
 | 
			
		||||
                    @endif
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
            @endif
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
<div>
 | 
			
		||||
    <x-server.navbar :server="$server" :parameters="$parameters" />
 | 
			
		||||
    <div class="flex gap-2">
 | 
			
		||||
        <x-server.sidebar :server="$server" :parameters="$parameters" />
 | 
			
		||||
        <div class="w-full">
 | 
			
		||||
            @if ($server->isFunctional())
 | 
			
		||||
    @if ($server->isFunctional())
 | 
			
		||||
        <div class="flex gap-2">
 | 
			
		||||
            <x-server.sidebar :server="$server" :parameters="$parameters" />
 | 
			
		||||
            <div class="w-full">
 | 
			
		||||
                <livewire:server.proxy :server="$server" />
 | 
			
		||||
            @endif
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
        @else
 | 
			
		||||
        <div>Server is not validated. Validate first.</div>
 | 
			
		||||
    @endif
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
                <div class="py-4"><span class="font-bold text-red-500">WARNING:</span> You must delete
 | 
			
		||||
                    {{ currentTeam()->servers->count() - $server_limits }} servers,
 | 
			
		||||
                    or upgrade your subscription. {{ currentTeam()->servers->count() - $server_limits }} servers will be
 | 
			
		||||
                    deactivated in the next billing cycle.</div>
 | 
			
		||||
                    deactivated.</div>
 | 
			
		||||
            @endif
 | 
			
		||||
            <h2 class="pt-4">Manage your subscription</h2>
 | 
			
		||||
            <div class="pb-4">Cancel, upgrade or downgrade your subscription.</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Api\Deploy;
 | 
			
		||||
use App\Http\Controllers\Api\Project;
 | 
			
		||||
use App\Http\Controllers\Api\Server;
 | 
			
		||||
use App\Http\Controllers\Api\APIDeploy as Deploy;
 | 
			
		||||
use App\Http\Controllers\Api\APIProject as Project;
 | 
			
		||||
use App\Http\Controllers\Api\APIServer as Server;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Http;
 | 
			
		||||
use Illuminate\Support\Facades\Route;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Api\Server as ApiServer;
 | 
			
		||||
use App\Models\GitlabApp;
 | 
			
		||||
use App\Models\PrivateKey;
 | 
			
		||||
use App\Models\Server;
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
use App\Enums\ProcessStatus;
 | 
			
		||||
use App\Jobs\ApplicationPullRequestUpdateJob;
 | 
			
		||||
use App\Jobs\GithubAppPermissionJob;
 | 
			
		||||
use App\Jobs\ServerOverflowJob;
 | 
			
		||||
use App\Jobs\ServerLimitCheckJob;
 | 
			
		||||
use App\Jobs\SubscriptionInvoiceFailedJob;
 | 
			
		||||
use App\Jobs\SubscriptionTrialEndedJob;
 | 
			
		||||
use App\Jobs\SubscriptionTrialEndsSoonJob;
 | 
			
		||||
@@ -883,7 +883,7 @@ Route::post('/payments/stripe/events', function () {
 | 
			
		||||
                    $team->update([
 | 
			
		||||
                        'custom_server_limit' => $quantity,
 | 
			
		||||
                    ]);
 | 
			
		||||
                    ServerOverflowJob::dispatch($team);
 | 
			
		||||
                    ServerLimitCheckJob::dispatch($team);
 | 
			
		||||
                }
 | 
			
		||||
                $subscription->update([
 | 
			
		||||
                    'stripe_feedback' => $feedback,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user