create network if doesn't already exist on server, wip test
This commit is contained in:
@@ -11,5 +11,6 @@ class CreatedServer
|
||||
public string $status,
|
||||
public string $ipv4,
|
||||
public string $ipv6,
|
||||
public string $networkId,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\GenerateRandomSlug;
|
||||
use App\Enums\NetworkType;
|
||||
use App\Enums\ServerStatus;
|
||||
use App\Jobs\Servers\WaitForServerToConnect;
|
||||
use App\Models\Organisation;
|
||||
@@ -57,7 +58,15 @@ class ServerController extends Controller
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'provider' => ['required', 'exists:providers,id'],
|
||||
'server_type' => ['required', 'string'],
|
||||
'location' => ['required', 'string'],
|
||||
'image' => ['required', 'string'],
|
||||
]);
|
||||
|
||||
$sudoPassword = Str::random(32);
|
||||
/** @var Provider $provider */
|
||||
$provider = Provider::findOrFail($request->provider);
|
||||
$providerService = $provider->service();
|
||||
|
||||
@@ -65,11 +74,27 @@ class ServerController extends Controller
|
||||
return back()->with('error', 'Invalid provider');
|
||||
}
|
||||
|
||||
if (! $network = $provider->networks()->first()) {
|
||||
// we need a keystone network to create this server
|
||||
$createdNetwork = $providerService->createNetwork(
|
||||
name: 'keystone',
|
||||
);
|
||||
|
||||
$network = $provider->networks()->create([
|
||||
'organisation_id' => $provider->organisation_id,
|
||||
'external_id' => $createdNetwork->id,
|
||||
'type' => NetworkType::EXTERNAL,
|
||||
'name' => $createdNetwork->name,
|
||||
'ip_range' => $createdNetwork->ipRange,
|
||||
]);
|
||||
}
|
||||
|
||||
$createdServer = $providerService->createServer(
|
||||
name: app(GenerateRandomSlug::class)->execute(), // @todo allow custom name
|
||||
serverType: $request->server_type,
|
||||
location: $request->location,
|
||||
image: $request->image,
|
||||
networkId: $network->external_id,
|
||||
);
|
||||
|
||||
$organisation = Organisation::findOrFail($request->route('organisation'));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Integrations\Requests\Hetzner\Servers;
|
||||
namespace App\Http\Integrations\Requests\Hetzner\Networks;
|
||||
|
||||
use Saloon\Contracts\Body\HasBody;
|
||||
use Saloon\Enums\Method;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Integrations\Requests\Hetzner\Servers;
|
||||
namespace App\Http\Integrations\Requests\Hetzner\Networks;
|
||||
|
||||
use Saloon\Contracts\Body\HasBody;
|
||||
use Saloon\Enums\Method;
|
||||
|
||||
@@ -18,6 +18,7 @@ class CreateServerRequest extends Request implements HasBody
|
||||
protected ?string $name = null,
|
||||
protected ?string $serverType = null,
|
||||
protected ?string $location = null,
|
||||
protected ?array $networks = null,
|
||||
) {}
|
||||
|
||||
protected function defaultBody(): array
|
||||
@@ -27,6 +28,7 @@ class CreateServerRequest extends Request implements HasBody
|
||||
'name' => $this->name,
|
||||
'server_type' => $this->serverType,
|
||||
'location' => $this->location,
|
||||
'networks' => $this->networks,
|
||||
'user_data' => file_get_contents(resource_path('scripts/hetzner-cloudinit.yml')),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -45,6 +45,11 @@ class Organisation extends Model
|
||||
return $this->hasMany(Provider::class);
|
||||
}
|
||||
|
||||
public function networks(): HasMany
|
||||
{
|
||||
return $this->hasMany(Network::class);
|
||||
}
|
||||
|
||||
public static function createUniqueSlug(string $name): string
|
||||
{
|
||||
$slug = Str::slug($name);
|
||||
|
||||
@@ -5,11 +5,15 @@ namespace App\Models;
|
||||
use App\Enums\ProviderType;
|
||||
use App\Services\ServerProviders\HetznerService;
|
||||
use App\Services\ServerProviders\ServerProviderService;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Provider extends Model
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\ProviderFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected function casts(): array
|
||||
@@ -33,7 +37,7 @@ class Provider extends Model
|
||||
public function service(): ?ServerProviderService
|
||||
{
|
||||
return match ($this->type) {
|
||||
ProviderType::HETZNER => new HetznerService($this),
|
||||
ProviderType::HETZNER => app(HetznerService::class, ['provider' => $this]),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,8 +10,9 @@ use App\Data\ServerProviders\ServerType;
|
||||
use App\Http\Integrations\Connectors\HetznerConnector;
|
||||
use App\Http\Integrations\Requests\Hetzner\Images\GetImagesRequest;
|
||||
use App\Http\Integrations\Requests\Hetzner\Locations\GetLocationsRequest;
|
||||
use App\Http\Integrations\Requests\Hetzner\Networks\CreateNetworkRequest;
|
||||
use App\Http\Integrations\Requests\Hetzner\Networks\GetNetworksRequest;
|
||||
use App\Http\Integrations\Requests\Hetzner\Servers\CreateServerRequest;
|
||||
use App\Http\Integrations\Requests\Hetzner\Servers\GetNetworksRequest;
|
||||
use App\Http\Integrations\Requests\Hetzner\ServerTypes\GetServerTypesRequest;
|
||||
use App\Models\Provider;
|
||||
use Exception;
|
||||
@@ -29,12 +30,16 @@ class HetznerService extends ServerProviderService
|
||||
string $serverType,
|
||||
string $location,
|
||||
string $image,
|
||||
string $networkId,
|
||||
): CreatedServer {
|
||||
$response = $this->connector->send(new CreateServerRequest(
|
||||
image: $image,
|
||||
name: $name,
|
||||
serverType: $serverType,
|
||||
location: $location,
|
||||
networks: [
|
||||
$networkId,
|
||||
],
|
||||
));
|
||||
|
||||
if ($response->status() !== 201) {
|
||||
@@ -48,6 +53,7 @@ class HetznerService extends ServerProviderService
|
||||
status: $response->json('server.status'),
|
||||
ipv4: $response->json('server.public_net.ipv4.ip'),
|
||||
ipv6: $response->json('server.public_net.ipv6.ip'),
|
||||
networkId: $networkId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,4 +138,21 @@ class HetznerService extends ServerProviderService
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function createNetwork(string $name): Network
|
||||
{
|
||||
$response = $this->connector->send(new CreateNetworkRequest(
|
||||
name: $name,
|
||||
));
|
||||
|
||||
if ($response->status() !== 201) {
|
||||
throw new Exception('Failed to create network on Hetzner');
|
||||
}
|
||||
|
||||
return new Network(
|
||||
id: $response->json('network.id'),
|
||||
name: $response->json('network.name'),
|
||||
ipRange: $response->json('network.ip_range'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ abstract class ServerProviderService
|
||||
string $serverType,
|
||||
string $location,
|
||||
string $image,
|
||||
string $networkId,
|
||||
): CreatedServer;
|
||||
|
||||
abstract public function getServerTypes(): Collection;
|
||||
@@ -25,4 +26,6 @@ abstract class ServerProviderService
|
||||
abstract public function getImages(): Collection;
|
||||
|
||||
abstract public function findNetwork(string $name): ?Network;
|
||||
|
||||
abstract public function createNetwork(string $name): Network;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user