diff --git a/api/swagger/docs.go b/api/swagger/docs.go index e696f4fc..ffdfc20e 100644 --- a/api/swagger/docs.go +++ b/api/swagger/docs.go @@ -1135,6 +1135,91 @@ const docTemplate = `{ } } }, + "/organizations/{organizationId}/app-serve-apps/app-id/exist": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "Get appServeApp by giving params", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AppServeApps" + ], + "summary": "Get appServeApp", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "boolean" + } + } + } + } + }, + "/organizations/{organizationId}/app-serve-apps/app-name/exist": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "Check duplicate appServeAppName by giving params", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AppServeApps" + ], + "summary": "Check duplicate appServeAppName", + "parameters": [ + { + "type": "string", + "description": "organizationId", + "name": "organizationId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "clusterId", + "name": "clusterId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "appName", + "name": "appName", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "namespace", + "name": "namespace", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "boolean" + } + } + } + } + }, "/organizations/{organizationId}/app-serve-apps/{appId}": { "get": { "security": [ @@ -1283,34 +1368,6 @@ const docTemplate = `{ } } }, - "/organizations/{organizationId}/app-serve-apps/{appId}/exist": { - "get": { - "security": [ - { - "JWT": [] - } - ], - "description": "Get appServeApp by giving params", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AppServeApps" - ], - "summary": "Get appServeApp", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "boolean" - } - } - } - } - }, "/organizations/{organizationId}/app-serve-apps/{appId}/rollback": { "post": { "security": [ diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index bd2bcada..e2b4956b 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -1128,6 +1128,91 @@ } } }, + "/organizations/{organizationId}/app-serve-apps/app-id/exist": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "Get appServeApp by giving params", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AppServeApps" + ], + "summary": "Get appServeApp", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "boolean" + } + } + } + } + }, + "/organizations/{organizationId}/app-serve-apps/app-name/exist": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "Check duplicate appServeAppName by giving params", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AppServeApps" + ], + "summary": "Check duplicate appServeAppName", + "parameters": [ + { + "type": "string", + "description": "organizationId", + "name": "organizationId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "clusterId", + "name": "clusterId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "appName", + "name": "appName", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "namespace", + "name": "namespace", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "boolean" + } + } + } + } + }, "/organizations/{organizationId}/app-serve-apps/{appId}": { "get": { "security": [ @@ -1276,34 +1361,6 @@ } } }, - "/organizations/{organizationId}/app-serve-apps/{appId}/exist": { - "get": { - "security": [ - { - "JWT": [] - } - ], - "description": "Get appServeApp by giving params", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AppServeApps" - ], - "summary": "Get appServeApp", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "boolean" - } - } - } - } - }, "/organizations/{organizationId}/app-serve-apps/{appId}/rollback": { "post": { "security": [ diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 9199ce2f..f4be3ae7 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -2484,23 +2484,6 @@ paths: summary: Update app endpoint tags: - AppServeApps - /organizations/{organizationId}/app-serve-apps/{appId}/exist: - get: - consumes: - - application/json - description: Get appServeApp by giving params - produces: - - application/json - responses: - "200": - description: OK - schema: - type: boolean - security: - - JWT: [] - summary: Get appServeApp - tags: - - AppServeApps /organizations/{organizationId}/app-serve-apps/{appId}/rollback: post: consumes: @@ -2554,6 +2537,60 @@ paths: summary: Update app status tags: - AppServeApps + /organizations/{organizationId}/app-serve-apps/app-id/exist: + get: + consumes: + - application/json + description: Get appServeApp by giving params + produces: + - application/json + responses: + "200": + description: OK + schema: + type: boolean + security: + - JWT: [] + summary: Get appServeApp + tags: + - AppServeApps + /organizations/{organizationId}/app-serve-apps/app-name/exist: + get: + consumes: + - application/json + description: Check duplicate appServeAppName by giving params + parameters: + - description: organizationId + in: path + name: organizationId + required: true + type: string + - description: clusterId + in: query + name: clusterId + required: true + type: string + - description: appName + in: query + name: appName + required: true + type: string + - description: namespace + in: query + name: namespace + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + type: boolean + security: + - JWT: [] + summary: Check duplicate appServeAppName + tags: + - AppServeApps /organizations/{organizationId}/cloud-accounts: get: consumes: diff --git a/internal/delivery/http/app-serve-app.go b/internal/delivery/http/app-serve-app.go index 6e300536..e9f921ca 100644 --- a/internal/delivery/http/app-serve-app.go +++ b/internal/delivery/http/app-serve-app.go @@ -388,7 +388,7 @@ func makeStage(app *domain.AppServeApp, status string) domain.StageResponse { // @Accept json // @Produce json // @Success 200 {object} bool -// @Router /organizations/{organizationId}/app-serve-apps/{appId}/exist [get] +// @Router /organizations/{organizationId}/app-serve-apps/app-id/exist [get] // @Security JWT func (h *AppServeAppHandler) IsAppServeAppExist(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -400,9 +400,9 @@ func (h *AppServeAppHandler) IsAppServeAppExist(w http.ResponseWriter, r *http.R return } - appId, ok := vars["appId"] - fmt.Printf("appId = [%s]\n", appId) - if !ok { + urlParams := r.URL.Query() + appId := urlParams.Get("appId") + if appId == "" { ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("invalid appId"))) return } @@ -420,6 +420,58 @@ func (h *AppServeAppHandler) IsAppServeAppExist(w http.ResponseWriter, r *http.R ResponseJSON(w, http.StatusOK, out) } +// IsAppServeAppNameExist godoc +// @Tags AppServeApps +// @Summary Check duplicate appServeAppName +// @Description Check duplicate appServeAppName by giving params +// @Accept json +// @Produce json +// @Param organizationId path string true "organizationId" +// @Param clusterId query string true "clusterId" +// @Param appName query string true "appName" +// @Param namespace query string false "namespace" +// @Success 200 {object} bool +// @Router /organizations/{organizationId}/app-serve-apps/app-name/exist [get] +// @Security JWT +func (h *AppServeAppHandler) IsAppServeAppNameExist(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + organizationId, ok := vars["organizationId"] + fmt.Printf("organizationId = [%v]\n", organizationId) + if !ok { + ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("invalid organizationId"))) + return + } + + urlParams := r.URL.Query() + + clusterId := urlParams.Get("clusterId") + if clusterId == "" { + ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("invalid clusterId"))) + return + } + + namespace := urlParams.Get("namespace") + + appName := urlParams.Get("appName") + if appName == "" { + ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("invalid appName"))) + return + } + + exist, err := h.usecase.IsAppServeAppNameExist(organizationId, clusterId, namespace, appName) + if err != nil { + ErrorJSON(w, httpErrors.NewInternalServerError(err)) + return + } + + var out = struct { + Exist bool `json:"exist"` + }{Exist: exist} + + ResponseJSON(w, http.StatusOK, out) +} + // UpdateAppServeApp godoc // @Tags AppServeApps // @Summary Update appServeApp diff --git a/internal/repository/app-serve-app.go b/internal/repository/app-serve-app.go index 934a8fb5..cd27277a 100644 --- a/internal/repository/app-serve-app.go +++ b/internal/repository/app-serve-app.go @@ -14,6 +14,7 @@ type IAppServeAppRepository interface { GetAppServeApps(organizationId string, showAll bool) ([]domain.AppServeApp, error) GetAppServeAppById(appId string) (*domain.AppServeApp, error) IsAppServeAppExist(appId string) (int64, error) + IsAppServeAppNameExist(orgId string, clusterId string, namespace string, appName string) (int64, error) CreateTask(task *domain.AppServeAppTask) (taskId string, err error) UpdateStatus(appId string, taskId string, status string, output string) error UpdateEndpoint(appId string, taskId string, endpoint string, previewEndpoint string, helmRevision int32) error @@ -110,6 +111,28 @@ func (r *AppServeAppRepository) IsAppServeAppExist(appId string) (int64, error) return result, nil } +func (r *AppServeAppRepository) IsAppServeAppNameExist(orgId string, clusterId string, namespace string, appName string) (int64, error) { + var result int64 + + queryString := fmt.Sprintf("organization_id = '%v' "+ + "AND target_cluster_id = '%v' "+ + "AND name = '%v' "+ + "AND status <> 'DELETE_SUCCESS'", orgId, clusterId, appName) + + if namespace != "" { + queryString += fmt.Sprintf("AND namespace = '%v' ", namespace) + } + + fmt.Println("query = ", queryString) + + res := r.db.Table("app_serve_apps").Where(queryString).Count(&result) + if res.Error != nil { + log.Debug(res.Error) + return 0, res.Error + } + return result, nil +} + func (r *AppServeAppRepository) UpdateStatus(appId string, taskId string, status string, output string) error { now := time.Now() app := domain.AppServeApp{ diff --git a/internal/route/route.go b/internal/route/route.go index 60d7b402..0e6040e9 100644 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -126,7 +126,8 @@ func SetupRouter(db *gorm.DB, argoClient argowf.ArgoClient, thanosClient thanos. r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.CreateAppServeApp))).Methods(http.MethodPost) r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.GetAppServeApps))).Methods(http.MethodGet) r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps/{appId}", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.GetAppServeApp))).Methods(http.MethodGet) - r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps/{appId}/exist", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.IsAppServeAppExist))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps/app-id/exist", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.IsAppServeAppExist))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps/app-name/exist", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.IsAppServeAppNameExist))).Methods(http.MethodGet) r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps/{appId}", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.DeleteAppServeApp))).Methods(http.MethodDelete) r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps/{appId}", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.UpdateAppServeApp))).Methods(http.MethodPut) r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/app-serve-apps/{appId}/status", authMiddleware.Handle(http.HandlerFunc(appServeAppHandler.UpdateAppServeAppStatus))).Methods(http.MethodPatch) diff --git a/internal/usecase/app-serve-app.go b/internal/usecase/app-serve-app.go index afef3eeb..61bb4d66 100644 --- a/internal/usecase/app-serve-app.go +++ b/internal/usecase/app-serve-app.go @@ -22,6 +22,7 @@ type IAppServeAppUsecase interface { GetAppServeApps(organizationId string, showAll bool) ([]domain.AppServeApp, error) GetAppServeAppById(appId string) (*domain.AppServeApp, error) IsAppServeAppExist(appId string) (bool, error) + IsAppServeAppNameExist(orgId string, clusterId string, namespace string, appName string) (bool, error) UpdateAppServeAppStatus(appId string, taskId string, status string, output string) (ret string, err error) DeleteAppServeApp(appId string) (res string, err error) UpdateAppServeApp(app *domain.AppServeApp, appTask *domain.AppServeAppTask) (ret string, err error) @@ -170,6 +171,19 @@ func (u *AppServeAppUsecase) IsAppServeAppExist(appId string) (bool, error) { return false, nil } +func (u *AppServeAppUsecase) IsAppServeAppNameExist(orgId string, clusterId string, namespace string, appName string) (bool, error) { + count, err := u.repo.IsAppServeAppNameExist(orgId, clusterId, namespace, appName) + if err != nil { + return false, err + } + + if count > 0 { + return true, nil + } + + return false, nil +} + func (u *AppServeAppUsecase) UpdateAppServeAppStatus( appId string, taskId string,