mirror of
https://github.com/coollabsio/coolify.git
synced 2025-12-28 05:34:50 +00:00
Allow manually-added servers to be linked to Hetzner Cloud instances by matching IP address. Once linked, servers gain power controls and status monitoring. Changes: - Add getServers() and findServerByIp() methods to HetznerService - Add Hetzner linking UI section to Server General page - Add unit tests for new HetznerService methods 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
153 lines
4.8 KiB
PHP
153 lines
4.8 KiB
PHP
<?php
|
|
|
|
use App\Services\HetznerService;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
beforeEach(function () {
|
|
Http::preventStrayRequests();
|
|
});
|
|
|
|
it('getServers returns list of servers from Hetzner API', function () {
|
|
Http::fake([
|
|
'api.hetzner.cloud/v1/servers*' => Http::response([
|
|
'servers' => [
|
|
[
|
|
'id' => 12345,
|
|
'name' => 'test-server-1',
|
|
'status' => 'running',
|
|
'public_net' => [
|
|
'ipv4' => ['ip' => '123.45.67.89'],
|
|
'ipv6' => ['ip' => '2a01:4f8::/64'],
|
|
],
|
|
],
|
|
[
|
|
'id' => 67890,
|
|
'name' => 'test-server-2',
|
|
'status' => 'off',
|
|
'public_net' => [
|
|
'ipv4' => ['ip' => '98.76.54.32'],
|
|
'ipv6' => ['ip' => '2a01:4f9::/64'],
|
|
],
|
|
],
|
|
],
|
|
'meta' => ['pagination' => ['next_page' => null]],
|
|
], 200),
|
|
]);
|
|
|
|
$service = new HetznerService('fake-token');
|
|
$servers = $service->getServers();
|
|
|
|
expect($servers)->toBeArray()
|
|
->and(count($servers))->toBe(2)
|
|
->and($servers[0]['id'])->toBe(12345)
|
|
->and($servers[1]['id'])->toBe(67890);
|
|
});
|
|
|
|
it('findServerByIp returns matching server by IPv4', function () {
|
|
Http::fake([
|
|
'api.hetzner.cloud/v1/servers*' => Http::response([
|
|
'servers' => [
|
|
[
|
|
'id' => 12345,
|
|
'name' => 'test-server',
|
|
'status' => 'running',
|
|
'public_net' => [
|
|
'ipv4' => ['ip' => '123.45.67.89'],
|
|
'ipv6' => ['ip' => '2a01:4f8::/64'],
|
|
],
|
|
],
|
|
],
|
|
'meta' => ['pagination' => ['next_page' => null]],
|
|
], 200),
|
|
]);
|
|
|
|
$service = new HetznerService('fake-token');
|
|
$result = $service->findServerByIp('123.45.67.89');
|
|
|
|
expect($result)->not->toBeNull()
|
|
->and($result['id'])->toBe(12345)
|
|
->and($result['name'])->toBe('test-server');
|
|
});
|
|
|
|
it('findServerByIp returns null when no match', function () {
|
|
Http::fake([
|
|
'api.hetzner.cloud/v1/servers*' => Http::response([
|
|
'servers' => [
|
|
[
|
|
'id' => 12345,
|
|
'name' => 'test-server',
|
|
'status' => 'running',
|
|
'public_net' => [
|
|
'ipv4' => ['ip' => '123.45.67.89'],
|
|
'ipv6' => ['ip' => '2a01:4f8::/64'],
|
|
],
|
|
],
|
|
],
|
|
'meta' => ['pagination' => ['next_page' => null]],
|
|
], 200),
|
|
]);
|
|
|
|
$service = new HetznerService('fake-token');
|
|
$result = $service->findServerByIp('1.2.3.4');
|
|
|
|
expect($result)->toBeNull();
|
|
});
|
|
|
|
it('findServerByIp returns null when server list is empty', function () {
|
|
Http::fake([
|
|
'api.hetzner.cloud/v1/servers*' => Http::response([
|
|
'servers' => [],
|
|
'meta' => ['pagination' => ['next_page' => null]],
|
|
], 200),
|
|
]);
|
|
|
|
$service = new HetznerService('fake-token');
|
|
$result = $service->findServerByIp('123.45.67.89');
|
|
|
|
expect($result)->toBeNull();
|
|
});
|
|
|
|
it('findServerByIp matches correct server among multiple', function () {
|
|
Http::fake([
|
|
'api.hetzner.cloud/v1/servers*' => Http::response([
|
|
'servers' => [
|
|
[
|
|
'id' => 11111,
|
|
'name' => 'server-a',
|
|
'status' => 'running',
|
|
'public_net' => [
|
|
'ipv4' => ['ip' => '10.0.0.1'],
|
|
'ipv6' => ['ip' => '2a01:4f8::/64'],
|
|
],
|
|
],
|
|
[
|
|
'id' => 22222,
|
|
'name' => 'server-b',
|
|
'status' => 'running',
|
|
'public_net' => [
|
|
'ipv4' => ['ip' => '10.0.0.2'],
|
|
'ipv6' => ['ip' => '2a01:4f9::/64'],
|
|
],
|
|
],
|
|
[
|
|
'id' => 33333,
|
|
'name' => 'server-c',
|
|
'status' => 'off',
|
|
'public_net' => [
|
|
'ipv4' => ['ip' => '10.0.0.3'],
|
|
'ipv6' => ['ip' => '2a01:4fa::/64'],
|
|
],
|
|
],
|
|
],
|
|
'meta' => ['pagination' => ['next_page' => null]],
|
|
], 200),
|
|
]);
|
|
|
|
$service = new HetznerService('fake-token');
|
|
$result = $service->findServerByIp('10.0.0.2');
|
|
|
|
expect($result)->not->toBeNull()
|
|
->and($result['id'])->toBe(22222)
|
|
->and($result['name'])->toBe('server-b');
|
|
});
|