feat(api): add scheduled tasks CRUD API with auth and validation (#8428)
This commit is contained in:
commit
48cb59b371
8 changed files with 2715 additions and 1 deletions
922
app/Http/Controllers/Api/ScheduledTasksController.php
Normal file
922
app/Http/Controllers/Api/ScheduledTasksController.php
Normal file
|
|
@ -0,0 +1,922 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Application;
|
||||
use App\Models\ScheduledTask;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\Request;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
class ScheduledTasksController extends Controller
|
||||
{
|
||||
private function removeSensitiveData($task)
|
||||
{
|
||||
$task->makeHidden([
|
||||
'id',
|
||||
'team_id',
|
||||
'application_id',
|
||||
'service_id',
|
||||
]);
|
||||
|
||||
return serializeApiResponse($task);
|
||||
}
|
||||
|
||||
private function resolveApplication(Request $request, int $teamId): ?Application
|
||||
{
|
||||
return Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
|
||||
}
|
||||
|
||||
private function resolveService(Request $request, int $teamId): ?Service
|
||||
{
|
||||
return Service::whereRelation('environment.project.team', 'id', $teamId)->where('uuid', $request->uuid)->first();
|
||||
}
|
||||
|
||||
private function listTasks(Application|Service $resource): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$this->authorize('view', $resource);
|
||||
|
||||
$tasks = $resource->scheduled_tasks->map(function ($task) {
|
||||
return $this->removeSensitiveData($task);
|
||||
});
|
||||
|
||||
return response()->json($tasks);
|
||||
}
|
||||
|
||||
private function createTask(Request $request, Application|Service $resource): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$this->authorize('update', $resource);
|
||||
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
$allowedFields = ['name', 'command', 'frequency', 'container', 'timeout', 'enabled'];
|
||||
|
||||
$validator = customApiValidator($request->all(), [
|
||||
'name' => 'required|string|max:255',
|
||||
'command' => 'required|string',
|
||||
'frequency' => 'required|string',
|
||||
'container' => 'string|nullable',
|
||||
'timeout' => 'integer|min:1',
|
||||
'enabled' => 'boolean',
|
||||
]);
|
||||
|
||||
$extraFields = array_diff(array_keys($request->all()), $allowedFields);
|
||||
if ($validator->fails() || ! empty($extraFields)) {
|
||||
$errors = $validator->errors();
|
||||
if (! empty($extraFields)) {
|
||||
foreach ($extraFields as $field) {
|
||||
$errors->add($field, 'This field is not allowed.');
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
}
|
||||
|
||||
if (! validate_cron_expression($request->frequency)) {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => ['frequency' => ['Invalid cron expression or frequency format.']],
|
||||
], 422);
|
||||
}
|
||||
|
||||
$teamId = getTeamIdFromToken();
|
||||
|
||||
$task = new ScheduledTask;
|
||||
$task->name = $request->name;
|
||||
$task->command = $request->command;
|
||||
$task->frequency = $request->frequency;
|
||||
$task->container = $request->container;
|
||||
$task->timeout = $request->has('timeout') ? $request->timeout : 300;
|
||||
$task->enabled = $request->has('enabled') ? $request->enabled : true;
|
||||
$task->team_id = $teamId;
|
||||
|
||||
if ($resource instanceof Application) {
|
||||
$task->application_id = $resource->id;
|
||||
} elseif ($resource instanceof Service) {
|
||||
$task->service_id = $resource->id;
|
||||
}
|
||||
|
||||
$task->save();
|
||||
|
||||
return response()->json($this->removeSensitiveData($task), 201);
|
||||
}
|
||||
|
||||
private function updateTask(Request $request, Application|Service $resource): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$this->authorize('update', $resource);
|
||||
|
||||
$return = validateIncomingRequest($request);
|
||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
if ($request->all() === []) {
|
||||
return response()->json(['message' => 'At least one field must be provided.'], 422);
|
||||
}
|
||||
|
||||
$allowedFields = ['name', 'command', 'frequency', 'container', 'timeout', 'enabled'];
|
||||
|
||||
$validator = customApiValidator($request->all(), [
|
||||
'name' => 'string|max:255',
|
||||
'command' => 'string',
|
||||
'frequency' => 'string',
|
||||
'container' => 'string|nullable',
|
||||
'timeout' => 'integer|min:1',
|
||||
'enabled' => 'boolean',
|
||||
]);
|
||||
|
||||
$extraFields = array_diff(array_keys($request->all()), $allowedFields);
|
||||
if ($validator->fails() || ! empty($extraFields)) {
|
||||
$errors = $validator->errors();
|
||||
if (! empty($extraFields)) {
|
||||
foreach ($extraFields as $field) {
|
||||
$errors->add($field, 'This field is not allowed.');
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $errors,
|
||||
], 422);
|
||||
}
|
||||
|
||||
if ($request->has('frequency') && ! validate_cron_expression($request->frequency)) {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => ['frequency' => ['Invalid cron expression or frequency format.']],
|
||||
], 422);
|
||||
}
|
||||
|
||||
$task = $resource->scheduled_tasks()->where('uuid', $request->task_uuid)->first();
|
||||
if (! $task) {
|
||||
return response()->json(['message' => 'Scheduled task not found.'], 404);
|
||||
}
|
||||
|
||||
$task->update($request->only($allowedFields));
|
||||
|
||||
return response()->json($this->removeSensitiveData($task), 200);
|
||||
}
|
||||
|
||||
private function deleteTask(Request $request, Application|Service $resource): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$this->authorize('update', $resource);
|
||||
|
||||
$deleted = $resource->scheduled_tasks()->where('uuid', $request->task_uuid)->delete();
|
||||
if (! $deleted) {
|
||||
return response()->json(['message' => 'Scheduled task not found.'], 404);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Scheduled task deleted.']);
|
||||
}
|
||||
|
||||
private function getExecutions(Request $request, Application|Service $resource): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$this->authorize('view', $resource);
|
||||
|
||||
$task = $resource->scheduled_tasks()->where('uuid', $request->task_uuid)->first();
|
||||
if (! $task) {
|
||||
return response()->json(['message' => 'Scheduled task not found.'], 404);
|
||||
}
|
||||
|
||||
$executions = $task->executions()->get()->map(function ($execution) {
|
||||
$execution->makeHidden(['id', 'scheduled_task_id']);
|
||||
|
||||
return serializeApiResponse($execution);
|
||||
});
|
||||
|
||||
return response()->json($executions);
|
||||
}
|
||||
|
||||
#[OA\Get(
|
||||
summary: 'List Tasks',
|
||||
description: 'List all scheduled tasks for an application.',
|
||||
path: '/applications/{uuid}/scheduled-tasks',
|
||||
operationId: 'list-scheduled-tasks-by-application-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the application.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Get all scheduled tasks for an application.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'array',
|
||||
items: new OA\Items(ref: '#/components/schemas/ScheduledTask')
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function scheduled_tasks_by_application_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$application = $this->resolveApplication($request, $teamId);
|
||||
if (! $application) {
|
||||
return response()->json(['message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->listTasks($application);
|
||||
}
|
||||
|
||||
#[OA\Post(
|
||||
summary: 'Create Task',
|
||||
description: 'Create a new scheduled task for an application.',
|
||||
path: '/applications/{uuid}/scheduled-tasks',
|
||||
operationId: 'create-scheduled-task-by-application-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the application.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
requestBody: new OA\RequestBody(
|
||||
description: 'Scheduled task data',
|
||||
required: true,
|
||||
content: new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
required: ['name', 'command', 'frequency'],
|
||||
properties: [
|
||||
'name' => ['type' => 'string', 'description' => 'The name of the scheduled task.'],
|
||||
'command' => ['type' => 'string', 'description' => 'The command to execute.'],
|
||||
'frequency' => ['type' => 'string', 'description' => 'The frequency of the scheduled task.'],
|
||||
'container' => ['type' => 'string', 'nullable' => true, 'description' => 'The container where the command should be executed.'],
|
||||
'timeout' => ['type' => 'integer', 'description' => 'The timeout of the scheduled task in seconds.', 'default' => 300],
|
||||
'enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if the scheduled task is enabled.', 'default' => true],
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 201,
|
||||
description: 'Scheduled task created.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(ref: '#/components/schemas/ScheduledTask')
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 422,
|
||||
ref: '#/components/responses/422',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function create_scheduled_task_by_application_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$application = $this->resolveApplication($request, $teamId);
|
||||
if (! $application) {
|
||||
return response()->json(['message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->createTask($request, $application);
|
||||
}
|
||||
|
||||
#[OA\Patch(
|
||||
summary: 'Update Task',
|
||||
description: 'Update a scheduled task for an application.',
|
||||
path: '/applications/{uuid}/scheduled-tasks/{task_uuid}',
|
||||
operationId: 'update-scheduled-task-by-application-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the application.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
new OA\Parameter(
|
||||
name: 'task_uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the scheduled task.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
requestBody: new OA\RequestBody(
|
||||
description: 'Scheduled task data',
|
||||
required: true,
|
||||
content: new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
properties: [
|
||||
'name' => ['type' => 'string', 'description' => 'The name of the scheduled task.'],
|
||||
'command' => ['type' => 'string', 'description' => 'The command to execute.'],
|
||||
'frequency' => ['type' => 'string', 'description' => 'The frequency of the scheduled task.'],
|
||||
'container' => ['type' => 'string', 'nullable' => true, 'description' => 'The container where the command should be executed.'],
|
||||
'timeout' => ['type' => 'integer', 'description' => 'The timeout of the scheduled task in seconds.', 'default' => 300],
|
||||
'enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if the scheduled task is enabled.', 'default' => true],
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Scheduled task updated.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(ref: '#/components/schemas/ScheduledTask')
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 422,
|
||||
ref: '#/components/responses/422',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function update_scheduled_task_by_application_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$application = $this->resolveApplication($request, $teamId);
|
||||
if (! $application) {
|
||||
return response()->json(['message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->updateTask($request, $application);
|
||||
}
|
||||
|
||||
#[OA\Delete(
|
||||
summary: 'Delete Task',
|
||||
description: 'Delete a scheduled task for an application.',
|
||||
path: '/applications/{uuid}/scheduled-tasks/{task_uuid}',
|
||||
operationId: 'delete-scheduled-task-by-application-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the application.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
new OA\Parameter(
|
||||
name: 'task_uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the scheduled task.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Scheduled task deleted.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
properties: [
|
||||
'message' => ['type' => 'string', 'example' => 'Scheduled task deleted.'],
|
||||
]
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function delete_scheduled_task_by_application_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$application = $this->resolveApplication($request, $teamId);
|
||||
if (! $application) {
|
||||
return response()->json(['message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->deleteTask($request, $application);
|
||||
}
|
||||
|
||||
#[OA\Get(
|
||||
summary: 'List Executions',
|
||||
description: 'List all executions for a scheduled task on an application.',
|
||||
path: '/applications/{uuid}/scheduled-tasks/{task_uuid}/executions',
|
||||
operationId: 'list-scheduled-task-executions-by-application-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the application.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
new OA\Parameter(
|
||||
name: 'task_uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the scheduled task.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Get all executions for a scheduled task.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'array',
|
||||
items: new OA\Items(ref: '#/components/schemas/ScheduledTaskExecution')
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function executions_by_application_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$application = $this->resolveApplication($request, $teamId);
|
||||
if (! $application) {
|
||||
return response()->json(['message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->getExecutions($request, $application);
|
||||
}
|
||||
|
||||
#[OA\Get(
|
||||
summary: 'List Tasks',
|
||||
description: 'List all scheduled tasks for a service.',
|
||||
path: '/services/{uuid}/scheduled-tasks',
|
||||
operationId: 'list-scheduled-tasks-by-service-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the service.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Get all scheduled tasks for a service.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'array',
|
||||
items: new OA\Items(ref: '#/components/schemas/ScheduledTask')
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function scheduled_tasks_by_service_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$service = $this->resolveService($request, $teamId);
|
||||
if (! $service) {
|
||||
return response()->json(['message' => 'Service not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->listTasks($service);
|
||||
}
|
||||
|
||||
#[OA\Post(
|
||||
summary: 'Create Task',
|
||||
description: 'Create a new scheduled task for a service.',
|
||||
path: '/services/{uuid}/scheduled-tasks',
|
||||
operationId: 'create-scheduled-task-by-service-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the service.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
requestBody: new OA\RequestBody(
|
||||
description: 'Scheduled task data',
|
||||
required: true,
|
||||
content: new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
required: ['name', 'command', 'frequency'],
|
||||
properties: [
|
||||
'name' => ['type' => 'string', 'description' => 'The name of the scheduled task.'],
|
||||
'command' => ['type' => 'string', 'description' => 'The command to execute.'],
|
||||
'frequency' => ['type' => 'string', 'description' => 'The frequency of the scheduled task.'],
|
||||
'container' => ['type' => 'string', 'nullable' => true, 'description' => 'The container where the command should be executed.'],
|
||||
'timeout' => ['type' => 'integer', 'description' => 'The timeout of the scheduled task in seconds.', 'default' => 300],
|
||||
'enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if the scheduled task is enabled.', 'default' => true],
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 201,
|
||||
description: 'Scheduled task created.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(ref: '#/components/schemas/ScheduledTask')
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 422,
|
||||
ref: '#/components/responses/422',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function create_scheduled_task_by_service_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$service = $this->resolveService($request, $teamId);
|
||||
if (! $service) {
|
||||
return response()->json(['message' => 'Service not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->createTask($request, $service);
|
||||
}
|
||||
|
||||
#[OA\Patch(
|
||||
summary: 'Update Task',
|
||||
description: 'Update a scheduled task for a service.',
|
||||
path: '/services/{uuid}/scheduled-tasks/{task_uuid}',
|
||||
operationId: 'update-scheduled-task-by-service-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the service.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
new OA\Parameter(
|
||||
name: 'task_uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the scheduled task.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
requestBody: new OA\RequestBody(
|
||||
description: 'Scheduled task data',
|
||||
required: true,
|
||||
content: new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
properties: [
|
||||
'name' => ['type' => 'string', 'description' => 'The name of the scheduled task.'],
|
||||
'command' => ['type' => 'string', 'description' => 'The command to execute.'],
|
||||
'frequency' => ['type' => 'string', 'description' => 'The frequency of the scheduled task.'],
|
||||
'container' => ['type' => 'string', 'nullable' => true, 'description' => 'The container where the command should be executed.'],
|
||||
'timeout' => ['type' => 'integer', 'description' => 'The timeout of the scheduled task in seconds.', 'default' => 300],
|
||||
'enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if the scheduled task is enabled.', 'default' => true],
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Scheduled task updated.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(ref: '#/components/schemas/ScheduledTask')
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 422,
|
||||
ref: '#/components/responses/422',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function update_scheduled_task_by_service_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$service = $this->resolveService($request, $teamId);
|
||||
if (! $service) {
|
||||
return response()->json(['message' => 'Service not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->updateTask($request, $service);
|
||||
}
|
||||
|
||||
#[OA\Delete(
|
||||
summary: 'Delete Task',
|
||||
description: 'Delete a scheduled task for a service.',
|
||||
path: '/services/{uuid}/scheduled-tasks/{task_uuid}',
|
||||
operationId: 'delete-scheduled-task-by-service-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the service.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
new OA\Parameter(
|
||||
name: 'task_uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the scheduled task.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Scheduled task deleted.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
properties: [
|
||||
'message' => ['type' => 'string', 'example' => 'Scheduled task deleted.'],
|
||||
]
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function delete_scheduled_task_by_service_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$service = $this->resolveService($request, $teamId);
|
||||
if (! $service) {
|
||||
return response()->json(['message' => 'Service not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->deleteTask($request, $service);
|
||||
}
|
||||
|
||||
#[OA\Get(
|
||||
summary: 'List Executions',
|
||||
description: 'List all executions for a scheduled task on a service.',
|
||||
path: '/services/{uuid}/scheduled-tasks/{task_uuid}/executions',
|
||||
operationId: 'list-scheduled-task-executions-by-service-uuid',
|
||||
security: [
|
||||
['bearerAuth' => []],
|
||||
],
|
||||
tags: ['Scheduled Tasks'],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
name: 'uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the service.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
new OA\Parameter(
|
||||
name: 'task_uuid',
|
||||
in: 'path',
|
||||
description: 'UUID of the scheduled task.',
|
||||
required: true,
|
||||
schema: new OA\Schema(
|
||||
type: 'string',
|
||||
)
|
||||
),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Get all executions for a scheduled task.',
|
||||
content: [
|
||||
new OA\MediaType(
|
||||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'array',
|
||||
items: new OA\Items(ref: '#/components/schemas/ScheduledTaskExecution')
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
new OA\Response(
|
||||
response: 401,
|
||||
ref: '#/components/responses/401',
|
||||
),
|
||||
new OA\Response(
|
||||
response: 404,
|
||||
ref: '#/components/responses/404',
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function executions_by_service_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
return invalidTokenResponse();
|
||||
}
|
||||
|
||||
$service = $this->resolveService($request, $teamId);
|
||||
if (! $service) {
|
||||
return response()->json(['message' => 'Service not found.'], 404);
|
||||
}
|
||||
|
||||
return $this->getExecutions($request, $service);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,13 +5,35 @@
|
|||
use App\Traits\HasSafeStringAttribute;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
#[OA\Schema(
|
||||
description: 'Scheduled Task model',
|
||||
type: 'object',
|
||||
properties: [
|
||||
'id' => ['type' => 'integer', 'description' => 'The unique identifier of the scheduled task in the database.'],
|
||||
'uuid' => ['type' => 'string', 'description' => 'The unique identifier of the scheduled task.'],
|
||||
'enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if the scheduled task is enabled.'],
|
||||
'name' => ['type' => 'string', 'description' => 'The name of the scheduled task.'],
|
||||
'command' => ['type' => 'string', 'description' => 'The command to execute.'],
|
||||
'frequency' => ['type' => 'string', 'description' => 'The frequency of the scheduled task.'],
|
||||
'container' => ['type' => 'string', 'nullable' => true, 'description' => 'The container where the command should be executed.'],
|
||||
'timeout' => ['type' => 'integer', 'description' => 'The timeout of the scheduled task in seconds.'],
|
||||
'created_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'The date and time when the scheduled task was created.'],
|
||||
'updated_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'The date and time when the scheduled task was last updated.'],
|
||||
],
|
||||
)]
|
||||
class ScheduledTask extends BaseModel
|
||||
{
|
||||
use HasSafeStringAttribute;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public static function ownedByCurrentTeamAPI(int $teamId)
|
||||
{
|
||||
return static::where('team_id', $teamId)->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -3,7 +3,23 @@
|
|||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
#[OA\Schema(
|
||||
description: 'Scheduled Task Execution model',
|
||||
type: 'object',
|
||||
properties: [
|
||||
'uuid' => ['type' => 'string', 'description' => 'The unique identifier of the execution.'],
|
||||
'status' => ['type' => 'string', 'enum' => ['success', 'failed', 'running'], 'description' => 'The status of the execution.'],
|
||||
'message' => ['type' => 'string', 'nullable' => true, 'description' => 'The output message of the execution.'],
|
||||
'retry_count' => ['type' => 'integer', 'description' => 'The number of retries.'],
|
||||
'duration' => ['type' => 'number', 'nullable' => true, 'description' => 'Duration in seconds.'],
|
||||
'started_at' => ['type' => 'string', 'format' => 'date-time', 'nullable' => true, 'description' => 'When the execution started.'],
|
||||
'finished_at' => ['type' => 'string', 'format' => 'date-time', 'nullable' => true, 'description' => 'When the execution finished.'],
|
||||
'created_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'When the record was created.'],
|
||||
'updated_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'When the record was last updated.'],
|
||||
],
|
||||
)]
|
||||
class ScheduledTaskExecution extends BaseModel
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
|
|
|||
21
database/factories/ScheduledTaskFactory.php
Normal file
21
database/factories/ScheduledTaskFactory.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Team;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class ScheduledTaskFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->word(),
|
||||
'command' => 'echo hello',
|
||||
'frequency' => '* * * * *',
|
||||
'timeout' => 300,
|
||||
'enabled' => true,
|
||||
'team_id' => Team::factory(),
|
||||
];
|
||||
}
|
||||
}
|
||||
800
openapi.json
800
openapi.json
|
|
@ -8049,6 +8049,698 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"\/applications\/{uuid}\/scheduled-tasks": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "List Tasks",
|
||||
"description": "List all scheduled tasks for an application.",
|
||||
"operationId": "list-scheduled-tasks-by-application-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the application.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Get all scheduled tasks for an application.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "Create Task",
|
||||
"description": "Create a new scheduled task for an application.",
|
||||
"operationId": "create-scheduled-task-by-application-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the application.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Scheduled task data",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"required": [
|
||||
"name",
|
||||
"command",
|
||||
"frequency"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the scheduled task."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "The command to execute."
|
||||
},
|
||||
"frequency": {
|
||||
"type": "string",
|
||||
"description": "The frequency of the scheduled task."
|
||||
},
|
||||
"container": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The container where the command should be executed."
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "The timeout of the scheduled task in seconds.",
|
||||
"default": 300
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "The flag to indicate if the scheduled task is enabled.",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Scheduled task created.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#\/components\/responses\/422"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/applications\/{uuid}\/scheduled-tasks\/{task_uuid}": {
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "Delete Task",
|
||||
"description": "Delete a scheduled task for an application.",
|
||||
"operationId": "delete-scheduled-task-by-application-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the application.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "task_uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the scheduled task.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Scheduled task deleted.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Scheduled task deleted."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"patch": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "Update Task",
|
||||
"description": "Update a scheduled task for an application.",
|
||||
"operationId": "update-scheduled-task-by-application-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the application.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "task_uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the scheduled task.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Scheduled task data",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the scheduled task."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "The command to execute."
|
||||
},
|
||||
"frequency": {
|
||||
"type": "string",
|
||||
"description": "The frequency of the scheduled task."
|
||||
},
|
||||
"container": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The container where the command should be executed."
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "The timeout of the scheduled task in seconds.",
|
||||
"default": 300
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "The flag to indicate if the scheduled task is enabled.",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Scheduled task updated.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#\/components\/responses\/422"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/applications\/{uuid}\/scheduled-tasks\/{task_uuid}\/executions": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "List Executions",
|
||||
"description": "List all executions for a scheduled task on an application.",
|
||||
"operationId": "list-scheduled-task-executions-by-application-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the application.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "task_uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the scheduled task.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Get all executions for a scheduled task.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTaskExecution"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/services\/{uuid}\/scheduled-tasks": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "List Tasks",
|
||||
"description": "List all scheduled tasks for a service.",
|
||||
"operationId": "list-scheduled-tasks-by-service-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the service.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Get all scheduled tasks for a service.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "Create Task",
|
||||
"description": "Create a new scheduled task for a service.",
|
||||
"operationId": "create-scheduled-task-by-service-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the service.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Scheduled task data",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"required": [
|
||||
"name",
|
||||
"command",
|
||||
"frequency"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the scheduled task."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "The command to execute."
|
||||
},
|
||||
"frequency": {
|
||||
"type": "string",
|
||||
"description": "The frequency of the scheduled task."
|
||||
},
|
||||
"container": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The container where the command should be executed."
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "The timeout of the scheduled task in seconds.",
|
||||
"default": 300
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "The flag to indicate if the scheduled task is enabled.",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Scheduled task created.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#\/components\/responses\/422"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/services\/{uuid}\/scheduled-tasks\/{task_uuid}": {
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "Delete Task",
|
||||
"description": "Delete a scheduled task for a service.",
|
||||
"operationId": "delete-scheduled-task-by-service-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the service.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "task_uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the scheduled task.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Scheduled task deleted.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Scheduled task deleted."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"patch": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "Update Task",
|
||||
"description": "Update a scheduled task for a service.",
|
||||
"operationId": "update-scheduled-task-by-service-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the service.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "task_uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the scheduled task.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"description": "Scheduled task data",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the scheduled task."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "The command to execute."
|
||||
},
|
||||
"frequency": {
|
||||
"type": "string",
|
||||
"description": "The frequency of the scheduled task."
|
||||
},
|
||||
"container": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The container where the command should be executed."
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "The timeout of the scheduled task in seconds.",
|
||||
"default": 300
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "The flag to indicate if the scheduled task is enabled.",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Scheduled task updated.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#\/components\/responses\/422"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/services\/{uuid}\/scheduled-tasks\/{task_uuid}\/executions": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Scheduled Tasks"
|
||||
],
|
||||
"summary": "List Executions",
|
||||
"description": "List all executions for a scheduled task on a service.",
|
||||
"operationId": "list-scheduled-task-executions-by-service-uuid",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the service.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "task_uuid",
|
||||
"in": "path",
|
||||
"description": "UUID of the scheduled task.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Get all executions for a scheduled task.",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#\/components\/schemas\/ScheduledTaskExecution"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#\/components\/responses\/401"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#\/components\/responses\/404"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/security\/keys": {
|
||||
"get": {
|
||||
"tags": [
|
||||
|
|
@ -10771,6 +11463,110 @@
|
|||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ScheduledTask": {
|
||||
"description": "Scheduled Task model",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "The unique identifier of the scheduled task in the database."
|
||||
},
|
||||
"uuid": {
|
||||
"type": "string",
|
||||
"description": "The unique identifier of the scheduled task."
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "The flag to indicate if the scheduled task is enabled."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the scheduled task."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "The command to execute."
|
||||
},
|
||||
"frequency": {
|
||||
"type": "string",
|
||||
"description": "The frequency of the scheduled task."
|
||||
},
|
||||
"container": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The container where the command should be executed."
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "The timeout of the scheduled task in seconds."
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The date and time when the scheduled task was created."
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The date and time when the scheduled task was last updated."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ScheduledTaskExecution": {
|
||||
"description": "Scheduled Task Execution model",
|
||||
"properties": {
|
||||
"uuid": {
|
||||
"type": "string",
|
||||
"description": "The unique identifier of the execution."
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success",
|
||||
"failed",
|
||||
"running"
|
||||
],
|
||||
"description": "The status of the execution."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The output message of the execution."
|
||||
},
|
||||
"retry_count": {
|
||||
"type": "integer",
|
||||
"description": "The number of retries."
|
||||
},
|
||||
"duration": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "Duration in seconds."
|
||||
},
|
||||
"started_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true,
|
||||
"description": "When the execution started."
|
||||
},
|
||||
"finished_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true,
|
||||
"description": "When the execution finished."
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "When the record was created."
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "When the record was last updated."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"Server": {
|
||||
"description": "Server model",
|
||||
"properties": {
|
||||
|
|
@ -11283,6 +12079,10 @@
|
|||
"name": "Resources",
|
||||
"description": "Resources"
|
||||
},
|
||||
{
|
||||
"name": "Scheduled Tasks",
|
||||
"description": "Scheduled Tasks"
|
||||
},
|
||||
{
|
||||
"name": "Private Keys",
|
||||
"description": "Private Keys"
|
||||
|
|
|
|||
555
openapi.yaml
555
openapi.yaml
|
|
@ -5085,6 +5085,478 @@ paths:
|
|||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
'/applications/{uuid}/scheduled-tasks':
|
||||
get:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'List Tasks'
|
||||
description: 'List all scheduled tasks for an application.'
|
||||
operationId: list-scheduled-tasks-by-application-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the application.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: 'Get all scheduled tasks for an application.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ScheduledTask'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
post:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'Create Task'
|
||||
description: 'Create a new scheduled task for an application.'
|
||||
operationId: create-scheduled-task-by-application-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the application.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
description: 'Scheduled task data'
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
required:
|
||||
- name
|
||||
- command
|
||||
- frequency
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 'The name of the scheduled task.'
|
||||
command:
|
||||
type: string
|
||||
description: 'The command to execute.'
|
||||
frequency:
|
||||
type: string
|
||||
description: 'The frequency of the scheduled task.'
|
||||
container:
|
||||
type: string
|
||||
nullable: true
|
||||
description: 'The container where the command should be executed.'
|
||||
timeout:
|
||||
type: integer
|
||||
description: 'The timeout of the scheduled task in seconds.'
|
||||
default: 300
|
||||
enabled:
|
||||
type: boolean
|
||||
description: 'The flag to indicate if the scheduled task is enabled.'
|
||||
default: true
|
||||
type: object
|
||||
responses:
|
||||
'201':
|
||||
description: 'Scheduled task created.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScheduledTask'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
'422':
|
||||
$ref: '#/components/responses/422'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
'/applications/{uuid}/scheduled-tasks/{task_uuid}':
|
||||
delete:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'Delete Task'
|
||||
description: 'Delete a scheduled task for an application.'
|
||||
operationId: delete-scheduled-task-by-application-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the application.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
-
|
||||
name: task_uuid
|
||||
in: path
|
||||
description: 'UUID of the scheduled task.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: 'Scheduled task deleted.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
message: { type: string, example: 'Scheduled task deleted.' }
|
||||
type: object
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
patch:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'Update Task'
|
||||
description: 'Update a scheduled task for an application.'
|
||||
operationId: update-scheduled-task-by-application-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the application.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
-
|
||||
name: task_uuid
|
||||
in: path
|
||||
description: 'UUID of the scheduled task.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
description: 'Scheduled task data'
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 'The name of the scheduled task.'
|
||||
command:
|
||||
type: string
|
||||
description: 'The command to execute.'
|
||||
frequency:
|
||||
type: string
|
||||
description: 'The frequency of the scheduled task.'
|
||||
container:
|
||||
type: string
|
||||
nullable: true
|
||||
description: 'The container where the command should be executed.'
|
||||
timeout:
|
||||
type: integer
|
||||
description: 'The timeout of the scheduled task in seconds.'
|
||||
default: 300
|
||||
enabled:
|
||||
type: boolean
|
||||
description: 'The flag to indicate if the scheduled task is enabled.'
|
||||
default: true
|
||||
type: object
|
||||
responses:
|
||||
'200':
|
||||
description: 'Scheduled task updated.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScheduledTask'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
'422':
|
||||
$ref: '#/components/responses/422'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
'/applications/{uuid}/scheduled-tasks/{task_uuid}/executions':
|
||||
get:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'List Executions'
|
||||
description: 'List all executions for a scheduled task on an application.'
|
||||
operationId: list-scheduled-task-executions-by-application-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the application.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
-
|
||||
name: task_uuid
|
||||
in: path
|
||||
description: 'UUID of the scheduled task.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: 'Get all executions for a scheduled task.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ScheduledTaskExecution'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
'/services/{uuid}/scheduled-tasks':
|
||||
get:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'List Tasks'
|
||||
description: 'List all scheduled tasks for a service.'
|
||||
operationId: list-scheduled-tasks-by-service-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the service.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: 'Get all scheduled tasks for a service.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ScheduledTask'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
post:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'Create Task'
|
||||
description: 'Create a new scheduled task for a service.'
|
||||
operationId: create-scheduled-task-by-service-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the service.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
description: 'Scheduled task data'
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
required:
|
||||
- name
|
||||
- command
|
||||
- frequency
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 'The name of the scheduled task.'
|
||||
command:
|
||||
type: string
|
||||
description: 'The command to execute.'
|
||||
frequency:
|
||||
type: string
|
||||
description: 'The frequency of the scheduled task.'
|
||||
container:
|
||||
type: string
|
||||
nullable: true
|
||||
description: 'The container where the command should be executed.'
|
||||
timeout:
|
||||
type: integer
|
||||
description: 'The timeout of the scheduled task in seconds.'
|
||||
default: 300
|
||||
enabled:
|
||||
type: boolean
|
||||
description: 'The flag to indicate if the scheduled task is enabled.'
|
||||
default: true
|
||||
type: object
|
||||
responses:
|
||||
'201':
|
||||
description: 'Scheduled task created.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScheduledTask'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
'422':
|
||||
$ref: '#/components/responses/422'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
'/services/{uuid}/scheduled-tasks/{task_uuid}':
|
||||
delete:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'Delete Task'
|
||||
description: 'Delete a scheduled task for a service.'
|
||||
operationId: delete-scheduled-task-by-service-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the service.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
-
|
||||
name: task_uuid
|
||||
in: path
|
||||
description: 'UUID of the scheduled task.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: 'Scheduled task deleted.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
message: { type: string, example: 'Scheduled task deleted.' }
|
||||
type: object
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
patch:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'Update Task'
|
||||
description: 'Update a scheduled task for a service.'
|
||||
operationId: update-scheduled-task-by-service-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the service.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
-
|
||||
name: task_uuid
|
||||
in: path
|
||||
description: 'UUID of the scheduled task.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
description: 'Scheduled task data'
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 'The name of the scheduled task.'
|
||||
command:
|
||||
type: string
|
||||
description: 'The command to execute.'
|
||||
frequency:
|
||||
type: string
|
||||
description: 'The frequency of the scheduled task.'
|
||||
container:
|
||||
type: string
|
||||
nullable: true
|
||||
description: 'The container where the command should be executed.'
|
||||
timeout:
|
||||
type: integer
|
||||
description: 'The timeout of the scheduled task in seconds.'
|
||||
default: 300
|
||||
enabled:
|
||||
type: boolean
|
||||
description: 'The flag to indicate if the scheduled task is enabled.'
|
||||
default: true
|
||||
type: object
|
||||
responses:
|
||||
'200':
|
||||
description: 'Scheduled task updated.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScheduledTask'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
'422':
|
||||
$ref: '#/components/responses/422'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
'/services/{uuid}/scheduled-tasks/{task_uuid}/executions':
|
||||
get:
|
||||
tags:
|
||||
- 'Scheduled Tasks'
|
||||
summary: 'List Executions'
|
||||
description: 'List all executions for a scheduled task on a service.'
|
||||
operationId: list-scheduled-task-executions-by-service-uuid
|
||||
parameters:
|
||||
-
|
||||
name: uuid
|
||||
in: path
|
||||
description: 'UUID of the service.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
-
|
||||
name: task_uuid
|
||||
in: path
|
||||
description: 'UUID of the scheduled task.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: 'Get all executions for a scheduled task.'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ScheduledTaskExecution'
|
||||
'401':
|
||||
$ref: '#/components/responses/401'
|
||||
'404':
|
||||
$ref: '#/components/responses/404'
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
/security/keys:
|
||||
get:
|
||||
tags:
|
||||
|
|
@ -6807,6 +7279,86 @@ components:
|
|||
description:
|
||||
type: string
|
||||
type: object
|
||||
ScheduledTask:
|
||||
description: 'Scheduled Task model'
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: 'The unique identifier of the scheduled task in the database.'
|
||||
uuid:
|
||||
type: string
|
||||
description: 'The unique identifier of the scheduled task.'
|
||||
enabled:
|
||||
type: boolean
|
||||
description: 'The flag to indicate if the scheduled task is enabled.'
|
||||
name:
|
||||
type: string
|
||||
description: 'The name of the scheduled task.'
|
||||
command:
|
||||
type: string
|
||||
description: 'The command to execute.'
|
||||
frequency:
|
||||
type: string
|
||||
description: 'The frequency of the scheduled task.'
|
||||
container:
|
||||
type: string
|
||||
nullable: true
|
||||
description: 'The container where the command should be executed.'
|
||||
timeout:
|
||||
type: integer
|
||||
description: 'The timeout of the scheduled task in seconds.'
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 'The date and time when the scheduled task was created.'
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 'The date and time when the scheduled task was last updated.'
|
||||
type: object
|
||||
ScheduledTaskExecution:
|
||||
description: 'Scheduled Task Execution model'
|
||||
properties:
|
||||
uuid:
|
||||
type: string
|
||||
description: 'The unique identifier of the execution.'
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- success
|
||||
- failed
|
||||
- running
|
||||
description: 'The status of the execution.'
|
||||
message:
|
||||
type: string
|
||||
nullable: true
|
||||
description: 'The output message of the execution.'
|
||||
retry_count:
|
||||
type: integer
|
||||
description: 'The number of retries.'
|
||||
duration:
|
||||
type: number
|
||||
nullable: true
|
||||
description: 'Duration in seconds.'
|
||||
started_at:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: 'When the execution started.'
|
||||
finished_at:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: 'When the execution finished.'
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 'When the record was created.'
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 'When the record was last updated.'
|
||||
type: object
|
||||
Server:
|
||||
description: 'Server model'
|
||||
properties:
|
||||
|
|
@ -7161,6 +7713,9 @@ tags:
|
|||
-
|
||||
name: Resources
|
||||
description: Resources
|
||||
-
|
||||
name: 'Scheduled Tasks'
|
||||
description: 'Scheduled Tasks'
|
||||
-
|
||||
name: 'Private Keys'
|
||||
description: 'Private Keys'
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
use App\Http\Controllers\Api\OtherController;
|
||||
use App\Http\Controllers\Api\ProjectController;
|
||||
use App\Http\Controllers\Api\ResourcesController;
|
||||
use App\Http\Controllers\Api\ScheduledTasksController;
|
||||
use App\Http\Controllers\Api\SecurityController;
|
||||
use App\Http\Controllers\Api\ServersController;
|
||||
use App\Http\Controllers\Api\ServicesController;
|
||||
|
|
@ -106,7 +107,7 @@
|
|||
|
||||
/**
|
||||
* @deprecated Use POST /api/v1/services instead. This endpoint creates a Service, not an Application and is a unstable duplicate of POST /api/v1/services.
|
||||
*/
|
||||
*/
|
||||
Route::post('/applications/dockercompose', [ApplicationsController::class, 'create_dockercompose_application'])->middleware(['api.ability:write']);
|
||||
|
||||
Route::get('/applications/{uuid}', [ApplicationsController::class, 'application_by_uuid'])->middleware(['api.ability:read']);
|
||||
|
|
@ -171,6 +172,18 @@
|
|||
Route::match(['get', 'post'], '/services/{uuid}/start', [ServicesController::class, 'action_deploy'])->middleware(['api.ability:write']);
|
||||
Route::match(['get', 'post'], '/services/{uuid}/restart', [ServicesController::class, 'action_restart'])->middleware(['api.ability:write']);
|
||||
Route::match(['get', 'post'], '/services/{uuid}/stop', [ServicesController::class, 'action_stop'])->middleware(['api.ability:write']);
|
||||
|
||||
Route::get('/applications/{uuid}/scheduled-tasks', [ScheduledTasksController::class, 'scheduled_tasks_by_application_uuid'])->middleware(['api.ability:read']);
|
||||
Route::post('/applications/{uuid}/scheduled-tasks', [ScheduledTasksController::class, 'create_scheduled_task_by_application_uuid'])->middleware(['api.ability:write']);
|
||||
Route::patch('/applications/{uuid}/scheduled-tasks/{task_uuid}', [ScheduledTasksController::class, 'update_scheduled_task_by_application_uuid'])->middleware(['api.ability:write']);
|
||||
Route::delete('/applications/{uuid}/scheduled-tasks/{task_uuid}', [ScheduledTasksController::class, 'delete_scheduled_task_by_application_uuid'])->middleware(['api.ability:write']);
|
||||
Route::get('/applications/{uuid}/scheduled-tasks/{task_uuid}/executions', [ScheduledTasksController::class, 'executions_by_application_uuid'])->middleware(['api.ability:read']);
|
||||
|
||||
Route::get('/services/{uuid}/scheduled-tasks', [ScheduledTasksController::class, 'scheduled_tasks_by_service_uuid'])->middleware(['api.ability:read']);
|
||||
Route::post('/services/{uuid}/scheduled-tasks', [ScheduledTasksController::class, 'create_scheduled_task_by_service_uuid'])->middleware(['api.ability:write']);
|
||||
Route::patch('/services/{uuid}/scheduled-tasks/{task_uuid}', [ScheduledTasksController::class, 'update_scheduled_task_by_service_uuid'])->middleware(['api.ability:write']);
|
||||
Route::delete('/services/{uuid}/scheduled-tasks/{task_uuid}', [ScheduledTasksController::class, 'delete_scheduled_task_by_service_uuid'])->middleware(['api.ability:write']);
|
||||
Route::get('/services/{uuid}/scheduled-tasks/{task_uuid}/executions', [ScheduledTasksController::class, 'executions_by_service_uuid'])->middleware(['api.ability:read']);
|
||||
});
|
||||
|
||||
Route::group([
|
||||
|
|
|
|||
365
tests/Feature/ScheduledTaskApiTest.php
Normal file
365
tests/Feature/ScheduledTaskApiTest.php
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\Project;
|
||||
use App\Models\ScheduledTask;
|
||||
use App\Models\ScheduledTaskExecution;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
$this->team = Team::factory()->create();
|
||||
$this->user = User::factory()->create();
|
||||
$this->team->members()->attach($this->user->id, ['role' => 'owner']);
|
||||
|
||||
session(['currentTeam' => $this->team]);
|
||||
|
||||
$this->token = $this->user->createToken('test-token', ['*']);
|
||||
$this->bearerToken = $this->token->plainTextToken;
|
||||
|
||||
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
|
||||
$this->destination = StandaloneDocker::factory()->create(['server_id' => $this->server->id]);
|
||||
$this->project = Project::factory()->create(['team_id' => $this->team->id]);
|
||||
$this->environment = Environment::factory()->create(['project_id' => $this->project->id]);
|
||||
});
|
||||
|
||||
function authHeaders($bearerToken): array
|
||||
{
|
||||
return [
|
||||
'Authorization' => 'Bearer '.$bearerToken,
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
}
|
||||
|
||||
describe('GET /api/v1/applications/{uuid}/scheduled-tasks', function () {
|
||||
test('returns empty array when no tasks exist', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->getJson("/api/v1/applications/{$application->uuid}/scheduled-tasks");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJson([]);
|
||||
});
|
||||
|
||||
test('returns tasks when they exist', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
ScheduledTask::factory()->create([
|
||||
'application_id' => $application->id,
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Test Task',
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->getJson("/api/v1/applications/{$application->uuid}/scheduled-tasks");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonCount(1);
|
||||
$response->assertJsonFragment(['name' => 'Test Task']);
|
||||
});
|
||||
|
||||
test('returns 404 for unknown application uuid', function () {
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->getJson('/api/v1/applications/nonexistent-uuid/scheduled-tasks');
|
||||
|
||||
$response->assertStatus(404);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/v1/applications/{uuid}/scheduled-tasks', function () {
|
||||
test('creates a task with valid data', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->postJson("/api/v1/applications/{$application->uuid}/scheduled-tasks", [
|
||||
'name' => 'Backup',
|
||||
'command' => 'php artisan backup',
|
||||
'frequency' => '0 0 * * *',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonFragment(['name' => 'Backup']);
|
||||
|
||||
$this->assertDatabaseHas('scheduled_tasks', [
|
||||
'name' => 'Backup',
|
||||
'command' => 'php artisan backup',
|
||||
'frequency' => '0 0 * * *',
|
||||
'application_id' => $application->id,
|
||||
'team_id' => $this->team->id,
|
||||
]);
|
||||
});
|
||||
|
||||
test('returns 422 when name is missing', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->postJson("/api/v1/applications/{$application->uuid}/scheduled-tasks", [
|
||||
'command' => 'echo test',
|
||||
'frequency' => '* * * * *',
|
||||
]);
|
||||
|
||||
$response->assertStatus(422);
|
||||
});
|
||||
|
||||
test('returns 422 for invalid cron expression', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->postJson("/api/v1/applications/{$application->uuid}/scheduled-tasks", [
|
||||
'name' => 'Test',
|
||||
'command' => 'echo test',
|
||||
'frequency' => 'not-a-cron',
|
||||
]);
|
||||
|
||||
$response->assertStatus(422);
|
||||
$response->assertJsonPath('errors.frequency.0', 'Invalid cron expression or frequency format.');
|
||||
});
|
||||
|
||||
test('returns 422 when extra fields are present', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->postJson("/api/v1/applications/{$application->uuid}/scheduled-tasks", [
|
||||
'name' => 'Test',
|
||||
'command' => 'echo test',
|
||||
'frequency' => '* * * * *',
|
||||
'unknown_field' => 'value',
|
||||
]);
|
||||
|
||||
$response->assertStatus(422);
|
||||
});
|
||||
|
||||
test('defaults timeout and enabled when not provided', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->postJson("/api/v1/applications/{$application->uuid}/scheduled-tasks", [
|
||||
'name' => 'Test',
|
||||
'command' => 'echo test',
|
||||
'frequency' => '* * * * *',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
|
||||
$this->assertDatabaseHas('scheduled_tasks', [
|
||||
'name' => 'Test',
|
||||
'timeout' => 300,
|
||||
'enabled' => true,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PATCH /api/v1/applications/{uuid}/scheduled-tasks/{task_uuid}', function () {
|
||||
test('updates task with partial data', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$task = ScheduledTask::factory()->create([
|
||||
'application_id' => $application->id,
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Old Name',
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$application->uuid}/scheduled-tasks/{$task->uuid}", [
|
||||
'name' => 'New Name',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonFragment(['name' => 'New Name']);
|
||||
});
|
||||
|
||||
test('returns 404 when task not found', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$application->uuid}/scheduled-tasks/nonexistent", [
|
||||
'name' => 'Test',
|
||||
]);
|
||||
|
||||
$response->assertStatus(404);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /api/v1/applications/{uuid}/scheduled-tasks/{task_uuid}', function () {
|
||||
test('deletes task successfully', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$task = ScheduledTask::factory()->create([
|
||||
'application_id' => $application->id,
|
||||
'team_id' => $this->team->id,
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->deleteJson("/api/v1/applications/{$application->uuid}/scheduled-tasks/{$task->uuid}");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJson(['message' => 'Scheduled task deleted.']);
|
||||
|
||||
$this->assertDatabaseMissing('scheduled_tasks', ['uuid' => $task->uuid]);
|
||||
});
|
||||
|
||||
test('returns 404 when task not found', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->deleteJson("/api/v1/applications/{$application->uuid}/scheduled-tasks/nonexistent");
|
||||
|
||||
$response->assertStatus(404);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/v1/applications/{uuid}/scheduled-tasks/{task_uuid}/executions', function () {
|
||||
test('returns executions for a task', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$task = ScheduledTask::factory()->create([
|
||||
'application_id' => $application->id,
|
||||
'team_id' => $this->team->id,
|
||||
]);
|
||||
|
||||
ScheduledTaskExecution::create([
|
||||
'scheduled_task_id' => $task->id,
|
||||
'status' => 'success',
|
||||
'message' => 'OK',
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->getJson("/api/v1/applications/{$application->uuid}/scheduled-tasks/{$task->uuid}/executions");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonCount(1);
|
||||
$response->assertJsonFragment(['status' => 'success']);
|
||||
});
|
||||
|
||||
test('returns 404 when task not found', function () {
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->getJson("/api/v1/applications/{$application->uuid}/scheduled-tasks/nonexistent/executions");
|
||||
|
||||
$response->assertStatus(404);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Service scheduled tasks API', function () {
|
||||
test('can list tasks for a service', function () {
|
||||
$service = Service::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
'environment_id' => $this->environment->id,
|
||||
]);
|
||||
|
||||
ScheduledTask::factory()->create([
|
||||
'service_id' => $service->id,
|
||||
'team_id' => $this->team->id,
|
||||
'name' => 'Service Task',
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->getJson("/api/v1/services/{$service->uuid}/scheduled-tasks");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonCount(1);
|
||||
$response->assertJsonFragment(['name' => 'Service Task']);
|
||||
});
|
||||
|
||||
test('can create a task for a service', function () {
|
||||
$service = Service::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
'environment_id' => $this->environment->id,
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->postJson("/api/v1/services/{$service->uuid}/scheduled-tasks", [
|
||||
'name' => 'Service Backup',
|
||||
'command' => 'pg_dump',
|
||||
'frequency' => '0 2 * * *',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonFragment(['name' => 'Service Backup']);
|
||||
});
|
||||
|
||||
test('can delete a task for a service', function () {
|
||||
$service = Service::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
'environment_id' => $this->environment->id,
|
||||
]);
|
||||
|
||||
$task = ScheduledTask::factory()->create([
|
||||
'service_id' => $service->id,
|
||||
'team_id' => $this->team->id,
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(authHeaders($this->bearerToken))
|
||||
->deleteJson("/api/v1/services/{$service->uuid}/scheduled-tasks/{$task->uuid}");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJson(['message' => 'Scheduled task deleted.']);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue