CluPilotCloud/app/Provisioning/Steps/Customer/RegisterMonitoring.php

73 lines
2.6 KiB
PHP

<?php
namespace App\Provisioning\Steps\Customer;
use App\Models\ProvisioningRun;
use App\Provisioning\StepResult;
use App\Services\Monitoring\MonitoringClient;
class RegisterMonitoring extends CustomerStep
{
public function __construct(private MonitoringClient $monitoring) {}
public function key(): string
{
return 'register_monitoring';
}
public function maxDuration(): int
{
return 120;
}
public function execute(ProvisioningRun $run): StepResult
{
if ($this->hasResource($run, 'monitoring_target_id')) {
return StepResult::advance();
}
$instance = $this->instance($run);
$url = 'https://'.$instance->subdomain.'.'.config('provisioning.dns.zone').'/status.php';
// Register with the monitoring service [E] before recording it.
// Monitoring is observability, not the product: a paid customer's cloud
// must not fail to be delivered because Kuma/the bridge is down. Retry a
// few times, then continue DEGRADED with a visible event — unless the
// operator declares monitoring mandatory.
try {
$targetId = $this->monitoring->registerTarget($instance->subdomain, $url);
} catch (\Throwable $e) {
if (config('provisioning.monitoring.required', false)) {
throw $e; // operator wants monitoring to gate delivery
}
// `attempt` is 0-based (this call IS attempt number attempt+1), so
// compare one-based: MONITORING_ATTEMPTS=2 really means two tries.
$allowed = max(1, (int) config('provisioning.monitoring.attempts', 2));
if ($run->attempt + 1 < $allowed) {
return StepResult::retry(30, 'monitoring unavailable: '.$e->getMessage());
}
// Give up on monitoring, keep the cloud. Recorded so it is visible in
// the admin console rather than silently missing.
$run->events()->create([
'step' => $this->key(),
'attempt' => $run->attempt,
'outcome' => 'info',
'message' => 'Monitoring übersprungen (Dienst nicht erreichbar): '.$e->getMessage(),
]);
return StepResult::advance();
}
// Local row BEFORE the breadcrumb (the short-circuit guard).
$instance->monitoringTargets()->firstOrCreate(
['external_id' => $targetId],
['url' => $url, 'status' => 'up'],
);
$this->recordResource($run, $instance->host, 'monitoring_target_id', $targetId);
return StepResult::advance();
}
}