mirror of
https://github.com/tiennm99/coolify.git
synced 2026-04-17 17:21:04 +00:00
feat: add Hetzner Cloud server linking for manually-added servers
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>
This commit is contained in:
152
tests/Unit/HetznerServiceTest.php
Normal file
152
tests/Unit/HetznerServiceTest.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?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');
|
||||
});
|
||||
Reference in New Issue
Block a user