Files
api/services/nginx/app/routes/cronRoute.php
T

207 lines
7.6 KiB
PHP

<?php
namespace routes;
use classes\authentication;
use classes\cron_scheduler;
use classes\cron_worker;
use classes\release_manager;
use objects\logs_o;
use Throwable;
use traits\route_t;
class cronRoute
{
use route_t;
public function run(): void
{
$this->get('/superuser/cron', function () {
global $response;
$this->requireClassicSuperuserPermission('superuser_cron_view');
$response->success((new cron_scheduler())->listTasks());
}, [
'superuser_cron_view' => 'View cron task schedule, run status, estimates, and history',
]);
$this->get('/superuser/cron/runs', function () {
global $response;
$this->requireClassicSuperuserPermission('superuser_cron_view');
$task_id = $this->getParameter('task_id');
$limit = (int)($this->getParameter('limit') ?? 50);
$response->success([
'runs' => (new cron_scheduler())->listRuns(is_string($task_id) ? $task_id : null, $limit),
]);
}, [
'superuser_cron_view' => 'View cron task schedule, run status, estimates, and history',
]);
$this->get('/superuser/cron/workers', function () {
global $response;
$this->requireClassicSuperuserPermission('superuser_cron_view');
$parameters = $this->getParametersAsArray();
$workers = (new cron_worker())->listWorkers();
try {
$workers['deployment'] = (new release_manager())->cronWorkerStatus($parameters);
} catch (Throwable $throwable) {
$workers['deployment'] = [
'ok' => false,
'error' => $throwable->getMessage(),
];
}
$response->success($workers);
}, [
'superuser_cron_view' => 'View cron worker deployment and heartbeat state',
]);
$this->post('/superuser/cron/workers/deploy', function () {
global $response;
$this->requireClassicSuperuserPermission('superuser_cron_manage');
$this->requirePermission('superuser_coolify_manage');
try {
$result = (new release_manager())->deployCronWorker(
$this->getParametersAsArray(),
$this->actorUserId()
);
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_WORKER_DEPLOY', 'Deployed cron worker');
$response->success($result);
} catch (Throwable $throwable) {
$response->error(['message' => $throwable->getMessage()], 409);
}
}, [
'superuser_cron_manage' => 'Deploy and configure cron workers',
'superuser_coolify_manage' => 'Deploy Coolify-managed infrastructure resources',
]);
$this->post('/superuser/cron/run', function () {
global $response;
$this->requireClassicSuperuserPermission('SUPERUSER_RUN_CRON');
$parameters = $this->getParametersAsArray();
$task_id = trim((string)($parameters['task_id'] ?? ''));
if ($task_id === '') {
$response->error('Missing cron task id.', 400);
}
try {
$run = (new cron_scheduler())->runTask(
$task_id,
'manual',
$this->actorUserId(),
$this->toBool($parameters['force'] ?? false, false)
);
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_JOB_RUN', 'Ran cron task: ' . $task_id);
$response->success($run);
} catch (Throwable $throwable) {
$response->error(['message' => $throwable->getMessage()], 409);
}
}, [
'SUPERUSER_RUN_CRON' => 'Run cron jobs',
]);
$this->patch('/superuser/cron/config', function () {
global $response;
$this->requireClassicSuperuserPermission('superuser_cron_manage');
$parameters = $this->getParametersAsArray();
$task_id = trim((string)($parameters['task_id'] ?? ''));
if ($task_id === '') {
$response->error('Missing cron task id.', 400);
}
try {
$config = [];
if (array_key_exists('enabled', $parameters)) {
$config['enabled'] = $this->toBool($parameters['enabled'], true);
}
if (array_key_exists('schedule', $parameters)) {
$config['schedule'] = $parameters['schedule'];
}
$result = (new cron_scheduler())->updateTaskConfig($task_id, $config);
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_TASK_CONFIG_UPDATED', 'Updated cron task: ' . $task_id);
$response->success($result);
} catch (Throwable $throwable) {
$response->error(['message' => $throwable->getMessage()], 409);
}
}, [
'superuser_cron_manage' => 'Configure cron task schedules and enabled state',
]);
$this->post('/superuser/cron', function () {
global $response;
$this->requireClassicSuperuserPermission('SUPERUSER_RUN_CRON');
$parameters = $this->getParametersAsArray();
$scheduler = new cron_scheduler();
try {
if (isset($parameters['job']) && trim((string)$parameters['job']) !== '') {
$job = trim((string)$parameters['job']);
$run = $scheduler->runTask($job, 'manual', $this->actorUserId(), true);
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_JOB_RUN', 'Ran cron job: ' . $job);
$response->success([
'message' => 'Cron job ran successfully',
'run' => $run,
]);
}
$result = $scheduler->runDue('manual');
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_RUN', 'Ran due cron jobs');
$response->success([
'message' => 'Due cron jobs ran successfully',
'data' => $result,
]);
} catch (Throwable $throwable) {
$response->error(['message' => $throwable->getMessage()], 409);
}
},
[
'SUPERUSER_RUN_CRON' => 'Run cron jobs'
]
);
}
private function requireClassicSuperuserPermission(string $permission): bool
{
global $response;
if ((new authentication())->get_subuser() !== false) {
$response->error('Subuser sessions cannot manage cron tasks.', 403);
}
return $this->requirePermission($permission);
}
private function actorUserId(): ?int
{
try {
$user = (new authentication())->get_user();
return $user !== false && isset($user->id) ? (int)$user->id : null;
} catch (Throwable) {
return null;
}
}
private function toBool(mixed $value, bool $default): bool
{
if (is_bool($value)) {
return $value;
}
if ($value === null) {
return $default;
}
$normalized = strtolower(trim((string)$value));
if (in_array($normalized, ['1', 'true', 'yes', 'on'], true)) {
return true;
}
if (in_array($normalized, ['0', 'false', 'no', 'off'], true)) {
return false;
}
return $default;
}
}