Skip to content

Commit 330b86d

Browse files
authored
feat: new task endpoints (#249)
2 parents 5d42c97 + cf8c511 commit 330b86d

File tree

30 files changed

+10257
-4215
lines changed

30 files changed

+10257
-4215
lines changed

api/apiv1/design/api.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,156 @@ var _ = g.Service("control-plane", func() {
526526
g.Meta("openapi:tag:Database")
527527
})
528528
})
529+
g.Method("list-host-tasks", func() {
530+
g.Description("Lists all tasks for a host.")
531+
g.Meta("openapi:summary", "List host tasks")
532+
g.Payload(func() {
533+
g.Attribute("host_id", Identifier, func() {
534+
g.Description("ID of the host to list tasks for.")
535+
g.Example("host-1")
536+
})
537+
g.Attribute("after_task_id", g.String, func() {
538+
g.Description("ID of the task to start from.")
539+
g.Format(g.FormatUUID)
540+
g.Example("3c875a27-f6a6-4c1c-ba5f-6972fb1fc348")
541+
})
542+
g.Attribute("limit", g.Int, func() {
543+
g.Description("Maximum number of tasks to return.")
544+
g.Example(100)
545+
})
546+
g.Attribute("sort_order", g.String, func() {
547+
g.Enum("asc", "ascend", "ascending", "desc", "descend", "descending")
548+
g.Description("Sort order for the tasks.")
549+
g.Example("ascend")
550+
})
551+
552+
g.Required("host_id")
553+
})
554+
g.Result(ListHostTasksResponse)
555+
g.Error("cluster_not_initialized")
556+
g.Error("invalid_input")
557+
g.Error("not_found")
558+
559+
g.HTTP(func() {
560+
g.GET("/v1/hosts/{host_id}/tasks")
561+
g.Param("after_task_id")
562+
g.Param("limit")
563+
g.Param("sort_order")
564+
565+
g.Meta("openapi:tag:Host")
566+
})
567+
})
568+
569+
g.Method("get-host-task", func() {
570+
g.Description("Returns information about a particular task for a host.")
571+
g.Meta("openapi:summary", "Get host task")
572+
g.Payload(func() {
573+
g.Attribute("host_id", Identifier, func() {
574+
g.Description("ID of the host the task belongs to.")
575+
g.Example("host-1")
576+
})
577+
g.Attribute("task_id", g.String, func() {
578+
g.Description("ID of the task to get.")
579+
g.Format(g.FormatUUID)
580+
g.Example("3c875a27-f6a6-4c1c-ba5f-6972fb1fc348")
581+
})
582+
583+
g.Required("host_id", "task_id")
584+
})
585+
g.Result(Task)
586+
g.Error("cluster_not_initialized")
587+
g.Error("invalid_input")
588+
g.Error("not_found")
589+
590+
g.HTTP(func() {
591+
g.GET("/v1/hosts/{host_id}/tasks/{task_id}")
592+
593+
g.Meta("openapi:tag:Host")
594+
})
595+
})
596+
597+
g.Method("get-host-task-log", func() {
598+
g.Description("Returns the log of a particular task for a host.")
599+
g.Meta("openapi:summary", "Get host task logs")
600+
g.Payload(func() {
601+
g.Attribute("host_id", Identifier, func() {
602+
g.Description("ID of the host to get the task logs for.")
603+
g.Example("host-1")
604+
})
605+
g.Attribute("task_id", g.String, func() {
606+
g.Description("ID of the task to get the logs for.")
607+
g.Format(g.FormatUUID)
608+
g.Example("3c875a27-f6a6-4c1c-ba5f-6972fb1fc348")
609+
})
610+
g.Attribute("after_entry_id", g.String, func() {
611+
g.Description("ID of the entry to start from.")
612+
g.Format(g.FormatUUID)
613+
g.Example("3c875a27-f6a6-4c1c-ba5f-6972fb1fc348")
614+
})
615+
g.Attribute("limit", g.Int, func() {
616+
g.Description("Maximum number of entries to return.")
617+
g.Example(100)
618+
})
619+
620+
g.Required("host_id", "task_id")
621+
})
622+
g.Result(TaskLog)
623+
g.Error("cluster_not_initialized")
624+
g.Error("invalid_input")
625+
g.Error("not_found")
626+
627+
g.HTTP(func() {
628+
g.GET("/v1/hosts/{host_id}/tasks/{task_id}/logs")
629+
g.Param("after_entry_id")
630+
g.Param("limit")
631+
632+
g.Meta("openapi:tag:Host")
633+
})
634+
})
635+
636+
g.Method("list-tasks", func() {
637+
g.Description("Lists tasks across all scopes with optional filtering by scope and entity ID.")
638+
g.Meta("openapi:summary", "List tasks")
639+
g.Payload(func() {
640+
g.Attribute("scope", g.String, func() {
641+
g.Enum("database", "host")
642+
g.Description("Optional scope to filter tasks (database or host).")
643+
g.Example("database")
644+
})
645+
g.Attribute("entity_id", Identifier, func() {
646+
g.Description("Optional entity ID to filter tasks. Requires scope to be set.")
647+
g.Example("my-app")
648+
})
649+
g.Attribute("after_task_id", g.String, func() {
650+
g.Description("ID of the task to start from.")
651+
g.Format(g.FormatUUID)
652+
g.Example("3c875a27-f6a6-4c1c-ba5f-6972fb1fc348")
653+
})
654+
g.Attribute("limit", g.Int, func() {
655+
g.Description("Maximum number of tasks to return.")
656+
g.Example(100)
657+
})
658+
g.Attribute("sort_order", g.String, func() {
659+
g.Enum("asc", "ascend", "ascending", "desc", "descend", "descending")
660+
g.Description("Sort order for the tasks.")
661+
g.Example("ascend")
662+
})
663+
})
664+
g.Result(ListTasksResponse)
665+
g.Error("cluster_not_initialized")
666+
g.Error("invalid_input")
667+
668+
g.HTTP(func() {
669+
g.GET("/v1/tasks")
670+
g.Param("scope")
671+
g.Param("entity_id")
672+
g.Param("after_task_id")
673+
g.Param("limit")
674+
g.Param("sort_order")
675+
676+
g.Meta("openapi:tag:System")
677+
})
678+
})
529679

