Integrate Coolify API client and module for managing Coolify services, enhancing automation and deployment processes.

This commit is contained in:
Jeppe Bundgaard
2026-05-19 13:17:07 +02:00
parent ab31cd6dbb
commit 00a8723347
69 changed files with 16632 additions and 215 deletions
@@ -842,11 +842,89 @@ class superuser_system_status_service
['key' => 'licenseplaterecognizer', 'module' => 'licenseplaterecognizer', 'enabled_variable' => 'enabled', 'required' => ['api_key'], 'probe' => fn(array $config): array => $this->probeLicensePlateRecognizerModule($config)],
['key' => 'virkdata', 'module' => 'virkdata', 'enabled_variable' => 'enabled', 'required' => ['secret_key']],
['key' => 'shelly', 'module' => 'shelly', 'enabled_variable' => 'enabled', 'required' => ['server_url', 'secret_key'], 'probe' => fn(array $config): array => $this->probeShellyModule($config)],
['key' => 'coolify', 'module' => 'Coolify', 'enabled_variable' => 'enabled', 'required' => [], 'probe' => fn(array $config): array => $this->probeCoolifyModule($config)],
['key' => 'releasemanager', 'module' => 'ReleaseManager', 'enabled_variable' => 'enabled', 'required' => [], 'always_enabled' => true, 'probe' => fn(array $config): array => $this->probeReleaseManagerModule($config)],
['key' => 'selfserve', 'module' => 'selfserve', 'enabled_variable' => 'enabled', 'required' => ['machine_wash_minutes_included', 'minute_product'], 'probe' => fn(array $config): array => $this->probeSelfserveModule($config)],
['key' => 'bird', 'module' => 'bird', 'enabled_variable' => 'enabled', 'required' => ['server_url', 'api_key', 'channelId', 'workplaceId'], 'probe' => fn(array $config): array => $this->probeBirdModule($config)],
];
}
protected function probeReleaseManagerModule(array $config): array
{
return (new release_manager())->healthProbe();
}
protected function probeCoolifyModule(array $config): array
{
$startedAt = microtime(true);
try {
$summary = (new coolify_manager())->summary();
$instances = is_array($summary['instances'] ?? null) ? $summary['instances'] : [];
$targets = is_array($summary['targets'] ?? null) ? $summary['targets'] : [];
if ($instances === []) {
return [
'status' => 'not_configured',
'status_reason' => 'Coolify is enabled, but no Coolify API instance is configured.',
'status_reason_key' => 'coolify_instances_missing',
'status_reason_params' => [],
'checked_at' => date('c'),
'latency_ms' => round((microtime(true) - $startedAt) * 1000, 2),
];
}
$downInstances = array_values(array_filter($instances, static fn(array $instance): bool => ($instance['status'] ?? 'unknown') === 'down'));
$blockedTargets = array_values(array_filter($targets, static function (array $target): bool {
$state = (string)($target['availability_state'] ?? 'degraded');
return $state === 'destructive_action_required' || str_contains($state, 'blocked');
}));
$failedTargets = array_values(array_filter($targets, static function (array $target): bool {
return in_array((string)($target['deployment_status'] ?? ''), ['reconcile_failed', 'restart_failed', 'provision_blocked'], true);
}));
$status = 'ok';
$reason = 'Coolify deployment state is available.';
$reasonKey = 'coolify_available';
if ($downInstances !== []) {
$status = 'down';
$reason = 'One or more Coolify API instances are unreachable.';
$reasonKey = 'coolify_instances_down';
} elseif ($blockedTargets !== [] || $failedTargets !== []) {
$status = 'degraded';
$reason = 'One or more Coolify targets need operator attention before availability can be protected.';
$reasonKey = 'coolify_targets_need_attention';
} elseif ($targets === []) {
$status = 'degraded';
$reason = 'Coolify is connected, but no replicated infrastructure targets are managed yet.';
$reasonKey = 'coolify_targets_missing';
}
return [
'status' => $status,
'status_reason' => $reason,
'status_reason_key' => $reasonKey,
'status_reason_params' => [
'instances' => count($instances),
'targets' => count($targets),
'blocked_targets' => count($blockedTargets),
'failed_targets' => count($failedTargets),
],
'checked_at' => date('c'),
'latency_ms' => round((microtime(true) - $startedAt) * 1000, 2),
];
} catch (Throwable $throwable) {
return [
'status' => 'down',
'status_reason' => 'Coolify module probe failed: ' . $throwable->getMessage(),
'status_reason_key' => 'coolify_probe_failed',
'status_reason_params' => ['error' => $throwable->getMessage()],
'checked_at' => date('c'),
'latency_ms' => round((microtime(true) - $startedAt) * 1000, 2),
];
}
}
protected function probeEconomicModule(array $config): array
{
$appSecretToken = trim((string)($GLOBALS['ECONOMIC_API']['app_secret_token'] ?? ''));