Skip to content

Commit 82a74a8

Browse files
committed
GET jobs status refactoring
1 parent a02b72f commit 82a74a8

File tree

2 files changed

+89
-8
lines changed

2 files changed

+89
-8
lines changed

internal/api/handlers.go

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,13 +1015,17 @@ func (h *Handler) GetScenarioRunStatus(w http.ResponseWriter, r *http.Request) {
10151015
clusterJobs := make([]ClusterJobStatusResponse, len(scenarioRun.Status.ClusterJobs))
10161016
for i, job := range scenarioRun.Status.ClusterJobs {
10171017
clusterJobs[i] = ClusterJobStatusResponse{
1018-
ClusterName: job.ClusterName,
1019-
JobId: job.JobId,
1020-
PodName: job.PodName,
1021-
Phase: job.Phase,
1022-
Message: job.Message,
1023-
StartTime: convertMetaTime(job.StartTime),
1024-
CompletionTime: convertMetaTime(job.CompletionTime),
1018+
ClusterName: job.ClusterName,
1019+
JobId: job.JobId,
1020+
PodName: job.PodName,
1021+
Phase: job.Phase,
1022+
Message: job.Message,
1023+
StartTime: convertMetaTime(job.StartTime),
1024+
CompletionTime: convertMetaTime(job.CompletionTime),
1025+
RetryCount: job.RetryCount,
1026+
MaxRetries: job.MaxRetries,
1027+
CancelRequested: job.CancelRequested,
1028+
FailureReason: job.FailureReason,
10251029
}
10261030
}
10271031

@@ -1490,6 +1494,73 @@ func (h *Handler) DeleteSingleJob(w http.ResponseWriter, r *http.Request) {
14901494
w.WriteHeader(http.StatusNoContent)
14911495
}
14921496

1497+
// GetSingleJob handles GET /api/v1/scenarios/run/jobs/{jobId}
1498+
// It returns the status of a single job by jobId (jobId is unique across all scenario runs)
1499+
func (h *Handler) GetSingleJob(w http.ResponseWriter, r *http.Request) {
1500+
// Parse path: /api/v1/scenarios/run/jobs/{jobId}
1501+
jobId, err := extractPathSuffix(r.URL.Path, "/api/v1/scenarios/run/jobs/")
1502+
if err != nil {
1503+
writeJSONError(w, http.StatusBadRequest, ErrorResponse{
1504+
Error: "bad_request",
1505+
Message: "jobId " + err.Error(),
1506+
})
1507+
return
1508+
}
1509+
1510+
ctx := context.Background()
1511+
1512+
// Find KrknScenarioRun containing this jobId
1513+
var scenarioRunList krknv1alpha1.KrknScenarioRunList
1514+
if err := h.client.List(ctx, &scenarioRunList, client.InNamespace(h.namespace)); err != nil {
1515+
writeJSONError(w, http.StatusInternalServerError, ErrorResponse{
1516+
Error: "internal_error",
1517+
Message: "Failed to list scenario runs: " + err.Error(),
1518+
})
1519+
return
1520+
}
1521+
1522+
// Search for job across all scenario runs
1523+
var foundJob *krknv1alpha1.ClusterJobStatus
1524+
1525+
for i := range scenarioRunList.Items {
1526+
sr := &scenarioRunList.Items[i]
1527+
for j := range sr.Status.ClusterJobs {
1528+
if sr.Status.ClusterJobs[j].JobId == jobId {
1529+
foundJob = &sr.Status.ClusterJobs[j]
1530+
break
1531+
}
1532+
}
1533+
if foundJob != nil {
1534+
break
1535+
}
1536+
}
1537+
1538+
if foundJob == nil {
1539+
writeJSONError(w, http.StatusNotFound, ErrorResponse{
1540+
Error: "not_found",
1541+
Message: "Job '" + jobId + "' not found",
1542+
})
1543+
return
1544+
}
1545+
1546+
// Convert to response type
1547+
response := ClusterJobStatusResponse{
1548+
ClusterName: foundJob.ClusterName,
1549+
JobId: foundJob.JobId,
1550+
PodName: foundJob.PodName,
1551+
Phase: foundJob.Phase,
1552+
Message: foundJob.Message,
1553+
StartTime: convertMetaTime(foundJob.StartTime),
1554+
CompletionTime: convertMetaTime(foundJob.CompletionTime),
1555+
RetryCount: foundJob.RetryCount,
1556+
MaxRetries: foundJob.MaxRetries,
1557+
CancelRequested: foundJob.CancelRequested,
1558+
FailureReason: foundJob.FailureReason,
1559+
}
1560+
1561+
writeJSON(w, http.StatusOK, response)
1562+
}
1563+
14931564
func (h *Handler) ScenariosRunRouter(w http.ResponseWriter, r *http.Request) {
14941565
path := r.URL.Path
14951566

@@ -1514,9 +1585,11 @@ func (h *Handler) ScenariosRunRouter(w http.ResponseWriter, r *http.Request) {
15141585
return
15151586
}
15161587

1517-
// Check for /jobs/{jobId} pattern (DELETE single job)
1588+
// Check for /jobs/{jobId} pattern (GET or DELETE single job)
15181589
if strings.HasPrefix(path, "/api/v1/scenarios/run/jobs/") {
15191590
switch r.Method {
1591+
case http.MethodGet:
1592+
h.GetSingleJob(w, r)
15201593
case http.MethodDelete:
15211594
h.DeleteSingleJob(w, r)
15221595
default:

internal/api/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,14 @@ type ClusterJobStatusResponse struct {
322322
CompletionTime *time.Time `json:"completionTime,omitempty"`
323323
// Message contains additional information about the job status
324324
Message string `json:"message,omitempty"`
325+
// RetryCount is the number of times this job has been retried
326+
RetryCount int `json:"retryCount,omitempty"`
327+
// MaxRetries is the maximum number of retries allowed
328+
MaxRetries int `json:"maxRetries,omitempty"`
329+
// CancelRequested indicates if cancellation was requested
330+
CancelRequested bool `json:"cancelRequested,omitempty"`
331+
// FailureReason contains the categorized failure reason
332+
FailureReason string `json:"failureReason,omitempty"`
325333
}
326334

327335
// ScenarioRunListItem represents a single scenario run in the list view

0 commit comments

Comments
 (0)