Skip to content

Commit 76c9f18

Browse files
committed
api refactoring multiple targets
1 parent 4f6dd68 commit 76c9f18

File tree

5 files changed

+140
-184
lines changed

5 files changed

+140
-184
lines changed

config/default/kustomization.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ namePrefix: krkn-operator-
1414
# pairs:
1515
# someName: someValue
1616

17-
#- ../crd
1817
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
1918
# crd/kustomization.yaml
2019
#- ../webhook
@@ -29,6 +28,7 @@ namePrefix: krkn-operator-
2928
# The 'make deploy' command will verify the namespace exists before proceeding
3029
#- ../manager/namespace.yaml
3130
resources:
31+
- ../crd
3232
- ../rbac
3333
- ../manager
3434
- metrics_service.yaml

config/rbac/role.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,12 @@ rules:
3737
- apiGroups: ["krkn.krkn-chaos.dev"]
3838
resources: ["krknoperatortargetproviders/finalizers"]
3939
verbs: ["update"]
40+
- apiGroups: ["krkn.krkn-chaos.dev"]
41+
resources: ["krknoperatortargets"]
42+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
43+
- apiGroups: ["krkn.krkn-chaos.dev"]
44+
resources: ["krknoperatortargets/status"]
45+
verbs: ["get", "update", "patch"]
46+
- apiGroups: ["krkn.krkn-chaos.dev"]
47+
resources: ["krknoperatortargets/finalizers"]
48+
verbs: ["update"]

