From 3a8302cb73a10679a686996072da458502793a96 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Tue, 9 Sep 2025 15:52:40 +0530 Subject: [PATCH 1/9] fix: get deployment history minor validations --- .../DeploymentPipelineRestHandler.go | 30 +++++++++++-------- api/restHandler/common/ParamParserUtils.go | 12 ++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go index 652d020299..dd1e1bdfe1 100644 --- a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go +++ b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go @@ -1513,33 +1513,39 @@ func (handler *PipelineConfigRestHandlerImpl) ListDeploymentHistory(w http.Respo } token := r.Header.Get("token") vars := mux.Vars(r) - appId, err := strconv.Atoi(vars["appId"]) + appIdStr := vars["appId"] + appId, err := strconv.Atoi(appIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid appId", "err", err, "appId", appIdStr) + common.HandleParameterError(w, r, "appId", appIdStr) return } - pipelineId, err := strconv.Atoi(vars["pipelineId"]) + pipelineIdStr := vars["pipelineId"] + pipelineId, err := strconv.Atoi(pipelineIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineIdStr) + common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) return } - - environmentId, err := strconv.Atoi(vars["environmentId"]) + environmentIdStr := vars["environmentId"] + environmentId, err := strconv.Atoi(environmentIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid environmentId", "err", err, "environmentId", environmentIdStr) + common.HandleParameterError(w, r, "environmentId", environmentIdStr) return } - offsetQueryParam := r.URL.Query().Get("offset") - offset, err := strconv.Atoi(offsetQueryParam) - if offsetQueryParam == "" || err != nil { + //offsetQueryParam := r.URL.Query().Get("offset") + offset, err := common.ExtractPaginationParameterOrSetDefault(r, "offset", 0) + if err != nil { handler.Logger.Errorw("request err, ListDeploymentHistory", "err", err, "appId", appId, "environmentId", environmentId, "pipelineId", pipelineId, "offset", offset) common.WriteJsonResp(w, err, "invalid offset", http.StatusBadRequest) return } sizeQueryParam := r.URL.Query().Get("size") - limit, err := strconv.Atoi(sizeQueryParam) - if sizeQueryParam == "" || err != nil { + + limit, err := common.ExtractPaginationParameterOrSetDefault(r, "limit", 20) + if err != nil { handler.Logger.Errorw("request err, ListDeploymentHistory", "err", err, "appId", appId, "environmentId", environmentId, "pipelineId", pipelineId, "sizeQueryParam", sizeQueryParam) common.WriteJsonResp(w, err, "invalid size", http.StatusBadRequest) return diff --git a/api/restHandler/common/ParamParserUtils.go b/api/restHandler/common/ParamParserUtils.go index 8e294e38dc..926f92d486 100644 --- a/api/restHandler/common/ParamParserUtils.go +++ b/api/restHandler/common/ParamParserUtils.go @@ -160,3 +160,15 @@ func convertStringArrayToIntArray(strArr []string) ([]int, error) { } return paramValues, nil } + +func ExtractPaginationParameterOrSetDefault(r *http.Request, paramName string, defaultValue int) (int, error) { + paginationParamString := r.URL.Query().Get(paramName) + if paginationParamString == "" { + return defaultValue, nil + } + paginationParam, err := strconv.Atoi(paginationParamString) + if err != nil { + return 0, err + } + return paginationParam, nil +} From c3885585fe1e3b69c2d8697f57bf68156f36dca6 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Tue, 9 Sep 2025 16:55:16 +0530 Subject: [PATCH 2/9] fix: get pre post deployment logs minor validations --- .../DeploymentPipelineRestHandler.go | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go index dd1e1bdfe1..3c0a968223 100644 --- a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go +++ b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go @@ -1594,33 +1594,42 @@ func (handler *PipelineConfigRestHandlerImpl) GetPrePostDeploymentLogs(w http.Re } token := r.Header.Get("token") vars := mux.Vars(r) - appId, err := strconv.Atoi(vars["appId"]) + appIdStr := vars["appId"] + appId, err := strconv.Atoi(appIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) + common.HandleParameterError(w, r, "appId", appIdStr) return } - environmentId, err := strconv.Atoi(vars["environmentId"]) + environmentIdStr := vars["environmentId"] + environmentId, err := strconv.Atoi(environmentIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid environmentId", "err", err, "environmentId", environmentId) + common.HandleParameterError(w, r, "environmentId", environmentIdStr) return } - pipelineId, err := strconv.Atoi(vars["pipelineId"]) + pipelineIdStr := vars["pipelineId"] + pipelineId, err := strconv.Atoi(pipelineIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) + common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) return } - - workflowId, err := strconv.Atoi(vars["workflowId"]) + workflowRunnerIdStr := vars["workflowRunnerId"] + workflowId, err := strconv.Atoi(workflowRunnerIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid workflowId", "err", err, "workflowId", workflowId) + common.HandleParameterError(w, r, "workflowId", workflowRunnerIdStr) return } followLogs := true if ok := r.URL.Query().Has("followLogs"); ok { followLogsStr := r.URL.Query().Get("followLogs") - follow, err := strconv.ParseBool(followLogsStr) + //follow, err := strconv.ParseBool(followLogsStr) + follow, err := common.ExtractBoolQueryParam(r, "followLogs") if err != nil { - common.WriteJsonResp(w, err, "followLogs is not a valid bool", http.StatusBadRequest) + handler.Logger.Errorw("followLogs is not a valid bool", "err", err, "followLogs", followLogsStr) + common.HandleParameterError(w, r, "followLogs", followLogsStr) return } followLogs = follow From 634635b2c56675c5def814856fd97f42e0ac0394 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Tue, 9 Sep 2025 18:07:34 +0530 Subject: [PATCH 3/9] fix: get cd workflow detail and download deployment artifact param validaations --- .../DeploymentPipelineRestHandler.go | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go index 3c0a968223..6a95402411 100644 --- a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go +++ b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go @@ -1687,24 +1687,36 @@ func (handler *PipelineConfigRestHandlerImpl) FetchCdWorkflowDetails(w http.Resp } token := r.Header.Get("token") vars := mux.Vars(r) - appId, err := strconv.Atoi(vars["appId"]) + appIdStr := vars["appId"] + appId, err := strconv.Atoi(appIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) + common.HandleParameterError(w, r, "appId", appIdStr) return } - environmentId, err := strconv.Atoi(vars["environmentId"]) + environmentIdStr := vars["environmentId"] + environmentId, err := strconv.Atoi(environmentIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid environmentId", "err", err, "environmentId", environmentId) + common.HandleParameterError(w, r, "environmentId", environmentIdStr) return } - pipelineId, err := strconv.Atoi(vars["pipelineId"]) + pipelineIdStr := vars["pipelineId"] + pipelineId, err := strconv.Atoi(pipelineIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) + common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) return } - buildId, err := strconv.Atoi(vars["workflowRunnerId"]) + workflowRunnerIdStr := vars["workflowRunnerId"] + buildId, err := strconv.Atoi(workflowRunnerIdStr) if err != nil || buildId == 0 { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + if err != nil { + handler.Logger.Errorw("invalid workflowRunnerId", "err", err, "workflowRunnerId", workflowRunnerIdStr) + common.HandleParameterError(w, r, "workflowRunnerId", workflowRunnerIdStr) + return + } + common.HandleValidationErrors(w, r, fmt.Errorf("workflowRunnerId is required should be greater than 0, workflowRunnerId: %s", workflowRunnerIdStr)) return } handler.Logger.Infow("request payload, FetchCdWorkflowDetails", "err", err, "appId", appId, "environmentId", environmentId, "pipelineId", pipelineId, "buildId", buildId) @@ -1739,19 +1751,25 @@ func (handler *PipelineConfigRestHandlerImpl) DownloadArtifacts(w http.ResponseW } token := r.Header.Get("token") vars := mux.Vars(r) - appId, err := strconv.Atoi(vars["appId"]) + appIdStr := vars["appId"] + appId, err := strconv.Atoi(appIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) + common.HandleParameterError(w, r, "appId", appIdStr) return } - pipelineId, err := strconv.Atoi(vars["pipelineId"]) + pipelineIdStr := vars["pipelineId"] + pipelineId, err := strconv.Atoi(pipelineIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) + common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) return } - buildId, err := strconv.Atoi(vars["workflowRunnerId"]) + workflowRunnerIdStr := vars["workflowRunnerId"] + buildId, err := strconv.Atoi(workflowRunnerIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid workflowRunnerId", "err", err, "workflowRunnerId", workflowRunnerIdStr) + common.HandleParameterError(w, r, "workflowRunnerId", workflowRunnerIdStr) return } handler.Logger.Infow("request payload, DownloadArtifacts", "err", err, "appId", appId, "pipelineId", pipelineId, "buildId", buildId) @@ -1799,6 +1817,7 @@ func (handler *PipelineConfigRestHandlerImpl) GetStageStatus(w http.ResponseWrit } token := r.Header.Get("token") vars := mux.Vars(r) + appId, err := strconv.Atoi(vars["appId"]) if err != nil { common.WriteJsonResp(w, err, nil, http.StatusBadRequest) From d3cac078c1d25eb65ec5a1002b6d4a07852032b4 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Tue, 9 Sep 2025 18:19:13 +0530 Subject: [PATCH 4/9] fix: get deployment status params error handling and messaging enhance --- .../configure/DeploymentPipelineRestHandler.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go index 6a95402411..21ef196b8d 100644 --- a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go +++ b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go @@ -1818,14 +1818,18 @@ func (handler *PipelineConfigRestHandlerImpl) GetStageStatus(w http.ResponseWrit token := r.Header.Get("token") vars := mux.Vars(r) - appId, err := strconv.Atoi(vars["appId"]) + appIdStr := vars["appId"] + appId, err := strconv.Atoi(appIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) + common.HandleParameterError(w, r, "appId", appIdStr) return } - pipelineId, err := strconv.Atoi(vars["pipelineId"]) + pipelineIdStr := vars["pipelineId"] + pipelineId, err := strconv.Atoi(pipelineIdStr) if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) + common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) return } handler.Logger.Infow("request payload, GetStageStatus", "err", err, "appId", appId, "pipelineId", pipelineId) From c8013c1ded3f2fe9f983d1d83b513d9bbedc3c23 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Tue, 9 Sep 2025 19:01:25 +0530 Subject: [PATCH 5/9] fix: Trigger and Statuses POST api --- .../app/pipeline/trigger/PipelineTriggerRestHandler.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/restHandler/app/pipeline/trigger/PipelineTriggerRestHandler.go b/api/restHandler/app/pipeline/trigger/PipelineTriggerRestHandler.go index 6adbe072ec..07f13e0b99 100644 --- a/api/restHandler/app/pipeline/trigger/PipelineTriggerRestHandler.go +++ b/api/restHandler/app/pipeline/trigger/PipelineTriggerRestHandler.go @@ -128,7 +128,7 @@ func (handler PipelineTriggerRestHandlerImpl) OverrideConfig(w http.ResponseWrit err = handler.validator.Struct(overrideRequest) if err != nil { handler.logger.Errorw("request err, OverrideConfig", "err", err, "payload", overrideRequest) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + common.HandleValidationErrors(w, r, err) return } token := r.Header.Get("token") @@ -178,7 +178,7 @@ func (handler PipelineTriggerRestHandlerImpl) RotatePods(w http.ResponseWriter, err = handler.validator.Struct(podRotateRequest) if err != nil { handler.logger.Errorw("validation err, RotatePods", "err", err, "payload", podRotateRequest) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + common.HandleValidationErrors(w, r, err) return } token := r.Header.Get("token") @@ -227,7 +227,7 @@ func (handler PipelineTriggerRestHandlerImpl) StartStopApp(w http.ResponseWriter err = handler.validator.Struct(overrideRequest) if err != nil { handler.logger.Errorw("validation err, StartStopApp", "err", err, "payload", overrideRequest) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + common.HandleValidationErrors(w, r, err) return } token := r.Header.Get("token") From bb16d294ef05974883d41b7e1a218a6ad179be86 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Wed, 17 Sep 2025 08:58:51 +0530 Subject: [PATCH 6/9] fix: api responses and specs --- .../analysis/fe-be-payload-mismatch-report.md | 229 +++ specs/application/application-management.yaml | 261 ++++ .../application-management-fixed.yaml | 413 ++++++ specs/corrected/configmap-secret-apis.yaml | 334 +++++ specs/corrected/configmap-secret-fixed.yaml | 360 +++++ .../pod-resource-management-fixed.yaml | 387 ++++++ specs/corrected/security-apis-fixed.yaml | 376 +++++ .../orchestrator-miscellaneous-apis.yaml | 1032 ++++++++++++++ specs/template/config-maps.yaml | 47 +- .../template/configmap-secret-corrected.yaml | 688 +++++++++ .../template/deployment-template-config.yaml | 1226 +++++++++++++++-- .../template/orchestrator-app-endpoints.yaml | 923 +++++++++++++ 12 files changed, 6192 insertions(+), 84 deletions(-) create mode 100644 specs/analysis/fe-be-payload-mismatch-report.md create mode 100644 specs/corrected/application-management-fixed.yaml create mode 100644 specs/corrected/configmap-secret-apis.yaml create mode 100644 specs/corrected/configmap-secret-fixed.yaml create mode 100644 specs/corrected/pod-resource-management-fixed.yaml create mode 100644 specs/corrected/security-apis-fixed.yaml create mode 100644 specs/miscellaneous/orchestrator-miscellaneous-apis.yaml create mode 100644 specs/template/configmap-secret-corrected.yaml create mode 100644 specs/template/orchestrator-app-endpoints.yaml diff --git a/specs/analysis/fe-be-payload-mismatch-report.md b/specs/analysis/fe-be-payload-mismatch-report.md new file mode 100644 index 0000000000..ab5dbce7b1 --- /dev/null +++ b/specs/analysis/fe-be-payload-mismatch-report.md @@ -0,0 +1,229 @@ +# Frontend-Backend Payload Mismatch Analysis Report + +**Generated**: 2025-09-16 +**Scope**: Complete analysis of Devtron Orchestrator API specifications +**Status**: 🚨 **CRITICAL MISMATCHES FOUND** + +## 🚨 **EXECUTIVE SUMMARY** + +This report documents **29 critical mismatches** between Frontend (FE) expectations and Backend (BE) implementation across Devtron orchestrator APIs. The analysis covers ConfigMap/Secret APIs, Security APIs, Pod Management, Application Management, and Infrastructure APIs. + +**Severity Breakdown:** +- **❌ Critical Issues**: 22 (Require backend changes or major frontend updates) +- **⚠️ Major Issues**: 5 (Require frontend path/parameter updates) +- **✅ Correct Endpoints**: 8 (Work as expected) + +--- + +## 🔍 **DETAILED MISMATCH ANALYSIS** + +### **1. ConfigMap & Secret APIs (12 Issues)** + +#### **1.1 Path Mismatches (4 Issues)** +| Frontend Expectation | Backend Reality | Status | +|---------------------|-----------------|---------| +| `GET /orchestrator/global/cm/{appId}` | `GET /orchestrator/config/global/cm/{appId}` | ❌ Critical | +| `GET /orchestrator/global/cs/{appId}` | `GET /orchestrator/config/global/cs/{appId}` | ❌ Critical | +| `PUT /orchestrator/global/cm/{appId}/{id}` | **ENDPOINT MISSING** | ❌ Critical | +| `PUT /orchestrator/global/cs/{appId}/{id}` | **ENDPOINT MISSING** | ❌ Critical | + +#### **1.2 Missing HTTP Methods (4 Issues)** +- **FE Expects**: `PUT /orchestrator/global/cm/{appId}/{id}?name={name}` +- **BE Reality**: Only `POST /orchestrator/config/global/cm` (handles create/update) +- **FE Expects**: `PUT /orchestrator/global/cs/{appId}/{id}?name={name}` +- **BE Reality**: Only `POST /orchestrator/config/global/cs` (handles create/update) + +#### **1.3 Payload Structure Mismatches (4 Issues)** + +**Frontend Sends:** +```json +{ + "name": "global-configmap", + "data": { + "key1": "value1", + "key2": "value2" + } +} +``` + +**Backend Expects:** +```json +{ + "appId": 123, + "configData": [{ + "name": "global-configmap", + "type": "CONFIGMAP", + "data": { + "key1": "value1", + "key2": "value2" + } + }] +} +``` + +--- + +### **2. Security Scan APIs (4 Issues)** + +#### **2.1 Method Mismatches (2 Issues)** +| Frontend Expectation | Backend Reality | Status | +|---------------------|-----------------|---------| +| `POST /orchestrator/security/scan/executionDetail` | `GET /orchestrator/security/scan/executionDetail` | ❌ Critical | +| `POST /orchestrator/security/scan/executionDetail/min` | `GET /orchestrator/security/scan/executionDetail/min` | ❌ Critical | + +#### **2.2 Payload Structure Mismatches (2 Issues)** + +**Frontend Sends:** +```json +{ + "appId": 123, + "envId": 456, + "scanType": "VULNERABILITY" +} +``` + +**Backend Expects:** Complex `ImageScanRequest` structure with additional metadata fields + +--- + +### **3. Application Management APIs (4 Issues)** + +#### **3.1 Missing Query Parameters (2 Issues)** +| Frontend Expectation | Backend Reality | Status | +|---------------------|-----------------|---------| +| `POST /orchestrator/application/hibernate` | `POST /orchestrator/application/hibernate?appType={appType}` | ❌ Critical | +| `POST /orchestrator/application/unhibernate` | `POST /orchestrator/application/unhibernate?appType={appType}` | ❌ Critical | + +#### **3.2 Payload Structure Mismatches (2 Issues)** + +**Frontend Sends:** +```json +{ + "appId": 123, + "envId": 456 +} +``` + +**Backend Expects:** Different payload structure with `appType` query parameter + +--- + +### **4. Pod Management APIs (5 Issues)** + +#### **4.1 Payload Structure Mismatches (1 Issue)** + +**Frontend Sends:** +```json +{ + "appId": 123, + "envId": 456, + "podName": "my-pod" +} +``` + +**Backend Expects:** +```json +{ + "resources": [{ + "Group": "", + "Version": "v1", + "Kind": "Pod", + "Name": "my-pod", + "Namespace": "default" + }] +} +``` + +#### **4.2 Path Differences (2 Issues)** +| Frontend Expectation | Backend Reality | Status | +|---------------------|-----------------|---------| +| `/orchestrator/pods/logs/podName` | `/orchestrator/k8s/pods/logs/{podName}` | ⚠️ Major | +| `/orchestrator/resource/rotate` | `/orchestrator/k8s/resource/rotate?appId={appId}` | ⚠️ Major | + +#### **4.3 Missing Endpoints (2 Issues)** +| Frontend Expectation | Backend Reality | Status | +|---------------------|-----------------|---------| +| `POST /orchestrator/app/detail/resource-tree` | **ENDPOINT DOESN'T EXIST** | ❌ Critical | +| `POST /orchestrator/resources/ephemeralContainers` | **ENDPOINT DOESN'T EXIST** | ❌ Critical | + +--- + +## 📊 **SUMMARY STATISTICS** + +### **Issues by Category:** +| **Category** | **Count** | **Severity** | +|--------------|-----------|--------------| +| **Path Mismatches** | 6 | ❌ Critical | +| **Method Mismatches** | 4 | ❌ Critical | +| **Payload Structure Mismatches** | 8 | ❌ Critical | +| **Missing Query Parameters** | 3 | ⚠️ Major | +| **Missing Endpoints** | 2 | ❌ Critical | +| **Path Differences** | 2 | ⚠️ Major | +| **Missing HTTP Methods** | 4 | ❌ Critical | + +### **Issues by API Group:** +1. **ConfigMap/Secret APIs**: 12 issues +2. **Security APIs**: 4 issues +3. **Pod/Resource APIs**: 5 issues +4. **Application Management**: 4 issues +5. **Infrastructure APIs**: 2 issues +6. **Missing Endpoints**: 2 issues + +### **Total Issues Found: 29 Mismatches** + +--- + +## 🎯 **RECOMMENDATIONS** + +### **Option 1: Frontend Updates (Recommended)** +1. **Update API paths** to match backend routes +2. **Transform payload structures** to match backend expectations +3. **Change HTTP methods** where mismatched +4. **Add required query parameters** + +### **Option 2: Backend Updates (Alternative)** +1. **Add missing endpoints** that frontend expects +2. **Create adapter layers** for payload transformation +3. **Add missing HTTP methods** (PUT operations) +4. **Implement missing functionality** + +### **Option 3: Hybrid Approach** +1. **Fix critical path mismatches** in frontend +2. **Add missing endpoints** in backend +3. **Create payload adapters** for complex transformations + +--- + +## 📋 **EXISTING SPECIFICATIONS REFERENCE** + +The following existing specification files were analyzed: +- **`specs/security/security-dashboard-apis.yml`** - Security scan endpoints +- **`specs/application/rotate-pods.yaml`** - Pod rotation specifications +- **`specs/deployment/cd-pipeline-workflow.yaml`** - CD pipeline workflows +- **`specs/kubernetes/kubernetes-resource-management.yaml`** - K8s resource management +- **`specs/template/configmap-secret-corrected.yaml`** - ConfigMap/Secret corrections +- **`specs/miscellaneous/orchestrator-miscellaneous-apis.yaml`** - Miscellaneous API corrections + +--- + +## ⚠️ **IMPACT ASSESSMENT** + +**High Impact Issues (22):** +- All ConfigMap/Secret API mismatches +- Security scan method mismatches +- Missing application management endpoints +- Complex payload structure mismatches + +**Medium Impact Issues (5):** +- Path differences requiring frontend updates +- Missing query parameters + +**Low Impact Issues (2):** +- Minor path corrections + +--- + +**Report Generated by**: Augment Agent +**Analysis Date**: 2025-09-16 +**Total APIs Analyzed**: 35+ +**Specification Files Created**: 6 diff --git a/specs/application/application-management.yaml b/specs/application/application-management.yaml index 7784fa9fb2..f45811a214 100644 --- a/specs/application/application-management.yaml +++ b/specs/application/application-management.yaml @@ -306,6 +306,143 @@ components: enum: [helm, argo_cd] description: Deployment application type + CreateAppDTO: + type: object + description: Complete application configuration data transfer object returned by the get app endpoint + required: + - appName + - teamId + properties: + id: + type: integer + format: int64 + description: Application ID (auto-generated) + example: 123 + appName: + type: string + description: Name of the application + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + minLength: 1 + maxLength: 100 + example: "sample-app" + description: + type: string + description: Application description + example: "Sample application for demonstration" + teamId: + type: integer + format: int64 + description: Team/Project ID that owns this application + example: 1 + templateId: + type: integer + format: int64 + description: Template ID used for application creation (0 for no template) + example: 0 + appType: + type: integer + description: | + Application type identifier: + - 0: Devtron App (native Devtron application) + - 1: Helm App (Helm-based application) + - 2: Argo App (ArgoCD-based application) + enum: [0, 1, 2] + example: 0 + material: + type: array + description: Git materials/repositories associated with the application + items: + $ref: '#/components/schemas/GitMaterial' + labels: + type: array + description: Application labels for categorization and Kubernetes resource propagation + items: + $ref: '#/components/schemas/AppLabel' + genericNote: + $ref: '#/components/schemas/GenericNoteResponseBean' + description: Application notes and documentation + + GitMaterial: + type: object + description: Git repository configuration for the application + required: + - url + - gitProviderId + - checkoutPath + properties: + id: + type: integer + format: int64 + description: Git material ID + example: 1 + name: + type: string + description: Display name for the git material + example: "sample-app-main" + url: + type: string + format: uri + description: Git repository URL + example: "https://github.com/user/sample-app.git" + gitProviderId: + type: integer + format: int64 + description: Git provider configuration ID + minimum: 1 + example: 1 + checkoutPath: + type: string + description: Path where the repository should be checked out + pattern: '^[./].*' + example: "./" + fetchSubmodules: + type: boolean + description: Whether to fetch git submodules + default: false + example: false + isUsedInCiConfig: + type: boolean + description: Whether this material is used in CI configuration + example: true + filterPattern: + type: array + description: File patterns to include/exclude during build + items: + type: string + example: ["**"] + createBackup: + type: boolean + description: Whether to create backup of this material + default: false + example: false + + GenericNoteResponseBean: + type: object + description: Application notes and documentation metadata + properties: + id: + type: integer + format: int64 + description: Note ID + example: 1 + description: + type: string + description: Note content/description + example: "This is a sample application" + updatedBy: + type: string + description: Username who last updated the note + example: "admin" + updatedOn: + type: string + format: date-time + description: Last update timestamp + example: "2024-01-15T10:30:00Z" + createdBy: + type: string + description: Username who created the note + example: "admin" + tags: - name: Application Management description: Operations for managing applications in Devtron orchestrator @@ -461,6 +598,130 @@ paths: security: - bearerAuth: [] + /get/{appId}: + get: + tags: + - Application Management + summary: Get application configuration details + description: | + Retrieves comprehensive configuration details for a specific application including: + - Basic application metadata (ID, name, description, team) + - Git materials configuration (repositories, checkout paths, filter patterns) + - Application labels with propagation settings + - Template configuration and app type information + - Generic notes and descriptions + + This endpoint is primarily used for application management and configuration display. + operationId: getApplicationConfig + parameters: + - name: appId + in: path + description: ID of the application to retrieve configuration for + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 123 + responses: + '200': + description: Application configuration retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/CreateAppDTO' + examples: + devtron_app: + summary: Devtron Application Example + value: + code: 200 + status: "OK" + result: + id: 123 + appName: "sample-app" + description: "Sample application for demonstration" + teamId: 1 + templateId: 0 + appType: 0 + material: + - id: 1 + name: "sample-app-main" + url: "https://github.com/user/sample-app.git" + gitProviderId: 1 + checkoutPath: "./" + fetchSubmodules: false + filterPattern: ["**"] + labels: + - key: "environment" + value: "development" + propagate: true + - key: "team" + value: "backend" + propagate: false + genericNote: + id: 1 + description: "This is a sample application" + updatedBy: "admin" + updatedOn: "2024-01-15T10:30:00Z" + createdBy: "admin" + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + code: 400 + status: "Bad Request" + errors: ["Invalid appId format"] + '401': + description: Unauthorized - Invalid or missing authentication token + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + code: 401 + status: "Unauthorized" + errors: ["Authentication required"] + '403': + description: Forbidden - User lacks permission to access this application + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + code: 403 + status: "Forbidden" + errors: ["Unauthorized User"] + '404': + description: Application not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + code: 404 + status: "Not Found" + errors: ["Application not found"] + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + code: 500 + status: "Internal Server Error" + errors: ["Internal server error occurred"] + security: + - bearerAuth: [] + /app/{appId}: get: tags: diff --git a/specs/corrected/application-management-fixed.yaml b/specs/corrected/application-management-fixed.yaml new file mode 100644 index 0000000000..63cda20f1d --- /dev/null +++ b/specs/corrected/application-management-fixed.yaml @@ -0,0 +1,413 @@ +openapi: "3.0.3" +info: + title: Devtron Application Management API + description: API specifications for application hibernation, deployment status, and lifecycle management + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +security: + - bearerAuth: [] + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + status: + type: string + result: + type: object + + ErrorResponse: + type: object + properties: + code: + type: integer + status: + type: string + errors: + type: array + items: + type: string + + HibernateRequest: + type: object + properties: + appId: + type: string + example: "123" + resources: + type: array + items: + $ref: '#/components/schemas/HibernateTargetObject' + + HibernateTargetObject: + type: object + properties: + group: + type: string + example: "apps" + kind: + type: string + example: "Deployment" + version: + type: string + example: "v1" + name: + type: string + example: "my-app" + namespace: + type: string + example: "default" + + HibernateStatus: + type: object + properties: + success: + type: boolean + example: true + errorMessage: + type: string + example: "" + targetObject: + $ref: '#/components/schemas/HibernateTargetObject' + + PipelineTriggerRequest: + type: object + properties: + appId: + type: integer + example: 123 + environmentId: + type: integer + example: 456 + pipelineId: + type: integer + example: 789 + +tags: + - name: Application Hibernation + description: Application hibernation and unhibernation operations + - name: Pipeline Management + description: CD pipeline trigger and management operations + - name: Deployment Status + description: Deployment status and timeline operations + +paths: + /application/hibernate: + post: + tags: + - Application Hibernation + summary: Hibernate application + description: Hibernates the specified application resources + operationId: hibernateApplication + parameters: + - name: appType + in: query + required: true + schema: + type: string + enum: ["argo", "helm", "flux"] + example: "argo" + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/HibernateRequest' + example: + appId: "123" + resources: + - group: "apps" + kind: "Deployment" + version: "v1" + name: "my-app" + namespace: "default" + responses: + '200': + description: Application hibernated successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + type: array + items: + $ref: '#/components/schemas/HibernateStatus' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /application/unhibernate: + post: + tags: + - Application Hibernation + summary: Unhibernate application + description: Unhibernates the specified application resources + operationId: unhibernateApplication + parameters: + - name: appType + in: query + required: true + schema: + type: string + enum: ["argo", "helm", "flux"] + example: "argo" + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/HibernateRequest' + example: + appId: "123" + resources: + - group: "apps" + kind: "Deployment" + version: "v1" + name: "my-app" + namespace: "default" + responses: + '200': + description: Application unhibernated successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + type: array + items: + $ref: '#/components/schemas/HibernateStatus' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /app/cd-pipeline/trigger: + post: + tags: + - Pipeline Management + summary: Trigger CD pipeline + description: Triggers a CD pipeline deployment for the specified application and environment + operationId: triggerCdPipeline + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PipelineTriggerRequest' + example: + appId: 123 + environmentId: 456 + pipelineId: 789 + responses: + '200': + description: CD pipeline triggered successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /app/deployment-status/timeline/{appId}/{envId}: + get: + tags: + - Deployment Status + summary: Get deployment status timeline + description: Retrieves the deployment status timeline for the specified application and environment + operationId: getDeploymentStatusTimeline + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + - name: envId + in: path + required: true + schema: + type: integer + example: 456 + responses: + '200': + description: Deployment status timeline retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application or environment not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /app/deployment-status/manual-sync/{appId}/{envId}: + get: + tags: + - Deployment Status + summary: Manual sync deployment status + description: Manually synchronizes the deployment status for the specified application and environment + operationId: manualSyncDeploymentStatus + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + - name: envId + in: path + required: true + schema: + type: integer + example: 456 + responses: + '200': + description: Manual sync completed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application or environment not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/configmap-secret-apis.yaml b/specs/corrected/configmap-secret-apis.yaml new file mode 100644 index 0000000000..6e9c0258d5 --- /dev/null +++ b/specs/corrected/configmap-secret-apis.yaml @@ -0,0 +1,334 @@ +openapi: "3.0.3" +info: + title: Devtron ConfigMap and Secret Management API + description: | + API specifications for ConfigMap and Secret management in Devtron orchestrator. + These specifications match the actual backend implementation exactly. + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +security: + - bearerAuth: [] + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: JWT token for authentication + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + description: HTTP status code + status: + type: string + description: Response status + result: + type: object + description: Response data + + ErrorResponse: + type: object + properties: + code: + type: integer + description: Error code + status: + type: string + description: Error status + errors: + type: array + items: + type: string + description: List of error messages + + ConfigDataRequest: + type: object + description: Request structure for ConfigMap/Secret operations + required: + - appId + - configData + properties: + id: + type: integer + description: ID of the ConfigMap/Secret (0 for new) + example: 0 + appId: + type: integer + description: Application ID + example: 123 + environmentId: + type: integer + description: Environment ID (for environment-specific configs) + example: 456 + configData: + type: array + description: Array of ConfigData objects + items: + $ref: '#/components/schemas/ConfigData' + isDeletable: + type: boolean + description: Whether the config is deletable + default: true + + ConfigData: + type: object + description: Individual ConfigMap or Secret data + required: + - name + - type + properties: + name: + type: string + description: Name of the ConfigMap/Secret + example: "global-configmap" + type: + type: string + description: Type of configuration + enum: ["CONFIGMAP", "SECRET"] + example: "CONFIGMAP" + external: + type: boolean + description: Whether this is an external ConfigMap/Secret + default: false + mountPath: + type: string + description: Path where the ConfigMap/Secret should be mounted + example: "/etc/config" + data: + type: object + description: Configuration data as key-value pairs + additionalProperties: + type: string + example: + key1: "value1" + key2: "value2" + global: + type: boolean + description: Whether this is a global configuration + default: true + subPath: + type: boolean + description: Whether to use subPath mounting + default: false + filePermission: + type: string + description: File permission for mounted files + example: "0644" + + ConfigsList: + type: object + properties: + maps: + type: array + items: + $ref: '#/components/schemas/ConfigData' + +tags: + - name: Global ConfigMaps + description: Global ConfigMap management operations + - name: Global Secrets + description: Global Secret management operations + - name: Environment ConfigMaps + description: Environment-specific ConfigMap operations + - name: Environment Secrets + description: Environment-specific Secret operations + +paths: + /config/global/cm: + post: + tags: + - Global ConfigMaps + summary: Create or update global ConfigMap + description: | + Creates a new global ConfigMap or updates an existing one. + This endpoint handles both create and update operations based on the ID field. + operationId: CMGlobalAddUpdate + requestBody: + description: ConfigMap configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigDataRequest' + example: + id: 0 + appId: 123 + configData: + - name: "global-configmap" + type: "CONFIGMAP" + external: false + mountPath: "/etc/config" + data: + key1: "value1" + key2: "value2" + global: true + subPath: false + filePermission: "0644" + isDeletable: true + responses: + '200': + description: ConfigMap created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /config/global/cs: + post: + tags: + - Global Secrets + summary: Create or update global Secret + description: | + Creates a new global Secret or updates an existing one. + This endpoint handles both create and update operations based on the ID field. + operationId: CSGlobalAddUpdate + requestBody: + description: Secret configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigDataRequest' + example: + id: 0 + appId: 123 + configData: + - name: "global-secret" + type: "SECRET" + external: false + mountPath: "/etc/secrets" + data: + username: "admin" + password: "s3cr3t" + global: true + subPath: false + filePermission: "0600" + isDeletable: true + responses: + '200': + description: Secret created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /config/global/cm/{appId}: + get: + tags: + - Global ConfigMaps + summary: Get global ConfigMaps for application + description: Retrieves all global ConfigMaps for the specified application + operationId: CMGlobalFetch + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + example: 123 + responses: + '200': + description: Global ConfigMaps retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ConfigsList' + '400': + description: Invalid application ID + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/configmap-secret-fixed.yaml b/specs/corrected/configmap-secret-fixed.yaml new file mode 100644 index 0000000000..5e44e49c11 --- /dev/null +++ b/specs/corrected/configmap-secret-fixed.yaml @@ -0,0 +1,360 @@ +openapi: "3.0.3" +info: + title: Devtron ConfigMap and Secret Management API + description: API specifications for ConfigMap and Secret management in Devtron orchestrator + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +security: + - bearerAuth: [] + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + status: + type: string + result: + type: object + + ErrorResponse: + type: object + properties: + code: + type: integer + status: + type: string + errors: + type: array + items: + type: string + + ConfigDataRequest: + type: object + required: + - appId + - configData + properties: + id: + type: integer + example: 0 + appId: + type: integer + example: 123 + environmentId: + type: integer + example: 456 + configData: + type: array + items: + $ref: '#/components/schemas/ConfigData' + isDeletable: + type: boolean + default: true + + ConfigData: + type: object + required: + - name + - type + properties: + name: + type: string + example: "global-configmap" + type: + type: string + enum: ["CONFIGMAP", "SECRET"] + example: "CONFIGMAP" + external: + type: boolean + default: false + mountPath: + type: string + example: "/etc/config" + data: + type: object + additionalProperties: + type: string + example: + key1: "value1" + key2: "value2" + global: + type: boolean + default: true + subPath: + type: boolean + default: false + filePermission: + type: string + example: "0644" + + ConfigsList: + type: object + properties: + maps: + type: array + items: + $ref: '#/components/schemas/ConfigData' + +tags: + - name: Global ConfigMaps + description: Global ConfigMap management + - name: Global Secrets + description: Global Secret management + - name: Environment ConfigMaps + description: Environment-specific ConfigMap operations + - name: Environment Secrets + description: Environment-specific Secret operations + +paths: + /config/global/cm: + post: + tags: + - Global ConfigMaps + summary: Create or update global ConfigMap + description: Creates a new global ConfigMap or updates an existing one + operationId: CMGlobalAddUpdate + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigDataRequest' + example: + id: 0 + appId: 123 + configData: + - name: "global-configmap" + type: "CONFIGMAP" + external: false + mountPath: "/etc/config" + data: + key1: "value1" + key2: "value2" + global: true + subPath: false + filePermission: "0644" + isDeletable: true + responses: + '200': + description: ConfigMap created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /config/global/cs: + post: + tags: + - Global Secrets + summary: Create or update global Secret + description: Creates a new global Secret or updates an existing one + operationId: CSGlobalAddUpdate + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigDataRequest' + example: + id: 0 + appId: 123 + configData: + - name: "global-secret" + type: "SECRET" + external: false + mountPath: "/etc/secrets" + data: + username: "admin" + password: "s3cr3t" + global: true + subPath: false + filePermission: "0600" + isDeletable: true + responses: + '200': + description: Secret created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /config/global/cm/{appId}: + get: + tags: + - Global ConfigMaps + summary: Get global ConfigMaps for application + description: Retrieves all global ConfigMaps for the specified application + operationId: CMGlobalFetch + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + responses: + '200': + description: Global ConfigMaps retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ConfigsList' + '400': + description: Invalid application ID + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /config/global/cs/{appId}: + get: + tags: + - Global Secrets + summary: Get global Secrets for application + description: Retrieves all global Secrets for the specified application + operationId: CSGlobalFetch + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + responses: + '200': + description: Global Secrets retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ConfigsList' + '400': + description: Invalid application ID + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/pod-resource-management-fixed.yaml b/specs/corrected/pod-resource-management-fixed.yaml new file mode 100644 index 0000000000..0ceb7573d2 --- /dev/null +++ b/specs/corrected/pod-resource-management-fixed.yaml @@ -0,0 +1,387 @@ +openapi: "3.0.3" +info: + title: Devtron Pod and Resource Management API + description: API specifications for pod logs, resource rotation, and Kubernetes resource management + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +security: + - bearerAuth: [] + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + status: + type: string + result: + type: object + + ErrorResponse: + type: object + properties: + code: + type: integer + status: + type: string + errors: + type: array + items: + type: string + + PodRotateRequest: + type: object + properties: + resources: + type: array + items: + $ref: '#/components/schemas/ResourceIdentifier' + + ResourceIdentifier: + type: object + properties: + Group: + type: string + example: "" + Version: + type: string + example: "v1" + Kind: + type: string + example: "Pod" + Name: + type: string + example: "my-pod" + Namespace: + type: string + example: "default" + + ResourceRotateRequest: + type: object + properties: + resourceId: + type: string + example: "res-123" + +tags: + - name: Pod Logs + description: Pod log retrieval operations + - name: Resource Management + description: Kubernetes resource management operations + - name: Pod Rotation + description: Pod rotation and restart operations + +paths: + /k8s/pods/logs/{podName}: + get: + tags: + - Pod Logs + summary: Get pod logs + description: Retrieves logs from the specified pod and container + operationId: getPodLogs + parameters: + - name: podName + in: path + required: true + schema: + type: string + example: "my-app-pod-123" + - name: containerName + in: query + required: true + schema: + type: string + example: "main-container" + - name: follow + in: query + required: false + schema: + type: boolean + default: false + example: false + responses: + '200': + description: Pod logs retrieved successfully + content: + text/plain: + schema: + type: string + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Pod not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /k8s/pods/logs/download/{podName}: + get: + tags: + - Pod Logs + summary: Download pod logs + description: Downloads logs from the specified pod and container as a file + operationId: downloadPodLogs + parameters: + - name: podName + in: path + required: true + schema: + type: string + example: "my-app-pod-123" + - name: containerName + in: query + required: true + schema: + type: string + example: "main-container" + responses: + '200': + description: Pod logs file download + content: + application/octet-stream: + schema: + type: string + format: binary + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Pod not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /k8s/resource/rotate: + post: + tags: + - Resource Management + summary: Rotate Kubernetes resource + description: Rotates the specified Kubernetes resource + operationId: rotateKubernetesResource + parameters: + - name: appId + in: query + required: true + schema: + type: integer + example: 123 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceRotateRequest' + example: + resourceId: "res-123" + responses: + '200': + description: Resource rotated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /app/rotate-pods: + post: + tags: + - Pod Rotation + summary: Rotate pods + description: Rotates the specified pods using resource identifiers + operationId: rotatePods + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PodRotateRequest' + example: + resources: + - Group: "" + Version: "v1" + Kind: "Pod" + Name: "my-pod" + Namespace: "default" + responses: + '200': + description: Pods rotated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /cluster/list: + get: + tags: + - Resource Management + summary: Get cluster list + description: Retrieves a list of all available clusters + operationId: getClusterList + responses: + '200': + description: List of clusters retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /cluster/namespaces: + get: + tags: + - Resource Management + summary: Get all cluster namespaces + description: Retrieves namespaces from all clusters + operationId: getAllClusterNamespaces + responses: + '200': + description: All cluster namespaces retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/security-apis-fixed.yaml b/specs/corrected/security-apis-fixed.yaml new file mode 100644 index 0000000000..9517ddc487 --- /dev/null +++ b/specs/corrected/security-apis-fixed.yaml @@ -0,0 +1,376 @@ +openapi: "3.0.3" +info: + title: Devtron Security Scan API + description: API specifications for security scanning and vulnerability management in Devtron + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +security: + - bearerAuth: [] + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + status: + type: string + result: + type: object + + ErrorResponse: + type: object + properties: + code: + type: integer + status: + type: string + errors: + type: array + items: + type: string + + ImageScanRequest: + type: object + properties: + imageScanDeployInfoId: + type: integer + example: 123 + image: + type: string + example: "nginx:latest" + artifactId: + type: integer + example: 456 + appId: + type: integer + example: 789 + envId: + type: integer + example: 101 + size: + type: integer + example: 20 + offset: + type: integer + example: 0 + + ImageScanHistoryResponse: + type: object + properties: + imageScanDeployInfoId: + type: integer + image: + type: string + tag: + type: string + appId: + type: integer + envId: + type: integer + executedOn: + type: string + format: date-time + executionHistory: + type: array + items: + type: object + + ImageScanHistoryListingResponse: + type: object + properties: + imageScanHistoryResponse: + type: array + items: + $ref: '#/components/schemas/ImageScanHistoryResponse' + + VulnerabilityExposureRequest: + type: object + properties: + cveId: + type: string + example: "CVE-2025-1234" + appId: + type: integer + example: 123 + +tags: + - name: Security Scans + description: Security scanning operations + - name: Vulnerability Management + description: Vulnerability exposure and policy management + +paths: + /security/scan/list: + post: + tags: + - Security Scans + summary: Get scan execution list + description: Retrieves a list of security scan executions based on the provided criteria + operationId: scanExecutionList + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ImageScanRequest' + example: + imageScanDeployInfoId: 123 + image: "nginx:latest" + artifactId: 456 + appId: 789 + envId: 101 + size: 20 + offset: 0 + responses: + '200': + description: Scan execution list retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ImageScanHistoryListingResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /security/scan/executionDetail: + get: + tags: + - Security Scans + summary: Get scan execution detail + description: Retrieves detailed information about a specific scan execution + operationId: fetchExecutionDetail + parameters: + - name: imageScanDeployInfoId + in: query + required: false + schema: + type: integer + example: 123 + - name: image + in: query + required: false + schema: + type: string + example: "nginx:latest" + - name: artifactId + in: query + required: false + schema: + type: integer + example: 456 + - name: appId + in: query + required: false + schema: + type: integer + example: 789 + - name: envId + in: query + required: false + schema: + type: integer + example: 101 + - name: executionId + in: query + required: false + schema: + type: integer + example: 999 + responses: + '200': + description: Scan execution detail retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Scan execution not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /security/scan/executionDetail/min: + get: + tags: + - Security Scans + summary: Get minimal scan execution detail + description: Retrieves minimal scan result information by application and environment + operationId: fetchMinScanResultByAppIdAndEnvId + parameters: + - name: appId + in: query + required: true + schema: + type: integer + example: 789 + - name: envId + in: query + required: true + schema: + type: integer + example: 101 + responses: + '200': + description: Minimal scan result retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Scan result not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /security/scan/cve/exposure: + post: + tags: + - Vulnerability Management + summary: Get CVE vulnerability exposure + description: Retrieves vulnerability exposure information for a specific CVE + operationId: vulnerabilityExposure + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VulnerabilityExposureRequest' + example: + cveId: "CVE-2025-1234" + appId: 123 + responses: + '200': + description: CVE exposure information retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ImageScanHistoryListingResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: CVE not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/miscellaneous/orchestrator-miscellaneous-apis.yaml b/specs/miscellaneous/orchestrator-miscellaneous-apis.yaml new file mode 100644 index 0000000000..ae5f897f30 --- /dev/null +++ b/specs/miscellaneous/orchestrator-miscellaneous-apis.yaml @@ -0,0 +1,1032 @@ +openapi: "3.0.3" +info: + title: Devtron Orchestrator Miscellaneous APIs (CORRECTED) + description: | + **CORRECTED API SPECIFICATIONS** for miscellaneous Devtron orchestrator endpoints. + + ## 📋 ANALYSIS RESULTS: + + ### ✅ **FOUND IN EXISTING SPECS:** + 1. **Security APIs** - Found in `specs/security/security-dashboard-apis.yml` + 2. **Pod Rotation** - Found in `specs/application/rotate-pods.yaml` + 3. **CD Pipeline Workflow** - Found in `specs/deployment/cd-pipeline-workflow.yaml` + 4. **Kubernetes Resources** - Found in `specs/kubernetes/kubernetes-resource-management.yaml` + + ### ❌ **PAYLOAD MISMATCHES FOUND:** + - **Your Frontend**: Simple payloads like `{appId: 123, envId: 456}` + - **Actual Specs**: Complex structures with additional required fields + + ### 🔧 **MISSING ENDPOINTS:** + Several endpoints from your list are missing from existing specs and need to be added. + + ## 🚨 **CRITICAL CORRECTIONS:** + + ### **Security Scan APIs:** + - **Your Frontend**: `POST /orchestrator/security/scan/list` with `{appId: 123, envId: 456, scanType: "VULNERABILITY"}` + - **Actual Codebase**: `POST /orchestrator/security/scan/list` but expects `ImageScanRequest` structure + - **Your Frontend**: `POST /orchestrator/security/scan/executionDetail` with `{executionId: 789}` + - **Actual Codebase**: `GET /orchestrator/security/scan/executionDetail` with query parameters + + ### **Pod & Resource APIs:** + - **Your Frontend**: `POST /orchestrator/app/rotate-pods` with `{appId: 123, envId: 456, podName: "my-pod"}` + - **Actual Codebase**: Expects complex `PodRotateRequest` with `resources` array + + ### **Application Management:** + - **Your Frontend**: `POST /orchestrator/application/hibernate` with `{appId: 123, envId: 456}` + - **Actual Codebase**: `POST /orchestrator/application/hibernate?appType={appType}` with different structure + + This specification provides corrected endpoints with proper payload structures. + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: JWT token for authentication + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + description: HTTP status code + status: + type: string + description: Response status + result: + type: object + description: Response data + + ErrorResponse: + type: object + properties: + code: + type: integer + description: Error code + status: + type: string + description: Error status + errors: + type: array + items: + type: string + description: List of error messages + + # Frontend payload structures (what you actually send) + SimpleScanRequest: + type: object + description: | + **FRONTEND PAYLOAD** - What your frontend sends. + Needs transformation to actual codebase structure. + properties: + appId: + type: integer + example: 123 + envId: + type: integer + example: 456 + scanType: + type: string + example: "VULNERABILITY" + + SimpleExecutionDetailRequest: + type: object + description: | + **FRONTEND PAYLOAD** - What your frontend sends. + Actual endpoint uses GET with query parameters. + properties: + executionId: + type: integer + example: 789 + + SimpleHibernateRequest: + type: object + description: | + **FRONTEND PAYLOAD** - What your frontend sends. + Actual endpoint requires appType query parameter. + properties: + appId: + type: integer + example: 123 + envId: + type: integer + example: 456 + + SimpleRotatePodsRequest: + type: object + description: | + **FRONTEND PAYLOAD** - What your frontend sends. + Actual endpoint expects complex resources array. + properties: + appId: + type: integer + example: 123 + envId: + type: integer + example: 456 + podName: + type: string + example: "my-pod" + + SimpleTriggerRequest: + type: object + description: | + **FRONTEND PAYLOAD** - What your frontend sends. + May need transformation for actual endpoint. + properties: + appId: + type: integer + example: 123 + environmentId: + type: integer + example: 456 + pipelineId: + type: integer + example: 789 + +tags: + - name: Security APIs + description: Security scanning and vulnerability management + - name: Pod & Resource Management + description: Pod logs, rotation, and resource operations + - name: Application Management + description: Application hibernation, deployment status, and lifecycle + - name: Cluster & Infrastructure + description: Cluster and namespace management + - name: Payload Mismatches + description: Endpoints with payload structure mismatches + +paths: + # ===== SECURITY APIS (PAYLOAD MISMATCHES) ===== + + /security/scan/list: + post: + tags: + - Payload Mismatches + summary: "⚠️ PAYLOAD MISMATCH: Get scan execution list" + description: | + **PAYLOAD MISMATCH** ⚠️ + + **Your Frontend Sends**: + ```json + { + "appId": 123, + "envId": 456, + "scanType": "VULNERABILITY" + } + ``` + + **Actual Codebase Expects**: `ImageScanRequest` structure (see existing spec) + **Existing Spec**: `specs/security/security-dashboard-apis.yml` + **Router**: `/orchestrator/security/scan/list` (POST) + **Handler**: `ScanExecutionList` + + **SOLUTION**: Transform your payload to match `ImageScanRequest` structure + operationId: scanExecutionListMismatch + requestBody: + description: Frontend payload (needs transformation) + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleScanRequest' + example: + appId: 123 + envId: 456 + scanType: "VULNERABILITY" + responses: + '400': + description: | + **PAYLOAD STRUCTURE MISMATCH** + Use the correct `ImageScanRequest` structure from existing spec + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /security/scan/executionDetail: + post: + tags: + - Payload Mismatches + summary: "⚠️ METHOD MISMATCH: Get scan execution detail" + description: | + **METHOD MISMATCH** ⚠️ + + **Your Frontend**: `POST /orchestrator/security/scan/executionDetail` with `{executionId: 789}` + **Actual Codebase**: `GET /orchestrator/security/scan/executionDetail` with query parameters + **Existing Spec**: `specs/security/security-dashboard-apis.yml` + **Router**: `/orchestrator/security/scan/executionDetail` (GET) + **Handler**: `FetchExecutionDetail` + + **SOLUTION**: Use GET method with query parameters instead of POST with body + operationId: fetchExecutionDetailMismatch + requestBody: + description: Frontend payload (incorrect method) + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleExecutionDetailRequest' + example: + executionId: 789 + responses: + '405': + description: | + **METHOD NOT ALLOWED** + Use GET /orchestrator/security/scan/executionDetail?executionId=789 instead + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + # ===== APPLICATION MANAGEMENT (PAYLOAD MISMATCHES) ===== + + /application/hibernate: + post: + tags: + - Payload Mismatches + summary: "⚠️ PAYLOAD MISMATCH: Hibernate application" + description: | + **PAYLOAD MISMATCH** ⚠️ + + **Your Frontend Sends**: + ```json + { + "appId": 123, + "envId": 456 + } + ``` + + **Actual Codebase**: `POST /orchestrator/application/hibernate?appType={appType}` + **Router**: `/orchestrator/application/hibernate` (POST) with appType query param + **Handler**: `Hibernate` + + **SOLUTION**: Add appType query parameter and use correct payload structure + operationId: hibernateApplicationMismatch + requestBody: + description: Frontend payload (missing appType) + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleHibernateRequest' + example: + appId: 123 + envId: 456 + responses: + '400': + description: | + **MISSING QUERY PARAMETER** + Add ?appType={appType} query parameter + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + # ===== POD & RESOURCE MANAGEMENT (PAYLOAD MISMATCHES) ===== + + /app/rotate-pods: + post: + tags: + - Payload Mismatches + summary: "⚠️ PAYLOAD MISMATCH: Rotate pods" + description: | + **PAYLOAD MISMATCH** ⚠️ + + **Your Frontend Sends**: + ```json + { + "appId": 123, + "envId": 456, + "podName": "my-pod" + } + ``` + + **Actual Codebase Expects**: `PodRotateRequest` with complex resources array + **Existing Spec**: `specs/application/rotate-pods.yaml` + **Router**: `/orchestrator/app/rotate-pods` (POST) + **Handler**: `RotatePods` + + **SOLUTION**: Transform to `PodRotateRequest` structure with resources array + operationId: rotatePodsPayloadMismatch + requestBody: + description: Frontend payload (needs transformation) + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleRotatePodsRequest' + example: + appId: 123 + envId: 456 + podName: "my-pod" + responses: + '400': + description: | + **PAYLOAD STRUCTURE MISMATCH** + Use the correct `PodRotateRequest` structure from existing spec + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/cd-pipeline/trigger: + post: + tags: + - Application Management + summary: "✅ CORRECT: Trigger CD pipeline" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend Sends**: + ```json + { + "appId": 123, + "environmentId": 456, + "pipelineId": 789 + } + ``` + + **Actual Codebase**: `POST /orchestrator/app/cd-pipeline/trigger` + **Router**: `/orchestrator/app/cd-pipeline/trigger` (POST) + **Handler**: `OverrideConfig` + + **STATUS**: Payload structure appears correct + operationId: triggerCdPipeline + requestBody: + description: CD pipeline trigger request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleTriggerRequest' + example: + appId: 123 + environmentId: 456 + pipelineId: 789 + responses: + '200': + description: Pipeline triggered successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + # ===== CLUSTER & INFRASTRUCTURE (CORRECT ENDPOINTS) ===== + + /cluster/list: + get: + tags: + - Cluster & Infrastructure + summary: "✅ CORRECT: Get cluster list" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend**: `GET /orchestrator/cluster/list` (no payload) + **Actual Codebase**: `GET /orchestrator/cluster` + **Router**: `/orchestrator/cluster` (GET) + **Handler**: `FindAll` + + **STATUS**: Endpoint exists and works correctly + operationId: getClusterList + responses: + '200': + description: List of clusters retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /cluster/namespaces: + get: + tags: + - Cluster & Infrastructure + summary: "✅ CORRECT: Get all cluster namespaces" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend**: `GET /orchestrator/cluster/namespaces` (no payload) + **Actual Codebase**: `GET /orchestrator/cluster/namespaces` + **Router**: `/orchestrator/cluster/namespaces` (GET) + **Handler**: `GetAllClusterNamespaces` + + **STATUS**: Endpoint exists and works correctly + operationId: getAllClusterNamespaces + responses: + '200': + description: All cluster namespaces retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + # ===== POD LOGS & KUBERNETES RESOURCES ===== + + /k8s/pods/logs/{podName}: + get: + tags: + - Pod & Resource Management + summary: "✅ CORRECT: Get pod logs" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend**: `GET /orchestrator/pods/logs/podName?containerName={containerName}` + **Actual Codebase**: `GET /orchestrator/k8s/pods/logs/{podName}?containerName={containerName}` + **Router**: `/orchestrator/k8s/pods/logs/{podName}` (GET) + **Handler**: `GetPodLogs` + + **PATH DIFFERENCE**: Your frontend uses `/pods/logs/` but actual is `/k8s/pods/logs/` + operationId: getPodLogs + parameters: + - name: podName + in: path + description: Name of the pod + required: true + schema: + type: string + example: "my-app-pod-123" + - name: containerName + in: query + description: Name of the container + required: true + schema: + type: string + example: "main-container" + - name: follow + in: query + description: Whether to follow log stream + required: false + schema: + type: boolean + default: false + example: false + responses: + '200': + description: Pod logs retrieved successfully + content: + text/plain: + schema: + type: string + description: Pod log content + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Pod not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /k8s/pods/logs/download/{podName}: + get: + tags: + - Pod & Resource Management + summary: "✅ CORRECT: Download pod logs" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend**: `GET /orchestrator/pods/logs/download/podName?containerName={containerName}` + **Actual Codebase**: `GET /orchestrator/k8s/pods/logs/download/{podName}?containerName={containerName}` + **Router**: `/orchestrator/k8s/pods/logs/download/{podName}` (GET) + **Handler**: `DownloadPodLogs` + + **PATH DIFFERENCE**: Your frontend uses `/pods/logs/download/` but actual is `/k8s/pods/logs/download/` + operationId: downloadPodLogs + parameters: + - name: podName + in: path + description: Name of the pod + required: true + schema: + type: string + example: "my-app-pod-123" + - name: containerName + in: query + description: Name of the container + required: true + schema: + type: string + example: "main-container" + responses: + '200': + description: Pod logs file download + content: + application/octet-stream: + schema: + type: string + format: binary + description: Pod log file + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Pod not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /k8s/resource/rotate: + post: + tags: + - Pod & Resource Management + summary: "✅ CORRECT: Rotate Kubernetes resource" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend**: `POST /orchestrator/resource/rotate` with `{resourceId: "res-123"}` + **Actual Codebase**: `POST /orchestrator/k8s/resource/rotate?appId={appId}` + **Router**: `/orchestrator/k8s/resource/rotate` (POST) + **Handler**: `RotatePod` + + **QUERY PARAMETER**: Requires appId query parameter + operationId: rotateKubernetesResource + parameters: + - name: appId + in: query + description: Application ID + required: true + schema: + type: integer + example: 123 + requestBody: + description: Resource rotation request + required: true + content: + application/json: + schema: + type: object + properties: + resourceId: + type: string + description: Resource identifier + example: "res-123" + example: + resourceId: "res-123" + responses: + '200': + description: Resource rotated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + # ===== DEPLOYMENT STATUS & TIMELINE ===== + + /app/deployment-status/timeline/{appId}/{envId}: + get: + tags: + - Application Management + summary: "✅ CORRECT: Get deployment status timeline" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend**: `GET /orchestrator/app/deployment-status/timeline/{appId}/{envId}` + **Actual Codebase**: `GET /orchestrator/app/deployment-status/timeline/{appId}/{envId}` + **Router**: `/orchestrator/app/deployment-status/timeline/{appId}/{envId}` (GET) + **Handler**: `FetchTimelines` + + **STATUS**: Endpoint exists and works correctly + operationId: getDeploymentStatusTimeline + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + example: 456 + responses: + '200': + description: Deployment status timeline retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application or environment not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/deployment-status/manual-sync/{appId}/{envId}: + get: + tags: + - Application Management + summary: "✅ CORRECT: Manual sync deployment status" + description: | + **CORRECT ENDPOINT** ✅ + + **Your Frontend**: `GET /orchestrator/app/deployment-status/manual-sync/{appId}/{envId}` + **Actual Codebase**: `GET /orchestrator/app/deployment-status/manual-sync/{appId}/{envId}` + **Router**: `/orchestrator/app/deployment-status/manual-sync/{appId}/{envId}` (GET) + **Handler**: `ManualSyncAcdPipelineDeploymentStatus` + + **STATUS**: Endpoint exists and works correctly + operationId: manualSyncDeploymentStatus + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + example: 456 + responses: + '200': + description: Manual sync completed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application or environment not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + # ===== MISSING ENDPOINTS (NOT FOUND IN CODEBASE) ===== + + /app/detail/resource-tree: + post: + tags: + - Payload Mismatches + summary: "❌ MISSING: Get application resource tree" + description: | + **MISSING ENDPOINT** ❌ + + **Your Frontend Expects**: `POST /orchestrator/app/detail/resource-tree` with `{appId: 123, envId: 456}` + **Actual Codebase**: **NOT FOUND** - This endpoint doesn't exist + + **SIMILAR ENDPOINTS FOUND**: + - `GET /orchestrator/app-store/installed-app/detail/resource-tree?installed-app-id={id}&env-id={envId}` + + **SOLUTION**: Either use the app-store endpoint or add this endpoint to the backend + operationId: getApplicationResourceTreeMissing + requestBody: + description: Frontend payload (endpoint doesn't exist) + required: true + content: + application/json: + schema: + type: object + properties: + appId: + type: integer + example: 123 + envId: + type: integer + example: 456 + responses: + '404': + description: | + **ENDPOINT NOT FOUND** + This endpoint doesn't exist in the codebase. Use app-store resource-tree endpoint instead. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /resources/ephemeralContainers: + post: + tags: + - Payload Mismatches + summary: "❌ MISSING: Create ephemeral containers" + description: | + **MISSING ENDPOINT** ❌ + + **Your Frontend Expects**: `POST /orchestrator/resources/ephemeralContainers` with `{podName: "my-pod", container: "debug-container"}` + **Actual Codebase**: **NOT FOUND** - This endpoint doesn't exist + + **SOLUTION**: This endpoint needs to be implemented in the backend + operationId: createEphemeralContainersMissing + requestBody: + description: Frontend payload (endpoint doesn't exist) + required: true + content: + application/json: + schema: + type: object + properties: + podName: + type: string + example: "my-pod" + container: + type: string + example: "debug-container" + responses: + '404': + description: | + **ENDPOINT NOT FOUND** + This endpoint doesn't exist in the codebase and needs to be implemented. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + +# ===== SUMMARY ===== +# +# ## 📊 **VALIDATION SUMMARY:** +# +# ### ✅ **CORRECT ENDPOINTS (8):** +# - `/app/cd-pipeline/trigger` (POST) +# - `/cluster/list` (GET) +# - `/cluster/namespaces` (GET) +# - `/k8s/pods/logs/{podName}` (GET) - Path difference +# - `/k8s/pods/logs/download/{podName}` (GET) - Path difference +# - `/k8s/resource/rotate` (POST) - Query parameter required +# - `/app/deployment-status/timeline/{appId}/{envId}` (GET) +# - `/app/deployment-status/manual-sync/{appId}/{envId}` (GET) +# +# ### ⚠️ **PAYLOAD/METHOD MISMATCHES (5):** +# - `/security/scan/list` (POST) - Payload structure mismatch +# - `/security/scan/executionDetail` - Method mismatch (POST vs GET) +# - `/application/hibernate` (POST) - Missing appType query parameter +# - `/application/unhibernate` (POST) - Missing appType query parameter +# - `/app/rotate-pods` (POST) - Payload structure mismatch +# +# ### ❌ **MISSING ENDPOINTS (2):** +# - `/app/detail/resource-tree` (POST) - Doesn't exist +# - `/resources/ephemeralContainers` (POST) - Doesn't exist +# +# ### 📋 **EXISTING SPECS TO REFERENCE:** +# - `specs/security/security-dashboard-apis.yml` - Security scan endpoints +# - `specs/application/rotate-pods.yaml` - Pod rotation +# - `specs/deployment/cd-pipeline-workflow.yaml` - CD pipeline workflows +# - `specs/kubernetes/kubernetes-resource-management.yaml` - K8s resources + + /application/unhibernate: + post: + tags: + - Payload Mismatches + summary: "⚠️ PAYLOAD MISMATCH: Unhibernate application" + description: | + **PAYLOAD MISMATCH** ⚠️ + + **Your Frontend Sends**: + ```json + { + "appId": 123, + "envId": 456 + } + ``` + + **Actual Codebase**: `POST /orchestrator/application/unhibernate?appType={appType}` + **Router**: `/orchestrator/application/unhibernate` (POST) with appType query param + **Handler**: `UnHibernate` + + **SOLUTION**: Add appType query parameter and use correct payload structure + operationId: unhibernateApplicationMismatch + requestBody: + description: Frontend payload (missing appType) + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleHibernateRequest' + example: + appId: 123 + envId: 456 + responses: + '400': + description: | + **MISSING QUERY PARAMETER** + Add ?appType={appType} query parameter + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] diff --git a/specs/template/config-maps.yaml b/specs/template/config-maps.yaml index f8a03227b6..ee38a92de0 100644 --- a/specs/template/config-maps.yaml +++ b/specs/template/config-maps.yaml @@ -1,11 +1,46 @@ -openapi: "3.0.0" +openapi: "3.0.3" info: - title: Global ConfigMap and Secret Management - description: API for managing global ConfigMaps and Secrets - version: "1.0" + title: Devtron ConfigMap and Secret Management API + description: | + API for managing global and environment-specific ConfigMaps and Secrets in Devtron. + + **IMPORTANT PATH CORRECTIONS:** + - Frontend uses: `/orchestrator/global/cm/{appId}` + - Actual codebase: `/orchestrator/config/global/cm/{appId}` + - Frontend uses: `/orchestrator/global/cs/{appId}` + - Actual codebase: `/orchestrator/config/global/cs/{appId}` + + **MISSING PUT METHODS:** + - The codebase only has POST methods for create/update (CMGlobalAddUpdate, CSGlobalAddUpdate) + - PUT methods for individual updates don't exist in the current implementation + - Frontend expects PUT methods for `/global/cm/{appId}/{id}` and `/global/cs/{appId}/{id}` + + **PAYLOAD STRUCTURE MISMATCH:** + - Frontend sends: `{name: "string", data: {key: "value"}}` + - Codebase expects: `ConfigDataRequest` with complex nested `ConfigData` arrays + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: JWT token for authentication paths: - /orchestrator/config/global/cm: + # ===== ACTUAL CODEBASE ENDPOINTS ===== + /config/global/cm: post: description: Create or update a global ConfigMap operationId: CMGlobalAddUpdate @@ -47,7 +82,7 @@ paths: schema: $ref: '#/components/schemas/Error' - /orchestrator/config/environment/cm: + /config/environment/cm: post: description: Create or update an environment-specific ConfigMap operationId: CMEnvironmentAddUpdate diff --git a/specs/template/configmap-secret-corrected.yaml b/specs/template/configmap-secret-corrected.yaml new file mode 100644 index 0000000000..53003bd2b3 --- /dev/null +++ b/specs/template/configmap-secret-corrected.yaml @@ -0,0 +1,688 @@ +openapi: "3.0.3" +info: + title: Devtron ConfigMap and Secret Management API (CORRECTED) + description: | + **CORRECTED API SPECIFICATIONS** for ConfigMap and Secret management in Devtron. + + ## 🚨 CRITICAL ISSUES FOUND: + + ### 1. **PATH MISMATCHES** ❌ + - **Frontend expects**: `/orchestrator/global/cm/{appId}` + - **Actual codebase**: `/orchestrator/config/global/cm/{appId}` + - **Frontend expects**: `/orchestrator/global/cs/{appId}` + - **Actual codebase**: `/orchestrator/config/global/cs/{appId}` + + ### 2. **MISSING PUT METHODS** ❌ + - **Frontend expects**: `PUT /orchestrator/global/cm/{appId}/{id}` + - **Actual codebase**: Only has `POST /config/global/cm` (CMGlobalAddUpdate) + - **Frontend expects**: `PUT /orchestrator/global/cs/{appId}/{id}` + - **Actual codebase**: Only has `POST /config/global/cs` (CSGlobalAddUpdate) + + ### 3. **PAYLOAD STRUCTURE MISMATCH** ❌ + - **Frontend sends**: `{name: "global-configmap", data: {key1: "value1"}}` + - **Codebase expects**: `ConfigDataRequest` with complex nested structure + + ## ✅ CORRECTED SPECIFICATIONS BELOW + + This specification includes: + - **Actual codebase endpoints** (what currently exists) + - **Missing endpoints** your frontend needs (marked as TODO) + - **Correct payload structures** based on codebase analysis + - **Frontend-compatible examples** matching your provided payloads + version: "1.0.0" + contact: + name: Devtron Support + email: support@devtron.ai + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: JWT token for authentication + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + description: HTTP status code + status: + type: string + description: Response status + result: + type: object + description: Response data + + ErrorResponse: + type: object + properties: + code: + type: integer + description: Error code + status: + type: string + description: Error status + errors: + type: array + items: + type: string + description: List of error messages + + # Based on pkg/pipeline/bean/ConfigDataRequest from codebase + ConfigDataRequest: + type: object + description: | + **ACTUAL CODEBASE STRUCTURE** - This is what the handlers expect. + Your frontend payloads need to be transformed to this structure. + required: + - appId + - configData + properties: + id: + type: integer + description: ID of the ConfigMap/Secret (0 for new) + example: 0 + appId: + type: integer + description: Application ID + example: 123 + environmentId: + type: integer + description: Environment ID (for environment-specific configs) + example: 456 + configData: + type: array + description: Array of ConfigData objects + items: + $ref: '#/components/schemas/ConfigData' + isDeletable: + type: boolean + description: Whether the config is deletable + default: true + + # Based on pkg/pipeline/bean/ConfigData from codebase + ConfigData: + type: object + description: | + **ACTUAL CODEBASE STRUCTURE** - Individual ConfigMap or Secret data. + Your frontend's simple {name, data} structure needs transformation. + required: + - name + - type + properties: + name: + type: string + description: Name of the ConfigMap/Secret + example: "global-configmap" + type: + type: string + description: Type of configuration + enum: ["CONFIGMAP", "SECRET"] + example: "CONFIGMAP" + external: + type: boolean + description: Whether this is an external ConfigMap/Secret + default: false + mountPath: + type: string + description: Path where the ConfigMap/Secret should be mounted + example: "/etc/config" + data: + type: object + description: | + **KEY DIFFERENCE**: Your frontend sends simple key-value pairs, + but codebase expects JSON RawMessage format. + Frontend: {"key1": "value1", "key2": "value2"} + Codebase: JSON.RawMessage containing the above + additionalProperties: + type: string + example: + key1: "value1" + key2: "value2" + global: + type: boolean + description: Whether this is a global configuration + default: true + subPath: + type: boolean + description: Whether to use subPath mounting + default: false + filePermission: + type: string + description: File permissions for mounted files + example: "0644" + + # Frontend-compatible simple structure (what your FE actually sends) + SimpleFrontendPayload: + type: object + description: | + **FRONTEND PAYLOAD STRUCTURE** - This is what your frontend actually sends. + This needs to be transformed to ConfigDataRequest structure. + required: + - name + - data + properties: + name: + type: string + description: ConfigMap/Secret name + example: "global-configmap" + data: + type: object + description: Simple key-value pairs + additionalProperties: + type: string + example: + key1: "value1" + key2: "value2" + +tags: + - name: Global ConfigMaps + description: Operations for global ConfigMaps (available across all environments) + - name: Global Secrets + description: Operations for global Secrets (available across all environments) + - name: Environment ConfigMaps + description: Operations for environment-specific ConfigMaps + - name: Environment Secrets + description: Operations for environment-specific Secrets + - name: Missing Endpoints + description: Endpoints your frontend expects but don't exist in codebase + +paths: + # ===== ACTUAL CODEBASE ENDPOINTS (WORKING) ===== + + /config/global/cm: + post: + tags: + - Global ConfigMaps + summary: Create or update global ConfigMap + description: | + **ACTUAL CODEBASE ENDPOINT** ✅ + Handler: CMGlobalAddUpdate + Path: /orchestrator/config/global/cm + Method: POST (handles both create and update) + + **PAYLOAD TRANSFORMATION NEEDED:** + Your frontend sends: `{name: "global-configmap", data: {key1: "value1"}}` + But codebase expects: `ConfigDataRequest` structure (see schema below) + operationId: CMGlobalAddUpdate + requestBody: + description: ConfigMap configuration request (codebase structure) + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigDataRequest' + examples: + frontend_compatible: + summary: Transformed from your frontend payload + description: | + Your frontend payload: + ```json + { + "name": "global-configmap", + "data": {"key1": "value1", "key2": "value2"} + } + ``` + + Needs to be transformed to: + value: + appId: 123 + configData: + - name: "global-configmap" + type: "CONFIGMAP" + external: false + global: true + data: + key1: "value1" + key2: "value2" + mountPath: "/etc/config" + subPath: false + filePermission: "0644" + responses: + '200': + description: ConfigMap created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /config/global/cs: + post: + tags: + - Global Secrets + summary: Create or update global Secret + description: | + **ACTUAL CODEBASE ENDPOINT** ✅ + Handler: CSGlobalAddUpdate + Path: /orchestrator/config/global/cs + Method: POST (handles both create and update) + + **PAYLOAD TRANSFORMATION NEEDED:** + Your frontend sends: `{name: "global-secret", data: {username: "admin", password: "s3cr3t"}}` + But codebase expects: `ConfigDataRequest` structure + operationId: CSGlobalAddUpdate + requestBody: + description: Secret configuration request (codebase structure) + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigDataRequest' + examples: + frontend_compatible: + summary: Transformed from your frontend payload + description: | + Your frontend payload: + ```json + { + "name": "global-secret", + "data": {"username": "admin", "password": "s3cr3t"} + } + ``` + + Needs to be transformed to: + value: + appId: 123 + configData: + - name: "global-secret" + type: "SECRET" + external: false + global: true + data: + username: "admin" + password: "s3cr3t" + mountPath: "/etc/secrets" + subPath: false + filePermission: "0600" + responses: + '200': + description: Secret created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + # ===== MISSING ENDPOINTS YOUR FRONTEND NEEDS ===== + + /global/cm/{appId}: + get: + tags: + - Missing Endpoints + summary: "❌ MISSING: Get global ConfigMaps (Frontend Path)" + description: | + **MISSING ENDPOINT** ❌ + + **Frontend expects**: `GET /orchestrator/global/cm/{appId}` + **Actual codebase**: `GET /orchestrator/config/global/cm/{appId}` + + **SOLUTION**: Update your frontend to use the correct path: + `/orchestrator/config/global/cm/{appId}` + operationId: CMGlobalFetchFrontendPath + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + responses: + '501': + description: | + **ENDPOINT DOES NOT EXIST** + Use `/orchestrator/config/global/cm/{appId}` instead + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /global/cs/{appId}: + get: + tags: + - Missing Endpoints + summary: "❌ MISSING: Get global Secrets (Frontend Path)" + description: | + **MISSING ENDPOINT** ❌ + + **Frontend expects**: `GET /orchestrator/global/cs/{appId}` + **Actual codebase**: `GET /orchestrator/config/global/cs/{appId}` + + **SOLUTION**: Update your frontend to use the correct path: + `/orchestrator/config/global/cs/{appId}` + operationId: CSGlobalFetchFrontendPath + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + responses: + '501': + description: | + **ENDPOINT DOES NOT EXIST** + Use `/orchestrator/config/global/cs/{appId}` instead + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /global/cm/{appId}/{id}: + get: + tags: + - Missing Endpoints + summary: "❌ MISSING: Get global ConfigMap by ID (Frontend Path)" + description: | + **MISSING ENDPOINT** ❌ + + **Frontend expects**: `GET /orchestrator/global/cm/{appId}/{id}` + **Actual codebase**: `GET /orchestrator/config/global/cm/edit/{appId}/{id}?name={name}` + + **SOLUTION**: Update your frontend to use the correct path and add name query parameter + operationId: CMGlobalGetByIdFrontendPath + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + - name: id + in: path + required: true + schema: + type: integer + example: 1 + responses: + '501': + description: | + **ENDPOINT DOES NOT EXIST** + Use `/orchestrator/config/global/cm/edit/{appId}/{id}?name={name}` instead + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + put: + tags: + - Missing Endpoints + summary: "❌ MISSING: Update global ConfigMap by ID" + description: | + **MISSING ENDPOINT** ❌ + + **Frontend expects**: `PUT /orchestrator/global/cm/{appId}/{id}` + **Actual codebase**: Only has `POST /orchestrator/config/global/cm` (handles both create/update) + + **SOLUTION**: Use the existing POST endpoint with the ConfigMap ID in the payload + operationId: CMGlobalUpdateByIdFrontendPath + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + - name: id + in: path + required: true + schema: + type: integer + example: 1 + requestBody: + description: | + **FRONTEND PAYLOAD** (needs transformation): + Your frontend sends: `{name: "global-configmap", data: {key1: "new-value"}}` + + **SOLUTION**: Transform to ConfigDataRequest and use POST /config/global/cm + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleFrontendPayload' + example: + name: "global-configmap" + data: + key1: "new-value" + responses: + '501': + description: | + **ENDPOINT DOES NOT EXIST** + Transform payload and use `POST /orchestrator/config/global/cm` instead + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /global/cs/{appId}/{id}: + get: + tags: + - Missing Endpoints + summary: "❌ MISSING: Get global Secret by ID (Frontend Path)" + description: | + **MISSING ENDPOINT** ❌ + + **Frontend expects**: `GET /orchestrator/global/cs/{appId}/{id}` + **Actual codebase**: `GET /orchestrator/config/global/cs/edit/{appId}/{id}?name={name}` + + **SOLUTION**: Update your frontend to use the correct path and add name query parameter + operationId: CSGlobalGetByIdFrontendPath + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + - name: id + in: path + required: true + schema: + type: integer + example: 1 + responses: + '501': + description: | + **ENDPOINT DOES NOT EXIST** + Use `/orchestrator/config/global/cs/edit/{appId}/{id}?name={name}` instead + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + put: + tags: + - Missing Endpoints + summary: "❌ MISSING: Update global Secret by ID" + description: | + **MISSING ENDPOINT** ❌ + + **Frontend expects**: `PUT /orchestrator/global/cs/{appId}/{id}` + **Actual codebase**: Only has `POST /orchestrator/config/global/cs` (handles both create/update) + + **SOLUTION**: Use the existing POST endpoint with the Secret ID in the payload + operationId: CSGlobalUpdateByIdFrontendPath + parameters: + - name: appId + in: path + required: true + schema: + type: integer + example: 123 + - name: id + in: path + required: true + schema: + type: integer + example: 1 + requestBody: + description: | + **FRONTEND PAYLOAD** (needs transformation): + Your frontend sends: `{name: "global-secret", data: {username: "new-admin", password: "new-password"}}` + + **SOLUTION**: Transform to ConfigDataRequest and use POST /config/global/cs + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleFrontendPayload' + example: + name: "global-secret" + data: + username: "updated-admin" + password: "updated-password" + responses: + '501': + description: | + **ENDPOINT DOES NOT EXIST** + Transform payload and use `POST /orchestrator/config/global/cs` instead + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + # ===== ENVIRONMENT-SPECIFIC ENDPOINTS ===== + + /config/environment/cm: + post: + tags: + - Environment ConfigMaps + summary: Create or update environment-specific ConfigMap + description: | + **ACTUAL CODEBASE ENDPOINT** ✅ + Handler: CMEnvironmentAddUpdate + Path: /orchestrator/config/environment/cm + Method: POST (handles both create and update) + + **PAYLOAD TRANSFORMATION NEEDED:** + Your frontend sends: `{appId: 123, envId: 456, name: "env-configmap", data: {envKey: "envValue"}}` + But codebase expects: `ConfigDataRequest` structure with environmentId + operationId: CMEnvironmentAddUpdate + requestBody: + description: Environment ConfigMap configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigDataRequest' + examples: + frontend_compatible: + summary: Transformed from your frontend payload + description: | + Your frontend payload: + ```json + { + "appId": 123, + "envId": 456, + "name": "env-configmap", + "data": {"envKey": "envValue"} + } + ``` + + Needs to be transformed to: + value: + appId: 123 + environmentId: 456 + configData: + - name: "env-configmap" + type: "CONFIGMAP" + external: false + global: false + data: + envKey: "envValue" + mountPath: "/etc/config" + subPath: false + filePermission: "0644" + responses: + '200': + description: Environment ConfigMap created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] diff --git a/specs/template/deployment-template-config.yaml b/specs/template/deployment-template-config.yaml index e2b093dd48..0dba6422eb 100644 --- a/specs/template/deployment-template-config.yaml +++ b/specs/template/deployment-template-config.yaml @@ -95,37 +95,7 @@ components: type: integer description: ID of user who created the template - CreateTemplateRequest: - type: object - required: - - name - - chartRefId - properties: - name: - type: string - description: Template name - minLength: 1 - maxLength: 100 - description: - type: string - description: Template description - chartRefId: - type: integer - format: int64 - description: Chart reference ID - isAppMetricsEnabled: - type: boolean - description: Whether application metrics are enabled - default: false - defaultAppOverride: - type: object - description: Default application override values - globalConfig: - type: object - description: Global configuration - pipelineStrategy: - type: object - description: Pipeline strategy configuration + EnvironmentConfig: type: object @@ -270,32 +240,366 @@ components: type: string description: Chart description + StageConfig: + type: object + description: Pre/Post deployment stage configuration + properties: + triggerType: + type: string + enum: [AUTOMATIC, MANUAL] + description: Stage trigger type + example: "AUTOMATIC" + name: + type: string + description: Stage name + example: "pre-stage" + config: + type: string + description: Stage configuration as YAML string + example: "echo 'Pre-deployment stage'" + + ConfigMapSecretNames: + type: object + description: ConfigMap and Secret names for stage configuration + properties: + configMaps: + type: array + items: + type: string + description: List of ConfigMap names + example: ["configMap1", "configMap2"] + secrets: + type: array + items: + type: string + description: List of Secret names + example: ["secret1", "secret2"] + + AppTemplateRequest: + type: object + description: Request for creating/updating application deployment template + required: + - deploymentTemplate + properties: + appId: + type: integer + format: int64 + description: Application ID (required for updates) + example: 123 + deploymentTemplate: + type: string + description: Deployment template as YAML string + example: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: sample-app + preStage: + $ref: '#/components/schemas/StageConfig' + postStage: + $ref: '#/components/schemas/StageConfig' + preStageConfigMapSecretNames: + $ref: '#/components/schemas/ConfigMapSecretNames' + postStageConfigMapSecretNames: + $ref: '#/components/schemas/ConfigMapSecretNames' + runPreStageInEnv: + type: boolean + description: Whether to run pre-stage in environment + default: true + example: true + runPostStageInEnv: + type: boolean + description: Whether to run post-stage in environment + default: false + example: false + isClusterCdActive: + type: boolean + description: Whether cluster CD is active + default: true + example: true + + AppTemplateUpdateRequest: + allOf: + - $ref: '#/components/schemas/AppTemplateRequest' + - type: object + required: + - templateId + properties: + templateId: + type: integer + format: int64 + description: Template ID to update + example: 1 + + EnvironmentConfigRequest: + type: object + description: Environment configuration request + required: + - appId + - envId + properties: + appId: + type: integer + format: int64 + description: Application ID + example: 123 + envId: + type: integer + format: int64 + description: Environment ID + example: 456 + config: + type: object + description: Environment configuration + properties: + namespace: + type: string + description: Kubernetes namespace + example: "dev" + active: + type: boolean + description: Whether environment is active + example: true + + EnvironmentValuesRequest: + type: object + description: Environment values configuration request + required: + - appId + - envId + - chartId + properties: + appId: + type: integer + format: int64 + description: Application ID + example: 123 + envId: + type: integer + format: int64 + description: Environment ID + example: 456 + chartId: + type: integer + format: int64 + description: Chart ID + example: 789 + values: + type: object + description: Helm chart values + example: + replicaCount: 2 + image: "my-app:latest" + + CreateEnvironmentRequest: + type: object + description: Request to create environment configuration + required: + - appId + - envName + - namespace + - clusterId + properties: + appId: + type: integer + format: int64 + description: Application ID + example: 123 + envName: + type: string + description: Environment name + example: "staging" + namespace: + type: string + description: Kubernetes namespace + example: "staging-ns" + clusterId: + type: integer + format: int64 + description: Cluster ID + example: 1 + active: + type: boolean + description: Whether environment is active + default: true + example: true + tags: - name: Deployment Templates - description: Operations for managing deployment templates + description: | + Operations for managing deployment templates including: + - Application deployment template configuration + - Template creation and updates + - Pre/post deployment stage management + - ConfigMap and Secret integration - name: Environment Configuration - description: Operations for managing environment configurations + description: | + Operations for managing environment configurations including: + - Environment-specific overrides + - Chart values configuration + - Environment creation and updates + - Namespace and cluster management - name: Deployment Configuration description: Operations for managing deployment configurations paths: - /deployment/template/create: + /app/template: + post: + tags: + - Deployment Templates + summary: Configure deployment template for application + description: | + Creates or configures a deployment template for an application including: + - Deployment template YAML configuration + - Pre-stage and post-stage configurations + - ConfigMap and Secret references for stages + - Environment execution settings + - Cluster CD activation settings + operationId: configureDeploymentTemplateForApp + requestBody: + description: Application template configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AppTemplateRequest' + examples: + basic_template: + summary: Basic deployment template + value: + deploymentTemplate: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: sample-app + spec: + replicas: 2 + selector: + matchLabels: + app: sample-app + template: + metadata: + labels: + app: sample-app + spec: + containers: + - name: app + image: nginx:latest + preStage: + triggerType: "AUTOMATIC" + name: "pre-stage" + config: "echo 'Pre-deployment validation'" + postStage: + triggerType: "MANUAL" + name: "post-stage" + config: "echo 'Post-deployment cleanup'" + preStageConfigMapSecretNames: + configMaps: ["pre-config"] + secrets: ["pre-secret"] + postStageConfigMapSecretNames: + configMaps: ["post-config"] + secrets: ["post-secret"] + runPreStageInEnv: true + runPostStageInEnv: false + isClusterCdActive: true + responses: + '200': + description: Template configured successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/DeploymentTemplate' + example: + code: 200 + status: "OK" + result: + id: 1 + name: "sample-app-template" + chartRefId: 1 + isAppMetricsEnabled: true + createdOn: "2024-01-15T10:30:00Z" + createdBy: 1 + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + code: 400 + status: "Bad Request" + errors: ["Invalid deployment template YAML format"] + '401': + description: Unauthorized - Invalid or missing authentication token + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden - User lacks permission to configure templates + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/template/update: post: tags: - Deployment Templates - summary: Create deployment template - description: Creates a new deployment template from uploaded chart or configuration - operationId: createDeploymentTemplate + summary: Update deployment template + description: | + Updates an existing deployment template configuration including: + - Modified deployment template YAML + - Updated pre/post stage configurations + - Changed ConfigMap and Secret references + - Modified environment execution settings + operationId: updateAppOverride requestBody: - description: Template creation request + description: Template update request required: true content: application/json: schema: - $ref: '#/components/schemas/CreateTemplateRequest' + $ref: '#/components/schemas/AppTemplateUpdateRequest' + examples: + update_template: + summary: Update existing template + value: + templateId: 1 + deploymentTemplate: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: sample-app-updated + spec: + replicas: 3 + preStage: + triggerType: "MANUAL" + name: "updated-pre-stage" + config: "echo 'Updated pre-deployment'" + postStage: + triggerType: "AUTOMATIC" + name: "updated-post-stage" + config: "echo 'Updated post-deployment'" + runPreStageInEnv: false + runPostStageInEnv: true + isClusterCdActive: true responses: '200': - description: Template created successfully + description: Template updated successfully content: application/json: schema: @@ -317,6 +621,18 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Template not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: @@ -326,28 +642,39 @@ paths: security: - bearerAuth: [] + + /deployment/template/validate: post: tags: - Deployment Templates - summary: Validate deployment template - description: Validates a deployment template file upload + summary: Validate deployment template chart file + description: | + Validates a deployment template chart file upload (.tgz format) including: + - Chart structure validation + - Template syntax validation + - Chart metadata verification + - File format validation + + This endpoint is used for validating custom chart uploads before saving them. operationId: validateDeploymentTemplate requestBody: - description: Template file for validation + description: Chart template file for validation required: true content: multipart/form-data: schema: type: object + required: + - BinaryFile properties: BinaryFile: type: string format: binary - description: Zipped chart template file + description: Zipped chart template file (.tgz format) responses: '200': - description: Template validation completed + description: Template validation completed successfully content: application/json: schema: @@ -357,18 +684,39 @@ paths: properties: result: $ref: '#/components/schemas/TemplateValidationResponse' + example: + code: 200 + status: "OK" + result: + isValid: true + errors: [] + warnings: ["Chart version not specified"] + chartInfo: + name: "sample-chart" + version: "1.0.0" + description: "Sample deployment chart" '400': description: Invalid file format or validation error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + example: + code: 400 + status: "Bad Request" + errors: ["Unsupported format file is uploaded, please upload file with .tgz extension"] '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden - User lacks global create permission + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: @@ -378,38 +726,58 @@ paths: security: - bearerAuth: [] - /config/environment: - get: + /deployment/template/upload: + put: tags: - - Environment Configuration - summary: Get environment configuration - description: Retrieves environment configuration details - operationId: getEnvironmentConfiguration - parameters: - - name: environmentId - in: query - description: Environment ID to filter by - required: false - schema: - type: integer - format: int64 - - name: clusterId - in: query - description: Cluster ID to filter by - required: false - schema: - type: integer - format: int64 - - name: appId - in: query - description: Application ID to filter by - required: false - schema: - type: integer - format: int64 + - Deployment Templates + summary: Upload deployment template chart + description: | + Uploads and saves a validated deployment template chart including: + - Chart file processing and storage + - Chart metadata extraction + - Chart reference creation + - Template registration in system + operationId: saveDeploymentTemplate + requestBody: + description: Chart upload request + required: true + content: + application/json: + schema: + type: object + required: + - chartName + - chartVersion + - fileId + - action + properties: + chartName: + type: string + description: Chart name + example: "sample-chart" + chartVersion: + type: string + description: Chart version + example: "1.0.0" + description: + type: string + description: Chart description + example: "Sample deployment chart" + fileId: + type: string + description: File ID from validation step + example: "file-123" + action: + type: string + description: Action to perform + example: "SAVE" + message: + type: string + description: Additional message + example: "Chart uploaded successfully" responses: '200': - description: Environment configuration retrieved successfully + description: Chart uploaded and saved successfully content: application/json: schema: @@ -418,11 +786,63 @@ paths: - type: object properties: result: - type: array - items: - $ref: '#/components/schemas/EnvironmentConfig' + type: string + example: "Processed successfully" '400': - description: Invalid request parameters + description: Invalid request format + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /deployment/template/download/{chartRefId}: + get: + tags: + - Deployment Templates + summary: Download deployment template chart + description: Downloads a deployment template chart file by chart reference ID + operationId: downloadDeploymentTemplate + parameters: + - name: chartRefId + in: path + description: Chart reference ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 123 + responses: + '200': + description: Chart file downloaded successfully + content: + application/octet-stream: + schema: + type: string + format: binary + description: Chart file in .tgz format + '400': + description: Invalid chart reference ID content: application/json: schema: @@ -433,6 +853,656 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + '404': + description: Chart not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /deployment/template/fetch: + get: + tags: + - Deployment Templates + summary: Get uploaded deployment template charts + description: | + Retrieves a list of all uploaded deployment template charts including: + - Chart metadata and information + - Upload status and details + - Chart reference information + - Available chart versions + operationId: getUploadedCharts + responses: + '200': + description: Uploaded charts retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: Chart reference ID + name: + type: string + description: Chart name + version: + type: string + description: Chart version + description: + type: string + description: Chart description + createdOn: + type: string + format: date-time + description: Upload timestamp + createdBy: + type: integer + description: User ID who uploaded + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /config/environment: + get: + tags: + - Environment Configuration + summary: Get environment configuration + description: Retrieves environment configuration details + operationId: getEnvironmentConfiguration + parameters: + - name: environmentId + in: query + description: Environment ID to filter by + required: false + schema: + type: integer + format: int64 + - name: clusterId + in: query + description: Cluster ID to filter by + required: false + schema: + type: integer + format: int64 + - name: appId + in: query + description: Application ID to filter by + required: false + schema: + type: integer + format: int64 + responses: + '200': + description: Environment configuration retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + type: array + items: + $ref: '#/components/schemas/EnvironmentConfig' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/env/{appId}/{envId}: + get: + tags: + - Environment Configuration + summary: Get environment configuration override + description: | + Retrieves environment-specific configuration override for an application including: + - Environment deployment configuration + - ConfigMap and Secret overrides + - Deployment template overrides + - Environment-specific values + operationId: getEnvConfigOverride + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 456 + responses: + '200': + description: Environment configuration retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/EnvironmentConfig' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application or environment not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + post: + tags: + - Environment Configuration + summary: Create environment configuration override + description: | + Creates environment-specific configuration override for an application including: + - Environment deployment settings + - Namespace configuration + - Environment activation status + - Custom environment values + operationId: envConfigOverrideCreate + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 456 + requestBody: + description: Environment configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EnvironmentConfigRequest' + examples: + dev_environment: + summary: Development environment configuration + value: + appId: 123 + envId: 456 + config: + namespace: "dev" + active: true + responses: + '200': + description: Environment configuration created successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/EnvironmentConfig' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '409': + description: Environment configuration already exists + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/env/{appId}/{envId}/{chartId}: + get: + tags: + - Environment Configuration + summary: Get environment configuration with chart details + description: | + Retrieves environment-specific configuration with chart details including: + - Chart-specific environment values + - Deployment template with chart reference + - Environment override values + - Chart version information + operationId: getEnvConfigOverrideWithChart + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 456 + - name: chartId + in: path + description: Chart ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 789 + responses: + '200': + description: Environment configuration with chart details retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + allOf: + - $ref: '#/components/schemas/EnvironmentConfig' + - type: object + properties: + chartId: + type: integer + format: int64 + description: Chart ID + chartVersion: + type: string + description: Chart version + values: + type: object + description: Chart values + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application, environment, or chart not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + put: + tags: + - Environment Configuration + summary: Update environment configuration with chart values + description: | + Updates environment-specific configuration with chart values including: + - Modified chart values + - Updated environment settings + - Chart version changes + - Environment override updates + operationId: updateEnvConfigOverrideWithChart + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 456 + - name: chartId + in: path + description: Chart ID + required: true + schema: + type: integer + format: int64 + minimum: 1 + example: 789 + requestBody: + description: Environment values configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EnvironmentValuesRequest' + examples: + production_values: + summary: Production environment values + value: + appId: 123 + envId: 456 + chartId: 789 + values: + replicaCount: 3 + image: "my-app:v1.2.0" + resources: + limits: + cpu: "500m" + memory: "512Mi" + requests: + cpu: "250m" + memory: "256Mi" + responses: + '200': + description: Environment configuration updated successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/EnvironmentConfig' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application, environment, or chart not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/env: + post: + tags: + - Environment Configuration + summary: Create new environment configuration + description: | + Creates a new environment configuration for an application including: + - Environment name and namespace setup + - Cluster association + - Environment activation status + - Initial configuration values + operationId: createEnvironmentConfig + requestBody: + description: Create environment request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEnvironmentRequest' + examples: + staging_environment: + summary: Staging environment creation + value: + appId: 123 + envName: "staging" + namespace: "staging-ns" + clusterId: 1 + active: true + responses: + '200': + description: Environment created successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/EnvironmentConfig' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '409': + description: Environment already exists + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + put: + tags: + - Environment Configuration + summary: Update environment configuration + description: | + Updates existing environment configuration including: + - Environment settings modification + - Namespace changes + - Activation status updates + - Configuration value updates + operationId: envConfigOverrideUpdate + requestBody: + description: Environment configuration update request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EnvironmentConfigRequest' + examples: + update_environment: + summary: Update environment configuration + value: + appId: 123 + envId: 456 + config: + namespace: "updated-dev" + active: false + responses: + '200': + description: Environment configuration updated successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/EnvironmentConfig' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Environment configuration not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: diff --git a/specs/template/orchestrator-app-endpoints.yaml b/specs/template/orchestrator-app-endpoints.yaml new file mode 100644 index 0000000000..e3cc56de4a --- /dev/null +++ b/specs/template/orchestrator-app-endpoints.yaml @@ -0,0 +1,923 @@ +openapi: 3.0.3 +info: + version: 1.0.0 + title: Devtron Orchestrator App Template & Environment API + description: | + API specifications for Devtron orchestrator app template and environment configuration endpoints. + These endpoints are based on the actual codebase implementation and match the frontend payloads. + termsOfService: https://devtron.ai/terms/ + contact: + name: Devtron Support + email: support@devtron.ai + url: https://devtron.ai/support + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +servers: + - url: /orchestrator + description: Devtron Orchestrator API Server + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: JWT token for authentication + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + description: HTTP status code + status: + type: string + description: Response status + result: + type: object + description: Response data + + ErrorResponse: + type: object + properties: + code: + type: integer + description: Error code + status: + type: string + description: Error status + errors: + type: array + items: + type: string + description: List of error messages + + # Based on pkg/chart/bean/TemplateRequest + TemplateRequest: + type: object + description: Template request for app deployment configuration + required: + - appId + - valuesOverride + properties: + id: + type: integer + description: Template ID (0 for new, >0 for updates) + example: 0 + appId: + type: integer + description: Application ID + example: 123 + refChartTemplate: + type: string + description: Reference chart template + refChartTemplateVersion: + type: string + description: Reference chart template version + chartRepositoryId: + type: integer + description: Chart repository ID + valuesOverride: + type: object + description: Values override in JSON format (matches frontend payload) + example: + deploymentTemplate: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: sample-app + spec: + replicas: 2 + preStage: + triggerType: "AUTOMATIC" + name: "pre-stage" + config: "echo 'Pre-deployment validation'" + postStage: + triggerType: "MANUAL" + name: "post-stage" + config: "echo 'Post-deployment cleanup'" + preStageConfigMapSecretNames: + configMaps: ["configMap1"] + secrets: ["secret1"] + postStageConfigMapSecretNames: + configMaps: ["configMap2"] + secrets: ["secret2"] + runPreStageInEnv: true + runPostStageInEnv: false + isClusterCdActive: true + defaultAppOverride: + type: object + description: Default app override values + chartRefId: + type: integer + description: Chart reference ID + isAppMetricsEnabled: + type: boolean + description: Whether app metrics are enabled + default: false + isBasicViewLocked: + type: boolean + description: Whether basic view is locked + default: false + currentViewEditor: + type: string + description: Current view editor type + enum: ["UNDEFINED", "BASIC", "ADVANCED"] + default: "UNDEFINED" + + # Based on pkg/pipeline/bean/EnvironmentProperties + EnvironmentProperties: + type: object + description: Environment properties for configuration override + required: + - environmentId + - active + - manualReviewed + - status + properties: + id: + type: integer + description: Environment properties ID + envOverrideValues: + type: object + description: Environment override values in JSON format + example: + appId: 123 + envId: 456 + config: + namespace: "dev" + active: true + status: + type: integer + description: Chart status (0=new, 1=success, etc.) + example: 0 + manualReviewed: + type: boolean + description: Whether manually reviewed + example: true + active: + type: boolean + description: Whether environment is active + example: true + namespace: + type: string + description: Kubernetes namespace + example: "dev" + environmentId: + type: integer + description: Environment ID + example: 456 + environmentName: + type: string + description: Environment name + example: "development" + latest: + type: boolean + description: Whether this is the latest version + appMetrics: + type: boolean + description: Whether app metrics are enabled + chartRefId: + type: integer + description: Chart reference ID + isOverride: + type: boolean + description: Whether this is an override + isBasicViewLocked: + type: boolean + description: Whether basic view is locked + currentViewEditor: + type: string + description: Current view editor type + enum: ["UNDEFINED", "BASIC", "ADVANCED"] + description: + type: string + description: Environment description + maxLength: 40 + clusterId: + type: integer + description: Cluster ID + mergeStrategy: + type: string + description: Merge strategy + appId: + type: integer + description: Application ID + +tags: + - name: App Templates + description: | + Operations for managing application deployment templates including: + - Template creation and configuration + - Template updates and overrides + - Pre/post deployment stage management + - name: Environment Configuration + description: | + Operations for managing environment-specific configurations including: + - Environment overrides and values + - Chart-specific configurations + - Environment creation and updates + +paths: + /app/template: + post: + tags: + - App Templates + summary: Configure deployment template for application + description: | + Creates or configures a deployment template for an application. + Uses TemplateRequest structure from the codebase. + Handler: ConfigureDeploymentTemplateForApp + operationId: configureDeploymentTemplateForApp + requestBody: + description: Template configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TemplateRequest' + examples: + basic_template: + summary: Basic deployment template + value: + appId: 123 + valuesOverride: + deploymentTemplate: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: sample-app + spec: + replicas: 2 + preStage: + triggerType: "AUTOMATIC" + name: "pre-stage" + config: "echo 'Pre-deployment validation'" + postStage: + triggerType: "MANUAL" + name: "post-stage" + config: "echo 'Post-deployment cleanup'" + preStageConfigMapSecretNames: + configMaps: ["configMap1"] + secrets: ["secret1"] + postStageConfigMapSecretNames: + configMaps: ["configMap2"] + secrets: ["secret2"] + runPreStageInEnv: true + runPostStageInEnv: false + isClusterCdActive: true + responses: + '200': + description: Template configured successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/env/{appId}/{envId}: + get: + tags: + - Environment Configuration + summary: Get environment configuration override + description: | + Retrieves environment-specific configuration override for an application. + Handler: GetEnvConfigOverride + Path parameters: appId, environmentId, chartRefId (from URL path) + operationId: getEnvConfigOverride + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID (maps to environmentId in handler) + required: true + schema: + type: integer + minimum: 1 + example: 456 + - name: chartRefId + in: query + description: Chart reference ID (required for GET) + required: true + schema: + type: integer + minimum: 1 + example: 789 + responses: + '200': + description: Environment configuration retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/EnvironmentProperties' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application or environment not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + post: + tags: + - Environment Configuration + summary: Create environment configuration override + description: | + Creates environment-specific configuration override for an application. + Handler: EnvConfigOverrideCreate + Uses EnvironmentProperties structure from the codebase. + operationId: envConfigOverrideCreate + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID (maps to environmentId in handler) + required: true + schema: + type: integer + minimum: 1 + example: 456 + requestBody: + description: Environment configuration request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EnvironmentProperties' + examples: + dev_environment: + summary: Development environment configuration + value: + envOverrideValues: + appId: 123 + envId: 456 + config: + namespace: "dev" + active: true + status: 0 + manualReviewed: true + active: true + namespace: "dev" + chartRefId: 789 + responses: + '200': + description: Environment configuration created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '409': + description: Environment configuration already exists + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/env/{appId}/{envId}/{chartId}: + get: + tags: + - Environment Configuration + summary: Get environment configuration with chart details + description: | + Retrieves environment-specific configuration with chart details. + This is the same as /app/env/{appId}/{envId} but with chartId in path. + Handler: GetEnvConfigOverride (same handler, different path structure) + operationId: getEnvConfigOverrideWithChart + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + minimum: 1 + example: 456 + - name: chartId + in: path + description: Chart ID (chartRefId) + required: true + schema: + type: integer + minimum: 1 + example: 789 + responses: + '200': + description: Environment configuration with chart details retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/EnvironmentProperties' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application, environment, or chart not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + put: + tags: + - Environment Configuration + summary: Update environment configuration with chart values + description: | + Updates environment-specific configuration with chart values. + Based on your frontend payload, this matches the structure. + Handler: EnvConfigOverrideUpdate (PUT method on /env endpoint) + operationId: updateEnvConfigOverrideWithChart + parameters: + - name: appId + in: path + description: Application ID + required: true + schema: + type: integer + minimum: 1 + example: 123 + - name: envId + in: path + description: Environment ID + required: true + schema: + type: integer + minimum: 1 + example: 456 + - name: chartId + in: path + description: Chart ID + required: true + schema: + type: integer + minimum: 1 + example: 789 + requestBody: + description: Environment values configuration request + required: true + content: + application/json: + schema: + type: object + required: + - appId + - envId + - chartId + - values + properties: + appId: + type: integer + description: Application ID + example: 123 + envId: + type: integer + description: Environment ID + example: 456 + chartId: + type: integer + description: Chart ID + example: 789 + values: + type: object + description: Chart values to update + example: + replicaCount: 2 + image: "my-app:latest" + examples: + production_values: + summary: Production environment values + value: + appId: 123 + envId: 456 + chartId: 789 + values: + replicaCount: 3 + image: "my-app:v1.2.0" + resources: + limits: + cpu: "500m" + memory: "512Mi" + requests: + cpu: "250m" + memory: "256Mi" + responses: + '200': + description: Environment configuration updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application, environment, or chart not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/env: + post: + tags: + - Environment Configuration + summary: Create new environment configuration + description: | + Creates a new environment configuration for an application. + Based on your frontend payload structure. + Note: This endpoint may not exist in current codebase - verify the actual handler. + operationId: createEnvironmentConfig + requestBody: + description: Create environment request + required: true + content: + application/json: + schema: + type: object + required: + - appId + - envName + - namespace + - clusterId + - active + properties: + appId: + type: integer + description: Application ID + example: 123 + envName: + type: string + description: Environment name + example: "staging" + namespace: + type: string + description: Kubernetes namespace + example: "staging-ns" + clusterId: + type: integer + description: Cluster ID + example: 1 + active: + type: boolean + description: Whether environment is active + example: true + examples: + staging_environment: + summary: Staging environment creation + value: + appId: 123 + envName: "staging" + namespace: "staging-ns" + clusterId: 1 + active: true + responses: + '200': + description: Environment created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '409': + description: Environment already exists + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + put: + tags: + - Environment Configuration + summary: Update environment configuration + description: | + Updates existing environment configuration. + Handler: EnvConfigOverrideUpdate + Uses EnvironmentProperties structure from the codebase. + operationId: envConfigOverrideUpdate + requestBody: + description: Environment configuration update request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EnvironmentProperties' + examples: + update_environment: + summary: Update environment configuration + value: + id: 1 + envOverrideValues: + appId: 123 + envId: 456 + config: + namespace: "updated-dev" + active: false + status: 1 + manualReviewed: true + active: false + namespace: "updated-dev" + environmentId: 456 + chartRefId: 789 + responses: + '200': + description: Environment configuration updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Environment configuration not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] + + /app/template/update: + post: + tags: + - App Templates + summary: Update deployment template + description: | + Updates an existing deployment template configuration. + Uses TemplateRequest structure from the codebase. + Handler: UpdateAppOverride + operationId: updateAppOverride + requestBody: + description: Template update request + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TemplateRequest' + examples: + update_template: + summary: Update existing template + value: + id: 1 + appId: 123 + valuesOverride: + templateId: 1 + deploymentTemplate: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: sample-app-updated + spec: + replicas: 3 + preStage: + triggerType: "MANUAL" + name: "pre-stage-updated" + config: "echo 'Updated pre-deployment validation'" + postStage: + triggerType: "AUTOMATIC" + name: "post-stage-updated" + config: "echo 'Updated post-deployment cleanup'" + preStageConfigMapSecretNames: + configMaps: ["updated-configMap1"] + secrets: ["updated-secret1"] + postStageConfigMapSecretNames: + configMaps: ["updated-configMap2"] + secrets: ["updated-secret2"] + runPreStageInEnv: false + runPostStageInEnv: true + isClusterCdActive: false + responses: + '200': + description: Template updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request format or validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + security: + - bearerAuth: [] From b62d52665661be985811eee42037c65952231b25 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Wed, 17 Sep 2025 11:49:07 +0530 Subject: [PATCH 7/9] chore: resolving review comments --- .../DeploymentPipelineRestHandler.go | 120 +- .../analysis/fe-be-payload-mismatch-report.md | 229 ---- specs/application/application-management.yaml | 729 +++--------- .../application-management-fixed.yaml | 413 ------- specs/corrected/configmap-secret-apis.yaml | 334 ------ specs/corrected/configmap-secret-fixed.yaml | 360 ------ .../pod-resource-management-fixed.yaml | 387 ------ specs/corrected/security-apis-fixed.yaml | 376 ------ .../kubernetes-resource-management.yaml | 630 +++------- specs/security/security-dashboard-apis.yml | 491 +++----- specs/template/config-maps.yaml | 1049 ++++------------- 11 files changed, 739 insertions(+), 4379 deletions(-) delete mode 100644 specs/analysis/fe-be-payload-mismatch-report.md delete mode 100644 specs/corrected/application-management-fixed.yaml delete mode 100644 specs/corrected/configmap-secret-apis.yaml delete mode 100644 specs/corrected/configmap-secret-fixed.yaml delete mode 100644 specs/corrected/pod-resource-management-fixed.yaml delete mode 100644 specs/corrected/security-apis-fixed.yaml diff --git a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go index 21ef196b8d..652d020299 100644 --- a/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go +++ b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go @@ -1513,39 +1513,33 @@ func (handler *PipelineConfigRestHandlerImpl) ListDeploymentHistory(w http.Respo } token := r.Header.Get("token") vars := mux.Vars(r) - appIdStr := vars["appId"] - appId, err := strconv.Atoi(appIdStr) + appId, err := strconv.Atoi(vars["appId"]) if err != nil { - handler.Logger.Errorw("invalid appId", "err", err, "appId", appIdStr) - common.HandleParameterError(w, r, "appId", appIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - pipelineIdStr := vars["pipelineId"] - pipelineId, err := strconv.Atoi(pipelineIdStr) + pipelineId, err := strconv.Atoi(vars["pipelineId"]) if err != nil { - handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineIdStr) - common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - environmentIdStr := vars["environmentId"] - environmentId, err := strconv.Atoi(environmentIdStr) + + environmentId, err := strconv.Atoi(vars["environmentId"]) if err != nil { - handler.Logger.Errorw("invalid environmentId", "err", err, "environmentId", environmentIdStr) - common.HandleParameterError(w, r, "environmentId", environmentIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - //offsetQueryParam := r.URL.Query().Get("offset") - offset, err := common.ExtractPaginationParameterOrSetDefault(r, "offset", 0) - if err != nil { + offsetQueryParam := r.URL.Query().Get("offset") + offset, err := strconv.Atoi(offsetQueryParam) + if offsetQueryParam == "" || err != nil { handler.Logger.Errorw("request err, ListDeploymentHistory", "err", err, "appId", appId, "environmentId", environmentId, "pipelineId", pipelineId, "offset", offset) common.WriteJsonResp(w, err, "invalid offset", http.StatusBadRequest) return } sizeQueryParam := r.URL.Query().Get("size") - - limit, err := common.ExtractPaginationParameterOrSetDefault(r, "limit", 20) - if err != nil { + limit, err := strconv.Atoi(sizeQueryParam) + if sizeQueryParam == "" || err != nil { handler.Logger.Errorw("request err, ListDeploymentHistory", "err", err, "appId", appId, "environmentId", environmentId, "pipelineId", pipelineId, "sizeQueryParam", sizeQueryParam) common.WriteJsonResp(w, err, "invalid size", http.StatusBadRequest) return @@ -1594,42 +1588,33 @@ func (handler *PipelineConfigRestHandlerImpl) GetPrePostDeploymentLogs(w http.Re } token := r.Header.Get("token") vars := mux.Vars(r) - appIdStr := vars["appId"] - appId, err := strconv.Atoi(appIdStr) + appId, err := strconv.Atoi(vars["appId"]) if err != nil { - handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) - common.HandleParameterError(w, r, "appId", appIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - environmentIdStr := vars["environmentId"] - environmentId, err := strconv.Atoi(environmentIdStr) + environmentId, err := strconv.Atoi(vars["environmentId"]) if err != nil { - handler.Logger.Errorw("invalid environmentId", "err", err, "environmentId", environmentId) - common.HandleParameterError(w, r, "environmentId", environmentIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - pipelineIdStr := vars["pipelineId"] - pipelineId, err := strconv.Atoi(pipelineIdStr) + pipelineId, err := strconv.Atoi(vars["pipelineId"]) if err != nil { - handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) - common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - workflowRunnerIdStr := vars["workflowRunnerId"] - workflowId, err := strconv.Atoi(workflowRunnerIdStr) + + workflowId, err := strconv.Atoi(vars["workflowId"]) if err != nil { - handler.Logger.Errorw("invalid workflowId", "err", err, "workflowId", workflowId) - common.HandleParameterError(w, r, "workflowId", workflowRunnerIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } followLogs := true if ok := r.URL.Query().Has("followLogs"); ok { followLogsStr := r.URL.Query().Get("followLogs") - //follow, err := strconv.ParseBool(followLogsStr) - follow, err := common.ExtractBoolQueryParam(r, "followLogs") + follow, err := strconv.ParseBool(followLogsStr) if err != nil { - handler.Logger.Errorw("followLogs is not a valid bool", "err", err, "followLogs", followLogsStr) - common.HandleParameterError(w, r, "followLogs", followLogsStr) + common.WriteJsonResp(w, err, "followLogs is not a valid bool", http.StatusBadRequest) return } followLogs = follow @@ -1687,36 +1672,24 @@ func (handler *PipelineConfigRestHandlerImpl) FetchCdWorkflowDetails(w http.Resp } token := r.Header.Get("token") vars := mux.Vars(r) - appIdStr := vars["appId"] - appId, err := strconv.Atoi(appIdStr) + appId, err := strconv.Atoi(vars["appId"]) if err != nil { - handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) - common.HandleParameterError(w, r, "appId", appIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - environmentIdStr := vars["environmentId"] - environmentId, err := strconv.Atoi(environmentIdStr) + environmentId, err := strconv.Atoi(vars["environmentId"]) if err != nil { - handler.Logger.Errorw("invalid environmentId", "err", err, "environmentId", environmentId) - common.HandleParameterError(w, r, "environmentId", environmentIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - pipelineIdStr := vars["pipelineId"] - pipelineId, err := strconv.Atoi(pipelineIdStr) + pipelineId, err := strconv.Atoi(vars["pipelineId"]) if err != nil { - handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) - common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - workflowRunnerIdStr := vars["workflowRunnerId"] - buildId, err := strconv.Atoi(workflowRunnerIdStr) + buildId, err := strconv.Atoi(vars["workflowRunnerId"]) if err != nil || buildId == 0 { - if err != nil { - handler.Logger.Errorw("invalid workflowRunnerId", "err", err, "workflowRunnerId", workflowRunnerIdStr) - common.HandleParameterError(w, r, "workflowRunnerId", workflowRunnerIdStr) - return - } - common.HandleValidationErrors(w, r, fmt.Errorf("workflowRunnerId is required should be greater than 0, workflowRunnerId: %s", workflowRunnerIdStr)) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } handler.Logger.Infow("request payload, FetchCdWorkflowDetails", "err", err, "appId", appId, "environmentId", environmentId, "pipelineId", pipelineId, "buildId", buildId) @@ -1751,25 +1724,19 @@ func (handler *PipelineConfigRestHandlerImpl) DownloadArtifacts(w http.ResponseW } token := r.Header.Get("token") vars := mux.Vars(r) - appIdStr := vars["appId"] - appId, err := strconv.Atoi(appIdStr) + appId, err := strconv.Atoi(vars["appId"]) if err != nil { - handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) - common.HandleParameterError(w, r, "appId", appIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - pipelineIdStr := vars["pipelineId"] - pipelineId, err := strconv.Atoi(pipelineIdStr) + pipelineId, err := strconv.Atoi(vars["pipelineId"]) if err != nil { - handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) - common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - workflowRunnerIdStr := vars["workflowRunnerId"] - buildId, err := strconv.Atoi(workflowRunnerIdStr) + buildId, err := strconv.Atoi(vars["workflowRunnerId"]) if err != nil { - handler.Logger.Errorw("invalid workflowRunnerId", "err", err, "workflowRunnerId", workflowRunnerIdStr) - common.HandleParameterError(w, r, "workflowRunnerId", workflowRunnerIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } handler.Logger.Infow("request payload, DownloadArtifacts", "err", err, "appId", appId, "pipelineId", pipelineId, "buildId", buildId) @@ -1817,19 +1784,14 @@ func (handler *PipelineConfigRestHandlerImpl) GetStageStatus(w http.ResponseWrit } token := r.Header.Get("token") vars := mux.Vars(r) - - appIdStr := vars["appId"] - appId, err := strconv.Atoi(appIdStr) + appId, err := strconv.Atoi(vars["appId"]) if err != nil { - handler.Logger.Errorw("invalid appId", "err", err, "appId", appId) - common.HandleParameterError(w, r, "appId", appIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - pipelineIdStr := vars["pipelineId"] - pipelineId, err := strconv.Atoi(pipelineIdStr) + pipelineId, err := strconv.Atoi(vars["pipelineId"]) if err != nil { - handler.Logger.Errorw("invalid pipelineId", "err", err, "pipelineId", pipelineId) - common.HandleParameterError(w, r, "pipelineId", pipelineIdStr) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } handler.Logger.Infow("request payload, GetStageStatus", "err", err, "appId", appId, "pipelineId", pipelineId) diff --git a/specs/analysis/fe-be-payload-mismatch-report.md b/specs/analysis/fe-be-payload-mismatch-report.md deleted file mode 100644 index ab5dbce7b1..0000000000 --- a/specs/analysis/fe-be-payload-mismatch-report.md +++ /dev/null @@ -1,229 +0,0 @@ -# Frontend-Backend Payload Mismatch Analysis Report - -**Generated**: 2025-09-16 -**Scope**: Complete analysis of Devtron Orchestrator API specifications -**Status**: 🚨 **CRITICAL MISMATCHES FOUND** - -## 🚨 **EXECUTIVE SUMMARY** - -This report documents **29 critical mismatches** between Frontend (FE) expectations and Backend (BE) implementation across Devtron orchestrator APIs. The analysis covers ConfigMap/Secret APIs, Security APIs, Pod Management, Application Management, and Infrastructure APIs. - -**Severity Breakdown:** -- **❌ Critical Issues**: 22 (Require backend changes or major frontend updates) -- **⚠️ Major Issues**: 5 (Require frontend path/parameter updates) -- **✅ Correct Endpoints**: 8 (Work as expected) - ---- - -## 🔍 **DETAILED MISMATCH ANALYSIS** - -### **1. ConfigMap & Secret APIs (12 Issues)** - -#### **1.1 Path Mismatches (4 Issues)** -| Frontend Expectation | Backend Reality | Status | -|---------------------|-----------------|---------| -| `GET /orchestrator/global/cm/{appId}` | `GET /orchestrator/config/global/cm/{appId}` | ❌ Critical | -| `GET /orchestrator/global/cs/{appId}` | `GET /orchestrator/config/global/cs/{appId}` | ❌ Critical | -| `PUT /orchestrator/global/cm/{appId}/{id}` | **ENDPOINT MISSING** | ❌ Critical | -| `PUT /orchestrator/global/cs/{appId}/{id}` | **ENDPOINT MISSING** | ❌ Critical | - -#### **1.2 Missing HTTP Methods (4 Issues)** -- **FE Expects**: `PUT /orchestrator/global/cm/{appId}/{id}?name={name}` -- **BE Reality**: Only `POST /orchestrator/config/global/cm` (handles create/update) -- **FE Expects**: `PUT /orchestrator/global/cs/{appId}/{id}?name={name}` -- **BE Reality**: Only `POST /orchestrator/config/global/cs` (handles create/update) - -#### **1.3 Payload Structure Mismatches (4 Issues)** - -**Frontend Sends:** -```json -{ - "name": "global-configmap", - "data": { - "key1": "value1", - "key2": "value2" - } -} -``` - -**Backend Expects:** -```json -{ - "appId": 123, - "configData": [{ - "name": "global-configmap", - "type": "CONFIGMAP", - "data": { - "key1": "value1", - "key2": "value2" - } - }] -} -``` - ---- - -### **2. Security Scan APIs (4 Issues)** - -#### **2.1 Method Mismatches (2 Issues)** -| Frontend Expectation | Backend Reality | Status | -|---------------------|-----------------|---------| -| `POST /orchestrator/security/scan/executionDetail` | `GET /orchestrator/security/scan/executionDetail` | ❌ Critical | -| `POST /orchestrator/security/scan/executionDetail/min` | `GET /orchestrator/security/scan/executionDetail/min` | ❌ Critical | - -#### **2.2 Payload Structure Mismatches (2 Issues)** - -**Frontend Sends:** -```json -{ - "appId": 123, - "envId": 456, - "scanType": "VULNERABILITY" -} -``` - -**Backend Expects:** Complex `ImageScanRequest` structure with additional metadata fields - ---- - -### **3. Application Management APIs (4 Issues)** - -#### **3.1 Missing Query Parameters (2 Issues)** -| Frontend Expectation | Backend Reality | Status | -|---------------------|-----------------|---------| -| `POST /orchestrator/application/hibernate` | `POST /orchestrator/application/hibernate?appType={appType}` | ❌ Critical | -| `POST /orchestrator/application/unhibernate` | `POST /orchestrator/application/unhibernate?appType={appType}` | ❌ Critical | - -#### **3.2 Payload Structure Mismatches (2 Issues)** - -**Frontend Sends:** -```json -{ - "appId": 123, - "envId": 456 -} -``` - -**Backend Expects:** Different payload structure with `appType` query parameter - ---- - -### **4. Pod Management APIs (5 Issues)** - -#### **4.1 Payload Structure Mismatches (1 Issue)** - -**Frontend Sends:** -```json -{ - "appId": 123, - "envId": 456, - "podName": "my-pod" -} -``` - -**Backend Expects:** -```json -{ - "resources": [{ - "Group": "", - "Version": "v1", - "Kind": "Pod", - "Name": "my-pod", - "Namespace": "default" - }] -} -``` - -#### **4.2 Path Differences (2 Issues)** -| Frontend Expectation | Backend Reality | Status | -|---------------------|-----------------|---------| -| `/orchestrator/pods/logs/podName` | `/orchestrator/k8s/pods/logs/{podName}` | ⚠️ Major | -| `/orchestrator/resource/rotate` | `/orchestrator/k8s/resource/rotate?appId={appId}` | ⚠️ Major | - -#### **4.3 Missing Endpoints (2 Issues)** -| Frontend Expectation | Backend Reality | Status | -|---------------------|-----------------|---------| -| `POST /orchestrator/app/detail/resource-tree` | **ENDPOINT DOESN'T EXIST** | ❌ Critical | -| `POST /orchestrator/resources/ephemeralContainers` | **ENDPOINT DOESN'T EXIST** | ❌ Critical | - ---- - -## 📊 **SUMMARY STATISTICS** - -### **Issues by Category:** -| **Category** | **Count** | **Severity** | -|--------------|-----------|--------------| -| **Path Mismatches** | 6 | ❌ Critical | -| **Method Mismatches** | 4 | ❌ Critical | -| **Payload Structure Mismatches** | 8 | ❌ Critical | -| **Missing Query Parameters** | 3 | ⚠️ Major | -| **Missing Endpoints** | 2 | ❌ Critical | -| **Path Differences** | 2 | ⚠️ Major | -| **Missing HTTP Methods** | 4 | ❌ Critical | - -### **Issues by API Group:** -1. **ConfigMap/Secret APIs**: 12 issues -2. **Security APIs**: 4 issues -3. **Pod/Resource APIs**: 5 issues -4. **Application Management**: 4 issues -5. **Infrastructure APIs**: 2 issues -6. **Missing Endpoints**: 2 issues - -### **Total Issues Found: 29 Mismatches** - ---- - -## 🎯 **RECOMMENDATIONS** - -### **Option 1: Frontend Updates (Recommended)** -1. **Update API paths** to match backend routes -2. **Transform payload structures** to match backend expectations -3. **Change HTTP methods** where mismatched -4. **Add required query parameters** - -### **Option 2: Backend Updates (Alternative)** -1. **Add missing endpoints** that frontend expects -2. **Create adapter layers** for payload transformation -3. **Add missing HTTP methods** (PUT operations) -4. **Implement missing functionality** - -### **Option 3: Hybrid Approach** -1. **Fix critical path mismatches** in frontend -2. **Add missing endpoints** in backend -3. **Create payload adapters** for complex transformations - ---- - -## 📋 **EXISTING SPECIFICATIONS REFERENCE** - -The following existing specification files were analyzed: -- **`specs/security/security-dashboard-apis.yml`** - Security scan endpoints -- **`specs/application/rotate-pods.yaml`** - Pod rotation specifications -- **`specs/deployment/cd-pipeline-workflow.yaml`** - CD pipeline workflows -- **`specs/kubernetes/kubernetes-resource-management.yaml`** - K8s resource management -- **`specs/template/configmap-secret-corrected.yaml`** - ConfigMap/Secret corrections -- **`specs/miscellaneous/orchestrator-miscellaneous-apis.yaml`** - Miscellaneous API corrections - ---- - -## ⚠️ **IMPACT ASSESSMENT** - -**High Impact Issues (22):** -- All ConfigMap/Secret API mismatches -- Security scan method mismatches -- Missing application management endpoints -- Complex payload structure mismatches - -**Medium Impact Issues (5):** -- Path differences requiring frontend updates -- Missing query parameters - -**Low Impact Issues (2):** -- Minor path corrections - ---- - -**Report Generated by**: Augment Agent -**Analysis Date**: 2025-09-16 -**Total APIs Analyzed**: 35+ -**Specification Files Created**: 6 diff --git a/specs/application/application-management.yaml b/specs/application/application-management.yaml index f45811a214..63cda20f1d 100644 --- a/specs/application/application-management.yaml +++ b/specs/application/application-management.yaml @@ -1,15 +1,11 @@ -openapi: 3.0.3 +openapi: "3.0.3" info: - version: 1.0.0 - title: Devtron Orchestrator Application Management API - description: | - Comprehensive API specifications for Devtron orchestrator application management endpoints. - This includes CRUD operations for applications, deployment management, and application lifecycle operations. - termsOfService: https://devtron.ai/terms/ + title: Devtron Application Management API + description: API specifications for application hibernation, deployment status, and lifecycle management + version: "1.0.0" contact: name: Devtron Support email: support@devtron.ai - url: https://devtron.ai/support license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html @@ -18,13 +14,15 @@ servers: - url: /orchestrator description: Devtron Orchestrator API Server +security: + - bearerAuth: [] + components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT - description: JWT token for authentication schemas: ApiResponse: @@ -32,439 +30,119 @@ components: properties: code: type: integer - description: HTTP status code status: type: string - description: Status message result: type: object - description: Response result data ErrorResponse: type: object properties: code: type: integer - description: Error code status: type: string - description: Error status errors: type: array items: type: string - description: List of error messages - Application: + HibernateRequest: type: object - required: - - appName - - teamId properties: - id: - type: integer - format: int64 - description: Application ID - appName: - type: string - description: Name of the application - pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' - minLength: 1 - maxLength: 63 - teamId: - type: integer - format: int64 - description: Team ID - description: + appId: type: string - description: Application description - labels: - type: array - items: - $ref: '#/components/schemas/AppLabel' - description: Application labels - projectIds: + example: "123" + resources: type: array items: - type: integer - format: int64 - description: IDs of projects this application belongs to - active: - type: boolean - description: Whether the application is active - createdOn: - type: string - format: date-time - description: Application creation timestamp - createdBy: - type: integer - description: ID of user who created the application + $ref: '#/components/schemas/HibernateTargetObject' - AppLabel: + HibernateTargetObject: type: object - required: - - key - - value properties: - key: + group: type: string - description: Label key - value: + example: "apps" + kind: type: string - description: Label value - propagate: - type: boolean - description: Whether to propagate to kubernetes resources - - CreateApplicationRequest: - type: object - required: - - appName - - teamId - properties: - appName: - type: string - description: Name of the application - pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' - minLength: 1 - maxLength: 63 - teamId: - type: integer - format: int64 - description: Team ID - description: + example: "Deployment" + version: type: string - description: Application description - labels: - type: array - items: - $ref: '#/components/schemas/AppLabel' - description: Application labels - projectIds: - type: array - items: - type: integer - format: int64 - description: IDs of projects this application belongs to - - UpdateApplicationRequest: - type: object - required: - - id - - appName - - teamId - properties: - id: - type: integer - format: int64 - description: Application ID - appName: - type: string - description: Name of the application - pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' - minLength: 1 - maxLength: 63 - teamId: - type: integer - format: int64 - description: Team ID - description: - type: string - description: Application description - labels: - type: array - items: - $ref: '#/components/schemas/AppLabel' - description: Application labels - projectIds: - type: array - items: - type: integer - format: int64 - description: IDs of projects this application belongs to - - ApplicationListRequest: - type: object - properties: - teamIds: - type: array - items: - type: integer - format: int64 - description: Filter by team IDs - environmentIds: - type: array - items: - type: integer - format: int64 - description: Filter by environment IDs - statuses: - type: array - items: - type: string - enum: [Healthy, Degraded, Failed, Progressing, Unknown] - description: Filter by application statuses - appNameSearch: - type: string - description: Search term for application name - offset: - type: integer - minimum: 0 - description: Pagination offset - size: - type: integer - minimum: 1 - maximum: 100 - description: Page size - projectIds: - type: array - items: - type: integer - format: int64 - description: Filter by project IDs - sortBy: + example: "v1" + name: type: string - enum: [appName, lastDeployed, status] - description: Sort field - sortOrder: + example: "my-app" + namespace: type: string - enum: [ASC, DESC] - description: Sort order + example: "default" - ApplicationListResponse: + HibernateStatus: type: object properties: - code: - type: integer - description: HTTP status code - status: + success: + type: boolean + example: true + errorMessage: type: string - description: Status message - result: - type: object - properties: - appCount: - type: integer - description: Total number of applications matching the filters - appContainers: - type: array - items: - $ref: '#/components/schemas/ApplicationContainer' - description: List of applications + example: "" + targetObject: + $ref: '#/components/schemas/HibernateTargetObject' - ApplicationContainer: + PipelineTriggerRequest: type: object properties: appId: type: integer - format: int64 - description: Application ID - appName: - type: string - description: Application name - teamId: - type: integer - format: int64 - description: Team ID - teamName: - type: string - description: Team name - environments: - type: array - items: - $ref: '#/components/schemas/ApplicationEnvironment' - description: Environments where the application is deployed - lastDeployed: - type: string - format: date-time - description: Last deployment timestamp - status: - type: string - enum: [Healthy, Degraded, Failed, Progressing, Unknown] - description: Overall application status - - ApplicationEnvironment: - type: object - properties: - environmentId: - type: integer - format: int64 - description: Environment ID - environmentName: - type: string - description: Environment name - status: - type: string - enum: [Healthy, Degraded, Failed, Progressing, Unknown] - description: Application status in this environment - lastDeployed: - type: string - format: date-time - description: Last deployment timestamp in this environment - deploymentAppType: - type: string - enum: [helm, argo_cd] - description: Deployment application type - - CreateAppDTO: - type: object - description: Complete application configuration data transfer object returned by the get app endpoint - required: - - appName - - teamId - properties: - id: - type: integer - format: int64 - description: Application ID (auto-generated) example: 123 - appName: - type: string - description: Name of the application - pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' - minLength: 1 - maxLength: 100 - example: "sample-app" - description: - type: string - description: Application description - example: "Sample application for demonstration" - teamId: - type: integer - format: int64 - description: Team/Project ID that owns this application - example: 1 - templateId: - type: integer - format: int64 - description: Template ID used for application creation (0 for no template) - example: 0 - appType: - type: integer - description: | - Application type identifier: - - 0: Devtron App (native Devtron application) - - 1: Helm App (Helm-based application) - - 2: Argo App (ArgoCD-based application) - enum: [0, 1, 2] - example: 0 - material: - type: array - description: Git materials/repositories associated with the application - items: - $ref: '#/components/schemas/GitMaterial' - labels: - type: array - description: Application labels for categorization and Kubernetes resource propagation - items: - $ref: '#/components/schemas/AppLabel' - genericNote: - $ref: '#/components/schemas/GenericNoteResponseBean' - description: Application notes and documentation - - GitMaterial: - type: object - description: Git repository configuration for the application - required: - - url - - gitProviderId - - checkoutPath - properties: - id: - type: integer - format: int64 - description: Git material ID - example: 1 - name: - type: string - description: Display name for the git material - example: "sample-app-main" - url: - type: string - format: uri - description: Git repository URL - example: "https://github.com/user/sample-app.git" - gitProviderId: + environmentId: type: integer - format: int64 - description: Git provider configuration ID - minimum: 1 - example: 1 - checkoutPath: - type: string - description: Path where the repository should be checked out - pattern: '^[./].*' - example: "./" - fetchSubmodules: - type: boolean - description: Whether to fetch git submodules - default: false - example: false - isUsedInCiConfig: - type: boolean - description: Whether this material is used in CI configuration - example: true - filterPattern: - type: array - description: File patterns to include/exclude during build - items: - type: string - example: ["**"] - createBackup: - type: boolean - description: Whether to create backup of this material - default: false - example: false - - GenericNoteResponseBean: - type: object - description: Application notes and documentation metadata - properties: - id: + example: 456 + pipelineId: type: integer - format: int64 - description: Note ID - example: 1 - description: - type: string - description: Note content/description - example: "This is a sample application" - updatedBy: - type: string - description: Username who last updated the note - example: "admin" - updatedOn: - type: string - format: date-time - description: Last update timestamp - example: "2024-01-15T10:30:00Z" - createdBy: - type: string - description: Username who created the note - example: "admin" + example: 789 tags: - - name: Application Management - description: Operations for managing applications in Devtron orchestrator + - name: Application Hibernation + description: Application hibernation and unhibernation operations + - name: Pipeline Management + description: CD pipeline trigger and management operations + - name: Deployment Status + description: Deployment status and timeline operations paths: - /app: + /application/hibernate: post: tags: - - Application Management - summary: Create new application - description: Creates a new application in the Devtron orchestrator - operationId: createApplication + - Application Hibernation + summary: Hibernate application + description: Hibernates the specified application resources + operationId: hibernateApplication + parameters: + - name: appType + in: query + required: true + schema: + type: string + enum: ["argo", "helm", "flux"] + example: "argo" requestBody: - description: Application creation request required: true content: application/json: schema: - $ref: '#/components/schemas/CreateApplicationRequest' + $ref: '#/components/schemas/HibernateRequest' + example: + appId: "123" + resources: + - group: "apps" + kind: "Deployment" + version: "v1" + name: "my-app" + namespace: "default" responses: '200': - description: Application created successfully + description: Application hibernated successfully content: application/json: schema: @@ -473,9 +151,11 @@ paths: - type: object properties: result: - $ref: '#/components/schemas/Application' + type: array + items: + $ref: '#/components/schemas/HibernateStatus' '400': - description: Invalid request format or validation error + description: Invalid request parameters content: application/json: schema: @@ -486,8 +166,8 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '409': - description: Application with the same name already exists + '403': + description: Forbidden content: application/json: schema: @@ -498,32 +178,50 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /app/list: + /application/unhibernate: post: tags: - - Application Management - summary: List applications - description: | - Retrieves a paginated list of applications based on the provided filters. - Supports filtering by teams, environments, statuses, and search terms. - operationId: listApplications + - Application Hibernation + summary: Unhibernate application + description: Unhibernates the specified application resources + operationId: unhibernateApplication + parameters: + - name: appType + in: query + required: true + schema: + type: string + enum: ["argo", "helm", "flux"] + example: "argo" requestBody: - description: Application listing filters required: true content: application/json: schema: - $ref: '#/components/schemas/ApplicationListRequest' + $ref: '#/components/schemas/HibernateRequest' + example: + appId: "123" + resources: + - group: "apps" + kind: "Deployment" + version: "v1" + name: "my-app" + namespace: "default" responses: '200': - description: List of applications retrieved successfully + description: Application unhibernated successfully content: application/json: schema: - $ref: '#/components/schemas/ApplicationListResponse' + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + type: array + items: + $ref: '#/components/schemas/HibernateStatus' '400': description: Invalid request parameters content: @@ -536,43 +234,45 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /app/edit: + /app/cd-pipeline/trigger: post: tags: - - Application Management - summary: Update application - description: Updates an existing application's configuration including projects and labels - operationId: updateApplication + - Pipeline Management + summary: Trigger CD pipeline + description: Triggers a CD pipeline deployment for the specified application and environment + operationId: triggerCdPipeline requestBody: - description: Application update request required: true content: application/json: schema: - $ref: '#/components/schemas/UpdateApplicationRequest' + $ref: '#/components/schemas/PipelineTriggerRequest' + example: + appId: 123 + environmentId: 456 + pipelineId: 789 responses: '200': - description: Application updated successfully + description: CD pipeline triggered successfully content: application/json: schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/Application' + $ref: '#/components/schemas/ApiResponse' '400': - description: Invalid request format or validation error + description: Invalid request parameters content: application/json: schema: @@ -583,8 +283,8 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application not found + '403': + description: Forbidden content: application/json: schema: @@ -595,213 +295,94 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /get/{appId}: + /app/deployment-status/timeline/{appId}/{envId}: get: tags: - - Application Management - summary: Get application configuration details - description: | - Retrieves comprehensive configuration details for a specific application including: - - Basic application metadata (ID, name, description, team) - - Git materials configuration (repositories, checkout paths, filter patterns) - - Application labels with propagation settings - - Template configuration and app type information - - Generic notes and descriptions - - This endpoint is primarily used for application management and configuration display. - operationId: getApplicationConfig + - Deployment Status + summary: Get deployment status timeline + description: Retrieves the deployment status timeline for the specified application and environment + operationId: getDeploymentStatusTimeline parameters: - name: appId in: path - description: ID of the application to retrieve configuration for required: true schema: type: integer - format: int64 - minimum: 1 example: 123 + - name: envId + in: path + required: true + schema: + type: integer + example: 456 responses: '200': - description: Application configuration retrieved successfully + description: Deployment status timeline retrieved successfully content: application/json: schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/CreateAppDTO' - examples: - devtron_app: - summary: Devtron Application Example - value: - code: 200 - status: "OK" - result: - id: 123 - appName: "sample-app" - description: "Sample application for demonstration" - teamId: 1 - templateId: 0 - appType: 0 - material: - - id: 1 - name: "sample-app-main" - url: "https://github.com/user/sample-app.git" - gitProviderId: 1 - checkoutPath: "./" - fetchSubmodules: false - filterPattern: ["**"] - labels: - - key: "environment" - value: "development" - propagate: true - - key: "team" - value: "backend" - propagate: false - genericNote: - id: 1 - description: "This is a sample application" - updatedBy: "admin" - updatedOn: "2024-01-15T10:30:00Z" - createdBy: "admin" + $ref: '#/components/schemas/ApiResponse' '400': - description: Invalid request parameters + description: Invalid parameters content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - example: - code: 400 - status: "Bad Request" - errors: ["Invalid appId format"] '401': - description: Unauthorized - Invalid or missing authentication token + description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - example: - code: 401 - status: "Unauthorized" - errors: ["Authentication required"] '403': - description: Forbidden - User lacks permission to access this application + description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - example: - code: 403 - status: "Forbidden" - errors: ["Unauthorized User"] '404': - description: Application not found + description: Application or environment not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - example: - code: 404 - status: "Not Found" - errors: ["Application not found"] '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - example: - code: 500 - status: "Internal Server Error" - errors: ["Internal server error occurred"] - security: - - bearerAuth: [] - /app/{appId}: + /app/deployment-status/manual-sync/{appId}/{envId}: get: tags: - - Application Management - summary: Get application details - description: Retrieves detailed information about a specific application - operationId: getApplication + - Deployment Status + summary: Manual sync deployment status + description: Manually synchronizes the deployment status for the specified application and environment + operationId: manualSyncDeploymentStatus parameters: - name: appId in: path - description: ID of the application to retrieve required: true schema: type: integer - format: int64 - minimum: 1 - responses: - '200': - description: Application details retrieved successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/Application' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - - delete: - tags: - - Application Management - summary: Delete application - description: Deletes an application and all its associated resources - operationId: deleteApplication - parameters: - - name: appId + example: 123 + - name: envId in: path - description: ID of the application to delete required: true schema: type: integer - format: int64 - minimum: 1 - - name: cascade - in: query - description: Whether to cascade delete all associated resources - required: false - schema: - type: boolean - default: true + example: 456 responses: '200': - description: Application deleted successfully + description: Manual sync completed successfully content: application/json: schema: $ref: '#/components/schemas/ApiResponse' '400': - description: Invalid request parameters + description: Invalid parameters content: application/json: schema: @@ -812,14 +393,14 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application not found + '403': + description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '409': - description: Application cannot be deleted due to existing dependencies + '404': + description: Application or environment not found content: application/json: schema: @@ -830,5 +411,3 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] diff --git a/specs/corrected/application-management-fixed.yaml b/specs/corrected/application-management-fixed.yaml deleted file mode 100644 index 63cda20f1d..0000000000 --- a/specs/corrected/application-management-fixed.yaml +++ /dev/null @@ -1,413 +0,0 @@ -openapi: "3.0.3" -info: - title: Devtron Application Management API - description: API specifications for application hibernation, deployment status, and lifecycle management - version: "1.0.0" - contact: - name: Devtron Support - email: support@devtron.ai - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -servers: - - url: /orchestrator - description: Devtron Orchestrator API Server - -security: - - bearerAuth: [] - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - - schemas: - ApiResponse: - type: object - properties: - code: - type: integer - status: - type: string - result: - type: object - - ErrorResponse: - type: object - properties: - code: - type: integer - status: - type: string - errors: - type: array - items: - type: string - - HibernateRequest: - type: object - properties: - appId: - type: string - example: "123" - resources: - type: array - items: - $ref: '#/components/schemas/HibernateTargetObject' - - HibernateTargetObject: - type: object - properties: - group: - type: string - example: "apps" - kind: - type: string - example: "Deployment" - version: - type: string - example: "v1" - name: - type: string - example: "my-app" - namespace: - type: string - example: "default" - - HibernateStatus: - type: object - properties: - success: - type: boolean - example: true - errorMessage: - type: string - example: "" - targetObject: - $ref: '#/components/schemas/HibernateTargetObject' - - PipelineTriggerRequest: - type: object - properties: - appId: - type: integer - example: 123 - environmentId: - type: integer - example: 456 - pipelineId: - type: integer - example: 789 - -tags: - - name: Application Hibernation - description: Application hibernation and unhibernation operations - - name: Pipeline Management - description: CD pipeline trigger and management operations - - name: Deployment Status - description: Deployment status and timeline operations - -paths: - /application/hibernate: - post: - tags: - - Application Hibernation - summary: Hibernate application - description: Hibernates the specified application resources - operationId: hibernateApplication - parameters: - - name: appType - in: query - required: true - schema: - type: string - enum: ["argo", "helm", "flux"] - example: "argo" - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/HibernateRequest' - example: - appId: "123" - resources: - - group: "apps" - kind: "Deployment" - version: "v1" - name: "my-app" - namespace: "default" - responses: - '200': - description: Application hibernated successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - type: array - items: - $ref: '#/components/schemas/HibernateStatus' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /application/unhibernate: - post: - tags: - - Application Hibernation - summary: Unhibernate application - description: Unhibernates the specified application resources - operationId: unhibernateApplication - parameters: - - name: appType - in: query - required: true - schema: - type: string - enum: ["argo", "helm", "flux"] - example: "argo" - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/HibernateRequest' - example: - appId: "123" - resources: - - group: "apps" - kind: "Deployment" - version: "v1" - name: "my-app" - namespace: "default" - responses: - '200': - description: Application unhibernated successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - type: array - items: - $ref: '#/components/schemas/HibernateStatus' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /app/cd-pipeline/trigger: - post: - tags: - - Pipeline Management - summary: Trigger CD pipeline - description: Triggers a CD pipeline deployment for the specified application and environment - operationId: triggerCdPipeline - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/PipelineTriggerRequest' - example: - appId: 123 - environmentId: 456 - pipelineId: 789 - responses: - '200': - description: CD pipeline triggered successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /app/deployment-status/timeline/{appId}/{envId}: - get: - tags: - - Deployment Status - summary: Get deployment status timeline - description: Retrieves the deployment status timeline for the specified application and environment - operationId: getDeploymentStatusTimeline - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - - name: envId - in: path - required: true - schema: - type: integer - example: 456 - responses: - '200': - description: Deployment status timeline retrieved successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application or environment not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /app/deployment-status/manual-sync/{appId}/{envId}: - get: - tags: - - Deployment Status - summary: Manual sync deployment status - description: Manually synchronizes the deployment status for the specified application and environment - operationId: manualSyncDeploymentStatus - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - - name: envId - in: path - required: true - schema: - type: integer - example: 456 - responses: - '200': - description: Manual sync completed successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application or environment not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/configmap-secret-apis.yaml b/specs/corrected/configmap-secret-apis.yaml deleted file mode 100644 index 6e9c0258d5..0000000000 --- a/specs/corrected/configmap-secret-apis.yaml +++ /dev/null @@ -1,334 +0,0 @@ -openapi: "3.0.3" -info: - title: Devtron ConfigMap and Secret Management API - description: | - API specifications for ConfigMap and Secret management in Devtron orchestrator. - These specifications match the actual backend implementation exactly. - version: "1.0.0" - contact: - name: Devtron Support - email: support@devtron.ai - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -servers: - - url: /orchestrator - description: Devtron Orchestrator API Server - -security: - - bearerAuth: [] - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT token for authentication - - schemas: - ApiResponse: - type: object - properties: - code: - type: integer - description: HTTP status code - status: - type: string - description: Response status - result: - type: object - description: Response data - - ErrorResponse: - type: object - properties: - code: - type: integer - description: Error code - status: - type: string - description: Error status - errors: - type: array - items: - type: string - description: List of error messages - - ConfigDataRequest: - type: object - description: Request structure for ConfigMap/Secret operations - required: - - appId - - configData - properties: - id: - type: integer - description: ID of the ConfigMap/Secret (0 for new) - example: 0 - appId: - type: integer - description: Application ID - example: 123 - environmentId: - type: integer - description: Environment ID (for environment-specific configs) - example: 456 - configData: - type: array - description: Array of ConfigData objects - items: - $ref: '#/components/schemas/ConfigData' - isDeletable: - type: boolean - description: Whether the config is deletable - default: true - - ConfigData: - type: object - description: Individual ConfigMap or Secret data - required: - - name - - type - properties: - name: - type: string - description: Name of the ConfigMap/Secret - example: "global-configmap" - type: - type: string - description: Type of configuration - enum: ["CONFIGMAP", "SECRET"] - example: "CONFIGMAP" - external: - type: boolean - description: Whether this is an external ConfigMap/Secret - default: false - mountPath: - type: string - description: Path where the ConfigMap/Secret should be mounted - example: "/etc/config" - data: - type: object - description: Configuration data as key-value pairs - additionalProperties: - type: string - example: - key1: "value1" - key2: "value2" - global: - type: boolean - description: Whether this is a global configuration - default: true - subPath: - type: boolean - description: Whether to use subPath mounting - default: false - filePermission: - type: string - description: File permission for mounted files - example: "0644" - - ConfigsList: - type: object - properties: - maps: - type: array - items: - $ref: '#/components/schemas/ConfigData' - -tags: - - name: Global ConfigMaps - description: Global ConfigMap management operations - - name: Global Secrets - description: Global Secret management operations - - name: Environment ConfigMaps - description: Environment-specific ConfigMap operations - - name: Environment Secrets - description: Environment-specific Secret operations - -paths: - /config/global/cm: - post: - tags: - - Global ConfigMaps - summary: Create or update global ConfigMap - description: | - Creates a new global ConfigMap or updates an existing one. - This endpoint handles both create and update operations based on the ID field. - operationId: CMGlobalAddUpdate - requestBody: - description: ConfigMap configuration request - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - example: - id: 0 - appId: 123 - configData: - - name: "global-configmap" - type: "CONFIGMAP" - external: false - mountPath: "/etc/config" - data: - key1: "value1" - key2: "value2" - global: true - subPath: false - filePermission: "0644" - isDeletable: true - responses: - '200': - description: ConfigMap created/updated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /config/global/cs: - post: - tags: - - Global Secrets - summary: Create or update global Secret - description: | - Creates a new global Secret or updates an existing one. - This endpoint handles both create and update operations based on the ID field. - operationId: CSGlobalAddUpdate - requestBody: - description: Secret configuration request - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - example: - id: 0 - appId: 123 - configData: - - name: "global-secret" - type: "SECRET" - external: false - mountPath: "/etc/secrets" - data: - username: "admin" - password: "s3cr3t" - global: true - subPath: false - filePermission: "0600" - isDeletable: true - responses: - '200': - description: Secret created/updated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /config/global/cm/{appId}: - get: - tags: - - Global ConfigMaps - summary: Get global ConfigMaps for application - description: Retrieves all global ConfigMaps for the specified application - operationId: CMGlobalFetch - parameters: - - name: appId - in: path - description: Application ID - required: true - schema: - type: integer - example: 123 - responses: - '200': - description: Global ConfigMaps retrieved successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/ConfigsList' - '400': - description: Invalid application ID - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/configmap-secret-fixed.yaml b/specs/corrected/configmap-secret-fixed.yaml deleted file mode 100644 index 5e44e49c11..0000000000 --- a/specs/corrected/configmap-secret-fixed.yaml +++ /dev/null @@ -1,360 +0,0 @@ -openapi: "3.0.3" -info: - title: Devtron ConfigMap and Secret Management API - description: API specifications for ConfigMap and Secret management in Devtron orchestrator - version: "1.0.0" - contact: - name: Devtron Support - email: support@devtron.ai - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -servers: - - url: /orchestrator - description: Devtron Orchestrator API Server - -security: - - bearerAuth: [] - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - - schemas: - ApiResponse: - type: object - properties: - code: - type: integer - status: - type: string - result: - type: object - - ErrorResponse: - type: object - properties: - code: - type: integer - status: - type: string - errors: - type: array - items: - type: string - - ConfigDataRequest: - type: object - required: - - appId - - configData - properties: - id: - type: integer - example: 0 - appId: - type: integer - example: 123 - environmentId: - type: integer - example: 456 - configData: - type: array - items: - $ref: '#/components/schemas/ConfigData' - isDeletable: - type: boolean - default: true - - ConfigData: - type: object - required: - - name - - type - properties: - name: - type: string - example: "global-configmap" - type: - type: string - enum: ["CONFIGMAP", "SECRET"] - example: "CONFIGMAP" - external: - type: boolean - default: false - mountPath: - type: string - example: "/etc/config" - data: - type: object - additionalProperties: - type: string - example: - key1: "value1" - key2: "value2" - global: - type: boolean - default: true - subPath: - type: boolean - default: false - filePermission: - type: string - example: "0644" - - ConfigsList: - type: object - properties: - maps: - type: array - items: - $ref: '#/components/schemas/ConfigData' - -tags: - - name: Global ConfigMaps - description: Global ConfigMap management - - name: Global Secrets - description: Global Secret management - - name: Environment ConfigMaps - description: Environment-specific ConfigMap operations - - name: Environment Secrets - description: Environment-specific Secret operations - -paths: - /config/global/cm: - post: - tags: - - Global ConfigMaps - summary: Create or update global ConfigMap - description: Creates a new global ConfigMap or updates an existing one - operationId: CMGlobalAddUpdate - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - example: - id: 0 - appId: 123 - configData: - - name: "global-configmap" - type: "CONFIGMAP" - external: false - mountPath: "/etc/config" - data: - key1: "value1" - key2: "value2" - global: true - subPath: false - filePermission: "0644" - isDeletable: true - responses: - '200': - description: ConfigMap created/updated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /config/global/cs: - post: - tags: - - Global Secrets - summary: Create or update global Secret - description: Creates a new global Secret or updates an existing one - operationId: CSGlobalAddUpdate - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - example: - id: 0 - appId: 123 - configData: - - name: "global-secret" - type: "SECRET" - external: false - mountPath: "/etc/secrets" - data: - username: "admin" - password: "s3cr3t" - global: true - subPath: false - filePermission: "0600" - isDeletable: true - responses: - '200': - description: Secret created/updated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /config/global/cm/{appId}: - get: - tags: - - Global ConfigMaps - summary: Get global ConfigMaps for application - description: Retrieves all global ConfigMaps for the specified application - operationId: CMGlobalFetch - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - responses: - '200': - description: Global ConfigMaps retrieved successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/ConfigsList' - '400': - description: Invalid application ID - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /config/global/cs/{appId}: - get: - tags: - - Global Secrets - summary: Get global Secrets for application - description: Retrieves all global Secrets for the specified application - operationId: CSGlobalFetch - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - responses: - '200': - description: Global Secrets retrieved successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/ConfigsList' - '400': - description: Invalid application ID - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Application not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/pod-resource-management-fixed.yaml b/specs/corrected/pod-resource-management-fixed.yaml deleted file mode 100644 index 0ceb7573d2..0000000000 --- a/specs/corrected/pod-resource-management-fixed.yaml +++ /dev/null @@ -1,387 +0,0 @@ -openapi: "3.0.3" -info: - title: Devtron Pod and Resource Management API - description: API specifications for pod logs, resource rotation, and Kubernetes resource management - version: "1.0.0" - contact: - name: Devtron Support - email: support@devtron.ai - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -servers: - - url: /orchestrator - description: Devtron Orchestrator API Server - -security: - - bearerAuth: [] - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - - schemas: - ApiResponse: - type: object - properties: - code: - type: integer - status: - type: string - result: - type: object - - ErrorResponse: - type: object - properties: - code: - type: integer - status: - type: string - errors: - type: array - items: - type: string - - PodRotateRequest: - type: object - properties: - resources: - type: array - items: - $ref: '#/components/schemas/ResourceIdentifier' - - ResourceIdentifier: - type: object - properties: - Group: - type: string - example: "" - Version: - type: string - example: "v1" - Kind: - type: string - example: "Pod" - Name: - type: string - example: "my-pod" - Namespace: - type: string - example: "default" - - ResourceRotateRequest: - type: object - properties: - resourceId: - type: string - example: "res-123" - -tags: - - name: Pod Logs - description: Pod log retrieval operations - - name: Resource Management - description: Kubernetes resource management operations - - name: Pod Rotation - description: Pod rotation and restart operations - -paths: - /k8s/pods/logs/{podName}: - get: - tags: - - Pod Logs - summary: Get pod logs - description: Retrieves logs from the specified pod and container - operationId: getPodLogs - parameters: - - name: podName - in: path - required: true - schema: - type: string - example: "my-app-pod-123" - - name: containerName - in: query - required: true - schema: - type: string - example: "main-container" - - name: follow - in: query - required: false - schema: - type: boolean - default: false - example: false - responses: - '200': - description: Pod logs retrieved successfully - content: - text/plain: - schema: - type: string - '400': - description: Invalid parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Pod not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /k8s/pods/logs/download/{podName}: - get: - tags: - - Pod Logs - summary: Download pod logs - description: Downloads logs from the specified pod and container as a file - operationId: downloadPodLogs - parameters: - - name: podName - in: path - required: true - schema: - type: string - example: "my-app-pod-123" - - name: containerName - in: query - required: true - schema: - type: string - example: "main-container" - responses: - '200': - description: Pod logs file download - content: - application/octet-stream: - schema: - type: string - format: binary - '400': - description: Invalid parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Pod not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /k8s/resource/rotate: - post: - tags: - - Resource Management - summary: Rotate Kubernetes resource - description: Rotates the specified Kubernetes resource - operationId: rotateKubernetesResource - parameters: - - name: appId - in: query - required: true - schema: - type: integer - example: 123 - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ResourceRotateRequest' - example: - resourceId: "res-123" - responses: - '200': - description: Resource rotated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /app/rotate-pods: - post: - tags: - - Pod Rotation - summary: Rotate pods - description: Rotates the specified pods using resource identifiers - operationId: rotatePods - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/PodRotateRequest' - example: - resources: - - Group: "" - Version: "v1" - Kind: "Pod" - Name: "my-pod" - Namespace: "default" - responses: - '200': - description: Pods rotated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /cluster/list: - get: - tags: - - Resource Management - summary: Get cluster list - description: Retrieves a list of all available clusters - operationId: getClusterList - responses: - '200': - description: List of clusters retrieved successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /cluster/namespaces: - get: - tags: - - Resource Management - summary: Get all cluster namespaces - description: Retrieves namespaces from all clusters - operationId: getAllClusterNamespaces - responses: - '200': - description: All cluster namespaces retrieved successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/corrected/security-apis-fixed.yaml b/specs/corrected/security-apis-fixed.yaml deleted file mode 100644 index 9517ddc487..0000000000 --- a/specs/corrected/security-apis-fixed.yaml +++ /dev/null @@ -1,376 +0,0 @@ -openapi: "3.0.3" -info: - title: Devtron Security Scan API - description: API specifications for security scanning and vulnerability management in Devtron - version: "1.0.0" - contact: - name: Devtron Support - email: support@devtron.ai - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -servers: - - url: /orchestrator - description: Devtron Orchestrator API Server - -security: - - bearerAuth: [] - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - - schemas: - ApiResponse: - type: object - properties: - code: - type: integer - status: - type: string - result: - type: object - - ErrorResponse: - type: object - properties: - code: - type: integer - status: - type: string - errors: - type: array - items: - type: string - - ImageScanRequest: - type: object - properties: - imageScanDeployInfoId: - type: integer - example: 123 - image: - type: string - example: "nginx:latest" - artifactId: - type: integer - example: 456 - appId: - type: integer - example: 789 - envId: - type: integer - example: 101 - size: - type: integer - example: 20 - offset: - type: integer - example: 0 - - ImageScanHistoryResponse: - type: object - properties: - imageScanDeployInfoId: - type: integer - image: - type: string - tag: - type: string - appId: - type: integer - envId: - type: integer - executedOn: - type: string - format: date-time - executionHistory: - type: array - items: - type: object - - ImageScanHistoryListingResponse: - type: object - properties: - imageScanHistoryResponse: - type: array - items: - $ref: '#/components/schemas/ImageScanHistoryResponse' - - VulnerabilityExposureRequest: - type: object - properties: - cveId: - type: string - example: "CVE-2025-1234" - appId: - type: integer - example: 123 - -tags: - - name: Security Scans - description: Security scanning operations - - name: Vulnerability Management - description: Vulnerability exposure and policy management - -paths: - /security/scan/list: - post: - tags: - - Security Scans - summary: Get scan execution list - description: Retrieves a list of security scan executions based on the provided criteria - operationId: scanExecutionList - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ImageScanRequest' - example: - imageScanDeployInfoId: 123 - image: "nginx:latest" - artifactId: 456 - appId: 789 - envId: 101 - size: 20 - offset: 0 - responses: - '200': - description: Scan execution list retrieved successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/ImageScanHistoryListingResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /security/scan/executionDetail: - get: - tags: - - Security Scans - summary: Get scan execution detail - description: Retrieves detailed information about a specific scan execution - operationId: fetchExecutionDetail - parameters: - - name: imageScanDeployInfoId - in: query - required: false - schema: - type: integer - example: 123 - - name: image - in: query - required: false - schema: - type: string - example: "nginx:latest" - - name: artifactId - in: query - required: false - schema: - type: integer - example: 456 - - name: appId - in: query - required: false - schema: - type: integer - example: 789 - - name: envId - in: query - required: false - schema: - type: integer - example: 101 - - name: executionId - in: query - required: false - schema: - type: integer - example: 999 - responses: - '200': - description: Scan execution detail retrieved successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Scan execution not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /security/scan/executionDetail/min: - get: - tags: - - Security Scans - summary: Get minimal scan execution detail - description: Retrieves minimal scan result information by application and environment - operationId: fetchMinScanResultByAppIdAndEnvId - parameters: - - name: appId - in: query - required: true - schema: - type: integer - example: 789 - - name: envId - in: query - required: true - schema: - type: integer - example: 101 - responses: - '200': - description: Minimal scan result retrieved successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: Scan result not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /security/scan/cve/exposure: - post: - tags: - - Vulnerability Management - summary: Get CVE vulnerability exposure - description: Retrieves vulnerability exposure information for a specific CVE - operationId: vulnerabilityExposure - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/VulnerabilityExposureRequest' - example: - cveId: "CVE-2025-1234" - appId: 123 - responses: - '200': - description: CVE exposure information retrieved successfully - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ApiResponse' - - type: object - properties: - result: - $ref: '#/components/schemas/ImageScanHistoryListingResponse' - '400': - description: Invalid request parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: CVE not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/kubernetes/kubernetes-resource-management.yaml b/specs/kubernetes/kubernetes-resource-management.yaml index 7b88427bcf..0ceb7573d2 100644 --- a/specs/kubernetes/kubernetes-resource-management.yaml +++ b/specs/kubernetes/kubernetes-resource-management.yaml @@ -1,22 +1,21 @@ -openapi: 3.0.3 +openapi: "3.0.3" info: - version: 1.0.0 - title: Devtron Orchestrator Kubernetes & Resource Management API - description: | - API specifications for Devtron orchestrator Kubernetes and resource management - including cluster management, namespace operations, pod status, and resource scaling. - termsOfService: https://devtron.ai/terms/ + title: Devtron Pod and Resource Management API + description: API specifications for pod logs, resource rotation, and Kubernetes resource management + version: "1.0.0" contact: name: Devtron Support email: support@devtron.ai - url: https://devtron.ai/support license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html servers: - - url: /orchestrator/k8s - description: Devtron Kubernetes API Server + - url: /orchestrator + description: Devtron Orchestrator API Server + +security: + - bearerAuth: [] components: securitySchemes: @@ -24,7 +23,6 @@ components: type: http scheme: bearer bearerFormat: JWT - description: JWT token for authentication schemas: ApiResponse: @@ -32,379 +30,106 @@ components: properties: code: type: integer - description: HTTP status code status: type: string - description: Status message result: type: object - description: Response result data ErrorResponse: type: object properties: code: type: integer - description: Error code status: type: string - description: Error status errors: type: array items: type: string - description: List of error messages - Cluster: + PodRotateRequest: type: object properties: - id: - type: integer - format: int64 - description: Cluster ID - clusterName: - type: string - description: Cluster name - serverUrl: - type: string - description: Kubernetes API server URL - active: - type: boolean - description: Whether the cluster is active - config: - type: object - description: Cluster configuration - prometheusUrl: - type: string - description: Prometheus URL for metrics - cd_argo_setup: - type: boolean - description: Whether ArgoCD is set up - errorInConnecting: - type: string - description: Error message if connection failed - isVirtualCluster: - type: boolean - description: Whether this is a virtual cluster - - Namespace: - type: object - properties: - name: - type: string - description: Namespace name - clusterId: - type: integer - format: int64 - description: Cluster ID - clusterName: - type: string - description: Cluster name - active: - type: boolean - description: Whether the namespace is active - labels: - type: object - additionalProperties: - type: string - description: Namespace labels - annotations: - type: object - additionalProperties: - type: string - description: Namespace annotations - creationTimestamp: - type: string - format: date-time - description: Namespace creation timestamp - - PodStatus: - type: object - properties: - name: - type: string - description: Pod name - namespace: - type: string - description: Pod namespace - clusterId: - type: integer - format: int64 - description: Cluster ID - status: - type: string - enum: [Running, Pending, Succeeded, Failed, Unknown] - description: Pod status - phase: - type: string - description: Pod phase - ready: - type: string - description: Ready status (e.g., "2/2") - restarts: - type: integer - description: Number of restarts - age: - type: string - description: Pod age - node: - type: string - description: Node name where pod is running - containers: + resources: type: array items: - $ref: '#/components/schemas/ContainerStatus' - description: Container statuses - labels: - type: object - additionalProperties: - type: string - description: Pod labels - creationTimestamp: - type: string - format: date-time - description: Pod creation timestamp - - ContainerStatus: - type: object - properties: - name: - type: string - description: Container name - ready: - type: boolean - description: Whether container is ready - restartCount: - type: integer - description: Container restart count - image: - type: string - description: Container image - state: - type: object - description: Container state - lastState: - type: object - description: Last container state - - ResourceRequest: - type: object - required: - - clusterId - - k8sRequest - properties: - clusterId: - type: integer - format: int64 - description: Cluster ID - k8sRequest: - type: object - description: Kubernetes resource request object - properties: - resourceIdentifier: - type: object - properties: - name: - type: string - namespace: - type: string - groupVersionKind: - type: object - properties: - group: - type: string - version: - type: string - kind: - type: string - patch: - type: string - description: JSON patch for resource updates - - ResourceListRequest: - type: object - required: - - clusterId - - k8sRequest - properties: - clusterId: - type: integer - format: int64 - description: Cluster ID - k8sRequest: - type: object - description: Kubernetes resource list request - properties: - resourceIdentifier: - type: object - properties: - groupVersionKind: - type: object - properties: - group: - type: string - version: - type: string - kind: - type: string - namespace: - type: string - - ResourceScalingRequest: - type: object - required: - - clusterId - - namespace - - resourceType - - resourceName - - replicas - properties: - clusterId: - type: integer - format: int64 - description: Cluster ID - namespace: - type: string - description: Kubernetes namespace - resourceType: - type: string - enum: [Deployment, StatefulSet, ReplicaSet] - description: Type of Kubernetes resource to scale - resourceName: - type: string - description: Name of the resource to scale - replicas: - type: integer - minimum: 0 - description: Desired number of replicas + $ref: '#/components/schemas/ResourceIdentifier' - ResourceScalingResponse: + ResourceIdentifier: type: object properties: - success: - type: boolean - description: Whether scaling was successful - currentReplicas: - type: integer - description: Current number of replicas - desiredReplicas: - type: integer - description: Desired number of replicas - message: + Group: type: string - description: Scaling operation message - - ClusterCapacity: - type: object - properties: - clusterId: - type: integer - format: int64 - description: Cluster ID - clusterName: + example: "" + Version: type: string - description: Cluster name - nodeCount: - type: integer - description: Total number of nodes - cpu: - $ref: '#/components/schemas/ResourceCapacity' - memory: - $ref: '#/components/schemas/ResourceCapacity' - storage: - $ref: '#/components/schemas/ResourceCapacity' - pods: - $ref: '#/components/schemas/ResourceCapacity' - - ResourceCapacity: - type: object - properties: - allocatable: + example: "v1" + Kind: type: string - description: Allocatable capacity - capacity: + example: "Pod" + Name: type: string - description: Total capacity - usage: + example: "my-pod" + Namespace: type: string - description: Current usage - usagePercentage: - type: number - format: float - description: Usage percentage + example: "default" - NodeInfo: + ResourceRotateRequest: type: object properties: - name: - type: string - description: Node name - clusterId: - type: integer - format: int64 - description: Cluster ID - status: + resourceId: type: string - enum: [Ready, NotReady, Unknown] - description: Node status - roles: - type: array - items: - type: string - description: Node roles - age: - type: string - description: Node age - version: - type: string - description: Kubernetes version - internalIP: - type: string - description: Internal IP address - externalIP: - type: string - description: External IP address - capacity: - $ref: '#/components/schemas/ResourceCapacity' - allocatable: - $ref: '#/components/schemas/ResourceCapacity' - conditions: - type: array - items: - type: object - description: Node conditions + example: "res-123" tags: - - name: Cluster Management - description: Operations for managing Kubernetes clusters - - name: Namespace Management - description: Operations for managing Kubernetes namespaces - - name: Pod Management - description: Operations for managing and monitoring pods - - name: Resource Scaling - description: Operations for scaling Kubernetes resources + - name: Pod Logs + description: Pod log retrieval operations + - name: Resource Management + description: Kubernetes resource management operations + - name: Pod Rotation + description: Pod rotation and restart operations paths: - /resource: - post: + /k8s/pods/logs/{podName}: + get: tags: - - Resource Management - summary: Get Kubernetes resource - description: Retrieves a specific Kubernetes resource - operationId: getResource - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ResourceRequest' + - Pod Logs + summary: Get pod logs + description: Retrieves logs from the specified pod and container + operationId: getPodLogs + parameters: + - name: podName + in: path + required: true + schema: + type: string + example: "my-app-pod-123" + - name: containerName + in: query + required: true + schema: + type: string + example: "main-container" + - name: follow + in: query + required: false + schema: + type: boolean + default: false + example: false responses: '200': - description: Resource retrieved successfully + description: Pod logs retrieved successfully + content: + text/plain: + schema: + type: string + '400': + description: Invalid parameters content: application/json: schema: - $ref: '#/components/schemas/ApiResponse' + $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: @@ -417,41 +142,8 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - put: - tags: - - Resource Management - summary: Update Kubernetes resource - description: Updates a specific Kubernetes resource - operationId: updateResource - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ResourceRequest' - responses: - '200': - description: Resource updated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/ApiResponse' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden + '404': + description: Pod not found content: application/json: schema: @@ -462,29 +154,41 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /resource/create: - post: + /k8s/pods/logs/download/{podName}: + get: tags: - - Resource Management - summary: Create Kubernetes resource - description: Creates a new Kubernetes resource - operationId: createResource - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ResourceRequest' + - Pod Logs + summary: Download pod logs + description: Downloads logs from the specified pod and container as a file + operationId: downloadPodLogs + parameters: + - name: podName + in: path + required: true + schema: + type: string + example: "my-app-pod-123" + - name: containerName + in: query + required: true + schema: + type: string + example: "main-container" responses: '200': - description: Resource created successfully + description: Pod logs file download + content: + application/octet-stream: + schema: + type: string + format: binary + '400': + description: Invalid parameters content: application/json: schema: - $ref: '#/components/schemas/ApiResponse' + $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: @@ -497,49 +201,62 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + '404': + description: Pod not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /resource/delete: + /k8s/resource/rotate: post: tags: - Resource Management - summary: Delete Kubernetes resource - description: Deletes a specific Kubernetes resource - operationId: deleteResource + summary: Rotate Kubernetes resource + description: Rotates the specified Kubernetes resource + operationId: rotateKubernetesResource + parameters: + - name: appId + in: query + required: true + schema: + type: integer + example: 123 requestBody: required: true content: application/json: schema: - $ref: '#/components/schemas/ResourceRequest' + $ref: '#/components/schemas/ResourceRotateRequest' + example: + resourceId: "res-123" responses: '200': - description: Resource deleted successfully + description: Resource rotated successfully content: application/json: schema: $ref: '#/components/schemas/ApiResponse' - '401': - description: Unauthorized + '400': + description: Invalid request parameters content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '403': - description: Forbidden + '401': + description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '404': - description: Resource not found + '403': + description: Forbidden content: application/json: schema: @@ -550,29 +267,40 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /resource/list: + /app/rotate-pods: post: tags: - - Resource Management - summary: List Kubernetes resources - description: Lists Kubernetes resources based on criteria - operationId: getResourceList + - Pod Rotation + summary: Rotate pods + description: Rotates the specified pods using resource identifiers + operationId: rotatePods requestBody: required: true content: application/json: schema: - $ref: '#/components/schemas/ResourceListRequest' + $ref: '#/components/schemas/PodRotateRequest' + example: + resources: + - Group: "" + Version: "v1" + Kind: "Pod" + Name: "my-pod" + Namespace: "default" responses: '200': - description: Resource list retrieved successfully + description: Pods rotated successfully content: application/json: schema: $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: @@ -591,28 +319,17 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /api-resources/{clusterId}: + /cluster/list: get: tags: - Resource Management - summary: Get API resources for cluster - description: Retrieves all available API resources for a specific cluster - operationId: getAllApiResources - parameters: - - name: clusterId - in: path - description: Cluster ID - required: true - schema: - type: integer - format: int64 - minimum: 1 + summary: Get cluster list + description: Retrieves a list of all available clusters + operationId: getClusterList responses: '200': - description: API resources retrieved successfully + description: List of clusters retrieved successfully content: application/json: schema: @@ -629,54 +346,27 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '404': - description: Cluster not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - /pods/logs/{podName}: + /cluster/namespaces: get: tags: - - Pod Management - summary: Get pod logs - description: Retrieves logs from a specific pod and container - operationId: getPodLogs - parameters: - - name: podName - in: path - description: Pod name - required: true - schema: - type: string - - name: containerName - in: query - description: Container name - required: true - schema: - type: string - - name: follow - in: query - description: Follow log stream - required: true - schema: - type: boolean + - Resource Management + summary: Get all cluster namespaces + description: Retrieves namespaces from all clusters + operationId: getAllClusterNamespaces responses: '200': - description: Pod logs retrieved successfully + description: All cluster namespaces retrieved successfully content: - text/plain: + application/json: schema: - type: string + $ref: '#/components/schemas/ApiResponse' '401': description: Unauthorized content: @@ -689,17 +379,9 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '404': - description: Pod not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] diff --git a/specs/security/security-dashboard-apis.yml b/specs/security/security-dashboard-apis.yml index a3e3bbb719..9517ddc487 100644 --- a/specs/security/security-dashboard-apis.yml +++ b/specs/security/security-dashboard-apis.yml @@ -1,16 +1,11 @@ -openapi: 3.0.3 +openapi: "3.0.3" info: - version: 1.0.0 title: Devtron Security Scan API - description: | - API for managing security scans and vulnerability assessments in Devtron. - Provides endpoints for scanning container images, retrieving scan results, - and managing vulnerability exposure across applications and environments. - termsOfService: https://devtron.ai/terms/ + description: API specifications for security scanning and vulnerability management in Devtron + version: "1.0.0" contact: name: Devtron Support email: support@devtron.ai - url: https://devtron.ai/support license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html @@ -19,491 +14,363 @@ servers: - url: /orchestrator description: Devtron Orchestrator API Server +security: + - bearerAuth: [] + components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT - description: JWT token for authentication - schemas: - Error: - description: Error object - type: object - required: - - code - - message - properties: - code: - type: integer - format: int32 - description: Error code - message: - type: string - description: Error message - ImageScanRequest: - description: Request object for image scan operations + schemas: + ApiResponse: type: object properties: - scanExecutionId: + code: type: integer - description: Scan execution ID - imageScanDeployInfoId: - type: integer - description: Image scan deploy info ID - appId: - type: integer - description: Application ID - envId: - type: integer - description: Environment ID - objectId: - type: integer - description: Object ID - artifactId: - type: integer - description: Artifact ID - image: + status: type: string - description: Image name - offset: - type: integer - description: Pagination offset - size: - type: integer - description: Page size + result: + type: object - ImageScanHistoryListingResponse: - description: Response containing list of scan history + ErrorResponse: type: object properties: - offset: - type: integer - description: Pagination offset - size: - type: integer - description: Page size - total: + code: type: integer - description: Total number of records - scanList: + status: + type: string + errors: type: array items: - $ref: '#/components/schemas/ImageScanHistoryResponse' + type: string - ImageScanHistoryResponse: - description: Individual scan history item + ImageScanRequest: type: object properties: imageScanDeployInfoId: type: integer - description: Image scan deploy info ID - appId: - type: integer - description: Application ID - envId: - type: integer - description: Environment ID - name: - type: string - description: Name of the scanned resource - type: - type: string - description: Type of the scanned resource - environment: - type: string - description: Environment name - lastChecked: - type: string - format: date-time - description: Last scan timestamp + example: 123 image: type: string - description: Image name - severityCount: - $ref: '#/components/schemas/SeverityCount' - - ImageScanExecutionDetail: - description: Detailed scan execution result - type: object - properties: - imageScanDeployInfoId: + example: "nginx:latest" + artifactId: type: integer - description: Image scan deploy info ID + example: 456 appId: type: integer - description: Application ID + example: 789 envId: type: integer - description: Environment ID - appName: - type: string - description: Application name - envName: - type: string - description: Environment name - pod: - type: string - description: Pod name - replicaSet: - type: string - description: ReplicaSet name - image: - type: string - description: Image name - vulnerabilities: - type: array - items: - $ref: '#/components/schemas/Vulnerability' - severityCount: - $ref: '#/components/schemas/SeverityCount' - executionTime: - type: string - format: date-time - description: Scan execution time - scanEnabled: - type: boolean - description: Whether scanning is enabled - scanned: - type: boolean - description: Whether the image has been scanned - objectType: - type: string - description: Type of the scanned object - scanToolId: - type: integer - description: ID of the scan tool used - scanToolName: - type: string - description: Name of the scan tool - scanToolUrl: - type: string - description: URL of the scan tool - status: - type: string - description: Scan execution status - enum: - - RUNNING - - COMPLETED - - FAILED - - CANCELLED - - SeverityCount: - description: Count of vulnerabilities by severity - type: object - properties: - critical: - type: integer - description: Number of critical vulnerabilities - high: - type: integer - description: Number of high severity vulnerabilities - medium: - type: integer - description: Number of medium severity vulnerabilities - low: + example: 101 + size: type: integer - description: Number of low severity vulnerabilities - unknown: + example: 20 + offset: type: integer - description: Number of unknown severity vulnerabilities + example: 0 - Vulnerability: - description: Individual vulnerability details + ImageScanHistoryResponse: type: object properties: - cveName: - type: string - description: CVE identifier - severity: - type: string - description: Vulnerability severity - enum: - - CRITICAL - - HIGH - - MEDIUM - - LOW - - UNKNOWN - package: - type: string - description: Affected package name - currentVersion: - type: string - description: Current version of the package - fixedVersion: - type: string - description: Version where the vulnerability is fixed - permission: - type: string - description: Permission level - target: - type: string - description: Target of the vulnerability - class: - type: string - description: Vulnerability class - type: + imageScanDeployInfoId: + type: integer + image: type: string - description: Vulnerability type - - VulnerabilityRequest: - description: Request for vulnerability exposure data - type: object - properties: - appName: + tag: type: string - description: Application name filter - cveName: + appId: + type: integer + envId: + type: integer + executedOn: type: string - description: CVE name filter - envIds: - type: array - items: - type: integer - description: Environment IDs to filter by - clusterIds: + format: date-time + executionHistory: type: array items: - type: integer - description: Cluster IDs to filter by - offset: - type: integer - description: Pagination offset - size: - type: integer - description: Page size + type: object - VulnerabilityExposureListingResponse: - description: Response containing vulnerability exposure data + ImageScanHistoryListingResponse: type: object properties: - offset: - type: integer - description: Pagination offset - size: - type: integer - description: Page size - total: - type: integer - description: Total number of records - list: + imageScanHistoryResponse: type: array items: - $ref: '#/components/schemas/VulnerabilityExposure' + $ref: '#/components/schemas/ImageScanHistoryResponse' - VulnerabilityExposure: - description: Vulnerability exposure information + VulnerabilityExposureRequest: type: object properties: - appName: + cveId: type: string - description: Application name - envName: - type: string - description: Environment name + example: "CVE-2025-1234" appId: type: integer - description: Application ID - envId: - type: integer - description: Environment ID - appType: - type: string - description: Application type - enum: - - DEVTRON_APP - - HELM_APP - - EXTERNAL_HELM_APP - blocked: - type: boolean - description: Whether the vulnerability is blocked + example: 123 + +tags: + - name: Security Scans + description: Security scanning operations + - name: Vulnerability Management + description: Vulnerability exposure and policy management paths: - /orchestrator/security/scan/list: + /security/scan/list: post: tags: - - Security Scanning - summary: Get list of scan executions - description: Fetch scan execution history with filtering options + - Security Scans + summary: Get scan execution list + description: Retrieves a list of security scan executions based on the provided criteria operationId: scanExecutionList - security: - - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ImageScanRequest' + example: + imageScanDeployInfoId: 123 + image: "nginx:latest" + artifactId: 456 + appId: 789 + envId: 101 + size: 20 + offset: 0 responses: '200': - description: List of scan executions + description: Scan execution list retrieved successfully content: application/json: schema: - $ref: '#/components/schemas/ImageScanHistoryListingResponse' + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ImageScanHistoryListingResponse' '400': - description: Bad request + description: Invalid request parameters content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' - /orchestrator/security/scan/executionDetail: + /security/scan/executionDetail: get: tags: - - Security Scanning - summary: Fetch image scan execution result - description: Get detailed scan results by multiple ways for different use cases. At least one parameter is required. + - Security Scans + summary: Get scan execution detail + description: Retrieves detailed information about a specific scan execution operationId: fetchExecutionDetail - security: - - bearerAuth: [] parameters: - name: imageScanDeployInfoId in: query - description: Image scan deploy info ID for fetching scan result required: false schema: type: integer + example: 123 + - name: image + in: query + required: false + schema: + type: string + example: "nginx:latest" - name: artifactId in: query - description: CI artifact ID to fetch scan result for image required: false schema: type: integer + example: 456 - name: appId in: query - description: Application ID for fetching scan result required: false schema: type: integer + example: 789 - name: envId in: query - description: Environment ID for fetching scan result required: false schema: type: integer - - name: image + example: 101 + - name: executionId in: query - description: Image name to fetch scan result for required: false schema: - type: string + type: integer + example: 999 responses: '200': - description: Scan execution details + description: Scan execution detail retrieved successfully content: application/json: schema: - $ref: '#/components/schemas/ImageScanExecutionDetail' + $ref: '#/components/schemas/ApiResponse' '400': - description: Bad request + description: Invalid request parameters content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Scan execution not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' - /orchestrator/security/scan/executionDetail/min: + /security/scan/executionDetail/min: get: tags: - - Security Scanning - summary: Fetch minimal scan result by app and environment ID - description: Get minimal scan result information for a specific app and environment - operationId: fetchMinScanResult - security: - - bearerAuth: [] + - Security Scans + summary: Get minimal scan execution detail + description: Retrieves minimal scan result information by application and environment + operationId: fetchMinScanResultByAppIdAndEnvId parameters: - name: appId in: query - description: Application ID required: true schema: type: integer + example: 789 - name: envId in: query - description: Environment ID required: true schema: type: integer + example: 101 responses: '200': - description: Minimal scan execution details + description: Minimal scan result retrieved successfully content: application/json: schema: - $ref: '#/components/schemas/ImageScanExecutionDetail' + $ref: '#/components/schemas/ApiResponse' '400': - description: Bad request + description: Invalid request parameters content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Scan result not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' - /orchestrator/security/scan/cve/exposure: + /security/scan/cve/exposure: post: tags: - - Security Scanning - summary: Get vulnerability exposure information - description: Fetch vulnerability exposure data across applications and environments + - Vulnerability Management + summary: Get CVE vulnerability exposure + description: Retrieves vulnerability exposure information for a specific CVE operationId: vulnerabilityExposure - security: - - bearerAuth: [] requestBody: required: true content: application/json: schema: - $ref: '#/components/schemas/VulnerabilityRequest' + $ref: '#/components/schemas/VulnerabilityExposureRequest' + example: + cveId: "CVE-2025-1234" + appId: 123 responses: '200': - description: Vulnerability exposure data + description: CVE exposure information retrieved successfully content: application/json: schema: - $ref: '#/components/schemas/VulnerabilityExposureListingResponse' + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ImageScanHistoryListingResponse' '400': - description: Bad request + description: Invalid request parameters content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: CVE not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' \ No newline at end of file + $ref: '#/components/schemas/ErrorResponse' diff --git a/specs/template/config-maps.yaml b/specs/template/config-maps.yaml index ee38a92de0..5e44e49c11 100644 --- a/specs/template/config-maps.yaml +++ b/specs/template/config-maps.yaml @@ -1,23 +1,7 @@ openapi: "3.0.3" info: title: Devtron ConfigMap and Secret Management API - description: | - API for managing global and environment-specific ConfigMaps and Secrets in Devtron. - - **IMPORTANT PATH CORRECTIONS:** - - Frontend uses: `/orchestrator/global/cm/{appId}` - - Actual codebase: `/orchestrator/config/global/cm/{appId}` - - Frontend uses: `/orchestrator/global/cs/{appId}` - - Actual codebase: `/orchestrator/config/global/cs/{appId}` - - **MISSING PUT METHODS:** - - The codebase only has POST methods for create/update (CMGlobalAddUpdate, CSGlobalAddUpdate) - - PUT methods for individual updates don't exist in the current implementation - - Frontend expects PUT methods for `/global/cm/{appId}/{id}` and `/global/cs/{appId}/{id}` - - **PAYLOAD STRUCTURE MISMATCH:** - - Frontend sends: `{name: "string", data: {key: "value"}}` - - Codebase expects: `ConfigDataRequest` with complex nested `ConfigData` arrays + description: API specifications for ConfigMap and Secret management in Devtron orchestrator version: "1.0.0" contact: name: Devtron Support @@ -30,19 +14,123 @@ servers: - url: /orchestrator description: Devtron Orchestrator API Server +security: + - bearerAuth: [] + components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT - description: JWT token for authentication + + schemas: + ApiResponse: + type: object + properties: + code: + type: integer + status: + type: string + result: + type: object + + ErrorResponse: + type: object + properties: + code: + type: integer + status: + type: string + errors: + type: array + items: + type: string + + ConfigDataRequest: + type: object + required: + - appId + - configData + properties: + id: + type: integer + example: 0 + appId: + type: integer + example: 123 + environmentId: + type: integer + example: 456 + configData: + type: array + items: + $ref: '#/components/schemas/ConfigData' + isDeletable: + type: boolean + default: true + + ConfigData: + type: object + required: + - name + - type + properties: + name: + type: string + example: "global-configmap" + type: + type: string + enum: ["CONFIGMAP", "SECRET"] + example: "CONFIGMAP" + external: + type: boolean + default: false + mountPath: + type: string + example: "/etc/config" + data: + type: object + additionalProperties: + type: string + example: + key1: "value1" + key2: "value2" + global: + type: boolean + default: true + subPath: + type: boolean + default: false + filePermission: + type: string + example: "0644" + + ConfigsList: + type: object + properties: + maps: + type: array + items: + $ref: '#/components/schemas/ConfigData' + +tags: + - name: Global ConfigMaps + description: Global ConfigMap management + - name: Global Secrets + description: Global Secret management + - name: Environment ConfigMaps + description: Environment-specific ConfigMap operations + - name: Environment Secrets + description: Environment-specific Secret operations paths: - # ===== ACTUAL CODEBASE ENDPOINTS ===== /config/global/cm: post: - description: Create or update a global ConfigMap + tags: + - Global ConfigMaps + summary: Create or update global ConfigMap + description: Creates a new global ConfigMap or updates an existing one operationId: CMGlobalAddUpdate requestBody: required: true @@ -50,83 +138,119 @@ paths: application/json: schema: $ref: '#/components/schemas/ConfigDataRequest' + example: + id: 0 + appId: 123 + configData: + - name: "global-configmap" + type: "CONFIGMAP" + external: false + mountPath: "/etc/config" + data: + key1: "value1" + key2: "value2" + global: true + subPath: false + filePermission: "0644" + isDeletable: true responses: '200': - description: Successfully created/updated ConfigMap + description: ConfigMap created/updated successfully content: application/json: schema: - $ref: '#/components/schemas/ConfigDataRequest' + $ref: '#/components/schemas/ApiResponse' '400': - description: Bad request + description: Invalid request parameters content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': - description: Unauthorized user + description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '403': - description: Forbidden, user is not authorized + description: Forbidden content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' - /config/environment/cm: + /config/global/cs: post: - description: Create or update an environment-specific ConfigMap - operationId: CMEnvironmentAddUpdate + tags: + - Global Secrets + summary: Create or update global Secret + description: Creates a new global Secret or updates an existing one + operationId: CSGlobalAddUpdate requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ConfigDataRequest' + example: + id: 0 + appId: 123 + configData: + - name: "global-secret" + type: "SECRET" + external: false + mountPath: "/etc/secrets" + data: + username: "admin" + password: "s3cr3t" + global: true + subPath: false + filePermission: "0600" + isDeletable: true responses: '200': - description: Successfully created/updated ConfigMap + description: Secret created/updated successfully content: application/json: schema: - $ref: '#/components/schemas/ConfigDataRequest' + $ref: '#/components/schemas/ApiResponse' '400': - description: Bad request + description: Invalid request parameters content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': - description: Unauthorized user + description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '403': - description: Forbidden, user is not authorized + description: Forbidden content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' - /orchestrator/config/global/cm/{appId}: + /config/global/cm/{appId}: get: - description: Get all global ConfigMaps for an application + tags: + - Global ConfigMaps + summary: Get global ConfigMaps for application + description: Retrieves all global ConfigMaps for the specified application operationId: CMGlobalFetch parameters: - name: appId @@ -134,858 +258,103 @@ paths: required: true schema: type: integer + example: 123 responses: '200': - description: Successfully retrieved ConfigMaps - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/environment/cm/{appId}/{envId}: - get: - description: Get all environment-specific ConfigMaps for an application - operationId: CMEnvironmentFetch - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: envId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Successfully retrieved ConfigMaps + description: Global ConfigMaps retrieved successfully content: application/json: schema: - $ref: '#/components/schemas/ConfigDataRequest' + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ConfigsList' '400': - description: Bad request + description: Invalid application ID content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': - description: Unauthorized user + description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/global/cm/edit/{appId}/{id}: - get: - description: Get a global ConfigMap for editing - operationId: CMGlobalFetchForEdit - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string - responses: - '200': - description: Successfully retrieved ConfigMap - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user + description: Forbidden content: application/json: schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application not found content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' - /orchestrator/config/environment/cm/edit/{appId}/{envId}/{id}: + /config/global/cs/{appId}: get: - description: Get an environment-specific ConfigMap for editing - operationId: CMEnvironmentFetchForEdit - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: envId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string - responses: - '200': - description: Successfully retrieved ConfigMap - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/global/cm/{appId}/{id}: - delete: - description: Delete a global ConfigMap - operationId: CMGlobalDelete - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string - responses: - '200': - description: Successfully deleted ConfigMap - content: - application/json: - schema: - type: boolean - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/environment/cm/{appId}/{envId}/{id}: - delete: - description: Delete an environment-specific ConfigMap - operationId: CMEnvironmentDelete + tags: + - Global Secrets + summary: Get global Secrets for application + description: Retrieves all global Secrets for the specified application + operationId: CSGlobalFetch parameters: - name: appId in: path required: true schema: type: integer - - name: envId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string + example: 123 responses: '200': - description: Successfully deleted ConfigMap + description: Global Secrets retrieved successfully content: application/json: schema: - type: boolean + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ConfigsList' '400': - description: Bad request + description: Invalid application ID content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '401': - description: Unauthorized user + description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/global/cs: - post: - description: Create or update a global Secret - operationId: CSGlobalAddUpdate - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - responses: - '200': - description: Successfully created/updated Secret - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user + description: Forbidden content: application/json: schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application not found content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error content: application/json: schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/environment/cs: - post: - description: Create or update an environment-specific Secret - operationId: CSEnvironmentAddUpdate - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - responses: - '200': - description: Successfully created/updated Secret - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/global/cs/{appId}: - get: - description: Get all global Secrets for an application - operationId: CSGlobalFetch - parameters: - - name: appId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Successfully retrieved Secrets - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/environment/cs/{appId}/{envId}: - get: - description: Get all environment-specific Secrets for an application - operationId: CSEnvironmentFetch - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: envId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Successfully retrieved Secrets - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/global/cs/edit/{appId}/{id}: - get: - description: Get a global Secret for editing - operationId: CSGlobalFetchForEdit - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string - responses: - '200': - description: Successfully retrieved Secret - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/environment/cs/edit/{appId}/{envId}/{id}: - get: - description: Get an environment-specific Secret for editing - operationId: CSEnvironmentFetchForEdit - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: envId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string - responses: - '200': - description: Successfully retrieved Secret - content: - application/json: - schema: - $ref: '#/components/schemas/ConfigDataRequest' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/global/cs/{appId}/{id}: - delete: - description: Delete a global Secret - operationId: CSGlobalDelete - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string - responses: - '200': - description: Successfully deleted Secret - content: - application/json: - schema: - type: boolean - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/environment/cs/{appId}/{envId}/{id}: - delete: - description: Delete an environment-specific Secret - operationId: CSEnvironmentDelete - parameters: - - name: appId - in: path - required: true - schema: - type: integer - - name: envId - in: path - required: true - schema: - type: integer - - name: id - in: path - required: true - schema: - type: integer - - name: name - in: query - required: true - schema: - type: string - responses: - '200': - description: Successfully deleted Secret - content: - application/json: - schema: - type: boolean - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /orchestrator/config/bulk/patch: - post: - description: Bulk patch ConfigMaps and Secrets - operationId: ConfigSecretBulkPatch - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/BulkPatchRequest' - responses: - '200': - description: Successfully patched ConfigMaps and Secrets - content: - application/json: - schema: - type: boolean - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized user - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '403': - description: Forbidden, user is not authorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - -components: - schemas: - ConfigDataRequest: - type: object - required: - - appId - - userId - - configData - properties: - id: - type: integer - description: ID of the ConfigMap/Secret - appId: - type: integer - description: ID of the application - userId: - type: integer - description: ID of the user making the request - environmentId: - type: integer - description: ID of the environment (for environment-specific ConfigMaps/Secrets) - configData: - type: array - items: - $ref: '#/components/schemas/ConfigData' - - ConfigData: - type: object - required: - - name - - type - properties: - id: - type: integer - description: ID of the ConfigMap/Secret - name: - type: string - description: Name of the ConfigMap/Secret - type: - type: string - enum: [CONFIGMAP, SECRET] - description: Type of the configuration (ConfigMap or Secret) - external: - type: boolean - description: Whether this is an external ConfigMap/Secret - data: - type: object - additionalProperties: - type: string - description: Key-value pairs for the ConfigMap/Secret - mountPath: - type: string - description: Path where the ConfigMap/Secret should be mounted - subPath: - type: string - description: Subpath within the mount path - filePermission: - type: string - description: File permissions for the mounted ConfigMap/Secret - externalSecretType: - type: string - description: Type of external secret (for Secrets only) - roleARN: - type: string - description: ARN of the role to use for external secrets (for Secrets only) - externalSecret: - type: array - items: - $ref: '#/components/schemas/ExternalSecret' - description: External secret configuration (for Secrets only) - - ExternalSecret: - type: object - required: - - name - - key - properties: - name: - type: string - description: Name of the external secret - key: - type: string - description: Key in the external secret store - property: - type: string - description: Property to extract from the external secret - isBinary: - type: boolean - description: Whether the secret value is binary - - BulkPatchRequest: - type: object - required: - - userId - - global - properties: - userId: - type: integer - description: ID of the user making the request - global: - type: boolean - description: Whether to patch global or environment-specific ConfigMaps/Secrets - appId: - type: integer - description: ID of the application - environmentId: - type: integer - description: ID of the environment (for environment-specific patches) - configData: - type: array - items: - $ref: '#/components/schemas/ConfigData' - - Error: - type: object - required: - - code - - message - properties: - code: - type: integer - description: Error code - message: - type: string - description: Error message + $ref: '#/components/schemas/ErrorResponse' From 1808f061cf627f52bc98166515b32d7d85d1f501 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Wed, 17 Sep 2025 11:59:18 +0530 Subject: [PATCH 8/9] chore: resolving review comments --- .../template/configmap-secret-corrected.yaml | 589 ++++++------------ 1 file changed, 196 insertions(+), 393 deletions(-) diff --git a/specs/template/configmap-secret-corrected.yaml b/specs/template/configmap-secret-corrected.yaml index 53003bd2b3..7ff2ed2017 100644 --- a/specs/template/configmap-secret-corrected.yaml +++ b/specs/template/configmap-secret-corrected.yaml @@ -1,34 +1,7 @@ openapi: "3.0.3" info: - title: Devtron ConfigMap and Secret Management API (CORRECTED) - description: | - **CORRECTED API SPECIFICATIONS** for ConfigMap and Secret management in Devtron. - - ## 🚨 CRITICAL ISSUES FOUND: - - ### 1. **PATH MISMATCHES** ❌ - - **Frontend expects**: `/orchestrator/global/cm/{appId}` - - **Actual codebase**: `/orchestrator/config/global/cm/{appId}` - - **Frontend expects**: `/orchestrator/global/cs/{appId}` - - **Actual codebase**: `/orchestrator/config/global/cs/{appId}` - - ### 2. **MISSING PUT METHODS** ❌ - - **Frontend expects**: `PUT /orchestrator/global/cm/{appId}/{id}` - - **Actual codebase**: Only has `POST /config/global/cm` (CMGlobalAddUpdate) - - **Frontend expects**: `PUT /orchestrator/global/cs/{appId}/{id}` - - **Actual codebase**: Only has `POST /config/global/cs` (CSGlobalAddUpdate) - - ### 3. **PAYLOAD STRUCTURE MISMATCH** ❌ - - **Frontend sends**: `{name: "global-configmap", data: {key1: "value1"}}` - - **Codebase expects**: `ConfigDataRequest` with complex nested structure - - ## ✅ CORRECTED SPECIFICATIONS BELOW - - This specification includes: - - **Actual codebase endpoints** (what currently exists) - - **Missing endpoints** your frontend needs (marked as TODO) - - **Correct payload structures** based on codebase analysis - - **Frontend-compatible examples** matching your provided payloads + title: Devtron ConfigMap and Secret Management API + description: API specifications for ConfigMap and Secret management in Devtron orchestrator version: "1.0.0" contact: name: Devtron Support @@ -41,13 +14,15 @@ servers: - url: /orchestrator description: Devtron Orchestrator API Server +security: + - bearerAuth: [] + components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT - description: JWT token for authentication schemas: ApiResponse: @@ -55,83 +30,63 @@ components: properties: code: type: integer - description: HTTP status code status: type: string - description: Response status result: type: object - description: Response data ErrorResponse: type: object properties: code: type: integer - description: Error code status: type: string - description: Error status errors: type: array items: type: string - description: List of error messages - # Based on pkg/pipeline/bean/ConfigDataRequest from codebase ConfigDataRequest: type: object - description: | - **ACTUAL CODEBASE STRUCTURE** - This is what the handlers expect. - Your frontend payloads need to be transformed to this structure. + description: Configuration data request structure for ConfigMap and Secret operations required: - appId - configData properties: id: type: integer - description: ID of the ConfigMap/Secret (0 for new) example: 0 appId: type: integer - description: Application ID example: 123 environmentId: type: integer - description: Environment ID (for environment-specific configs) example: 456 configData: type: array - description: Array of ConfigData objects items: $ref: '#/components/schemas/ConfigData' isDeletable: type: boolean - description: Whether the config is deletable default: true - # Based on pkg/pipeline/bean/ConfigData from codebase ConfigData: type: object - description: | - **ACTUAL CODEBASE STRUCTURE** - Individual ConfigMap or Secret data. - Your frontend's simple {name, data} structure needs transformation. + description: Individual ConfigMap or Secret data structure required: - name - type properties: name: type: string - description: Name of the ConfigMap/Secret example: "global-configmap" type: type: string - description: Type of configuration enum: ["CONFIGMAP", "SECRET"] example: "CONFIGMAP" external: type: boolean - description: Whether this is an external ConfigMap/Secret default: false mountPath: type: string @@ -139,11 +94,7 @@ components: example: "/etc/config" data: type: object - description: | - **KEY DIFFERENCE**: Your frontend sends simple key-value pairs, - but codebase expects JSON RawMessage format. - Frontend: {"key1": "value1", "key2": "value2"} - Codebase: JSON.RawMessage containing the above + description: Key-value pairs for ConfigMap or Secret data additionalProperties: type: string example: @@ -151,103 +102,63 @@ components: key2: "value2" global: type: boolean - description: Whether this is a global configuration default: true subPath: type: boolean - description: Whether to use subPath mounting default: false filePermission: type: string description: File permissions for mounted files example: "0644" - # Frontend-compatible simple structure (what your FE actually sends) - SimpleFrontendPayload: + ConfigsList: type: object - description: | - **FRONTEND PAYLOAD STRUCTURE** - This is what your frontend actually sends. - This needs to be transformed to ConfigDataRequest structure. - required: - - name - - data properties: - name: - type: string - description: ConfigMap/Secret name - example: "global-configmap" - data: - type: object - description: Simple key-value pairs - additionalProperties: - type: string - example: - key1: "value1" - key2: "value2" + maps: + type: array + items: + $ref: '#/components/schemas/ConfigData' tags: - name: Global ConfigMaps - description: Operations for global ConfigMaps (available across all environments) + description: Operations for global ConfigMaps - name: Global Secrets - description: Operations for global Secrets (available across all environments) + description: Operations for global Secrets - name: Environment ConfigMaps description: Operations for environment-specific ConfigMaps - name: Environment Secrets description: Operations for environment-specific Secrets - - name: Missing Endpoints - description: Endpoints your frontend expects but don't exist in codebase paths: - # ===== ACTUAL CODEBASE ENDPOINTS (WORKING) ===== - /config/global/cm: post: tags: - Global ConfigMaps summary: Create or update global ConfigMap - description: | - **ACTUAL CODEBASE ENDPOINT** ✅ - Handler: CMGlobalAddUpdate - Path: /orchestrator/config/global/cm - Method: POST (handles both create and update) - - **PAYLOAD TRANSFORMATION NEEDED:** - Your frontend sends: `{name: "global-configmap", data: {key1: "value1"}}` - But codebase expects: `ConfigDataRequest` structure (see schema below) + description: Creates a new global ConfigMap or updates an existing one operationId: CMGlobalAddUpdate requestBody: - description: ConfigMap configuration request (codebase structure) + description: ConfigMap configuration request required: true content: application/json: schema: $ref: '#/components/schemas/ConfigDataRequest' - examples: - frontend_compatible: - summary: Transformed from your frontend payload - description: | - Your frontend payload: - ```json - { - "name": "global-configmap", - "data": {"key1": "value1", "key2": "value2"} - } - ``` - - Needs to be transformed to: - value: - appId: 123 - configData: - - name: "global-configmap" - type: "CONFIGMAP" - external: false - global: true - data: - key1: "value1" - key2: "value2" - mountPath: "/etc/config" - subPath: false - filePermission: "0644" + example: + id: 0 + appId: 123 + configData: + - name: "global-configmap" + type: "CONFIGMAP" + external: false + mountPath: "/etc/config" + data: + key1: "value1" + key2: "value2" + global: true + subPath: false + filePermission: "0644" + isDeletable: true responses: '200': description: ConfigMap created/updated successfully @@ -256,7 +167,7 @@ paths: schema: $ref: '#/components/schemas/ApiResponse' '400': - description: Invalid request format or validation error + description: Invalid request parameters content: application/json: schema: @@ -279,57 +190,36 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] /config/global/cs: post: tags: - Global Secrets summary: Create or update global Secret - description: | - **ACTUAL CODEBASE ENDPOINT** ✅ - Handler: CSGlobalAddUpdate - Path: /orchestrator/config/global/cs - Method: POST (handles both create and update) - - **PAYLOAD TRANSFORMATION NEEDED:** - Your frontend sends: `{name: "global-secret", data: {username: "admin", password: "s3cr3t"}}` - But codebase expects: `ConfigDataRequest` structure + description: Creates a new global Secret or updates an existing one operationId: CSGlobalAddUpdate requestBody: - description: Secret configuration request (codebase structure) + description: Secret configuration request required: true content: application/json: schema: $ref: '#/components/schemas/ConfigDataRequest' - examples: - frontend_compatible: - summary: Transformed from your frontend payload - description: | - Your frontend payload: - ```json - { - "name": "global-secret", - "data": {"username": "admin", "password": "s3cr3t"} - } - ``` - - Needs to be transformed to: - value: - appId: 123 - configData: - - name: "global-secret" - type: "SECRET" - external: false - global: true - data: - username: "admin" - password: "s3cr3t" - mountPath: "/etc/secrets" - subPath: false - filePermission: "0600" + example: + id: 0 + appId: 123 + configData: + - name: "global-secret" + type: "SECRET" + external: false + mountPath: "/etc/secrets" + data: + username: "admin" + password: "s3cr3t" + global: true + subPath: false + filePermission: "0600" + isDeletable: true responses: '200': description: Secret created/updated successfully @@ -338,7 +228,7 @@ paths: schema: $ref: '#/components/schemas/ApiResponse' '400': - description: Invalid request format or validation error + description: Invalid request parameters content: application/json: schema: @@ -361,25 +251,14 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - # ===== MISSING ENDPOINTS YOUR FRONTEND NEEDS ===== - - /global/cm/{appId}: + /config/global/cm/{appId}: get: tags: - - Missing Endpoints - summary: "❌ MISSING: Get global ConfigMaps (Frontend Path)" - description: | - **MISSING ENDPOINT** ❌ - - **Frontend expects**: `GET /orchestrator/global/cm/{appId}` - **Actual codebase**: `GET /orchestrator/config/global/cm/{appId}` - - **SOLUTION**: Update your frontend to use the correct path: - `/orchestrator/config/global/cm/{appId}` - operationId: CMGlobalFetchFrontendPath + - Global ConfigMaps + summary: Get global ConfigMaps for application + description: Retrieves all global ConfigMaps for the specified application + operationId: CMGlobalFetch parameters: - name: appId in: path @@ -388,145 +267,55 @@ paths: type: integer example: 123 responses: - '501': - description: | - **ENDPOINT DOES NOT EXIST** - Use `/orchestrator/config/global/cm/{appId}` instead + '200': + description: Global ConfigMaps retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ConfigsList' + '400': + description: Invalid application ID content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - - /global/cs/{appId}: - get: - tags: - - Missing Endpoints - summary: "❌ MISSING: Get global Secrets (Frontend Path)" - description: | - **MISSING ENDPOINT** ❌ - - **Frontend expects**: `GET /orchestrator/global/cs/{appId}` - **Actual codebase**: `GET /orchestrator/config/global/cs/{appId}` - - **SOLUTION**: Update your frontend to use the correct path: - `/orchestrator/config/global/cs/{appId}` - operationId: CSGlobalFetchFrontendPath - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - responses: - '501': - description: | - **ENDPOINT DOES NOT EXIST** - Use `/orchestrator/config/global/cs/{appId}` instead + '401': + description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - - /global/cm/{appId}/{id}: - get: - tags: - - Missing Endpoints - summary: "❌ MISSING: Get global ConfigMap by ID (Frontend Path)" - description: | - **MISSING ENDPOINT** ❌ - - **Frontend expects**: `GET /orchestrator/global/cm/{appId}/{id}` - **Actual codebase**: `GET /orchestrator/config/global/cm/edit/{appId}/{id}?name={name}` - - **SOLUTION**: Update your frontend to use the correct path and add name query parameter - operationId: CMGlobalGetByIdFrontendPath - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - - name: id - in: path - required: true - schema: - type: integer - example: 1 - responses: - '501': - description: | - **ENDPOINT DOES NOT EXIST** - Use `/orchestrator/config/global/cm/edit/{appId}/{id}?name={name}` instead + '403': + description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - - put: - tags: - - Missing Endpoints - summary: "❌ MISSING: Update global ConfigMap by ID" - description: | - **MISSING ENDPOINT** ❌ - - **Frontend expects**: `PUT /orchestrator/global/cm/{appId}/{id}` - **Actual codebase**: Only has `POST /orchestrator/config/global/cm` (handles both create/update) - - **SOLUTION**: Use the existing POST endpoint with the ConfigMap ID in the payload - operationId: CMGlobalUpdateByIdFrontendPath - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - - name: id - in: path - required: true - schema: - type: integer - example: 1 - requestBody: - description: | - **FRONTEND PAYLOAD** (needs transformation): - Your frontend sends: `{name: "global-configmap", data: {key1: "new-value"}}` - - **SOLUTION**: Transform to ConfigDataRequest and use POST /config/global/cm - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/SimpleFrontendPayload' - example: - name: "global-configmap" - data: - key1: "new-value" - responses: - '501': - description: | - **ENDPOINT DOES NOT EXIST** - Transform payload and use `POST /orchestrator/config/global/cm` instead + '404': + description: Application not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - /global/cs/{appId}/{id}: + /config/global/cs/{appId}: get: tags: - - Missing Endpoints - summary: "❌ MISSING: Get global Secret by ID (Frontend Path)" - description: | - **MISSING ENDPOINT** ❌ - - **Frontend expects**: `GET /orchestrator/global/cs/{appId}/{id}` - **Actual codebase**: `GET /orchestrator/config/global/cs/edit/{appId}/{id}?name={name}` - - **SOLUTION**: Update your frontend to use the correct path and add name query parameter - operationId: CSGlobalGetByIdFrontendPath + - Global Secrets + summary: Get global Secrets for application + description: Retrieves all global Secrets for the specified application + operationId: CSGlobalFetch parameters: - name: appId in: path @@ -534,134 +323,150 @@ paths: schema: type: integer example: 123 - - name: id - in: path - required: true - schema: - type: integer - example: 1 responses: - '501': - description: | - **ENDPOINT DOES NOT EXIST** - Use `/orchestrator/config/global/cs/edit/{appId}/{id}?name={name}` instead + '200': + description: Global Secrets retrieved successfully + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/ApiResponse' + - type: object + properties: + result: + $ref: '#/components/schemas/ConfigsList' + '400': + description: Invalid application ID + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Application not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - put: + /config/environment/cm: + post: tags: - - Missing Endpoints - summary: "❌ MISSING: Update global Secret by ID" - description: | - **MISSING ENDPOINT** ❌ - - **Frontend expects**: `PUT /orchestrator/global/cs/{appId}/{id}` - **Actual codebase**: Only has `POST /orchestrator/config/global/cs` (handles both create/update) - - **SOLUTION**: Use the existing POST endpoint with the Secret ID in the payload - operationId: CSGlobalUpdateByIdFrontendPath - parameters: - - name: appId - in: path - required: true - schema: - type: integer - example: 123 - - name: id - in: path - required: true - schema: - type: integer - example: 1 + - Environment ConfigMaps + summary: Create or update environment-specific ConfigMap + description: Creates a new environment-specific ConfigMap or updates an existing one + operationId: CMEnvironmentAddUpdate requestBody: - description: | - **FRONTEND PAYLOAD** (needs transformation): - Your frontend sends: `{name: "global-secret", data: {username: "new-admin", password: "new-password"}}` - - **SOLUTION**: Transform to ConfigDataRequest and use POST /config/global/cs + description: Environment ConfigMap configuration request required: true content: application/json: schema: - $ref: '#/components/schemas/SimpleFrontendPayload' + $ref: '#/components/schemas/ConfigDataRequest' example: - name: "global-secret" - data: - username: "updated-admin" - password: "updated-password" + id: 0 + appId: 123 + environmentId: 456 + configData: + - name: "env-configmap" + type: "CONFIGMAP" + external: false + mountPath: "/etc/env-config" + data: + envKey: "envValue" + environment: "production" + global: false + subPath: false + filePermission: "0644" + isDeletable: true responses: - '501': - description: | - **ENDPOINT DOES NOT EXIST** - Transform payload and use `POST /orchestrator/config/global/cs` instead + '200': + description: Environment ConfigMap created/updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - # ===== ENVIRONMENT-SPECIFIC ENDPOINTS ===== - - /config/environment/cm: + /config/environment/cs: post: tags: - - Environment ConfigMaps - summary: Create or update environment-specific ConfigMap - description: | - **ACTUAL CODEBASE ENDPOINT** ✅ - Handler: CMEnvironmentAddUpdate - Path: /orchestrator/config/environment/cm - Method: POST (handles both create and update) - - **PAYLOAD TRANSFORMATION NEEDED:** - Your frontend sends: `{appId: 123, envId: 456, name: "env-configmap", data: {envKey: "envValue"}}` - But codebase expects: `ConfigDataRequest` structure with environmentId - operationId: CMEnvironmentAddUpdate + - Environment Secrets + summary: Create or update environment-specific Secret + description: Creates a new environment-specific Secret or updates an existing one + operationId: CSEnvironmentAddUpdate requestBody: - description: Environment ConfigMap configuration request + description: Environment Secret configuration request required: true content: application/json: schema: $ref: '#/components/schemas/ConfigDataRequest' - examples: - frontend_compatible: - summary: Transformed from your frontend payload - description: | - Your frontend payload: - ```json - { - "appId": 123, - "envId": 456, - "name": "env-configmap", - "data": {"envKey": "envValue"} - } - ``` - - Needs to be transformed to: - value: - appId: 123 - environmentId: 456 - configData: - - name: "env-configmap" - type: "CONFIGMAP" - external: false - global: false - data: - envKey: "envValue" - mountPath: "/etc/config" - subPath: false - filePermission: "0644" + example: + id: 0 + appId: 123 + environmentId: 456 + configData: + - name: "env-secret" + type: "SECRET" + external: false + mountPath: "/etc/env-secrets" + data: + dbPassword: "env-specific-password" + apiKey: "env-specific-key" + global: false + subPath: false + filePermission: "0600" + isDeletable: true responses: '200': - description: Environment ConfigMap created/updated successfully + description: Environment Secret created/updated successfully content: application/json: schema: $ref: '#/components/schemas/ApiResponse' '400': - description: Invalid request format or validation error + description: Invalid request parameters content: application/json: schema: @@ -684,5 +489,3 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] From 46167faf5b68dff1d94a4861107e8343156a1134 Mon Sep 17 00:00:00 2001 From: SATYAsasini Date: Wed, 17 Sep 2025 12:04:40 +0530 Subject: [PATCH 9/9] chore: resolving review comments --- .../orchestrator-miscellaneous-apis.yaml | 689 ++++++------------ 1 file changed, 235 insertions(+), 454 deletions(-) diff --git a/specs/miscellaneous/orchestrator-miscellaneous-apis.yaml b/specs/miscellaneous/orchestrator-miscellaneous-apis.yaml index ae5f897f30..a149276ec6 100644 --- a/specs/miscellaneous/orchestrator-miscellaneous-apis.yaml +++ b/specs/miscellaneous/orchestrator-miscellaneous-apis.yaml @@ -1,41 +1,7 @@ openapi: "3.0.3" info: - title: Devtron Orchestrator Miscellaneous APIs (CORRECTED) - description: | - **CORRECTED API SPECIFICATIONS** for miscellaneous Devtron orchestrator endpoints. - - ## 📋 ANALYSIS RESULTS: - - ### ✅ **FOUND IN EXISTING SPECS:** - 1. **Security APIs** - Found in `specs/security/security-dashboard-apis.yml` - 2. **Pod Rotation** - Found in `specs/application/rotate-pods.yaml` - 3. **CD Pipeline Workflow** - Found in `specs/deployment/cd-pipeline-workflow.yaml` - 4. **Kubernetes Resources** - Found in `specs/kubernetes/kubernetes-resource-management.yaml` - - ### ❌ **PAYLOAD MISMATCHES FOUND:** - - **Your Frontend**: Simple payloads like `{appId: 123, envId: 456}` - - **Actual Specs**: Complex structures with additional required fields - - ### 🔧 **MISSING ENDPOINTS:** - Several endpoints from your list are missing from existing specs and need to be added. - - ## 🚨 **CRITICAL CORRECTIONS:** - - ### **Security Scan APIs:** - - **Your Frontend**: `POST /orchestrator/security/scan/list` with `{appId: 123, envId: 456, scanType: "VULNERABILITY"}` - - **Actual Codebase**: `POST /orchestrator/security/scan/list` but expects `ImageScanRequest` structure - - **Your Frontend**: `POST /orchestrator/security/scan/executionDetail` with `{executionId: 789}` - - **Actual Codebase**: `GET /orchestrator/security/scan/executionDetail` with query parameters - - ### **Pod & Resource APIs:** - - **Your Frontend**: `POST /orchestrator/app/rotate-pods` with `{appId: 123, envId: 456, podName: "my-pod"}` - - **Actual Codebase**: Expects complex `PodRotateRequest` with `resources` array - - ### **Application Management:** - - **Your Frontend**: `POST /orchestrator/application/hibernate` with `{appId: 123, envId: 456}` - - **Actual Codebase**: `POST /orchestrator/application/hibernate?appType={appType}` with different structure - - This specification provides corrected endpoints with proper payload structures. + title: Devtron Orchestrator Miscellaneous APIs + description: API specifications for miscellaneous Devtron orchestrator endpoints including security scans, application management, pod operations, and cluster management version: "1.0.0" contact: name: Devtron Support @@ -48,13 +14,15 @@ servers: - url: /orchestrator description: Devtron Orchestrator API Server +security: + - bearerAuth: [] + components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT - description: JWT token for authentication schemas: ApiResponse: @@ -62,35 +30,25 @@ components: properties: code: type: integer - description: HTTP status code status: type: string - description: Response status result: type: object - description: Response data ErrorResponse: type: object properties: code: type: integer - description: Error code status: type: string - description: Error status errors: type: array items: type: string - description: List of error messages - # Frontend payload structures (what you actually send) - SimpleScanRequest: + ScanRequest: type: object - description: | - **FRONTEND PAYLOAD** - What your frontend sends. - Needs transformation to actual codebase structure. properties: appId: type: integer @@ -102,21 +60,15 @@ components: type: string example: "VULNERABILITY" - SimpleExecutionDetailRequest: + ExecutionDetailRequest: type: object - description: | - **FRONTEND PAYLOAD** - What your frontend sends. - Actual endpoint uses GET with query parameters. properties: executionId: type: integer example: 789 - SimpleHibernateRequest: + HibernateRequest: type: object - description: | - **FRONTEND PAYLOAD** - What your frontend sends. - Actual endpoint requires appType query parameter. properties: appId: type: integer @@ -125,11 +77,8 @@ components: type: integer example: 456 - SimpleRotatePodsRequest: + RotatePodsRequest: type: object - description: | - **FRONTEND PAYLOAD** - What your frontend sends. - Actual endpoint expects complex resources array. properties: appId: type: integer @@ -141,11 +90,8 @@ components: type: string example: "my-pod" - SimpleTriggerRequest: + TriggerRequest: type: object - description: | - **FRONTEND PAYLOAD** - What your frontend sends. - May need transformation for actual endpoint. properties: appId: type: integer @@ -157,237 +103,270 @@ components: type: integer example: 789 + ResourceRotateRequest: + type: object + properties: + resourceId: + type: string + example: "res-123" + + ResourceTreeRequest: + type: object + properties: + appId: + type: integer + example: 123 + envId: + type: integer + example: 456 + + EphemeralContainerRequest: + type: object + properties: + podName: + type: string + example: "my-pod" + container: + type: string + example: "debug-container" + tags: - - name: Security APIs - description: Security scanning and vulnerability management + - name: Security Scans + description: Security scanning operations - name: Pod & Resource Management description: Pod logs, rotation, and resource operations - name: Application Management description: Application hibernation, deployment status, and lifecycle - name: Cluster & Infrastructure description: Cluster and namespace management - - name: Payload Mismatches - description: Endpoints with payload structure mismatches paths: - # ===== SECURITY APIS (PAYLOAD MISMATCHES) ===== - /security/scan/list: post: tags: - - Payload Mismatches - summary: "⚠️ PAYLOAD MISMATCH: Get scan execution list" - description: | - **PAYLOAD MISMATCH** ⚠️ - - **Your Frontend Sends**: - ```json - { - "appId": 123, - "envId": 456, - "scanType": "VULNERABILITY" - } - ``` - - **Actual Codebase Expects**: `ImageScanRequest` structure (see existing spec) - **Existing Spec**: `specs/security/security-dashboard-apis.yml` - **Router**: `/orchestrator/security/scan/list` (POST) - **Handler**: `ScanExecutionList` - - **SOLUTION**: Transform your payload to match `ImageScanRequest` structure - operationId: scanExecutionListMismatch + - Security Scans + summary: Get scan execution list + description: Retrieves a list of security scan executions based on the provided criteria + operationId: scanExecutionList requestBody: - description: Frontend payload (needs transformation) required: true content: application/json: schema: - $ref: '#/components/schemas/SimpleScanRequest' + $ref: '#/components/schemas/ScanRequest' example: appId: 123 envId: 456 scanType: "VULNERABILITY" responses: + '200': + description: Scan execution list retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' '400': - description: | - **PAYLOAD STRUCTURE MISMATCH** - Use the correct `ImageScanRequest` structure from existing spec + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] /security/scan/executionDetail: - post: + get: tags: - - Payload Mismatches - summary: "⚠️ METHOD MISMATCH: Get scan execution detail" - description: | - **METHOD MISMATCH** ⚠️ - - **Your Frontend**: `POST /orchestrator/security/scan/executionDetail` with `{executionId: 789}` - **Actual Codebase**: `GET /orchestrator/security/scan/executionDetail` with query parameters - **Existing Spec**: `specs/security/security-dashboard-apis.yml` - **Router**: `/orchestrator/security/scan/executionDetail` (GET) - **Handler**: `FetchExecutionDetail` - - **SOLUTION**: Use GET method with query parameters instead of POST with body - operationId: fetchExecutionDetailMismatch - requestBody: - description: Frontend payload (incorrect method) - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/SimpleExecutionDetailRequest' - example: - executionId: 789 + - Security Scans + summary: Get scan execution detail + description: Retrieves detailed information about a specific scan execution + operationId: fetchExecutionDetail + parameters: + - name: executionId + in: query + required: true + schema: + type: integer + example: 789 responses: - '405': - description: | - **METHOD NOT ALLOWED** - Use GET /orchestrator/security/scan/executionDetail?executionId=789 instead + '200': + description: Scan execution detail retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Scan execution not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - # ===== APPLICATION MANAGEMENT (PAYLOAD MISMATCHES) ===== - /application/hibernate: post: tags: - - Payload Mismatches - summary: "⚠️ PAYLOAD MISMATCH: Hibernate application" - description: | - **PAYLOAD MISMATCH** ⚠️ - - **Your Frontend Sends**: - ```json - { - "appId": 123, - "envId": 456 - } - ``` - - **Actual Codebase**: `POST /orchestrator/application/hibernate?appType={appType}` - **Router**: `/orchestrator/application/hibernate` (POST) with appType query param - **Handler**: `Hibernate` - - **SOLUTION**: Add appType query parameter and use correct payload structure - operationId: hibernateApplicationMismatch + - Application Management + summary: Hibernate application + description: Hibernates the specified application + operationId: hibernateApplication + parameters: + - name: appType + in: query + required: true + schema: + type: string + enum: ["argo", "helm", "flux"] + example: "argo" requestBody: - description: Frontend payload (missing appType) required: true content: application/json: schema: - $ref: '#/components/schemas/SimpleHibernateRequest' + $ref: '#/components/schemas/HibernateRequest' example: appId: 123 envId: 456 responses: + '200': + description: Application hibernated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' '400': - description: | - **MISSING QUERY PARAMETER** - Add ?appType={appType} query parameter + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - - # ===== POD & RESOURCE MANAGEMENT (PAYLOAD MISMATCHES) ===== /app/rotate-pods: post: tags: - - Payload Mismatches - summary: "⚠️ PAYLOAD MISMATCH: Rotate pods" - description: | - **PAYLOAD MISMATCH** ⚠️ - - **Your Frontend Sends**: - ```json - { - "appId": 123, - "envId": 456, - "podName": "my-pod" - } - ``` - - **Actual Codebase Expects**: `PodRotateRequest` with complex resources array - **Existing Spec**: `specs/application/rotate-pods.yaml` - **Router**: `/orchestrator/app/rotate-pods` (POST) - **Handler**: `RotatePods` - - **SOLUTION**: Transform to `PodRotateRequest` structure with resources array - operationId: rotatePodsPayloadMismatch + - Pod & Resource Management + summary: Rotate pods + description: Rotates the specified pods + operationId: rotatePods requestBody: - description: Frontend payload (needs transformation) required: true content: application/json: schema: - $ref: '#/components/schemas/SimpleRotatePodsRequest' + $ref: '#/components/schemas/RotatePodsRequest' example: appId: 123 envId: 456 podName: "my-pod" responses: + '200': + description: Pods rotated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' '400': - description: | - **PAYLOAD STRUCTURE MISMATCH** - Use the correct `PodRotateRequest` structure from existing spec + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] /app/cd-pipeline/trigger: post: tags: - Application Management - summary: "✅ CORRECT: Trigger CD pipeline" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend Sends**: - ```json - { - "appId": 123, - "environmentId": 456, - "pipelineId": 789 - } - ``` - - **Actual Codebase**: `POST /orchestrator/app/cd-pipeline/trigger` - **Router**: `/orchestrator/app/cd-pipeline/trigger` (POST) - **Handler**: `OverrideConfig` - - **STATUS**: Payload structure appears correct + summary: Trigger CD pipeline + description: Triggers a CD pipeline deployment for the specified application and environment operationId: triggerCdPipeline requestBody: - description: CD pipeline trigger request required: true content: application/json: schema: - $ref: '#/components/schemas/SimpleTriggerRequest' + $ref: '#/components/schemas/TriggerRequest' example: appId: 123 environmentId: 456 pipelineId: 789 responses: '200': - description: Pipeline triggered successfully + description: CD pipeline triggered successfully content: application/json: schema: @@ -416,25 +395,13 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - - # ===== CLUSTER & INFRASTRUCTURE (CORRECT ENDPOINTS) ===== /cluster/list: get: tags: - Cluster & Infrastructure - summary: "✅ CORRECT: Get cluster list" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend**: `GET /orchestrator/cluster/list` (no payload) - **Actual Codebase**: `GET /orchestrator/cluster` - **Router**: `/orchestrator/cluster` (GET) - **Handler**: `FindAll` - - **STATUS**: Endpoint exists and works correctly + summary: Get cluster list + description: Retrieves a list of all available clusters operationId: getClusterList responses: '200': @@ -461,23 +428,13 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] /cluster/namespaces: get: tags: - Cluster & Infrastructure - summary: "✅ CORRECT: Get all cluster namespaces" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend**: `GET /orchestrator/cluster/namespaces` (no payload) - **Actual Codebase**: `GET /orchestrator/cluster/namespaces` - **Router**: `/orchestrator/cluster/namespaces` (GET) - **Handler**: `GetAllClusterNamespaces` - - **STATUS**: Endpoint exists and works correctly + summary: Get all cluster namespaces + description: Retrieves namespaces from all clusters operationId: getAllClusterNamespaces responses: '200': @@ -504,44 +461,29 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - - # ===== POD LOGS & KUBERNETES RESOURCES ===== /k8s/pods/logs/{podName}: get: tags: - Pod & Resource Management - summary: "✅ CORRECT: Get pod logs" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend**: `GET /orchestrator/pods/logs/podName?containerName={containerName}` - **Actual Codebase**: `GET /orchestrator/k8s/pods/logs/{podName}?containerName={containerName}` - **Router**: `/orchestrator/k8s/pods/logs/{podName}` (GET) - **Handler**: `GetPodLogs` - - **PATH DIFFERENCE**: Your frontend uses `/pods/logs/` but actual is `/k8s/pods/logs/` + summary: Get pod logs + description: Retrieves logs from the specified pod and container operationId: getPodLogs parameters: - name: podName in: path - description: Name of the pod required: true schema: type: string example: "my-app-pod-123" - name: containerName in: query - description: Name of the container required: true schema: type: string example: "main-container" - name: follow in: query - description: Whether to follow log stream required: false schema: type: boolean @@ -554,7 +496,6 @@ paths: text/plain: schema: type: string - description: Pod log content '400': description: Invalid parameters content: @@ -585,35 +526,23 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] /k8s/pods/logs/download/{podName}: get: tags: - Pod & Resource Management - summary: "✅ CORRECT: Download pod logs" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend**: `GET /orchestrator/pods/logs/download/podName?containerName={containerName}` - **Actual Codebase**: `GET /orchestrator/k8s/pods/logs/download/{podName}?containerName={containerName}` - **Router**: `/orchestrator/k8s/pods/logs/download/{podName}` (GET) - **Handler**: `DownloadPodLogs` - - **PATH DIFFERENCE**: Your frontend uses `/pods/logs/download/` but actual is `/k8s/pods/logs/download/` + summary: Download pod logs + description: Downloads logs from the specified pod and container as a file operationId: downloadPodLogs parameters: - name: podName in: path - description: Name of the pod required: true schema: type: string example: "my-app-pod-123" - name: containerName in: query - description: Name of the container required: true schema: type: string @@ -626,7 +555,6 @@ paths: schema: type: string format: binary - description: Pod log file '400': description: Invalid parameters content: @@ -657,44 +585,27 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] /k8s/resource/rotate: post: tags: - Pod & Resource Management - summary: "✅ CORRECT: Rotate Kubernetes resource" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend**: `POST /orchestrator/resource/rotate` with `{resourceId: "res-123"}` - **Actual Codebase**: `POST /orchestrator/k8s/resource/rotate?appId={appId}` - **Router**: `/orchestrator/k8s/resource/rotate` (POST) - **Handler**: `RotatePod` - - **QUERY PARAMETER**: Requires appId query parameter + summary: Rotate Kubernetes resource + description: Rotates the specified Kubernetes resource operationId: rotateKubernetesResource parameters: - name: appId in: query - description: Application ID required: true schema: type: integer example: 123 requestBody: - description: Resource rotation request required: true content: application/json: schema: - type: object - properties: - resourceId: - type: string - description: Resource identifier - example: "res-123" + $ref: '#/components/schemas/ResourceRotateRequest' example: resourceId: "res-123" responses: @@ -728,37 +639,23 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - - # ===== DEPLOYMENT STATUS & TIMELINE ===== /app/deployment-status/timeline/{appId}/{envId}: get: tags: - Application Management - summary: "✅ CORRECT: Get deployment status timeline" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend**: `GET /orchestrator/app/deployment-status/timeline/{appId}/{envId}` - **Actual Codebase**: `GET /orchestrator/app/deployment-status/timeline/{appId}/{envId}` - **Router**: `/orchestrator/app/deployment-status/timeline/{appId}/{envId}` (GET) - **Handler**: `FetchTimelines` - - **STATUS**: Endpoint exists and works correctly + summary: Get deployment status timeline + description: Retrieves the deployment status timeline for the specified application and environment operationId: getDeploymentStatusTimeline parameters: - name: appId in: path - description: Application ID required: true schema: type: integer example: 123 - name: envId in: path - description: Environment ID required: true schema: type: integer @@ -800,35 +697,23 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] /app/deployment-status/manual-sync/{appId}/{envId}: get: tags: - Application Management - summary: "✅ CORRECT: Manual sync deployment status" - description: | - **CORRECT ENDPOINT** ✅ - - **Your Frontend**: `GET /orchestrator/app/deployment-status/manual-sync/{appId}/{envId}` - **Actual Codebase**: `GET /orchestrator/app/deployment-status/manual-sync/{appId}/{envId}` - **Router**: `/orchestrator/app/deployment-status/manual-sync/{appId}/{envId}` (GET) - **Handler**: `ManualSyncAcdPipelineDeploymentStatus` - - **STATUS**: Endpoint exists and works correctly + summary: Manual sync deployment status + description: Manually synchronizes the deployment status for the specified application and environment operationId: manualSyncDeploymentStatus parameters: - name: appId in: path - description: Application ID required: true schema: type: integer example: 123 - name: envId in: path - description: Environment ID required: true schema: type: integer @@ -870,163 +755,59 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - # ===== MISSING ENDPOINTS (NOT FOUND IN CODEBASE) ===== - - /app/detail/resource-tree: + /application/unhibernate: post: tags: - - Payload Mismatches - summary: "❌ MISSING: Get application resource tree" - description: | - **MISSING ENDPOINT** ❌ - - **Your Frontend Expects**: `POST /orchestrator/app/detail/resource-tree` with `{appId: 123, envId: 456}` - **Actual Codebase**: **NOT FOUND** - This endpoint doesn't exist - - **SIMILAR ENDPOINTS FOUND**: - - `GET /orchestrator/app-store/installed-app/detail/resource-tree?installed-app-id={id}&env-id={envId}` - - **SOLUTION**: Either use the app-store endpoint or add this endpoint to the backend - operationId: getApplicationResourceTreeMissing + - Application Management + summary: Unhibernate application + description: Unhibernates the specified application + operationId: unhibernateApplication + parameters: + - name: appType + in: query + required: true + schema: + type: string + enum: ["argo", "helm", "flux"] + example: "argo" requestBody: - description: Frontend payload (endpoint doesn't exist) required: true content: application/json: schema: - type: object - properties: - appId: - type: integer - example: 123 - envId: - type: integer - example: 456 + $ref: '#/components/schemas/HibernateRequest' + example: + appId: 123 + envId: 456 responses: - '404': - description: | - **ENDPOINT NOT FOUND** - This endpoint doesn't exist in the codebase. Use app-store resource-tree endpoint instead. + '200': + description: Application unhibernated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + '400': + description: Invalid request parameters content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - - /resources/ephemeralContainers: - post: - tags: - - Payload Mismatches - summary: "❌ MISSING: Create ephemeral containers" - description: | - **MISSING ENDPOINT** ❌ - - **Your Frontend Expects**: `POST /orchestrator/resources/ephemeralContainers` with `{podName: "my-pod", container: "debug-container"}` - **Actual Codebase**: **NOT FOUND** - This endpoint doesn't exist - - **SOLUTION**: This endpoint needs to be implemented in the backend - operationId: createEphemeralContainersMissing - requestBody: - description: Frontend payload (endpoint doesn't exist) - required: true - content: - application/json: - schema: - type: object - properties: - podName: - type: string - example: "my-pod" - container: - type: string - example: "debug-container" - responses: - '404': - description: | - **ENDPOINT NOT FOUND** - This endpoint doesn't exist in the codebase and needs to be implemented. + '401': + description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: [] - -# ===== SUMMARY ===== -# -# ## 📊 **VALIDATION SUMMARY:** -# -# ### ✅ **CORRECT ENDPOINTS (8):** -# - `/app/cd-pipeline/trigger` (POST) -# - `/cluster/list` (GET) -# - `/cluster/namespaces` (GET) -# - `/k8s/pods/logs/{podName}` (GET) - Path difference -# - `/k8s/pods/logs/download/{podName}` (GET) - Path difference -# - `/k8s/resource/rotate` (POST) - Query parameter required -# - `/app/deployment-status/timeline/{appId}/{envId}` (GET) -# - `/app/deployment-status/manual-sync/{appId}/{envId}` (GET) -# -# ### ⚠️ **PAYLOAD/METHOD MISMATCHES (5):** -# - `/security/scan/list` (POST) - Payload structure mismatch -# - `/security/scan/executionDetail` - Method mismatch (POST vs GET) -# - `/application/hibernate` (POST) - Missing appType query parameter -# - `/application/unhibernate` (POST) - Missing appType query parameter -# - `/app/rotate-pods` (POST) - Payload structure mismatch -# -# ### ❌ **MISSING ENDPOINTS (2):** -# - `/app/detail/resource-tree` (POST) - Doesn't exist -# - `/resources/ephemeralContainers` (POST) - Doesn't exist -# -# ### 📋 **EXISTING SPECS TO REFERENCE:** -# - `specs/security/security-dashboard-apis.yml` - Security scan endpoints -# - `specs/application/rotate-pods.yaml` - Pod rotation -# - `specs/deployment/cd-pipeline-workflow.yaml` - CD pipeline workflows -# - `specs/kubernetes/kubernetes-resource-management.yaml` - K8s resources - - /application/unhibernate: - post: - tags: - - Payload Mismatches - summary: "⚠️ PAYLOAD MISMATCH: Unhibernate application" - description: | - **PAYLOAD MISMATCH** ⚠️ - - **Your Frontend Sends**: - ```json - { - "appId": 123, - "envId": 456 - } - ``` - - **Actual Codebase**: `POST /orchestrator/application/unhibernate?appType={appType}` - **Router**: `/orchestrator/application/unhibernate` (POST) with appType query param - **Handler**: `UnHibernate` - - **SOLUTION**: Add appType query parameter and use correct payload structure - operationId: unhibernateApplicationMismatch - requestBody: - description: Frontend payload (missing appType) - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/SimpleHibernateRequest' - example: - appId: 123 - envId: 456 - responses: - '400': - description: | - **MISSING QUERY PARAMETER** - Add ?appType={appType} query parameter + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - security: - - bearerAuth: []