From a32692de9777df9d14c01908160e7570f61688e4 Mon Sep 17 00:00:00 2001 From: Gireesh Naidu <111440205+gireesh-devtron@users.noreply.github.com> Date: Mon, 5 Feb 2024 18:12:01 +0530 Subject: [PATCH] clean appListing api (#4628) --- api/restHandler/AppListingRestHandler.go | 444 ++---------------- api/router/AppListingRouter.go | 8 +- .../sql/repository/AppListingRepository.go | 97 +--- .../AppListingRepositoryQueryBuilder.go | 49 +- pkg/app/AppListingService.go | 136 ++---- 5 files changed, 78 insertions(+), 656 deletions(-) diff --git a/api/restHandler/AppListingRestHandler.go b/api/restHandler/AppListingRestHandler.go index 870f54bae61..9c4f19bb1ad 100644 --- a/api/restHandler/AppListingRestHandler.go +++ b/api/restHandler/AppListingRestHandler.go @@ -66,7 +66,6 @@ import ( ) type AppListingRestHandler interface { - FetchAppsByEnvironment(w http.ResponseWriter, r *http.Request) FetchAppDetails(w http.ResponseWriter, r *http.Request) FetchJobs(w http.ResponseWriter, r *http.Request) FetchJobOverviewCiPipelines(w http.ResponseWriter, r *http.Request) @@ -84,8 +83,6 @@ type AppListingRestHandler interface { ManualSyncAcdPipelineDeploymentStatus(w http.ResponseWriter, r *http.Request) GetClusterTeamAndEnvListForAutocomplete(w http.ResponseWriter, r *http.Request) FetchAppsByEnvironmentV2(w http.ResponseWriter, r *http.Request) - FetchAppsByEnvironmentV1(w http.ResponseWriter, r *http.Request) - FetchAppsByEnvironmentVersioned(w http.ResponseWriter, r *http.Request) FetchOverviewAppsByEnvironment(w http.ResponseWriter, r *http.Request) } @@ -196,13 +193,13 @@ func (handler AppListingRestHandlerImpl) FetchAllDevtronManagedApps(w http.Respo return } handler.logger.Infow("got request to fetch all devtron managed apps ", "userId", userId) - //RBAC starts + // RBAC starts if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok { handler.logger.Infow("user forbidden to fetch all devtron managed apps", "userId", userId) common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden) return } - //RBAC ends + // RBAC ends res, err := handler.appListingService.FetchAllDevtronManagedApps() common.WriteJsonResp(w, err, res, http.StatusOK) } @@ -216,7 +213,7 @@ func (handler AppListingRestHandlerImpl) FetchJobs(w http.ResponseWriter, r *htt token := r.Header.Get("token") isSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*") var validAppIds []int - //for non super admin users + // for non super admin users if !isSuperAdmin { rbacObjectsForAllAppsMap := handler.enforcerUtil.GetRbacObjectsForAllApps(helper.Job) rbacObjectToAppIdMap := make(map[string]int) @@ -229,7 +226,7 @@ func (handler AppListingRestHandlerImpl) FetchJobs(w http.ResponseWriter, r *htt } result := handler.enforcer.EnforceInBatch(token, casbin.ResourceJobs, casbin.ActionGet, rbacObjects) - //O(n) loop, n = len(rbacObjectsForAllAppsMap) + // O(n) loop, n = len(rbacObjectsForAllAppsMap) for object, ok := range result { if ok { validAppIds = append(validAppIds, rbacObjectToAppIdMap[object]) @@ -292,14 +289,14 @@ func (handler AppListingRestHandlerImpl) FetchJobOverviewCiPipelines(w http.Resp common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - //RBAC + // RBAC token := r.Header.Get("token") object := handler.enforcerUtil.GetAppRBACNameByAppId(jobId) if ok := handler.enforcer.Enforce(token, casbin.ResourceJobs, casbin.ActionGet, object); !ok { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden) return } - //RBAC ENDS + // RBAC ENDS job, err := handler.pipeline.GetApp(jobId) if err != nil || job == nil || job.AppType != helper.Job { handler.logger.Errorw("Job with the given Id does not exist", "err", err, "jobId", jobId) @@ -316,380 +313,9 @@ func (handler AppListingRestHandlerImpl) FetchJobOverviewCiPipelines(w http.Resp common.WriteJsonResp(w, err, jobCi, http.StatusOK) } -func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentVersioned(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - version := vars["version"] - if version == app.APIVersionV1 { - handler.FetchAppsByEnvironmentV1(w, r) - return - } - if version == app.APIVersionV2 { - handler.FetchAppsByEnvironmentV2(w, r) - return - } -} -func (handler AppListingRestHandlerImpl) FetchAppsByEnvironment(w http.ResponseWriter, r *http.Request) { - //Allow CORS here By * or specific origin - setupResponse(&w, r) - token := r.Header.Get("token") - t0 := time.Now() - t1 := time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "stage", "1") - newCtx, span := otel.Tracer("userService").Start(r.Context(), "GetLoggedInUser") - userId, err := handler.userService.GetLoggedInUser(r) - span.End() - if userId == 0 || err != nil { - common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) - return - } - newCtx, span = otel.Tracer("userService").Start(newCtx, "GetById") - span.End() - var fetchAppListingRequest app.FetchAppListingRequest - decoder := json.NewDecoder(r.Body) - err = decoder.Decode(&fetchAppListingRequest) - if err != nil { - handler.logger.Errorw("request err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - newCtx, span = otel.Tracer("fetchAppListingRequest").Start(newCtx, "GetNamespaceClusterMapping") - _, _, err = fetchAppListingRequest.GetNamespaceClusterMapping() - span.End() - if err != nil { - handler.logger.Errorw("request err, GetNamespaceClusterMapping", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - - var dg *deploymentGroup.DeploymentGroupDTO - if fetchAppListingRequest.DeploymentGroupId > 0 { - newCtx, span = otel.Tracer("deploymentGroupService").Start(newCtx, "FindById") - dg, err = handler.deploymentGroupService.FindById(fetchAppListingRequest.DeploymentGroupId) - span.End() - if err != nil { - handler.logger.Errorw("service err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, "", http.StatusInternalServerError) - } - } - - newCtx, span = otel.Tracer("appListingService").Start(newCtx, "FetchAppsByEnvironment") - start := time.Now() - envContainers, err := handler.appListingService.FetchAppsByEnvironment(fetchAppListingRequest, w, r, token, "") - middleware.AppListingDuration.WithLabelValues("fetchAppsByEnvironment", "devtron").Observe(time.Since(start).Seconds()) - span.End() - if err != nil { - handler.logger.Errorw("service err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, "", http.StatusInternalServerError) - } - t2 := time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "time diff", t2.Unix()-t1.Unix(), "stage", "2") - t1 = t2 - newCtx, span = otel.Tracer("userService").Start(newCtx, "IsSuperAdmin") - isActionUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*") - span.End() - appEnvContainers := make([]*bean.AppEnvironmentContainer, 0) - if isActionUserSuperAdmin { - appEnvContainers = append(appEnvContainers, envContainers...) - } else { - uniqueTeams := make(map[int]string) - authorizedTeams := make(map[int]bool) - for _, envContainer := range envContainers { - if _, ok := uniqueTeams[envContainer.TeamId]; !ok { - uniqueTeams[envContainer.TeamId] = envContainer.TeamName - } - } - - objectArray := make([]string, len(uniqueTeams)) - for _, teamName := range uniqueTeams { - object := strings.ToLower(teamName) - objectArray = append(objectArray, object) - } - - newCtx, span = otel.Tracer("enforcer").Start(newCtx, "EnforceByEmailInBatchForTeams") - start = time.Now() - resultMap := handler.enforcer.EnforceInBatch(token, casbin.ResourceTeam, casbin.ActionGet, objectArray) - middleware.AppListingDuration.WithLabelValues("enforceByEmailInBatchResourceTeam", "devtron").Observe(time.Since(start).Seconds()) - span.End() - for teamId, teamName := range uniqueTeams { - object := strings.ToLower(teamName) - if ok := resultMap[object]; ok { - authorizedTeams[teamId] = true - } - } - - filteredAppEnvContainers := make([]*bean.AppEnvironmentContainer, 0) - for _, envContainer := range envContainers { - if _, ok := authorizedTeams[envContainer.TeamId]; ok { - filteredAppEnvContainers = append(filteredAppEnvContainers, envContainer) - } - } - - objectArray = make([]string, len(filteredAppEnvContainers)) - for _, filteredAppEnvContainer := range filteredAppEnvContainers { - if fetchAppListingRequest.DeploymentGroupId > 0 { - if filteredAppEnvContainer.EnvironmentId != 0 && filteredAppEnvContainer.EnvironmentId != dg.EnvironmentId { - continue - } - } - object := fmt.Sprintf("%s/%s", filteredAppEnvContainer.TeamName, filteredAppEnvContainer.AppName) - object = strings.ToLower(object) - objectArray = append(objectArray, object) - } - - newCtx, span = otel.Tracer("enforcer").Start(newCtx, "EnforceByEmailInBatchForApps") - start = time.Now() - resultMap = handler.enforcer.EnforceInBatch(token, casbin.ResourceApplications, casbin.ActionGet, objectArray) - middleware.AppListingDuration.WithLabelValues("enforceByEmailInBatchResourceApplication", "devtron").Observe(time.Since(start).Seconds()) - span.End() - for _, filteredAppEnvContainer := range filteredAppEnvContainers { - if fetchAppListingRequest.DeploymentGroupId > 0 { - if filteredAppEnvContainer.EnvironmentId != 0 && filteredAppEnvContainer.EnvironmentId != dg.EnvironmentId { - continue - } - } - object := fmt.Sprintf("%s/%s", filteredAppEnvContainer.TeamName, filteredAppEnvContainer.AppName) - object = strings.ToLower(object) - if ok := resultMap[object]; ok { - appEnvContainers = append(appEnvContainers, filteredAppEnvContainer) - } - } - - } - t2 = time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "time diff", t2.Unix()-t1.Unix(), "stage", "3") - t1 = t2 - newCtx, span = otel.Tracer("appListingService").Start(newCtx, "BuildAppListingResponse") - apps, err := handler.appListingService.BuildAppListingResponse(fetchAppListingRequest, appEnvContainers) - span.End() - if err != nil { - handler.logger.Errorw("service err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, "", http.StatusInternalServerError) - } - - // Apply pagination - appsCount := len(apps) - offset := fetchAppListingRequest.Offset - limit := fetchAppListingRequest.Size - - if limit > 0 { - if offset+limit <= len(apps) { - apps = apps[offset : offset+limit] - } else { - apps = apps[offset:] - } - } - appContainerResponse := bean.AppContainerResponse{ - AppContainers: apps, - AppCount: appsCount, - } - if fetchAppListingRequest.DeploymentGroupId > 0 { - var ciMaterialDTOs []bean.CiMaterialDTO - for _, ci := range dg.CiMaterialDTOs { - ciMaterialDTOs = append(ciMaterialDTOs, bean.CiMaterialDTO{ - Name: ci.Name, - SourceValue: ci.SourceValue, - SourceType: ci.SourceType, - }) - } - appContainerResponse.DeploymentGroupDTO = bean.DeploymentGroupDTO{ - Id: dg.Id, - Name: dg.Name, - AppCount: dg.AppCount, - NoOfApps: dg.NoOfApps, - EnvironmentId: dg.EnvironmentId, - CiPipelineId: dg.CiPipelineId, - CiMaterialDTOs: ciMaterialDTOs, - } - } - t2 = time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "time diff", t2.Unix()-t1.Unix(), "stage", "4") - t1 = t2 - handler.logger.Infow("api response time testing", "total time", time.Now().String(), "total time", t1.Unix()-t0.Unix()) - common.WriteJsonResp(w, err, appContainerResponse, http.StatusOK) -} -func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentV1(w http.ResponseWriter, r *http.Request) { - //Allow CORS here By * or specific origin - setupResponse(&w, r) - token := r.Header.Get("token") - t0 := time.Now() - t1 := time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "stage", "1") - newCtx, span := otel.Tracer("userService").Start(r.Context(), "GetLoggedInUser") - userId, err := handler.userService.GetLoggedInUser(r) - span.End() - if userId == 0 || err != nil { - common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) - return - } - newCtx, span = otel.Tracer("userService").Start(newCtx, "GetById") - span.End() - var fetchAppListingRequest app.FetchAppListingRequest - decoder := json.NewDecoder(r.Body) - err = decoder.Decode(&fetchAppListingRequest) - if err != nil { - handler.logger.Errorw("request err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - newCtx, span = otel.Tracer("fetchAppListingRequest").Start(newCtx, "GetNamespaceClusterMapping") - _, _, err = fetchAppListingRequest.GetNamespaceClusterMapping() - span.End() - if err != nil { - handler.logger.Errorw("request err, GetNamespaceClusterMapping", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - - var dg *deploymentGroup.DeploymentGroupDTO - if fetchAppListingRequest.DeploymentGroupId > 0 { - newCtx, span = otel.Tracer("deploymentGroupService").Start(newCtx, "FindById") - dg, err = handler.deploymentGroupService.FindById(fetchAppListingRequest.DeploymentGroupId) - span.End() - if err != nil { - handler.logger.Errorw("service err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, "", http.StatusInternalServerError) - } - } - - newCtx, span = otel.Tracer("appListingService").Start(newCtx, "FetchAppsByEnvironment") - start := time.Now() - envContainers, err := handler.appListingService.FetchAppsByEnvironment(fetchAppListingRequest, w, r, token, app.APIVersionV1) - middleware.AppListingDuration.WithLabelValues("fetchAppsByEnvironment", "devtron").Observe(time.Since(start).Seconds()) - span.End() - if err != nil { - handler.logger.Errorw("service err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, "", http.StatusInternalServerError) - } - t2 := time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "time diff", t2.Unix()-t1.Unix(), "stage", "2") - t1 = t2 - - newCtx, span = otel.Tracer("userService").Start(newCtx, "IsSuperAdmin") - isActionUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*") - span.End() - appEnvContainers := make([]*bean.AppEnvironmentContainer, 0) - if isActionUserSuperAdmin { - appEnvContainers = append(appEnvContainers, envContainers...) - } else { - uniqueTeams := make(map[int]string) - authorizedTeams := make(map[int]bool) - for _, envContainer := range envContainers { - if _, ok := uniqueTeams[envContainer.TeamId]; !ok { - uniqueTeams[envContainer.TeamId] = envContainer.TeamName - } - } - - objectArray := make([]string, len(uniqueTeams)) - for _, teamName := range uniqueTeams { - object := strings.ToLower(teamName) - objectArray = append(objectArray, object) - } - - newCtx, span = otel.Tracer("enforcer").Start(newCtx, "EnforceByEmailInBatchForTeams") - start = time.Now() - resultMap := handler.enforcer.EnforceInBatch(token, casbin.ResourceTeam, casbin.ActionGet, objectArray) - middleware.AppListingDuration.WithLabelValues("enforceByEmailInBatchResourceTeam", "devtron").Observe(time.Since(start).Seconds()) - span.End() - for teamId, teamName := range uniqueTeams { - object := strings.ToLower(teamName) - if ok := resultMap[object]; ok { - authorizedTeams[teamId] = true - } - } - - filteredAppEnvContainers := make([]*bean.AppEnvironmentContainer, 0) - for _, envContainer := range envContainers { - if _, ok := authorizedTeams[envContainer.TeamId]; ok { - filteredAppEnvContainers = append(filteredAppEnvContainers, envContainer) - } - } - - objectArray = make([]string, len(filteredAppEnvContainers)) - for _, filteredAppEnvContainer := range filteredAppEnvContainers { - if fetchAppListingRequest.DeploymentGroupId > 0 { - if filteredAppEnvContainer.EnvironmentId != 0 && filteredAppEnvContainer.EnvironmentId != dg.EnvironmentId { - continue - } - } - object := fmt.Sprintf("%s/%s", filteredAppEnvContainer.TeamName, filteredAppEnvContainer.AppName) - object = strings.ToLower(object) - objectArray = append(objectArray, object) - } - - newCtx, span = otel.Tracer("enforcer").Start(newCtx, "EnforceByEmailInBatchForApps") - start = time.Now() - resultMap = handler.enforcer.EnforceInBatch(token, casbin.ResourceApplications, casbin.ActionGet, objectArray) - middleware.AppListingDuration.WithLabelValues("enforceByEmailInBatchResourceApplication", "devtron").Observe(time.Since(start).Seconds()) - span.End() - for _, filteredAppEnvContainer := range filteredAppEnvContainers { - if fetchAppListingRequest.DeploymentGroupId > 0 { - if filteredAppEnvContainer.EnvironmentId != 0 && filteredAppEnvContainer.EnvironmentId != dg.EnvironmentId { - continue - } - } - object := fmt.Sprintf("%s/%s", filteredAppEnvContainer.TeamName, filteredAppEnvContainer.AppName) - object = strings.ToLower(object) - if ok := resultMap[object]; ok { - appEnvContainers = append(appEnvContainers, filteredAppEnvContainer) - } - } - - } - t2 = time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "time diff", t2.Unix()-t1.Unix(), "stage", "3") - t1 = t2 - newCtx, span = otel.Tracer("appListingService").Start(newCtx, "BuildAppListingResponse") - apps, err := handler.appListingService.BuildAppListingResponse(fetchAppListingRequest, appEnvContainers) - span.End() - if err != nil { - handler.logger.Errorw("service err, FetchAppsByEnvironment", "err", err, "payload", fetchAppListingRequest) - common.WriteJsonResp(w, err, "", http.StatusInternalServerError) - } - - // Apply pagination - appsCount := len(apps) - offset := fetchAppListingRequest.Offset - limit := fetchAppListingRequest.Size - - if limit > 0 { - if offset+limit <= len(apps) { - apps = apps[offset : offset+limit] - } else { - apps = apps[offset:] - } - } - appContainerResponse := bean.AppContainerResponse{ - AppContainers: apps, - AppCount: appsCount, - } - if fetchAppListingRequest.DeploymentGroupId > 0 { - var ciMaterialDTOs []bean.CiMaterialDTO - for _, ci := range dg.CiMaterialDTOs { - ciMaterialDTOs = append(ciMaterialDTOs, bean.CiMaterialDTO{ - Name: ci.Name, - SourceValue: ci.SourceValue, - SourceType: ci.SourceType, - }) - } - appContainerResponse.DeploymentGroupDTO = bean.DeploymentGroupDTO{ - Id: dg.Id, - Name: dg.Name, - AppCount: dg.AppCount, - NoOfApps: dg.NoOfApps, - EnvironmentId: dg.EnvironmentId, - CiPipelineId: dg.CiPipelineId, - CiMaterialDTOs: ciMaterialDTOs, - } - } - t2 = time.Now() - handler.logger.Infow("api response time testing", "time", time.Now().String(), "time diff", t2.Unix()-t1.Unix(), "stage", "4") - t1 = t2 - handler.logger.Infow("api response time testing", "total time", time.Now().String(), "total time", t1.Unix()-t0.Unix()) - common.WriteJsonResp(w, err, appContainerResponse, http.StatusOK) -} func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentV2(w http.ResponseWriter, r *http.Request) { - //Allow CORS here By * or specific origin + // Allow CORS here By * or specific origin setupResponse(&w, r) token := r.Header.Get("token") t0 := time.Now() @@ -708,7 +334,7 @@ func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentV2(w http.Respons isActionUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*") span.End() validAppIds := make([]int, 0) - //for non super admin users + // for non super admin users if !isActionUserSuperAdmin { rbacObjectsForAllAppsMap := handler.enforcerUtil.GetRbacObjectsForAllApps(helper.CustomApp) rbacObjectToAppIdMap := make(map[string]int) @@ -721,7 +347,7 @@ func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentV2(w http.Respons } result := handler.enforcer.EnforceInBatch(token, casbin.ResourceApplications, casbin.ActionGet, rbacObjects) - //O(n) loop, n = len(rbacObjectsForAllAppsMap) + // O(n) loop, n = len(rbacObjectsForAllAppsMap) for object, ok := range result { if ok { validAppIds = append(validAppIds, rbacObjectToAppIdMap[object]) @@ -845,20 +471,20 @@ func (handler AppListingRestHandlerImpl) FetchOverviewAppsByEnvironment(w http.R return } resp.AppCount = len(resp.Apps) - //return all if user is super admin + // return all if user is super admin if isActionUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); isActionUserSuperAdmin { common.WriteJsonResp(w, err, resp, http.StatusOK) return } - //get all the appIds + // get all the appIds appIds := make([]int, 0) appContainers := resp.Apps for _, appBean := range resp.Apps { appIds = append(appIds, appBean.AppId) } - //get rbac objects for the appids + // get rbac objects for the appids rbacObjectsWithAppId := handler.enforcerUtil.GetRbacObjectsByAppIds(appIds) rbacObjects := make([]string, len(rbacObjectsWithAppId)) itr := 0 @@ -866,9 +492,9 @@ func (handler AppListingRestHandlerImpl) FetchOverviewAppsByEnvironment(w http.R rbacObjects[itr] = object itr++ } - //enforce rbac in batch + // enforce rbac in batch rbacResult := handler.enforcer.EnforceInBatch(token, casbin.ResourceApplications, casbin.ActionGet, rbacObjects) - //filter out rbac passed apps + // filter out rbac passed apps resp.Apps = make([]*bean.AppEnvironmentContainer, 0) for _, appBean := range appContainers { rbacObject := rbacObjectsWithAppId[appBean.AppId] @@ -1049,7 +675,7 @@ func (handler AppListingRestHandlerImpl) handleResourceTreeErrAndDeletePipelineI } } } - //not returned yet therefore no specific error to be handled, send error in internal message + // not returned yet therefore no specific error to be handled, send error in internal message common.WriteJsonResp(w, &util.ApiError{ InternalMessage: err.Error(), UserMessage: "unable to fetch resource tree", @@ -1074,7 +700,7 @@ func (handler AppListingRestHandlerImpl) FetchAppTriggerView(w http.ResponseWrit return } - //TODO: environment based auth, purge data of environment on which user doesnt have access, only show environment name + // TODO: environment based auth, purge data of environment on which user doesnt have access, only show environment name // RBAC enforcer applying if len(triggerView) > 0 { object := handler.enforcerUtil.GetAppRBACName(triggerView[0].AppName) @@ -1083,7 +709,7 @@ func (handler AppListingRestHandlerImpl) FetchAppTriggerView(w http.ResponseWrit return } } - //RBAC enforcer Ends + // RBAC enforcer Ends ctx, cancel := context.WithCancel(r.Context()) if cn, ok := w.(http.CloseNotifier); ok { @@ -1210,7 +836,7 @@ func (handler AppListingRestHandlerImpl) FetchAppStageStatus(w http.ResponseWrit common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) return } - //RBAC enforcer Ends + // RBAC enforcer Ends triggerView, err := handler.appListingService.FetchAppStageStatus(appId, int(app.AppType)) if err != nil { @@ -1245,7 +871,7 @@ func (handler AppListingRestHandlerImpl) FetchOtherEnvironment(w http.ResponseWr common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden) return } - //RBAC enforcer Ends + // RBAC enforcer Ends newCtx, span = otel.Tracer("appListingService").Start(newCtx, "FetchOtherEnvironment") otherEnvironment, err := handler.appListingService.FetchOtherEnvironment(newCtx, appId) @@ -1256,7 +882,7 @@ func (handler AppListingRestHandlerImpl) FetchOtherEnvironment(w http.ResponseWr return } - //TODO - rbac env level + // TODO - rbac env level common.WriteJsonResp(w, err, otherEnvironment, http.StatusOK) } @@ -1284,7 +910,7 @@ func (handler AppListingRestHandlerImpl) FetchMinDetailOtherEnvironment(w http.R common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden) return } - //RBAC enforcer Ends + // RBAC enforcer Ends otherEnvironment, err := handler.appListingService.FetchMinDetailOtherEnvironment(appId) if err != nil { @@ -1293,7 +919,7 @@ func (handler AppListingRestHandlerImpl) FetchMinDetailOtherEnvironment(w http.R return } - //TODO - rbac env level + // TODO - rbac env level common.WriteJsonResp(w, err, otherEnvironment, http.StatusOK) } @@ -1334,7 +960,7 @@ func (handler AppListingRestHandlerImpl) RedirectToLinkouts(w http.ResponseWrite common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden) return } - //RBAC enforcer Ends + // RBAC enforcer Ends link, err := handler.appListingService.RedirectToLinkouts(Id, appId, envId, podName, containerName) if err != nil || len(link) == 0 { @@ -1397,7 +1023,7 @@ func (handler AppListingRestHandlerImpl) GetHostUrlsByBatch(w http.ResponseWrite common.WriteJsonResp(w, fmt.Errorf("app is neither helm app or devtron app"), nil, http.StatusBadRequest) return } - //check user authorization for this app + // check user authorization for this app if installedAppIdParam != "" { object, object2 := handler.enforcerUtil.GetHelmObjectByAppNameAndEnvId(appDetail.AppName, appDetail.EnvironmentId) ok := handler.enforcer.Enforce(token, casbin.ResourceHelmApp, casbin.ActionGet, object) || handler.enforcer.Enforce(token, casbin.ResourceHelmApp, casbin.ActionGet, object2) @@ -1458,7 +1084,7 @@ func (handler AppListingRestHandlerImpl) GetHostUrlsByBatch(w http.ResponseWrite common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } - //valid batch requests, only valid requests will be sent for batch processing + // valid batch requests, only valid requests will be sent for batch processing validRequests := handler.k8sCommonService.FilterK8sResources(r.Context(), resourceTree, appDetail, "", []string{k8sCommonBean.ServiceKind, k8sCommonBean.IngressKind}) if len(validRequests) == 0 { handler.logger.Error("neither service nor ingress found for", "appId", appIdParam, "envId", envIdParam, "installedAppId", installedAppIdParam) @@ -1500,7 +1126,7 @@ func (handler AppListingRestHandlerImpl) getAppDetails(ctx context.Context, appI func (handler AppListingRestHandlerImpl) fetchResourceTree(w http.ResponseWriter, r *http.Request, appId int, envId int, acdToken string, cdPipeline *pipelineConfig.Pipeline) (map[string]interface{}, error) { var resourceTree map[string]interface{} if len(cdPipeline.DeploymentAppName) > 0 && cdPipeline.EnvironmentId > 0 && util.IsAcdApp(cdPipeline.DeploymentAppType) { - //RBAC enforcer Ends + // RBAC enforcer Ends query := &application2.ResourcesQuery{ ApplicationName: &cdPipeline.DeploymentAppName, } @@ -1530,7 +1156,7 @@ func (handler AppListingRestHandlerImpl) fetchResourceTree(w http.ResponseWriter return resourceTree, err } - //we currently add appId and envId as labels for devtron apps deployed via acd + // we currently add appId and envId as labels for devtron apps deployed via acd label := fmt.Sprintf("appId=%v,envId=%v", cdPipeline.AppId, cdPipeline.EnvironmentId) pods, err := handler.k8sApplicationService.GetPodListByLabel(cdPipeline.Environment.ClusterId, cdPipeline.Environment.Namespace, label) if err != nil { @@ -1566,7 +1192,7 @@ func (handler AppListingRestHandlerImpl) fetchResourceTree(w http.ResponseWriter handler.logger.Errorw("error in syncing pipeline status", "err", err) } } - //updating app_status table here + // updating app_status table here err = handler.appStatusService.UpdateStatusWithAppIdEnvId(appId, envId, resp.Status) if err != nil { handler.logger.Warnw("error in updating app status", "err", err, "appId", cdPipeline.AppId, "envId", cdPipeline.EnvironmentId) @@ -1663,7 +1289,7 @@ func (handler AppListingRestHandlerImpl) ManualSyncAcdPipelineDeploymentStatus(w common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden) return } - //RBAC enforcer Ends + // RBAC enforcer Ends if app.AppType == helper.ChartStoreApp { err = handler.cdApplicationStatusUpdateHandler.ManualSyncPipelineStatus(appId, 0, userId) } else { @@ -1702,7 +1328,7 @@ func (handler AppListingRestHandlerImpl) GetClusterTeamAndEnvListForAutocomplete if err != nil { authEnabled = true err = nil - //ignore error, apply rbac by default + // ignore error, apply rbac by default } } // RBAC enforcer applying @@ -1720,13 +1346,13 @@ func (handler AppListingRestHandlerImpl) GetClusterTeamAndEnvListForAutocomplete } handler.logger.Infow("Cluster elapsed Time for enforcer", "dbElapsedTime", dbOperationTime, "enforcerTime", time.Since(start), "envSize", len(granterClusters)) - //RBAC enforcer Ends + // RBAC enforcer Ends if len(granterClusters) == 0 { granterClusters = make([]cluster.ClusterBean, 0) } - //getting environment for autocomplete + // getting environment for autocomplete start = time.Now() environments, err := handler.environmentClusterMappingsService.GetEnvironmentOnlyListForAutocomplete() if err != nil { @@ -1766,13 +1392,13 @@ func (handler AppListingRestHandlerImpl) GetClusterTeamAndEnvListForAutocomplete grantedEnvironment = append(grantedEnvironment, item) } } - //RBAC enforcer Ends + // RBAC enforcer Ends } elapsedTime := time.Since(start) handler.logger.Infow("Env elapsed Time for enforcer", "dbElapsedTime", dbElapsedTime, "elapsedTime", elapsedTime, "envSize", len(grantedEnvironment)) - //getting teams for autocomplete + // getting teams for autocomplete start = time.Now() teams, err := handler.teamService.FetchForAutocomplete() if err != nil { @@ -1802,7 +1428,7 @@ func (handler AppListingRestHandlerImpl) GetClusterTeamAndEnvListForAutocomplete handler.logger.Infow("Team elapsed Time for enforcer", "dbElapsedTime", dbElapsedTime, "elapsedTime", time.Since(start), "envSize", len(grantedTeams)) - //RBAC enforcer Ends + // RBAC enforcer Ends resp := &AppAutocomplete{ Teams: grantedTeams, Environments: grantedEnvironment, diff --git a/api/router/AppListingRouter.go b/api/router/AppListingRouter.go index affdb158237..ea7b21bd9d4 100644 --- a/api/router/AppListingRouter.go +++ b/api/router/AppListingRouter.go @@ -45,11 +45,11 @@ func (router AppListingRouterImpl) initAppListingRouter(appListingRouter *mux.Ro HandlerFunc(router.appListingRestHandler.GetHostUrlsByBatch).Methods("GET") appListingRouter.Path("/list"). - HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironment). + HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironmentV2). Methods("POST") - appListingRouter.Path("/list/{version}"). - HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironmentVersioned). + appListingRouter.Path("/list/v2"). + HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironmentV2). Methods("POST") appListingRouter.Path("/list/group/{env-id}"). @@ -60,7 +60,7 @@ func (router AppListingRouterImpl) initAppListingRouter(appListingRouter *mux.Ro Queries("size", "{size}", "offset", "{offset}"). HandlerFunc(router.appListingRestHandler.FetchOverviewAppsByEnvironment). Methods("GET") - //This API used for fetch app details, not deployment details + // This API used for fetch app details, not deployment details appListingRouter.Path("/detail").Queries("app-id", "{app-id}").Queries("env-id", "{env-id}"). HandlerFunc(router.appListingRestHandler.FetchAppDetails). Methods("GET") diff --git a/internal/sql/repository/AppListingRepository.go b/internal/sql/repository/AppListingRepository.go index ecff1f94c22..ab7a5fc7160 100644 --- a/internal/sql/repository/AppListingRepository.go +++ b/internal/sql/repository/AppListingRepository.go @@ -27,7 +27,6 @@ import ( "github.com/devtron-labs/devtron/internal/middleware" repository2 "github.com/devtron-labs/devtron/pkg/cluster/repository" "go.opentelemetry.io/otel" - "strconv" "strings" "time" @@ -38,7 +37,6 @@ import ( ) type AppListingRepository interface { - FetchAppsByEnvironment(appListingFilter helper.AppListingFilter) ([]*bean.AppEnvironmentContainer, error) FetchJobs(appIds []int, statuses []string, environmentIds []int, sortOrder string) ([]*bean.JobListingContainer, error) FetchOverviewCiPipelines(jobId int) ([]*bean.JobListingContainer, error) FetchJobsLastSucceededOn(ciPipelineIDs []int) ([]*bean.CiPipelineLastSucceededTime, error) @@ -47,7 +45,7 @@ type AppListingRepository interface { FetchAppTriggerView(appId int) ([]bean.TriggerView, error) FetchAppStageStatus(appId int, appType int) ([]bean.AppStageStatus, error) - //Not in used + // Not in used PrometheusApiByEnvId(id int) (*string, error) FetchOtherEnvironment(appId int) ([]*bean.Environment, error) @@ -193,81 +191,6 @@ func getRequiredAppIdsInSequence(appIds []int) []int { return resIDs } -func (impl AppListingRepositoryImpl) FetchAppsByEnvironment(appListingFilter helper.AppListingFilter) ([]*bean.AppEnvironmentContainer, error) { - impl.Logger.Debug("reached at FetchAppsByEnvironment:") - var appEnvArr []*bean.AppEnvironmentContainer - - query := impl.appListingRepositoryQueryBuilder.BuildAppListingQueryLastDeploymentTime() - impl.Logger.Debugw("basic app detail query: ", query) - var lastDeployedTimeDTO []*bean.AppEnvironmentContainer - lastDeployedTimeMap := map[int]*bean.AppEnvironmentContainer{} - start := time.Now() - _, err := impl.dbConnection.Query(&lastDeployedTimeDTO, query) - middleware.AppListingDuration.WithLabelValues("buildAppListingQueryLastDeploymentTime", "devtron").Observe(time.Since(start).Seconds()) - if err != nil { - impl.Logger.Error(err) - return appEnvArr, err - } - for _, item := range lastDeployedTimeDTO { - if _, ok := lastDeployedTimeMap[item.PipelineId]; ok { - continue - } - lastDeployedTimeMap[item.PipelineId] = &bean.AppEnvironmentContainer{ - LastDeployedTime: item.LastDeployedTime, - DataSource: item.DataSource, - MaterialInfoJson: item.MaterialInfoJson, - CiArtifactId: item.CiArtifactId, - } - } - - var appEnvContainer []*bean.AppEnvironmentContainer - appsEnvquery := impl.appListingRepositoryQueryBuilder.BuildAppListingQuery(appListingFilter) - impl.Logger.Debugw("basic app detail query: ", appsEnvquery) - start = time.Now() - _, appsErr := impl.dbConnection.Query(&appEnvContainer, appsEnvquery) - middleware.AppListingDuration.WithLabelValues("buildAppListingQuery", "devtron").Observe(time.Since(start).Seconds()) - if appsErr != nil { - impl.Logger.Error(appsErr) - return appEnvContainer, appsErr - } - latestDeploymentStatusMap := map[string]*bean.AppEnvironmentContainer{} - for _, item := range appEnvContainer { - if item.EnvironmentId > 0 && item.PipelineId > 0 && item.Active == false { - // skip adding apps which have linked with cd pipeline and that environment has marked as deleted. - continue - } - // include only apps which are not linked with any cd pipeline + those linked with cd pipeline and env has active. - key := strconv.Itoa(item.AppId) + "_" + strconv.Itoa(item.EnvironmentId) - if _, ok := latestDeploymentStatusMap[key]; ok { - continue - } - - if lastDeployedTime, ok := lastDeployedTimeMap[item.PipelineId]; ok { - item.LastDeployedTime = lastDeployedTime.LastDeployedTime - item.DataSource = lastDeployedTime.DataSource - item.MaterialInfoJson = lastDeployedTime.MaterialInfoJson - item.CiArtifactId = lastDeployedTime.CiArtifactId - } - - if len(item.DataSource) > 0 { - mInfo, err := parseMaterialInfo(item.MaterialInfoJson, item.DataSource) - if err == nil && len(mInfo) > 0 { - item.MaterialInfo = mInfo - } else { - item.MaterialInfo = []byte("[]") - } - item.MaterialInfoJson = "" - } else { - item.MaterialInfo = []byte("[]") - item.MaterialInfoJson = "" - } - appEnvArr = append(appEnvArr, item) - latestDeploymentStatusMap[key] = item - } - - return appEnvArr, nil -} - func (impl AppListingRepositoryImpl) FetchAppsByEnvironmentV2(appListingFilter helper.AppListingFilter) ([]*bean.AppEnvironmentContainer, int, error) { impl.Logger.Debugw("reached at FetchAppsByEnvironment ", "appListingFilter", appListingFilter) var appEnvArr []*bean.AppEnvironmentContainer @@ -306,7 +229,7 @@ func (impl AppListingRepositoryImpl) FetchAppsByEnvironmentV2(appListingFilter h } else { - //to get all the appIds in appEnvs allowed for user and filtered by the appListing filter and sorted by name + // to get all the appIds in appEnvs allowed for user and filtered by the appListing filter and sorted by name appIdCountDtos := make([]*bean.AppEnvironmentContainer, 0) appIdCountQuery := impl.appListingRepositoryQueryBuilder.GetAppIdsQueryWithPaginationForAppNameSearch(appListingFilter) impl.Logger.Debug("GetAppIdsQueryWithPaginationForAppNameSearch query ", appIdCountQuery) @@ -327,7 +250,7 @@ func (impl AppListingRepositoryImpl) FetchAppsByEnvironmentV2(appListingFilter h uniqueAppIds[i] = obj.AppId } appListingFilter.AppIds = uniqueAppIds - //set appids required for this page in the filter and get the appEnv containers of these apps + // set appids required for this page in the filter and get the appEnv containers of these apps appListingFilter.AppIds = uniqueAppIds appsEnvquery := impl.appListingRepositoryQueryBuilder.GetQueryForAppEnvContainerss(appListingFilter) impl.Logger.Debug("GetQueryForAppEnvContainerss query: ", appsEnvquery) @@ -341,8 +264,8 @@ func (impl AppListingRepositoryImpl) FetchAppsByEnvironmentV2(appListingFilter h } - //filter out unique pipelineIds from the above result and get the deployment times for them - //some items don't have pipelineId if no pipeline is configured for the app in the appEnv container + // filter out unique pipelineIds from the above result and get the deployment times for them + // some items don't have pipelineId if no pipeline is configured for the app in the appEnv container pipelineIdsSet := make(map[int]bool) pipelineIds := make([]int, 0) for _, item := range appEnvContainer { @@ -353,7 +276,7 @@ func (impl AppListingRepositoryImpl) FetchAppsByEnvironmentV2(appListingFilter h } } - //if any pipeline found get the latest deployment time + // if any pipeline found get the latest deployment time if len(pipelineIds) > 0 { query := impl.appListingRepositoryQueryBuilder.BuildAppListingQueryLastDeploymentTimeV2(pipelineIds) impl.Logger.Debugw("basic app detail query: ", query) @@ -366,7 +289,7 @@ func (impl AppListingRepositoryImpl) FetchAppsByEnvironmentV2(appListingFilter h } } - //get the last deployment time for all the items + // get the last deployment time for all the items for _, item := range lastDeployedTimeDTO { if _, ok := lastDeployedTimeMap[item.PipelineId]; ok { continue @@ -375,7 +298,7 @@ func (impl AppListingRepositoryImpl) FetchAppsByEnvironmentV2(appListingFilter h } - //set the time for corresponding appEnv container + // set the time for corresponding appEnv container for _, item := range appEnvContainer { if lastDeployedTime, ok := lastDeployedTimeMap[item.PipelineId]; ok { item.LastDeployedTime = lastDeployedTime @@ -483,7 +406,7 @@ func (impl AppListingRepositoryImpl) FetchAppDetail(ctx context.Context, appId i var appDetailContainer bean.AppDetailContainer newCtx, span := otel.Tracer("orchestrator").Start(ctx, "DeploymentDetailsByAppIdAndEnvId") defer span.End() - //Fetch deployment detail of cd pipeline latest triggered within env of any App. + // Fetch deployment detail of cd pipeline latest triggered within env of any App. deploymentDetail, err := impl.deploymentDetailsByAppIdAndEnvId(newCtx, appId, envId) if err != nil { impl.Logger.Warn("unable to fetch deployment detail for app") @@ -511,7 +434,7 @@ func (impl AppListingRepositoryImpl) PrometheusApiByEnvId(id int) (*string, erro query := "SELECT env.prometheus_endpoint from environment env" + " WHERE env.id = ? AND env.active = TRUE" impl.Logger.Debugw("query", query) - //environments := []string{"QA"} + // environments := []string{"QA"} _, err := impl.dbConnection.Query(&prometheusEndpoint, query, id) if err != nil { impl.Logger.Error("Exception caught:", err) diff --git a/internal/sql/repository/helper/AppListingRepositoryQueryBuilder.go b/internal/sql/repository/helper/AppListingRepositoryQueryBuilder.go index dd686ae16df..42409bb5900 100644 --- a/internal/sql/repository/helper/AppListingRepositoryQueryBuilder.go +++ b/internal/sql/repository/helper/AppListingRepositoryQueryBuilder.go @@ -54,7 +54,7 @@ type AppListingFilter struct { Offset int `json:"offset"` Size int `json:"size"` DeploymentGroupId int `json:"deploymentGroupId"` - AppIds []int `json:"-"` //internal use only + AppIds []int `json:"-"` // internal use only } type SortBy string @@ -128,17 +128,6 @@ func getAppListingCommonQueryString() string { " LEFT JOIN app_status aps on aps.app_id = a.id and p.environment_id = aps.env_id " } -func (impl AppListingRepositoryQueryBuilder) BuildAppListingQueryForAppIds(appListingFilter AppListingFilter) string { - whereCondition := impl.buildAppListingWhereCondition(appListingFilter) - orderByClause := impl.buildAppListingSortBy(appListingFilter) - query := "SELECT a.id as app_id " + getAppListingCommonQueryString() - if appListingFilter.DeploymentGroupId != 0 { - query = query + " INNER JOIN deployment_group_app dga ON a.id = dga.app_id " - } - query = query + whereCondition + orderByClause - return query -} - func (impl AppListingRepositoryQueryBuilder) BuildAppListingQuery(appListingFilter AppListingFilter) string { whereCondition := impl.buildAppListingWhereCondition(appListingFilter) orderByClause := impl.buildAppListingSortBy(appListingFilter) @@ -152,15 +141,6 @@ func (impl AppListingRepositoryQueryBuilder) BuildAppListingQuery(appListingFilt return query } -func (impl AppListingRepositoryQueryBuilder) BuildAppListingQueryLastDeploymentTime() string { - query := "select DISTINCT ON( pco.pipeline_id) pco.pipeline_id, pco.pipeline_release_counter, pco.created_on as last_deployed_time," + - " cia.data_source, cia.material_info as material_info_json, cia.id as ci_artifact_id" + - " from pipeline_config_override pco" + - " inner join ci_artifact cia on cia.id=pco.ci_artifact_id" + - " order by pco.pipeline_id,pco.pipeline_release_counter desc;" - return query -} - func (impl AppListingRepositoryQueryBuilder) GetQueryForAppEnvContainerss(appListingFilter AppListingFilter) string { query := "SELECT p.environment_id , a.id AS app_id, a.app_name,p.id as pipeline_id, a.team_id ,aps.status as app_status " @@ -242,31 +222,6 @@ func (impl AppListingRepositoryQueryBuilder) buildAppListingSortBy(appListingFil return orderByCondition } -func (impl AppListingRepositoryQueryBuilder) buildJobListingSortBy(appListingFilter AppListingFilter) string { - orderByCondition := " ORDER BY a.name" - return orderByCondition -} - -func (impl AppListingRepositoryQueryBuilder) buildJobListingWhereCondition(jobListingFilter AppListingFilter) string { - whereCondition := "WHERE a.active = true and a.app_type = 2 " - - if len(jobListingFilter.Teams) > 0 { - teamIds := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(jobListingFilter.Teams)), ","), "[]") - whereCondition = whereCondition + "and a.team_id IN (" + teamIds + ") " - } - - if jobListingFilter.AppNameSearch != "" { - likeClause := "'%" + jobListingFilter.AppNameSearch + "%'" - whereCondition = whereCondition + "and a.display_name like " + likeClause + " " - } - // add job stats filter here - if len(jobListingFilter.AppStatuses) > 0 { - appStatuses := util.ProcessAppStatuses(jobListingFilter.AppStatuses) - whereCondition = whereCondition + "and aps.status IN (" + appStatuses + ") " - } - return whereCondition -} - func (impl AppListingRepositoryQueryBuilder) buildAppListingWhereCondition(appListingFilter AppListingFilter) string { whereCondition := "WHERE a.active = true and a.app_type = 0 " if len(appListingFilter.Environments) > 0 { @@ -287,7 +242,7 @@ func (impl AppListingRepositoryQueryBuilder) buildAppListingWhereCondition(appLi if appListingFilter.DeploymentGroupId > 0 { whereCondition = whereCondition + "and dga.deployment_group_id = " + strconv.Itoa(appListingFilter.DeploymentGroupId) + " " } - //add app-status filter here + // add app-status filter here var appStatusExcludingNotDeployed []string var isNotDeployedFilterApplied bool if len(appListingFilter.AppStatuses) > 0 { diff --git a/pkg/app/AppListingService.go b/pkg/app/AppListingService.go index f93bd4408af..9a43fd519d2 100644 --- a/pkg/app/AppListingService.go +++ b/pkg/app/AppListingService.go @@ -56,10 +56,8 @@ import ( ) type AppListingService interface { - FetchAppsByEnvironment(fetchAppListingRequest FetchAppListingRequest, w http.ResponseWriter, r *http.Request, token string, apiVersion string) ([]*bean.AppEnvironmentContainer, error) FetchJobs(fetchJobListingRequest FetchAppListingRequest) ([]*bean.JobContainer, error) FetchOverviewCiPipelines(jobId int) ([]*bean.JobListingContainer, error) - BuildAppListingResponse(fetchAppListingRequest FetchAppListingRequest, envContainers []*bean.AppEnvironmentContainer) ([]*bean.AppContainer, error) BuildAppListingResponseV2(fetchAppListingRequest FetchAppListingRequest, envContainers []*bean.AppEnvironmentContainer) ([]*bean.AppContainer, error) FetchAllDevtronManagedApps() ([]AppNameTypeIdContainer, error) FetchAppDetails(ctx context.Context, appId int, envId int) (bean.AppDetailContainer, error) @@ -73,13 +71,13 @@ type AppListingService interface { MemoryUsageGroupByPod(namespace string, env string, proEndpoint string) map[string]string MemoryRequestGroupByPod(namespace string, env string, proEndpoint string) map[string]string - //Currently not in use + // Currently not in use CpuUsageGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string CpuRequestGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string MemoryUsageGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string MemoryRequestGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string - //Currently not in use (intent to fetch graph data from prometheus) + // Currently not in use (intent to fetch graph data from prometheus) CpuUsageGroupByPodGraph(podName string, namespace string, env string, proEndpoint string, r v1.Range) map[string][]interface{} MemoryUsageGroupByPodGraph(podName string, namespace string, env string, proEndpoint string, r v1.Range) map[string][]interface{} GraphAPI(appId int, envId int) error @@ -115,10 +113,10 @@ type FetchAppListingRequest struct { Offset int `json:"offset"` Size int `json:"size"` DeploymentGroupId int `json:"deploymentGroupId"` - Namespaces []string `json:"namespaces"` //{clusterId}_{namespace} + Namespaces []string `json:"namespaces"` // {clusterId}_{namespace} AppStatuses []string `json:"appStatuses"` - AppIds []int `json:"-"` //internal use only - //IsClusterOrNamespaceSelected bool `json:"isClusterOrNamespaceSelected"` + AppIds []int `json:"-"` // internal use only + // IsClusterOrNamespaceSelected bool `json:"isClusterOrNamespaceSelected"` } type AppNameTypeIdContainer struct { AppName string `json:"appName"` @@ -345,72 +343,6 @@ func (impl AppListingServiceImpl) FetchOverviewCiPipelines(jobId int) ([]*bean.J return jobCiContainers, nil } -func (impl AppListingServiceImpl) FetchAppsByEnvironment(fetchAppListingRequest FetchAppListingRequest, w http.ResponseWriter, r *http.Request, token string, apiVersion string) ([]*bean.AppEnvironmentContainer, error) { - impl.Logger.Debugw("reached at FetchAppsByEnvironment", "fetchAppListingRequest", fetchAppListingRequest) - if apiVersion == APIVersionV1 { - if len(fetchAppListingRequest.Namespaces) != 0 && len(fetchAppListingRequest.Environments) == 0 { - return []*bean.AppEnvironmentContainer{}, nil - } - } else { - newCtx, span := otel.Tracer("fetchAppListingRequest").Start(r.Context(), "GetNamespaceClusterMapping") - mappings, clusterIds, err := fetchAppListingRequest.GetNamespaceClusterMapping() - span.End() - if err != nil { - impl.Logger.Errorw("error in fetching app list", "error", err) - return []*bean.AppEnvironmentContainer{}, err - } - if len(mappings) > 0 { - newCtx, span = otel.Tracer("environmentRepository").Start(newCtx, "FindByClusterIdAndNamespace") - envs, err := impl.environmentRepository.FindByClusterIdAndNamespace(mappings) - span.End() - if err != nil { - impl.Logger.Errorw("error in cluster ns mapping") - return []*bean.AppEnvironmentContainer{}, err - } - for _, env := range envs { - fetchAppListingRequest.Environments = append(fetchAppListingRequest.Environments, env.Id) - } - } - if len(clusterIds) > 0 { - newCtx, span = otel.Tracer("environmentRepository").Start(newCtx, "FindByClusterIds") - envs, err := impl.environmentRepository.FindByClusterIds(clusterIds) - span.End() - if err != nil { - impl.Logger.Errorw("error in cluster ns mapping") - return []*bean.AppEnvironmentContainer{}, err - } - for _, env := range envs { - fetchAppListingRequest.Environments = append(fetchAppListingRequest.Environments, env.Id) - } - - } - if (len(clusterIds) > 0 || len(mappings) > 0) && len(fetchAppListingRequest.Environments) == 0 { - // no result when no matching cluster and env - return []*bean.AppEnvironmentContainer{}, nil - } - } - // TODO: check statuses - appListingFilter := helper.AppListingFilter{ - Environments: fetchAppListingRequest.Environments, - Statuses: fetchAppListingRequest.Statuses, - Teams: fetchAppListingRequest.Teams, - AppNameSearch: fetchAppListingRequest.AppNameSearch, - SortOrder: fetchAppListingRequest.SortOrder, - SortBy: fetchAppListingRequest.SortBy, - Offset: fetchAppListingRequest.Offset, - Size: fetchAppListingRequest.Size, - DeploymentGroupId: fetchAppListingRequest.DeploymentGroupId, - AppStatuses: fetchAppListingRequest.AppStatuses, - } - _, span := otel.Tracer("appListingRepository").Start(r.Context(), "FetchAppsByEnvironment") - envContainers, err := impl.appListingRepository.FetchAppsByEnvironment(appListingFilter) - span.End() - if err != nil { - impl.Logger.Errorw("error in fetching app list", "error", err) - return []*bean.AppEnvironmentContainer{}, err - } - return envContainers, err -} func (impl AppListingServiceImpl) FetchAppsByEnvironmentV2(fetchAppListingRequest FetchAppListingRequest, w http.ResponseWriter, r *http.Request, token string) ([]*bean.AppEnvironmentContainer, int, error) { impl.Logger.Debug("reached at FetchAppsByEnvironment:") if len(fetchAppListingRequest.Namespaces) != 0 && len(fetchAppListingRequest.Environments) == 0 { @@ -531,20 +463,6 @@ func (impl AppListingServiceImpl) GetReleaseCount(appId, envId int) (int, error) } } -func (impl AppListingServiceImpl) BuildAppListingResponse(fetchAppListingRequest FetchAppListingRequest, envContainers []*bean.AppEnvironmentContainer) ([]*bean.AppContainer, error) { - start := time.Now() - appEnvMapping, err := impl.fetchACDAppStatus(fetchAppListingRequest, envContainers) - middleware.AppListingDuration.WithLabelValues("fetchACDAppStatus", "devtron").Observe(time.Since(start).Seconds()) - if err != nil { - impl.Logger.Errorw("error in fetching app statuses", "error", err) - return []*bean.AppContainer{}, err - } - start = time.Now() - appContainerResponses, err := impl.appListingViewBuilder.BuildView(fetchAppListingRequest, appEnvMapping) - middleware.AppListingDuration.WithLabelValues("buildView", "devtron").Observe(time.Since(start).Seconds()) - return appContainerResponses, err -} - func (impl AppListingServiceImpl) BuildAppListingResponseV2(fetchAppListingRequest FetchAppListingRequest, envContainers []*bean.AppEnvironmentContainer) ([]*bean.AppContainer, error) { start := time.Now() appEnvMapping, err := impl.fetchACDAppStatusV2(fetchAppListingRequest, envContainers) @@ -575,7 +493,7 @@ func BuildJobListingResponse(jobContainers []*bean.JobListingContainer, JobsLast lastSucceededTimeMapping[lastSuccessTime.CiPipelineID] = lastSuccessTime.LastSucceededOn } - //Storing the sequence in appIds array + // Storing the sequence in appIds array for _, jobContainer := range jobContainers { val, ok := jobContainersMapping[jobContainer.JobId] if !ok { @@ -599,7 +517,7 @@ func BuildJobListingResponse(jobContainers []*bean.JobListingContainer, JobsLast EnvironmentName: jobContainer.EnvironmentName, EnvironmentId: jobContainer.EnvironmentId, LastTriggeredEnvironmentName: jobContainer.LastTriggeredEnvironmentName, - //LastSuccessAt: jobContainer.LastSuccessAt, + // LastSuccessAt: jobContainer.LastSuccessAt, } if lastSuccessAt, ok := lastSucceededTimeMapping[jobContainer.CiPipelineID]; ok { ciPipelineObj.LastSuccessAt = lastSuccessAt @@ -639,14 +557,14 @@ func (impl AppListingServiceImpl) fetchACDAppStatus(fetchAppListingRequest Fetch appEnvCdWorkflowMap := make(map[string]*pipelineConfig.CdWorkflow) appEnvCdWorkflowRunnerMap := make(map[int][]*pipelineConfig.CdWorkflowRunner) - //get all the active cd pipelines + // get all the active cd pipelines if len(pipelineIds) > 0 { - pipelinesAll, err := impl.pipelineRepository.FindByIdsIn(pipelineIds) //TODO - OPTIMIZE 1 + pipelinesAll, err := impl.pipelineRepository.FindByIdsIn(pipelineIds) // TODO - OPTIMIZE 1 if err != nil && !util.IsErrNoRows(err) { impl.Logger.Errorw("err", err) return nil, err } - //here to build a map of pipelines list for each (appId and envId) + // here to build a map of pipelines list for each (appId and envId) for _, p := range pipelinesAll { key := fmt.Sprintf("%d-%d", p.AppId, p.EnvironmentId) if _, ok := appEnvPipelinesMap[key]; !ok { @@ -661,7 +579,7 @@ func (impl AppListingServiceImpl) fetchACDAppStatus(fetchAppListingRequest Fetch } // from all the active pipeline, get all the cd workflow - cdWorkflowAll, err := impl.cdWorkflowRepository.FindLatestCdWorkflowByPipelineIdV2(pipelineIds) //TODO - OPTIMIZE 2 + cdWorkflowAll, err := impl.cdWorkflowRepository.FindLatestCdWorkflowByPipelineIdV2(pipelineIds) // TODO - OPTIMIZE 2 if err != nil && !util.IsErrNoRows(err) { impl.Logger.Error(err) return nil, err @@ -679,19 +597,19 @@ func (impl AppListingServiceImpl) fetchACDAppStatus(fetchAppListingRequest Fetch } } } - //if no cd wf found for appid-envid, add it into map with nil + // if no cd wf found for appid-envid, add it into map with nil if _, ok := appEnvCdWorkflowMap[key]; !ok { appEnvCdWorkflowMap[key] = nil } } } - //fetch all the cd workflow runner from cdWF ids, - cdWorkflowRunnersAll, err := impl.cdWorkflowRepository.FindWorkflowRunnerByCdWorkflowId(wfIds) //TODO - OPTIMIZE 3 + // fetch all the cd workflow runner from cdWF ids, + cdWorkflowRunnersAll, err := impl.cdWorkflowRepository.FindWorkflowRunnerByCdWorkflowId(wfIds) // TODO - OPTIMIZE 3 if err != nil { impl.Logger.Errorw("error in getting wf", "err", err) } - //build a map with key cdWF containing cdWFRunner List, which are later put in map for further requirement + // build a map with key cdWF containing cdWFRunner List, which are later put in map for further requirement for _, item := range cdWorkflowRunnersAll { if _, ok := appEnvCdWorkflowRunnerMap[item.CdWorkflowId]; !ok { var cdWorkflowRunners []*pipelineConfig.CdWorkflowRunner @@ -814,7 +732,7 @@ func (impl AppListingServiceImpl) fetchACDAppStatusV2(fetchAppListingRequest Fet } func (impl AppListingServiceImpl) getAppACDStatus(env bean.AppEnvironmentContainer, w http.ResponseWriter, r *http.Request, token string) (string, error) { - //not being used now + // not being used now if len(env.AppName) > 0 && len(env.EnvironmentName) > 0 { acdAppName := env.AppName + "-" + env.EnvironmentName query := &application.ResourcesQuery{ @@ -1006,7 +924,7 @@ func (impl AppListingServiceImpl) PodCountByAppLabel(appLabel string, namespace for k, v := range ito.(map[string]interface{}) { if k == "value" { vArr := v.([]interface{}) - //t := (vArr[1].(string)) + // t := (vArr[1].(string)) feetInt, err := strconv.Atoi(vArr[1].(string)) if err != nil { feetInt = 0 @@ -1718,8 +1636,8 @@ func (impl AppListingServiceImpl) FetchOtherEnvironment(ctx context.Context, app impl.Logger.Errorw("err", err) return envs, err } - appLevelAppMetrics := false //default value - appLevelInfraMetrics := true //default val + appLevelAppMetrics := false // default value + appLevelInfraMetrics := true // default val newCtx, span = otel.Tracer("appLevelMetricsRepository").Start(newCtx, "FindByAppId") appLevelMetrics, err := impl.appLevelMetricsRepository.FindByAppId(appId) span.End() @@ -1727,9 +1645,9 @@ func (impl AppListingServiceImpl) FetchOtherEnvironment(ctx context.Context, app impl.Logger.Errorw("error in fetching app metrics", "err", err) return envs, err } else if util.IsErrNoRows(err) { - //populate default val - appLevelAppMetrics = false //default value - appLevelInfraMetrics = true //default val + // populate default val + appLevelAppMetrics = false // default value + appLevelInfraMetrics = true // default val } else { appLevelAppMetrics = appLevelMetrics.AppMetrics appLevelInfraMetrics = appLevelMetrics.InfraMetrics @@ -1770,16 +1688,16 @@ func (impl AppListingServiceImpl) FetchMinDetailOtherEnvironment(appId int) ([]* impl.Logger.Errorw("err", err) return envs, err } - appLevelAppMetrics := false //default value - appLevelInfraMetrics := true //default val + appLevelAppMetrics := false // default value + appLevelInfraMetrics := true // default val appLevelMetrics, err := impl.appLevelMetricsRepository.FindByAppId(appId) if err != nil && !util.IsErrNoRows(err) { impl.Logger.Errorw("error in fetching app metrics", "err", err) return envs, err } else if util.IsErrNoRows(err) { - //populate default val - appLevelAppMetrics = false //default value - appLevelInfraMetrics = true //default val + // populate default val + appLevelAppMetrics = false // default value + appLevelInfraMetrics = true // default val } else { appLevelAppMetrics = appLevelMetrics.AppMetrics appLevelInfraMetrics = appLevelMetrics.InfraMetrics