wowowowowo
This commit is contained in:
171
app/Http/Controllers/OperationController.php
Normal file
171
app/Http/Controllers/OperationController.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\OperationKind;
|
||||
use App\Enums\OperationStatus;
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\Operation;
|
||||
use App\Models\Organisation;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceReplica;
|
||||
use App\Models\ServiceSlice;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class OperationController extends Controller
|
||||
{
|
||||
public function index(Request $request, Organisation $organisation): Response
|
||||
{
|
||||
$applicationIds = $organisation->applications()->pluck('id');
|
||||
$environmentIds = Environment::query()
|
||||
->whereIn('application_id', $applicationIds)
|
||||
->pluck('id');
|
||||
$serverIds = $organisation->servers()->pluck('id');
|
||||
$serviceIds = $organisation->services()->pluck('id');
|
||||
$replicaIds = ServiceReplica::query()
|
||||
->whereIn('service_id', $serviceIds)
|
||||
->pluck('id');
|
||||
$sliceIds = ServiceSlice::query()
|
||||
->whereIn('service_id', $serviceIds)
|
||||
->pluck('id');
|
||||
|
||||
$operations = Operation::query()
|
||||
->with(['target', 'parent', 'children.target'])
|
||||
->withCount('steps', 'children')
|
||||
->where(function (Builder $query) use ($applicationIds, $environmentIds, $serverIds, $serviceIds, $replicaIds, $sliceIds): void {
|
||||
$query
|
||||
->where(function (Builder $query) use ($applicationIds): void {
|
||||
$query->where('target_type', (new Application)->getMorphClass())
|
||||
->whereIn('target_id', $applicationIds);
|
||||
})
|
||||
->orWhere(function (Builder $query) use ($environmentIds): void {
|
||||
$query->where('target_type', (new Environment)->getMorphClass())
|
||||
->whereIn('target_id', $environmentIds);
|
||||
})
|
||||
->orWhere(function (Builder $query) use ($serverIds): void {
|
||||
$query->where('target_type', (new Server)->getMorphClass())
|
||||
->whereIn('target_id', $serverIds);
|
||||
})
|
||||
->orWhere(function (Builder $query) use ($serviceIds): void {
|
||||
$query->where('target_type', (new Service)->getMorphClass())
|
||||
->whereIn('target_id', $serviceIds);
|
||||
})
|
||||
->orWhere(function (Builder $query) use ($replicaIds): void {
|
||||
$query->where('target_type', (new ServiceReplica)->getMorphClass())
|
||||
->whereIn('target_id', $replicaIds);
|
||||
})
|
||||
->orWhere(function (Builder $query) use ($sliceIds): void {
|
||||
$query->where('target_type', (new ServiceSlice)->getMorphClass())
|
||||
->whereIn('target_id', $sliceIds);
|
||||
});
|
||||
})
|
||||
->when($request->filled('kind'), fn (Builder $query) => $query->where('kind', $request->string('kind')->toString()))
|
||||
->when($request->filled('status'), fn (Builder $query) => $query->where('status', $request->string('status')->toString()))
|
||||
->latest()
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
return inertia('operations/Index', [
|
||||
'operations' => $operations,
|
||||
'filters' => $request->only(['kind', 'status']),
|
||||
'operationKinds' => OperationKind::toArray(),
|
||||
'operationStatuses' => OperationStatus::toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Organisation $organisation, Operation $operation): Response
|
||||
{
|
||||
abort_unless($this->operationBelongsToOrganisation($operation, $organisation), 404);
|
||||
|
||||
$operation->load([
|
||||
'target',
|
||||
'parent.target',
|
||||
'children.target',
|
||||
'children.steps',
|
||||
'steps',
|
||||
]);
|
||||
|
||||
return inertia('operations/Show', [
|
||||
'operation' => $operation,
|
||||
]);
|
||||
}
|
||||
|
||||
public function retry(Organisation $organisation, Operation $operation): RedirectResponse
|
||||
{
|
||||
abort_unless($this->operationBelongsToOrganisation($operation, $organisation), 404);
|
||||
|
||||
$operation->update([
|
||||
'status' => OperationStatus::PENDING,
|
||||
'started_at' => null,
|
||||
'finished_at' => null,
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('operations.show', [
|
||||
'organisation' => $organisation->id,
|
||||
'operation' => $operation->id,
|
||||
])
|
||||
->with('success', 'Operation queued to run again.');
|
||||
}
|
||||
|
||||
public function cancel(Organisation $organisation, Operation $operation): RedirectResponse
|
||||
{
|
||||
abort_unless($this->operationBelongsToOrganisation($operation, $organisation), 404);
|
||||
|
||||
$operation->update([
|
||||
'status' => OperationStatus::CANCELLED,
|
||||
'finished_at' => now(),
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('operations.show', [
|
||||
'organisation' => $organisation->id,
|
||||
'operation' => $operation->id,
|
||||
])
|
||||
->with('success', 'Operation cancelled.');
|
||||
}
|
||||
|
||||
public function downloadLogs(Organisation $organisation, Operation $operation): StreamedResponse
|
||||
{
|
||||
abort_unless($this->operationBelongsToOrganisation($operation, $organisation), 404);
|
||||
|
||||
$operation->load('steps');
|
||||
|
||||
return response()->streamDownload(function () use ($operation): void {
|
||||
foreach ($operation->steps as $step) {
|
||||
echo "# {$step->name}\n\n";
|
||||
|
||||
if ($step->logs) {
|
||||
echo "## Logs\n{$step->logs}\n\n";
|
||||
}
|
||||
|
||||
if ($step->error_logs) {
|
||||
echo "## Error Logs\n{$step->error_logs}\n\n";
|
||||
}
|
||||
}
|
||||
}, "operation-{$operation->hash}.log", [
|
||||
'Content-Type' => 'text/plain',
|
||||
]);
|
||||
}
|
||||
|
||||
private function operationBelongsToOrganisation(Operation $operation, Organisation $organisation): bool
|
||||
{
|
||||
$target = $operation->target;
|
||||
|
||||
return match (true) {
|
||||
$target instanceof Application => $target->organisation_id === $organisation->id,
|
||||
$target instanceof Environment => $target->application()->where('organisation_id', $organisation->id)->exists(),
|
||||
$target instanceof Server => $target->organisation_id === $organisation->id,
|
||||
$target instanceof Service => $target->organisation_id === $organisation->id,
|
||||
$target instanceof ServiceReplica => $target->service()->where('organisation_id', $organisation->id)->exists(),
|
||||
$target instanceof ServiceSlice => $target->service()->where('organisation_id', $organisation->id)->exists(),
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user