internal/api/handlers.go

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -577,12 +577,12 @@ func (h *Handler) PostScenarioGlobals(w http.ResponseWriter, r *http.Request) {
577577

578578
// PostScenarioRun handles POST /api/v1/scenarios/run endpoint
579579
// It creates and starts a new scenario job as a Kubernetes pod
580-
// createScenarioJob creates a krkn scenario job for a single target
580+
// createScenarioJob creates a krkn scenario job for a single cluster
581581
// Returns jobId, podName, and error
582582
func (h *Handler) createScenarioJob(
583583
ctx context.Context,
584584
req ScenarioRunRequest,
585-
targetUUID string,
585+
clusterName string,
586586
) (jobId string, podName string, err error) {
587587
// Generate unique job ID
588588
jobId = uuid.New().String()
@@ -593,8 +593,8 @@ func (h *Handler) createScenarioJob(
593593
kubeconfigPath = "/home/krkn/.kube/config"
594594
}
595595

596-
// Get kubeconfig using new system only
597-
kubeconfigBase64, err := h.getKubeconfig(ctx, targetUUID, "", "")
596+
// Get kubeconfig using targetRequestId and clusterName
597+
kubeconfigBase64, err := h.getKubeconfig(ctx, "", req.TargetRequestId, clusterName)
598598
if err != nil {
599599
return "", "", fmt.Errorf("failed to get kubeconfig: %w", err)
600600
}
@@ -810,10 +810,11 @@ func (h *Handler) createScenarioJob(
810810
Name: podName,
811811
Namespace: h.namespace,
812812
Labels: map[string]string{
813-
"app": "krkn-scenario",
814-
"krkn-job-id": jobId,
815-
"krkn-scenario-name": req.ScenarioName,
816-
"krkn-target-uuid": targetUUID,
813+
"app": "krkn-scenario",
814+
"krkn-job-id": jobId,
815+
"krkn-scenario-name": req.ScenarioName,
816+
"krkn-cluster-name": clusterName,
817+
"krkn-target-request": req.TargetRequestId,
817818
},
818819
},
819820
Spec: corev1.PodSpec{
@@ -858,10 +859,18 @@ func (h *Handler) PostScenarioRun(w http.ResponseWriter, r *http.Request) {
858859
}
859860

860861
// Validate required fields
861-
if len(req.TargetUUIDs) == 0 {
862+
if req.TargetRequestId == "" {
862863
writeJSONError(w, http.StatusBadRequest, ErrorResponse{
863864
Error: "bad_request",
864-
Message: "targetUUIDs is required and must contain at least one UUID",
865+
Message: "targetRequestId is required",
866+
})
867+
return
868+
}
869+
870+
if len(req.ClusterNames) == 0 {
871+
writeJSONError(w, http.StatusBadRequest, ErrorResponse{
872+
Error: "bad_request",
873+
Message: "clusterNames is required and must contain at least one cluster name",
865874
})
866875
return
867876
}
@@ -882,55 +891,51 @@ func (h *Handler) PostScenarioRun(w http.ResponseWriter, r *http.Request) {
882891
return
883892
}
884893

885-
// Check for duplicates
886-
seen := make(map[string]bool)
887-
for _, uuid := range req.TargetUUIDs {
888-
if uuid == "" {
894+
// Validate cluster names (no duplicates or empty strings)
895+
seen := make(map[string]bool, len(req.ClusterNames))
896+
for _, clusterName := range req.ClusterNames {
897+
if clusterName == "" {
889898
writeJSONError(w, http.StatusBadRequest, ErrorResponse{
890899
Error: "bad_request",
891-
Message: "targetUUIDs cannot contain empty strings",
900+
Message: "clusterNames cannot contain empty strings",
892901
})
893902
return
894903
}
895-
if seen[uuid] {
904+
if seen[clusterName] {
896905
writeJSONError(w, http.StatusBadRequest, ErrorResponse{
897906
Error: "bad_request",
898-
Message: "targetUUIDs contains duplicates: " + uuid,
907+
Message: "clusterNames contains duplicates: " + clusterName,
899908
})
900909
return
901910
}
902-
seen[uuid] = true
911+
seen[clusterName] = true
903912
}
904913

905914
ctx := context.Background()
906915

907-
// Execute job creation for each target (best-effort)
916+
// Execute job creation for each cluster (best-effort)
908917
var results []TargetJobResult
909918

910-
for _, targetUUID := range req.TargetUUIDs {
911-
jobId, podName, err := h.createScenarioJob(ctx, req, targetUUID)
919+
for _, clusterName := range req.ClusterNames {
920+
jobId, podName, err := h.createScenarioJob(ctx, req, clusterName)
921+
922+
result := TargetJobResult{
923+
ClusterName: clusterName,
924+
JobId: jobId,
925+
PodName: podName,
926+
}
912927

913928
if err != nil {
914-
// Job creation failed for this target
915-
results = append(results, TargetJobResult{
916-
TargetUUID: targetUUID,
917-
JobId: "",
918-
Status: "Failed",
919-
PodName: "",
920-
Success: false,
921-
Error: err.Error(),
922-
})
929+
// Job creation failed for this cluster
930+
result.Status = "Failed"
931+
result.Error = err.Error()
923932
} else {
924933
// Job created successfully
925-
results = append(results, TargetJobResult{
926-
TargetUUID: targetUUID,
927-
JobId: jobId,
928-
Status: "Pending",
929-
PodName: podName,
930-
Success: true,
931-
Error: "",
932-
})
934+
result.Status = "Pending"
935+
result.Success = true
933936
}
937+
938+
results = append(results, result)
934939
}
935940

936941
successfulJobs := 0
@@ -992,7 +997,7 @@ func (h *Handler) GetScenarioRunStatus(w http.ResponseWriter, r *http.Request) {
992997

993998
response := JobStatusResponse{
994999
JobId: jobId,
995-
TargetUUID: pod.Labels["krkn-target-uuid"],
1000+
ClusterName: pod.Labels["krkn-cluster-name"],
9961001
ScenarioName: pod.Labels["krkn-scenario-name"],
9971002
Status: string(pod.Status.Phase),
9981003
PodName: pod.Name,
@@ -1182,7 +1187,7 @@ func (h *Handler) ListScenarioRuns(w http.ResponseWriter, r *http.Request) {
11821187
// Parse query parameters for filtering
11831188
statusFilter := r.URL.Query().Get("status")
11841189
scenarioNameFilter := r.URL.Query().Get("scenarioName")
1185-
targetUUIDFilter := r.URL.Query().Get("targetUUID")
1190+
clusterNameFilter := r.URL.Query().Get("clusterName")
11861191

11871192
// List all pods with krkn-scenario label
11881193
var podList corev1.PodList
@@ -1202,18 +1207,18 @@ func (h *Handler) ListScenarioRuns(w http.ResponseWriter, r *http.Request) {
12021207

12031208
for _, pod := range podList.Items {
12041209
jobId := pod.Labels["krkn-job-id"]
1205-
targetUUID := pod.Labels["krkn-target-uuid"]
1210+
clusterName := pod.Labels["krkn-cluster-name"]
12061211
scenarioName := pod.Labels["krkn-scenario-name"]
12071212

12081213
if (statusFilter != "" && string(pod.Status.Phase) != statusFilter) ||
12091214
(scenarioNameFilter != "" && scenarioName != scenarioNameFilter) ||
1210-
(targetUUIDFilter != "" && targetUUID != targetUUIDFilter) {
1215+
(clusterNameFilter != "" && clusterName != clusterNameFilter) {
12111216
continue
12121217
}
12131218

12141219
jobStatus := JobStatusResponse{
12151220
JobId: jobId,
1216-
TargetUUID: targetUUID,
1221+
ClusterName: clusterName,
12171222
ScenarioName: scenarioName,
12181223
Status: string(pod.Status.Phase),
12191224
PodName: pod.Name,

0 commit comments

Comments
 (0)