tests pass!
This commit is contained in:
@@ -11,6 +11,7 @@ class CreatedServer
|
||||
public string $status,
|
||||
public string $ipv4,
|
||||
public string $ipv6,
|
||||
public string $privateIp,
|
||||
public string $networkId,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -105,12 +105,14 @@ class ServerController extends Controller
|
||||
'external_id' => $createdServer->id,
|
||||
'ipv4' => $createdServer->ipv4,
|
||||
'ipv6' => $createdServer->ipv6,
|
||||
'private_ip' => $createdServer->privateIp,
|
||||
'provider_status' => $createdServer->status,
|
||||
'status' => ServerStatus::WAITING_FOR_PROVIDER,
|
||||
'region' => $request->location,
|
||||
'os' => $request->image,
|
||||
'plan' => $request->server_type,
|
||||
'user' => 'keystone',
|
||||
'external_network_id' => $network->id,
|
||||
]);
|
||||
|
||||
dispatch(new WaitForServerToConnect(
|
||||
|
||||
@@ -7,11 +7,6 @@ use Saloon\Http\Connector;
|
||||
|
||||
class HetznerConnector extends Connector
|
||||
{
|
||||
public function __construct(protected readonly Provider $provider)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function resolveBaseUrl(): string
|
||||
{
|
||||
return 'https://api.hetzner.cloud/v1';
|
||||
@@ -22,7 +17,6 @@ class HetznerConnector extends Connector
|
||||
return [
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
'Authorization' => 'Bearer '.$this->provider->token,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class Provider extends Model
|
||||
public function service(): ?ServerProviderService
|
||||
{
|
||||
return match ($this->type) {
|
||||
ProviderType::HETZNER => app(HetznerService::class, ['provider' => $this]),
|
||||
ProviderType::HETZNER => app(HetznerService::class)->forProvider($this),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,9 +20,17 @@ use Illuminate\Support\Collection;
|
||||
|
||||
class HetznerService extends ServerProviderService
|
||||
{
|
||||
public function __construct(Provider $provider)
|
||||
protected Provider $provider;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->connector = new HetznerConnector($provider);
|
||||
$this->connector = new HetznerConnector();
|
||||
}
|
||||
|
||||
public function forProvider(Provider $provider): static
|
||||
{
|
||||
$this->provider = $provider;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function createServer(
|
||||
@@ -54,6 +62,7 @@ class HetznerService extends ServerProviderService
|
||||
ipv4: $response->json('server.public_net.ipv4.ip'),
|
||||
ipv6: $response->json('server.public_net.ipv6.ip'),
|
||||
networkId: $networkId,
|
||||
privateIp: $response->json('server.private_net.0.ip'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Services\ServerProviders;
|
||||
|
||||
use App\Data\ServerProviders\CreatedServer;
|
||||
use App\Data\ServerProviders\Network;
|
||||
use App\Models\Provider;
|
||||
use Illuminate\Support\Collection;
|
||||
use Saloon\Http\Connector;
|
||||
|
||||
@@ -19,6 +20,8 @@ abstract class ServerProviderService
|
||||
string $networkId,
|
||||
): CreatedServer;
|
||||
|
||||
abstract public function forProvider(Provider $provider): static;
|
||||
|
||||
abstract public function getServerTypes(): Collection;
|
||||
|
||||
abstract public function getLocations(): Collection;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\ProviderType;
|
||||
use App\Models\Organisation;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
@@ -26,10 +27,10 @@ class ProviderFactory extends Factory
|
||||
];
|
||||
}
|
||||
|
||||
public function forOrganisation($organisationId): static
|
||||
public function forOrganisation(string|Organisation $organisation): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'organisation_id' => $organisationId,
|
||||
'organisation_id' => is_string($organisation) ? $organisation : $organisation->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ test('index route displays servers for an organisation', function () {
|
||||
'name' => 'keystone',
|
||||
'external_id' => 'net-12345',
|
||||
'provider_id' => $provider->id,
|
||||
'ip_range' => fake()->ipv4() . '/24',
|
||||
'ip_range' => fake()->ipv4().'/24',
|
||||
]);
|
||||
|
||||
Server::factory()->count(2)->create([
|
||||
@@ -43,7 +43,7 @@ test('index route displays servers for an organisation', function () {
|
||||
|
||||
$response = $this->get(route('servers.index', ['organisation' => $organisation->id]));
|
||||
$response->assertStatus(200);
|
||||
$response->assertInertia(fn(AssertableInertia $page) => $page
|
||||
$response->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('servers/Index'));
|
||||
});
|
||||
|
||||
@@ -51,7 +51,7 @@ test('create route returns inertia view', function () {
|
||||
$organisation = Organisation::factory()->create();
|
||||
$response = $this->get(route('servers.create', ['organisation' => $organisation->id]));
|
||||
$response->assertStatus(200);
|
||||
$response->assertInertia(fn(AssertableInertia $page) => $page
|
||||
$response->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('servers/Create'));
|
||||
});
|
||||
|
||||
@@ -77,7 +77,7 @@ test('store route creates a server with valid data', function () {
|
||||
'name' => 'hetzner',
|
||||
'type' => ProviderType::HETZNER,
|
||||
'token' => Str::uuid(),
|
||||
'organisation_id' => $organisation->id
|
||||
'organisation_id' => $organisation->id,
|
||||
]);
|
||||
|
||||
$network = $organisation->networks()->create([
|
||||
@@ -85,21 +85,12 @@ test('store route creates a server with valid data', function () {
|
||||
'name' => 'keystone',
|
||||
'external_id' => 'net-12345',
|
||||
'provider_id' => $provider->id,
|
||||
'ip_range' => fake()->ipv4() . '/24',
|
||||
'ip_range' => fake()->ipv4().'/24',
|
||||
]);
|
||||
|
||||
$this->mock(HetznerService::class, function (MockInterface $mock) use ($network) {
|
||||
$this->partialMock(HetznerService::class, function (MockInterface $mock) use ($network) {
|
||||
$mock->shouldReceive('createServer')
|
||||
->once()
|
||||
->with(
|
||||
Mockery::on(function ($arg) {
|
||||
return is_string($arg['name']) && strlen($arg['name']) > 0;
|
||||
}),
|
||||
'cx11',
|
||||
'hel1',
|
||||
'ubuntu-20.04',
|
||||
$network->external_id
|
||||
)
|
||||
->andReturn(new CreatedServer(
|
||||
name: 'test-server-from-mock',
|
||||
rootPassword: 'password123',
|
||||
@@ -108,6 +99,7 @@ test('store route creates a server with valid data', function () {
|
||||
ipv4: '192.0.2.100',
|
||||
ipv6: '2001:db8::100',
|
||||
networkId: $network->external_id,
|
||||
privateIp: '10.0.0.1',
|
||||
));
|
||||
|
||||
$mock->shouldReceive('createNetwork')->never();
|
||||
@@ -132,14 +124,18 @@ test('store route creates a server with valid data', function () {
|
||||
|
||||
test('show route displays a single server', function () {
|
||||
$organisation = Organisation::factory()->create();
|
||||
$provider = Provider::factory()->forOrganisation($organisation)->create();
|
||||
$network = $organisation->networks()->create([
|
||||
'type' => NetworkType::EXTERNAL,
|
||||
'name' => 'keystone',
|
||||
'external_id' => 'net-12345',
|
||||
'provider_id' => $provider->id,
|
||||
'ip_range' => fake()->ipv4().'/24',
|
||||
]);
|
||||
$server = Server::factory()->create([
|
||||
'organisation_id' => $organisation->id,
|
||||
'external_network_id' => $network->id,
|
||||
'provider_id' => $provider->id,
|
||||
]);
|
||||
|
||||
$response = $this->get(route('servers.show', [
|
||||
@@ -148,6 +144,6 @@ test('show route displays a single server', function () {
|
||||
]));
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertInertia(fn(AssertableInertia $page) => $page
|
||||
$response->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('servers/Show'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user