wowowowowo
This commit is contained in:
@@ -2,12 +2,54 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Applications\CreateLaravelEnvironment;
|
||||
use App\Enums\BuildStrategy;
|
||||
use App\Enums\EnvironmentAttachmentRole;
|
||||
use App\Enums\SchedulerMode;
|
||||
use App\Enums\ServiceType;
|
||||
use App\Http\Requests\StoreEnvironmentRequest;
|
||||
use App\Http\Requests\UpdateEnvironmentRequest;
|
||||
use App\Models\Environment;
|
||||
use App\Models\Organisation;
|
||||
use App\Support\CaddyRouteRenderer;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Inertia\Response;
|
||||
|
||||
class EnvironmentController extends Controller
|
||||
{
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
$organisation = Organisation::findOrFail($request->route('organisation'));
|
||||
$application = $organisation->applications()->findOrFail($request->route('application'));
|
||||
|
||||
return inertia('environments/Create', [
|
||||
'application' => $application,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreEnvironmentRequest $request): RedirectResponse
|
||||
{
|
||||
$organisation = Organisation::findOrFail($request->route('organisation'));
|
||||
$application = $organisation->applications()->findOrFail($request->route('application'));
|
||||
|
||||
$environment = app(CreateLaravelEnvironment::class)->execute(
|
||||
application: $application,
|
||||
name: $request->string('name')->toString(),
|
||||
branch: $request->string('branch')->toString(),
|
||||
phpVersion: $request->string('php_version')->toString(),
|
||||
);
|
||||
|
||||
return redirect()
|
||||
->route('environments.show', [
|
||||
'organisation' => $organisation->id,
|
||||
'application' => $application->id,
|
||||
'environment' => $environment->id,
|
||||
])
|
||||
->with('success', 'Environment created.');
|
||||
}
|
||||
|
||||
public function show(Request $request): Response
|
||||
{
|
||||
$organisation = Organisation::findOrFail($request->route('organisation'));
|
||||
@@ -15,18 +57,151 @@ class EnvironmentController extends Controller
|
||||
$environment = $application->environments()
|
||||
->with([
|
||||
'services.replicas',
|
||||
'services.endpoints',
|
||||
'services.slices',
|
||||
'services.operations.steps',
|
||||
'attachments.service',
|
||||
'attachments.serviceSlice',
|
||||
'variables',
|
||||
'buildArtifacts.builtByService',
|
||||
'operations.steps',
|
||||
'operations.children.target',
|
||||
])
|
||||
->findOrFail($request->route('environment'));
|
||||
|
||||
$serverCount = $this->serverIdsFor($environment)->count();
|
||||
|
||||
return inertia('environments/Show', [
|
||||
'application' => $application,
|
||||
'environment' => $environment,
|
||||
'deploymentRequirements' => [
|
||||
'registryRequired' => $organisation->registries()->doesntExist() && $serverCount > 1,
|
||||
'registryCount' => $organisation->registries()->count(),
|
||||
'serverCount' => $serverCount,
|
||||
],
|
||||
'gatewayRoutePreviews' => $this->gatewayRoutePreviews($environment),
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(Request $request): Response
|
||||
{
|
||||
$organisation = Organisation::findOrFail($request->route('organisation'));
|
||||
$application = $organisation->applications()->findOrFail($request->route('application'));
|
||||
$environment = $application->environments()
|
||||
->with('services')
|
||||
->findOrFail($request->route('environment'));
|
||||
|
||||
return inertia('environments/Edit', [
|
||||
'application' => $application,
|
||||
'environment' => $environment,
|
||||
'schedulerModes' => array_values(SchedulerMode::toArray()),
|
||||
'buildStrategies' => array_values(BuildStrategy::toArray()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdateEnvironmentRequest $request): RedirectResponse
|
||||
{
|
||||
$organisation = Organisation::findOrFail($request->route('organisation'));
|
||||
$application = $organisation->applications()->findOrFail($request->route('application'));
|
||||
$environment = $application->environments()
|
||||
->with('services')
|
||||
->findOrFail($request->route('environment'));
|
||||
|
||||
$schedulerTargetServiceId = $request->integer('scheduler_target_service_id') ?: null;
|
||||
|
||||
if ($schedulerTargetServiceId !== null) {
|
||||
abort_unless($environment->services()->whereKey($schedulerTargetServiceId)->exists(), 422);
|
||||
}
|
||||
|
||||
$environment->update([
|
||||
'name' => $request->string('name')->toString(),
|
||||
'branch' => $request->string('branch')->toString(),
|
||||
'status' => $request->string('status')->toString(),
|
||||
'scheduler_enabled' => $request->boolean('scheduler_enabled'),
|
||||
'scheduler_target_service_id' => $schedulerTargetServiceId,
|
||||
'scheduler_mode' => $request->enum('scheduler_mode', SchedulerMode::class),
|
||||
'build_config' => [
|
||||
...($environment->build_config ?? []),
|
||||
'build_strategy' => $request->enum('build_strategy', BuildStrategy::class)?->value,
|
||||
'php_version' => $request->string('php_version')->toString(),
|
||||
'document_root' => $request->string('document_root')->toString(),
|
||||
'health_path' => $request->string('health_path')->toString(),
|
||||
'js_package_manager' => $request->string('js_package_manager')->toString(),
|
||||
'js_build_command' => $request->filled('js_build_command')
|
||||
? $request->string('js_build_command')->toString()
|
||||
: null,
|
||||
],
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('environments.show', [
|
||||
'organisation' => $organisation->id,
|
||||
'application' => $application->id,
|
||||
'environment' => $environment->id,
|
||||
])
|
||||
->with('success', 'Environment updated.');
|
||||
}
|
||||
|
||||
public function destroy(Request $request): RedirectResponse
|
||||
{
|
||||
$organisation = Organisation::findOrFail($request->route('organisation'));
|
||||
$application = $organisation->applications()->findOrFail($request->route('application'));
|
||||
$environment = $application->environments()->findOrFail($request->route('environment'));
|
||||
|
||||
$environment->delete();
|
||||
|
||||
return redirect()
|
||||
->route('applications.show', [
|
||||
'organisation' => $organisation->id,
|
||||
'application' => $application->id,
|
||||
])
|
||||
->with('success', 'Environment deleted.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection<int, int>
|
||||
*/
|
||||
private function serverIdsFor(Environment $environment): Collection
|
||||
{
|
||||
return $environment->services
|
||||
->flatMap(fn ($service) => [
|
||||
$service->server_id,
|
||||
...$service->replicas->pluck('server_id')->all(),
|
||||
])
|
||||
->filter()
|
||||
->unique()
|
||||
->values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, array{attachment_id: int, caddyfile: string}>
|
||||
*/
|
||||
private function gatewayRoutePreviews(Environment $environment): Collection
|
||||
{
|
||||
$upstreams = $this->previewGatewayUpstreams($environment);
|
||||
$renderer = app(CaddyRouteRenderer::class);
|
||||
|
||||
return $environment->attachments
|
||||
->filter(fn ($attachment): bool => $attachment->role === EnvironmentAttachmentRole::GATEWAY)
|
||||
->map(fn ($attachment): array => [
|
||||
'attachment_id' => $attachment->id,
|
||||
'caddyfile' => $renderer->render($attachment, $upstreams),
|
||||
])
|
||||
->values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function previewGatewayUpstreams(Environment $environment): array
|
||||
{
|
||||
return $environment->services
|
||||
->filter(fn ($service): bool => $service->type === ServiceType::LARAVEL && in_array('web', $service->process_roles ?? [], true))
|
||||
->flatMap(fn ($service) => $service->replicas->map(
|
||||
fn ($replica): string => ($replica->internal_host ?: $replica->container_name).':'.($replica->internal_port ?: 80)
|
||||
))
|
||||
->values()
|
||||
->whenEmpty(fn ($upstreams) => $upstreams->push('web:80'))
|
||||
->all();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user