mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 10:42:23 +00:00
fix(hetzner): validate over SSH when the Hetzner API call fails
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c4a7cd6d4a
commit
597a878d80
3 files changed
+33
-2
No files matched your search
@@ -3,6 +3,7 @@
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class ValidateServer
|
||||
@@ -38,7 +39,13 @@ class ValidateServer
|
||||
'validation_logs' => null,
|
||||
]);
|
||||
if ($server->hetzner_server_id) {
|
||||
$status = $server->refreshHetznerState();
|
||||
try {
|
||||
$status = $server->refreshHetznerState();
|
||||
} catch (\Throwable $e) {
|
||||
// The provider API can be down or the token revoked; the SSH checks below still decide.
|
||||
Log::warning('Could not refresh the Hetzner server status before validation', ['server_id' => $server->id, 'error' => $e->getMessage()]);
|
||||
$status = null;
|
||||
}
|
||||
if (in_array($status, ['initializing', 'starting', 'stopping', 'off', 'deleting', 'rebuilding', 'migrating'], true)) {
|
||||
$this->error = $status === 'off'
|
||||
? 'Hetzner server is off. Power it on before validating.'
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Events\ServerValidated;
|
||||
use App\Jobs\CheckAndStartSentinelJob;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Component;
|
||||
|
||||
@@ -117,7 +118,13 @@ class ValidateAndInstall extends Component
|
||||
$this->authorize('update', $this->server);
|
||||
Server::throttleValidation($this->server->team_id, $this->server->ip);
|
||||
if ($this->server->hetzner_server_id) {
|
||||
$status = $this->server->refreshHetznerState();
|
||||
try {
|
||||
$status = $this->server->refreshHetznerState();
|
||||
} catch (\Throwable $e) {
|
||||
// The provider API can be down or the token revoked; the SSH checks below still decide.
|
||||
Log::warning('Could not refresh the Hetzner server status before validation', ['server_id' => $this->server->id, 'error' => $e->getMessage()]);
|
||||
$status = null;
|
||||
}
|
||||
$this->server->refresh();
|
||||
|
||||
if (in_array($status, ['initializing', 'starting', 'stopping', 'off', 'deleting', 'rebuilding', 'migrating'], true)) {
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Process;
|
||||
use Livewire\Livewire;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
@@ -84,3 +85,19 @@ it('blocks validation modal connection checks when the Hetzner server is off', f
|
||||
'validation_logs' => 'Hetzner server is off. Power it on before validating.',
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates over SSH when the Hetzner API call fails', function () {
|
||||
Http::fake(['https://api.hetzner.cloud/v1/servers/456' => Http::response(['error' => ['code' => 'unauthorized']], 401)]);
|
||||
$this->server->update(['ip' => '203.0.113.10']);
|
||||
Process::fake();
|
||||
|
||||
Livewire::test(ValidateAndInstall::class, ['server' => $this->server])
|
||||
->call('validateConnection')
|
||||
->assertSet('error', null)
|
||||
->assertSet('uptime', true)
|
||||
->assertDispatched('validateOS');
|
||||
|
||||
Process::fake(['*' => Process::result(errorOutput: 'ssh: connect to host 203.0.113.10 port 22: Connection refused', exitCode: 255)]);
|
||||
|
||||
expect(fn () => ValidateServer::run($this->server))->toThrow(Exception::class, 'Connection refused');
|
||||
});
|
||||
Reference in new issue
Block a user