This commit is contained in:
2025-04-07 14:47:39 +01:00
parent b800a9d83a
commit 7f546c1678
9 changed files with 23 additions and 42 deletions

View File

@@ -1,17 +0,0 @@
<?php
namespace App\Actions;
use App\Services\ServerProviders\HetznerService;
use App\Services\ServerProviders\ServerProviderService;
class GetProviderService
{
public function execute(string $provider): ?ServerProviderService
{
return match ($provider) {
'hetzner' => new HetznerService,
default => null,
};
}
}

View File

@@ -4,10 +4,10 @@ namespace App\Http\Controllers;
use App\Actions\GenerateRandomSlug; use App\Actions\GenerateRandomSlug;
use App\Actions\GetProviderService; use App\Actions\GetProviderService;
use App\Enums\ServerProvider;
use App\Enums\ServerStatus; use App\Enums\ServerStatus;
use App\Jobs\Servers\WaitForServerToConnect; use App\Jobs\Servers\WaitForServerToConnect;
use App\Models\Organisation; use App\Models\Organisation;
use App\Models\Provider;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@@ -30,7 +30,8 @@ class ServerController extends Controller
$images = null; $images = null;
if ($request->has('provider')) { if ($request->has('provider')) {
$providerService = app(GetProviderService::class)->execute($request->provider); $provider = Provider::findOrFail($request->provider);
$providerService = $provider->service();
if ($providerService) { if ($providerService) {
$locations = Cache::remember($request->provider.'.locations', now()->addHour(), function () use ($providerService) { $locations = Cache::remember($request->provider.'.locations', now()->addHour(), function () use ($providerService) {

View File

@@ -2,10 +2,16 @@
namespace App\Http\Integrations\Connectors; namespace App\Http\Integrations\Connectors;
use App\Models\Provider;
use Saloon\Http\Connector; use Saloon\Http\Connector;
class HetznerConnector extends Connector class HetznerConnector extends Connector
{ {
public function __construct(protected readonly Provider $provider)
{
//
}
public function resolveBaseUrl(): string public function resolveBaseUrl(): string
{ {
return 'https://api.hetzner.cloud/v1'; return 'https://api.hetzner.cloud/v1';
@@ -16,7 +22,7 @@ class HetznerConnector extends Connector
return [ return [
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',
'Accept' => 'application/json', 'Accept' => 'application/json',
'Authorization' => 'Bearer '.config('services.hetzner.key'), 'Authorization' => 'Bearer '.$this->provider->token,
]; ];
} }
} }

View File

@@ -3,7 +3,6 @@
namespace App\Models; namespace App\Models;
use App\Enums\NetworkType; use App\Enums\NetworkType;
use App\Enums\ServerProvider;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;

View File

@@ -3,6 +3,8 @@
namespace App\Models; namespace App\Models;
use App\Enums\ProviderType; use App\Enums\ProviderType;
use App\Services\ServerProviders\HetznerService;
use App\Services\ServerProviders\ServerProviderService;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -27,4 +29,12 @@ class Provider extends Model
{ {
return $this->hasMany(Server::class); return $this->hasMany(Server::class);
} }
public function service(): ?ServerProviderService
{
return match ($this->type) {
ProviderType::HETZNER => new HetznerService($this),
default => null,
};
}
} }

View File

@@ -2,7 +2,6 @@
namespace App\Models; namespace App\Models;
use App\Enums\ServerProvider;
use App\Enums\ServerStatus; use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;

View File

@@ -11,14 +11,15 @@ use App\Http\Integrations\Requests\Hetzner\Images\GetImagesRequest;
use App\Http\Integrations\Requests\Hetzner\Locations\GetLocationsRequest; use App\Http\Integrations\Requests\Hetzner\Locations\GetLocationsRequest;
use App\Http\Integrations\Requests\Hetzner\Servers\CreateServerRequest; use App\Http\Integrations\Requests\Hetzner\Servers\CreateServerRequest;
use App\Http\Integrations\Requests\Hetzner\ServerTypes\GetServerTypesRequest; use App\Http\Integrations\Requests\Hetzner\ServerTypes\GetServerTypesRequest;
use App\Models\Provider;
use Exception; use Exception;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
class HetznerService extends ServerProviderService class HetznerService extends ServerProviderService
{ {
public function __construct() public function __construct(Provider $provider)
{ {
$this->connector = new HetznerConnector; $this->connector = new HetznerConnector($provider);
} }
public function createServer( public function createServer(

View File

@@ -2,7 +2,6 @@
namespace Database\Factories; namespace Database\Factories;
use App\Enums\ServerProvider;
use App\Enums\ServerStatus; use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;

View File

@@ -54,23 +54,6 @@ test('store route fails with invalid provider', function () {
test('store route creates a server with valid data', function () { test('store route creates a server with valid data', function () {
$organisation = Organisation::factory()->create(); $organisation = Organisation::factory()->create();
$this->mock(GetProviderService::class, function ($mock) {
$providerMock = \Mockery::mock(\App\Services\ServerProviders\ServerProviderService::class);
$providerMock->shouldReceive('createServer')->andReturn(
new CreatedServer(
name: 'test-server',
id: 123,
ipv4: '127.0.0.1',
ipv6: '::1',
status: 'running',
rootPassword: Str::random(16),
)
);
$mock->shouldReceive('execute')->andReturn($providerMock);
});
$response = $this->post(route('servers.store', ['organisation' => $organisation->id]), [ $response = $this->post(route('servers.store', ['organisation' => $organisation->id]), [
'provider' => 'hetzner', 'provider' => 'hetzner',
'server_type' => 'cx11', 'server_type' => 'cx11',