530680
g.Method("restore-database", func() {
531681
g.Description("Perform an in-place restore of one or more nodes using the given restore configuration.")

api/apiv1/design/task.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,52 @@ var ListDatabaseTasksResponse = g.Type("ListDatabaseTasksResponse", func() {
310310
},
311311
})
312312
})
313+
314+
var ListHostTasksResponse = g.Type("ListHostTasksResponse", func() {
315+
g.Attribute("tasks", g.ArrayOf(Task))
316+
317+
g.Example(map[string]any{
318+
"tasks": []map[string]any{
319+
{
320+
"completed_at": "2025-06-18T17:54:36Z",
321+
"created_at": "2025-06-18T17:54:28Z",
322+
"scope": "host",
323+
"entity_id": "host-1",
324+
"host_id": "host-1",
325+
"status": "completed",
326+
"task_id": "0197842d-9082-7496-b787-77bd2e11809f",
327+
"type": "remove_host",
328+
},
329+
},
330+
})
331+
})
332+
333+
var ListTasksResponse = g.Type("ListTasksResponse", func() {
334+
g.Attribute("tasks", g.ArrayOf(Task))
335+
336+
g.Example(map[string]any{
337+
"tasks": []map[string]any{
338+
{
339+
"completed_at": "2025-06-18T17:54:36Z",
340+
"created_at": "2025-06-18T17:54:28Z",
341+
"scope": "database",
342+
"entity_id": "storefront",
343+
"database_id": "storefront",
344+
"instance_id": "storefront-n1-689qacsi",
345+
"status": "completed",
346+
"task_id": "0197842d-9082-7496-b787-77bd2e11809f",
347+
"type": "node_backup",
348+
},
349+
{
350+
"completed_at": "2025-06-18T17:54:36Z",
351+
"created_at": "2025-06-18T17:54:28Z",
352+
"scope": "host",
353+
"entity_id": "host-1",
354+
"host_id": "host-1",
355+
"status": "completed",
356+
"task_id": "0197842d-9082-7496-b787-77bd2e11809f",
357+
"type": "remove_host",
358+
},
359+
},
360+
})
361+
})

api/apiv1/gen/control_plane/client.go

Lines changed: 75 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/apiv1/gen/control_plane/endpoints.go

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)