diff --git a/Wire.go b/Wire.go index a0307b98a9..590d4bbfa8 100644 --- a/Wire.go +++ b/Wire.go @@ -44,9 +44,26 @@ import ( "github.com/devtron-labs/devtron/api/k8s" "github.com/devtron-labs/devtron/api/module" "github.com/devtron-labs/devtron/api/restHandler" - pipeline2 "github.com/devtron-labs/devtron/api/restHandler/app" + "github.com/devtron-labs/devtron/api/restHandler/app/appInfo" + appList2 "github.com/devtron-labs/devtron/api/restHandler/app/appList" + pipeline3 "github.com/devtron-labs/devtron/api/restHandler/app/pipeline" + pipeline2 "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/configure" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/history" + status2 "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/status" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/trigger" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/webhook" + "github.com/devtron-labs/devtron/api/restHandler/app/workflow" "github.com/devtron-labs/devtron/api/restHandler/scopedVariable" "github.com/devtron-labs/devtron/api/router" + app3 "github.com/devtron-labs/devtron/api/router/app" + appInfo2 "github.com/devtron-labs/devtron/api/router/app/appInfo" + "github.com/devtron-labs/devtron/api/router/app/appList" + pipeline5 "github.com/devtron-labs/devtron/api/router/app/pipeline" + pipeline4 "github.com/devtron-labs/devtron/api/router/app/pipeline/configure" + history2 "github.com/devtron-labs/devtron/api/router/app/pipeline/history" + status3 "github.com/devtron-labs/devtron/api/router/app/pipeline/status" + trigger2 "github.com/devtron-labs/devtron/api/router/app/pipeline/trigger" + workflow2 "github.com/devtron-labs/devtron/api/router/app/workflow" "github.com/devtron-labs/devtron/api/router/pubsub" "github.com/devtron-labs/devtron/api/server" "github.com/devtron-labs/devtron/api/sse" @@ -81,7 +98,6 @@ import ( resourceGroup "github.com/devtron-labs/devtron/internal/sql/repository/resourceGroup" security2 "github.com/devtron-labs/devtron/internal/sql/repository/security" "github.com/devtron-labs/devtron/internal/util" - "github.com/devtron-labs/devtron/internal/util/ArgoUtil" "github.com/devtron-labs/devtron/pkg/app" "github.com/devtron-labs/devtron/pkg/app/status" "github.com/devtron-labs/devtron/pkg/appClone" @@ -183,8 +199,8 @@ func InitializeApp() (*App, error) { wire.Bind(new(session2.ServiceClient), new(*middleware.LoginService)), sse.NewSSE, - router.NewPipelineTriggerRouter, - wire.Bind(new(router.PipelineTriggerRouter), new(*router.PipelineTriggerRouterImpl)), + trigger2.NewPipelineTriggerRouter, + wire.Bind(new(trigger2.PipelineTriggerRouter), new(*trigger2.PipelineTriggerRouterImpl)), //---- pprof start ---- restHandler.NewPProfRestHandler, @@ -194,8 +210,8 @@ func InitializeApp() (*App, error) { wire.Bind(new(router.PProfRouter), new(*router.PProfRouterImpl)), //---- pprof end ---- - restHandler.NewPipelineRestHandler, - wire.Bind(new(restHandler.PipelineTriggerRestHandler), new(*restHandler.PipelineTriggerRestHandlerImpl)), + trigger.NewPipelineRestHandler, + wire.Bind(new(trigger.PipelineTriggerRestHandler), new(*trigger.PipelineTriggerRestHandlerImpl)), app.GetAppServiceConfig, app.NewAppService, wire.Bind(new(app.AppService), new(*app.AppServiceImpl)), @@ -249,13 +265,25 @@ func InitializeApp() (*App, error) { wire.Bind(new(pipeline.CdPipelineConfigService), new(*pipeline.CdPipelineConfigServiceImpl)), pipeline.NewDevtronAppConfigServiceImpl, wire.Bind(new(pipeline.DevtronAppConfigService), new(*pipeline.DevtronAppConfigServiceImpl)), + pipeline3.NewDevtronAppAutoCompleteRestHandlerImpl, + wire.Bind(new(pipeline3.DevtronAppAutoCompleteRestHandler), new(*pipeline3.DevtronAppAutoCompleteRestHandlerImpl)), util5.NewLoggingMiddlewareImpl, wire.Bind(new(util5.LoggingMiddleware), new(*util5.LoggingMiddlewareImpl)), pipeline2.NewPipelineRestHandlerImpl, wire.Bind(new(pipeline2.PipelineConfigRestHandler), new(*pipeline2.PipelineConfigRestHandlerImpl)), - router.NewPipelineRouterImpl, - wire.Bind(new(router.PipelineConfigRouter), new(*router.PipelineConfigRouterImpl)), + + pipeline4.NewPipelineRouterImpl, + wire.Bind(new(pipeline4.PipelineConfigRouter), new(*pipeline4.PipelineConfigRouterImpl)), + history2.NewPipelineHistoryRouterImpl, + wire.Bind(new(history2.PipelineHistoryRouter), new(*history2.PipelineHistoryRouterImpl)), + status3.NewPipelineStatusRouterImpl, + wire.Bind(new(status3.PipelineStatusRouter), new(*status3.PipelineStatusRouterImpl)), + pipeline5.NewDevtronAppAutoCompleteRouterImpl, + wire.Bind(new(pipeline5.DevtronAppAutoCompleteRouter), new(*pipeline5.DevtronAppAutoCompleteRouterImpl)), + workflow2.NewAppWorkflowRouterImpl, + wire.Bind(new(workflow2.AppWorkflowRouter), new(*workflow2.AppWorkflowRouterImpl)), + pipeline.NewCiCdPipelineOrchestrator, wire.Bind(new(pipeline.CiCdPipelineOrchestrator), new(*pipeline.CiCdPipelineOrchestratorImpl)), pipelineConfig.NewMaterialRepositoryImpl, @@ -306,10 +334,15 @@ func InitializeApp() (*App, error) { pipeline.NewGitRegistryConfigImpl, wire.Bind(new(pipeline.GitRegistryConfig), new(*pipeline.GitRegistryConfigImpl)), - router.NewAppListingRouterImpl, - wire.Bind(new(router.AppListingRouter), new(*router.AppListingRouterImpl)), - restHandler.NewAppListingRestHandlerImpl, - wire.Bind(new(restHandler.AppListingRestHandler), new(*restHandler.AppListingRestHandlerImpl)), + appList.NewAppFilteringRouterImpl, + wire.Bind(new(appList.AppFilteringRouter), new(*appList.AppFilteringRouterImpl)), + appList2.NewAppFilteringRestHandlerImpl, + wire.Bind(new(appList2.AppFilteringRestHandler), new(*appList2.AppFilteringRestHandlerImpl)), + + appList.NewAppListingRouterImpl, + wire.Bind(new(appList.AppListingRouter), new(*appList.AppListingRouterImpl)), + appList2.NewAppListingRestHandlerImpl, + wire.Bind(new(appList2.AppListingRestHandler), new(*appList2.AppListingRestHandlerImpl)), app.NewAppListingServiceImpl, wire.Bind(new(app.AppListingService), new(*app.AppListingServiceImpl)), repository.NewAppListingRepositoryImpl, @@ -361,28 +394,9 @@ func InitializeApp() (*App, error) { repository2.NewServiceClientImpl, wire.Bind(new(repository2.ServiceClient), new(*repository2.ServiceClientImpl)), wire.Bind(new(connector.Pump), new(*connector.PumpImpl)), - restHandler.NewArgoApplicationRestHandlerImpl, - wire.Bind(new(restHandler.ArgoApplicationRestHandler), new(*restHandler.ArgoApplicationRestHandlerImpl)), - router.NewApplicationRouterImpl, - wire.Bind(new(router.ApplicationRouter), new(*router.ApplicationRouterImpl)), + //app.GetConfig, - router.NewCDRouterImpl, - wire.Bind(new(router.CDRouter), new(*router.CDRouterImpl)), - restHandler.NewCDRestHandlerImpl, - wire.Bind(new(restHandler.CDRestHandler), new(*restHandler.CDRestHandlerImpl)), - - ArgoUtil.GetArgoConfig, - ArgoUtil.NewArgoSession, - ArgoUtil.NewResourceServiceImpl, - wire.Bind(new(ArgoUtil.ResourceService), new(*ArgoUtil.ResourceServiceImpl)), - //ArgoUtil.NewApplicationServiceImpl, - //wire.Bind(new(ArgoUtil.ApplicationService), new(ArgoUtil.ApplicationServiceImpl)), - //ArgoUtil.NewRepositoryService, - //wire.Bind(new(ArgoUtil.RepositoryService), new(ArgoUtil.RepositoryServiceImpl)), - - //ArgoUtil.NewClusterServiceImpl, - //wire.Bind(new(ArgoUtil.ClusterService), new(ArgoUtil.ClusterServiceImpl)), pipeline.GetEcrConfig, //otel.NewOtelTracingServiceImpl, //wire.Bind(new(otel.OtelTracingService), new(*otel.OtelTracingServiceImpl)), @@ -514,8 +528,8 @@ func InitializeApp() (*App, error) { appStoreRestHandler.NewAppStoreRouterImpl, wire.Bind(new(appStoreRestHandler.AppStoreRouter), new(*appStoreRestHandler.AppStoreRouterImpl)), - restHandler.NewAppWorkflowRestHandlerImpl, - wire.Bind(new(restHandler.AppWorkflowRestHandler), new(*restHandler.AppWorkflowRestHandlerImpl)), + workflow.NewAppWorkflowRestHandlerImpl, + wire.Bind(new(workflow.AppWorkflowRestHandler), new(*workflow.AppWorkflowRestHandlerImpl)), appWorkflow.NewAppWorkflowServiceImpl, wire.Bind(new(appWorkflow.AppWorkflowService), new(*appWorkflow.AppWorkflowServiceImpl)), @@ -712,13 +726,15 @@ func InitializeApp() (*App, error) { wire.Bind(new(repository.WebhookEventDataRepository), new(*repository.WebhookEventDataRepositoryImpl)), pipeline.NewWebhookEventDataConfigImpl, wire.Bind(new(pipeline.WebhookEventDataConfig), new(*pipeline.WebhookEventDataConfigImpl)), - restHandler.NewWebhookDataRestHandlerImpl, - wire.Bind(new(restHandler.WebhookDataRestHandler), new(*restHandler.WebhookDataRestHandlerImpl)), + webhook.NewWebhookDataRestHandlerImpl, + wire.Bind(new(webhook.WebhookDataRestHandler), new(*webhook.WebhookDataRestHandlerImpl)), - router.NewAppRouterImpl, - wire.Bind(new(router.AppRouter), new(*router.AppRouterImpl)), - restHandler.NewAppRestHandlerImpl, - wire.Bind(new(restHandler.AppRestHandler), new(*restHandler.AppRestHandlerImpl)), + app3.NewAppRouterImpl, + wire.Bind(new(app3.AppRouter), new(*app3.AppRouterImpl)), + appInfo2.NewAppInfoRouterImpl, + wire.Bind(new(appInfo2.AppInfoRouter), new(*appInfo2.AppInfoRouterImpl)), + appInfo.NewAppInfoRestHandlerImpl, + wire.Bind(new(appInfo.AppInfoRestHandler), new(*appInfo.AppInfoRestHandlerImpl)), app.NewAppCrudOperationServiceImpl, wire.Bind(new(app.AppCrudOperationService), new(*app.AppCrudOperationServiceImpl)), @@ -737,8 +753,8 @@ func InitializeApp() (*App, error) { // util2.NewGoJsonSchemaCustomFormatChecker, //history starts - restHandler.NewPipelineHistoryRestHandlerImpl, - wire.Bind(new(restHandler.PipelineHistoryRestHandler), new(*restHandler.PipelineHistoryRestHandlerImpl)), + history.NewPipelineHistoryRestHandlerImpl, + wire.Bind(new(history.PipelineHistoryRestHandler), new(*history.PipelineHistoryRestHandlerImpl)), repository3.NewConfigMapHistoryRepositoryImpl, wire.Bind(new(repository3.ConfigMapHistoryRepository), new(*repository3.ConfigMapHistoryRepositoryImpl)), @@ -827,8 +843,8 @@ func InitializeApp() (*App, error) { cron.NewCiTriggerCronImpl, wire.Bind(new(cron.CiTriggerCron), new(*cron.CiTriggerCronImpl)), - restHandler.NewPipelineStatusTimelineRestHandlerImpl, - wire.Bind(new(restHandler.PipelineStatusTimelineRestHandler), new(*restHandler.PipelineStatusTimelineRestHandlerImpl)), + status2.NewPipelineStatusTimelineRestHandlerImpl, + wire.Bind(new(status2.PipelineStatusTimelineRestHandler), new(*status2.PipelineStatusTimelineRestHandlerImpl)), status.NewPipelineStatusTimelineServiceImpl, wire.Bind(new(status.PipelineStatusTimelineService), new(*status.PipelineStatusTimelineServiceImpl)), diff --git a/api/connector/Connector.go b/api/connector/Connector.go index 5e5d0d6310..56d61c590b 100644 --- a/api/connector/Connector.go +++ b/api/connector/Connector.go @@ -21,7 +21,6 @@ import ( "bufio" "encoding/json" "fmt" - "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" "github.com/devtron-labs/devtron/api/bean" "github.com/gogo/protobuf/proto" "github.com/grpc-ecosystem/grpc-gateway/runtime" @@ -41,9 +40,6 @@ import ( var delimiter = []byte("\n\n") type Pump interface { - StartStream(w http.ResponseWriter, recv func() (proto.Message, error), err error) - StartStreamWithHeartBeat(w http.ResponseWriter, isReconnect bool, recv func() (*application.LogEntry, error), err error) - StartMessage(w http.ResponseWriter, resp proto.Message, perr error) StartStreamWithTransformer(w http.ResponseWriter, recv func() (proto.Message, error), err error, transformer func(interface{}) interface{}) StartK8sStreamWithHeartBeat(w http.ResponseWriter, isReconnect bool, stream io.ReadCloser, err error) } @@ -148,7 +144,7 @@ func (impl PumpImpl) StartK8sStreamWithHeartBeat(w http.ResponseWriter, isReconn // heartbeat end } -func (impl PumpImpl) StartStreamWithHeartBeat(w http.ResponseWriter, isReconnect bool, recv func() (*application.LogEntry, error), err error) { +func (impl PumpImpl) StartStreamWithTransformer(w http.ResponseWriter, recv func() (proto.Message, error), err error, transformer func(interface{}) interface{}) { f, ok := w.(http.Flusher) if !ok { http.Error(w, "unexpected server doesnt support streaming", http.StatusInternalServerError) @@ -162,41 +158,6 @@ func (impl PumpImpl) StartStreamWithHeartBeat(w http.ResponseWriter, isReconnect w.Header().Set("X-Content-Type-Options", "nosniff") var wroteHeader bool - if isReconnect { - err := impl.sendEvent(nil, []byte("RECONNECT_STREAM"), []byte("RECONNECT_STREAM"), w) - if err != nil { - impl.logger.Errorw("error in writing data over sse", "err", err) - return - } - } - // heartbeat start - ticker := time.NewTicker(30 * time.Second) - done := make(chan bool) - var mux sync.Mutex - go func() error { - for { - select { - case <-done: - return nil - case t := <-ticker.C: - mux.Lock() - err := impl.sendEvent(nil, []byte("PING"), []byte(t.String()), w) - mux.Unlock() - if err != nil { - impl.logger.Errorw("error in writing PING over sse", "err", err) - return err - } - f.Flush() - } - } - }() - defer func() { - ticker.Stop() - done <- true - }() - - // heartbeat end - for { resp, err := recv() if err == io.EOF { @@ -208,20 +169,18 @@ func (impl PumpImpl) StartStreamWithHeartBeat(w http.ResponseWriter, isReconnect return } response := bean.Response{} - response.Result = resp + response.Result = transformer(resp) buf, err := json.Marshal(response) - if err != nil { - impl.logger.Errorw("error in marshaling data", "err", err) + data := "data: " + string(buf) + if _, err = w.Write([]byte(data)); err != nil { + impl.logger.Errorf("Failed to send response chunk: %v", err) return } - mux.Lock() - err = impl.sendEvent([]byte(strconv.FormatInt(resp.GetTimeStamp().UnixNano(), 10)), nil, buf, w) - mux.Unlock() - if err != nil { - impl.logger.Errorw("error in writing data over sse", "err", err) + wroteHeader = true + if _, err = w.Write(delimiter); err != nil { + impl.logger.Errorf("Failed to send delimiter chunk: %v", err) return } - wroteHeader = true f.Flush() } } @@ -251,88 +210,6 @@ func (impl *PumpImpl) sendEvent(eventId []byte, eventName []byte, payload []byte return nil } -func (impl PumpImpl) StartStream(w http.ResponseWriter, recv func() (proto.Message, error), err error) { - f, ok := w.(http.Flusher) - if !ok { - http.Error(w, "unexpected server doesnt support streaming", http.StatusInternalServerError) - } - if err != nil { - http.Error(w, errors.Details(err), http.StatusInternalServerError) - } - w.Header().Set("Transfer-Encoding", "chunked") - w.Header().Set("Content-Type", "text/event-stream") - w.Header().Set("X-Accel-Buffering", "no") - w.Header().Set("X-Content-Type-Options", "nosniff") - - var wroteHeader bool - for { - resp, err := recv() - if err == io.EOF { - return - } - if err != nil { - impl.logger.Errorf("Error occurred while reading data from argocd %+v\n", err) - impl.handleForwardResponseStreamError(wroteHeader, w, err) - return - } - response := bean.Response{} - response.Result = resp - buf, err := json.Marshal(response) - data := "data: " + string(buf) - if _, err = w.Write([]byte(data)); err != nil { - impl.logger.Errorf("Failed to send response chunk: %v", err) - return - } - wroteHeader = true - if _, err = w.Write(delimiter); err != nil { - impl.logger.Errorf("Failed to send delimiter chunk: %v", err) - return - } - f.Flush() - } -} - -func (impl PumpImpl) StartStreamWithTransformer(w http.ResponseWriter, recv func() (proto.Message, error), err error, transformer func(interface{}) interface{}) { - f, ok := w.(http.Flusher) - if !ok { - http.Error(w, "unexpected server doesnt support streaming", http.StatusInternalServerError) - } - if err != nil { - http.Error(w, errors.Details(err), http.StatusInternalServerError) - } - w.Header().Set("Transfer-Encoding", "chunked") - w.Header().Set("Content-Type", "text/event-stream") - w.Header().Set("X-Accel-Buffering", "no") - w.Header().Set("X-Content-Type-Options", "nosniff") - - var wroteHeader bool - for { - resp, err := recv() - if err == io.EOF { - return - } - if err != nil { - impl.logger.Errorf("Error occurred while reading data from argocd %+v\n", err) - impl.handleForwardResponseStreamError(wroteHeader, w, err) - return - } - response := bean.Response{} - response.Result = transformer(resp) - buf, err := json.Marshal(response) - data := "data: " + string(buf) - if _, err = w.Write([]byte(data)); err != nil { - impl.logger.Errorf("Failed to send response chunk: %v", err) - return - } - wroteHeader = true - if _, err = w.Write(delimiter); err != nil { - impl.logger.Errorf("Failed to send delimiter chunk: %v", err) - return - } - f.Flush() - } -} - func (impl PumpImpl) handleForwardResponseStreamError(wroteHeader bool, w http.ResponseWriter, err error) { code := "000" if !wroteHeader { @@ -357,58 +234,3 @@ func (impl PumpImpl) handleForwardResponseStreamError(wroteHeader bool, w http.R return } } - -func (impl PumpImpl) StartMessage(w http.ResponseWriter, resp proto.Message, perr error) { - //w.Header().Set("Transfer-Encoding", "chunked") - w.Header().Set("Content-Type", "application/json") - - response := bean.Response{} - if perr != nil { - impl.handleForwardResponseMessageError(w, perr) - return - } - var buf []byte - var err error - if rb, ok := resp.(responseBody); ok { - response.Result = rb.XXX_ResponseBody() - buf, err = json.Marshal(response) - } else { - response.Result = resp - buf, err = json.Marshal(response) - } - if err != nil { - impl.logger.Errorf("Marshal error: %v", err) - return - } - - if _, err = w.Write(buf); err != nil { - impl.logger.Errorf("Failed to write response: %v", err) - } -} - -func (impl PumpImpl) handleForwardResponseMessageError(w http.ResponseWriter, err error) { - code := "000" - s, ok := status.FromError(err) - if !ok { - s = status.New(codes.Unknown, err.Error()) - } - w.WriteHeader(runtime.HTTPStatusFromCode(s.Code())) - code = fmt.Sprint(s.Code()) - response := bean.Response{} - apiErr := bean.ApiError{} - apiErr.Code = code // 000=unknown - apiErr.InternalMessage = errors.Details(err) - response.Errors = []bean.ApiError{apiErr} - buf, merr := json.Marshal(response) - if merr != nil { - impl.logger.Errorf("Failed to marshal response %+v\n", merr) - } - if _, werr := w.Write(buf); werr != nil { - impl.logger.Errorf("Failed to notify error to client: %v", werr) - return - } -} - -type responseBody interface { - XXX_ResponseBody() interface{} -} diff --git a/api/restHandler/ArgoApplicationRestHandler.go b/api/restHandler/ArgoApplicationRestHandler.go deleted file mode 100644 index 8672538739..0000000000 --- a/api/restHandler/ArgoApplicationRestHandler.go +++ /dev/null @@ -1,811 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package restHandler - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "strconv" - "strings" - - application2 "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" - "github.com/devtron-labs/devtron/api/connector" - "github.com/devtron-labs/devtron/api/restHandler/common" - "github.com/devtron-labs/devtron/client/argocdServer/application" - "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" - "github.com/devtron-labs/devtron/pkg/auth/user" - "github.com/devtron-labs/devtron/pkg/cluster" - "github.com/devtron-labs/devtron/pkg/kubernetesResourceAuditLogs" - "github.com/devtron-labs/devtron/pkg/team" - "github.com/devtron-labs/devtron/pkg/terminal" - "github.com/devtron-labs/devtron/util" - "github.com/devtron-labs/devtron/util/argo" - "github.com/devtron-labs/devtron/util/rbac" - - "github.com/gogo/protobuf/proto" - "github.com/gorilla/mux" - "go.uber.org/zap" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type ArgoApplicationRestHandler interface { - GetPodLogs(w http.ResponseWriter, r *http.Request) - GetResourceTree(w http.ResponseWriter, r *http.Request) - ListResourceEvents(w http.ResponseWriter, r *http.Request) - GetResource(w http.ResponseWriter, r *http.Request) - List(w http.ResponseWriter, r *http.Request) - Watch(w http.ResponseWriter, r *http.Request) - ManagedResources(w http.ResponseWriter, r *http.Request) - Rollback(w http.ResponseWriter, r *http.Request) - GetManifests(w http.ResponseWriter, r *http.Request) - Get(w http.ResponseWriter, r *http.Request) - - TerminateOperation(w http.ResponseWriter, r *http.Request) - PatchResource(w http.ResponseWriter, r *http.Request) - DeleteResource(w http.ResponseWriter, r *http.Request) - - GetServiceLink(w http.ResponseWriter, r *http.Request) - GetTerminalSession(w http.ResponseWriter, r *http.Request) -} - -type ArgoApplicationRestHandlerImpl struct { - client application.ServiceClient - logger *zap.SugaredLogger - pump connector.Pump - enforcer casbin.Enforcer - teamService team.TeamService - environmentService cluster.EnvironmentService - enforcerUtil rbac.EnforcerUtil - terminalSessionHandler terminal.TerminalSessionHandler - argoUserService argo.ArgoUserService - K8sResourceHistoryService kubernetesResourceAuditLogs.K8sResourceHistoryService - userService user.UserService -} - -func NewArgoApplicationRestHandlerImpl(client application.ServiceClient, - pump connector.Pump, - enforcer casbin.Enforcer, - teamService team.TeamService, - environmentService cluster.EnvironmentService, - logger *zap.SugaredLogger, - enforcerUtil rbac.EnforcerUtil, - terminalSessionHandler terminal.TerminalSessionHandler, - argoUserService argo.ArgoUserService, - K8sResourceHistoryService kubernetesResourceAuditLogs.K8sResourceHistoryService, - userService user.UserService) *ArgoApplicationRestHandlerImpl { - return &ArgoApplicationRestHandlerImpl{ - client: client, - logger: logger, - pump: pump, - enforcer: enforcer, - teamService: teamService, - environmentService: environmentService, - enforcerUtil: enforcerUtil, - terminalSessionHandler: terminalSessionHandler, - argoUserService: argoUserService, - K8sResourceHistoryService: K8sResourceHistoryService, - userService: userService, - } -} - -func (impl ArgoApplicationRestHandlerImpl) GetTerminalSession(w http.ResponseWriter, r *http.Request) { - token := r.Header.Get("token") - userId, err := impl.userService.GetLoggedInUser(r) - if userId == 0 || err != nil { - common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) - return - } - request := &terminal.TerminalSessionRequest{} - vars := mux.Vars(r) - request.ContainerName = vars["container"] - request.Namespace = vars["namespace"] - request.PodName = vars["pod"] - request.Shell = vars["shell"] - appId := vars["appId"] - envId := vars["environmentId"] - //---------auth - id, err := strconv.Atoi(appId) - if err != nil { - common.WriteJsonResp(w, fmt.Errorf("appId is not integer"), nil, http.StatusBadRequest) - return - } - eId, err := strconv.Atoi(envId) - if err != nil { - common.WriteJsonResp(w, fmt.Errorf("envId is not integer"), nil, http.StatusBadRequest) - return - } - request.AppId = id - //below method is for getting new object, i.e. team/env/app for new trigger policy - teamEnvRbacObject := impl.enforcerUtil.GetTeamEnvRBACNameByAppId(id, eId) - if teamEnvRbacObject == "" { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - //below methods are for getting old objects for old policies (admin, manager roles) - appRbacObject := impl.enforcerUtil.GetAppRBACNameByAppId(id) - if appRbacObject == "" { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - envRbacObject := impl.enforcerUtil.GetEnvRBACNameByAppId(id, eId) - if envRbacObject == "" { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), nil, http.StatusBadRequest) - return - } - request.EnvironmentId = eId - valid := false - - //checking if the user has access of terminal with new trigger policy, if not then will check old rbac - if ok := impl.enforcer.Enforce(token, casbin.ResourceTerminal, casbin.ActionExec, teamEnvRbacObject); !ok { - appRbacOk := impl.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionCreate, appRbacObject) - envRbacOk := impl.enforcer.Enforce(token, casbin.ResourceEnvironment, casbin.ActionCreate, envRbacObject) - if appRbacOk && envRbacOk { - valid = true - } - } else { - valid = true - } - //checking rbac for charts - if ok := impl.enforcer.Enforce(token, casbin.ResourceHelmApp, casbin.ActionCreate, teamEnvRbacObject); ok { - valid = true - } - //if both the new rbac(trigger access) and old rbac fails then user is forbidden to access terminal - if !valid { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - //---------auth end - //TODO apply validation - request.UserId = userId - status, message, err := impl.terminalSessionHandler.GetTerminalSession(request) - common.WriteJsonResp(w, err, message, status) -} - -func (impl ArgoApplicationRestHandlerImpl) Watch(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - query := application2.ApplicationQuery{Name: &name} - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - app, conn, err := impl.client.Watch(ctx, &query) - defer util.Close(conn, impl.logger) - impl.pump.StartStream(w, func() (proto.Message, error) { return app.Recv() }, err) -} - -func (impl ArgoApplicationRestHandlerImpl) GetPodLogs(w http.ResponseWriter, r *http.Request) { - v := r.URL.Query() - vars := mux.Vars(r) - name := vars["name"] - podName := vars["podName"] - containerName := v.Get("container") - namespace := v.Get("namespace") - sinceSeconds, err := strconv.ParseInt(v.Get("sinceSeconds"), 10, 64) - if err != nil { - sinceSeconds = 0 - } - follow, err := strconv.ParseBool(v.Get("follow")) - if err != nil { - follow = false - } - tailLines, err := strconv.ParseInt(v.Get("tailLines"), 10, 64) - if err != nil { - tailLines = 0 - } - query := application2.ApplicationPodLogsQuery{ - Name: &name, - PodName: &podName, - Container: &containerName, - Namespace: &namespace, - TailLines: &tailLines, - Follow: &follow, - SinceSeconds: &sinceSeconds, - } - lastEventId := r.Header.Get("Last-Event-ID") - isReconnect := false - if len(lastEventId) > 0 { - lastSeenMsgId, err := strconv.ParseInt(lastEventId, 10, 64) - if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - lastSeenMsgId = lastSeenMsgId + 1 //increased by one ns to avoid duplicate //FIXME still not fixed - t := v1.Unix(0, lastSeenMsgId) - query.SinceTime = &t - //set this ti zero since its reconnect request - var sinceSecondsForReconnectRequest int64 = 0 - query.SinceSeconds = &sinceSecondsForReconnectRequest - isReconnect = true - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - logs, conn, err := impl.client.PodLogs(ctx, &query) - defer util.Close(conn, impl.logger) - impl.pump.StartStreamWithHeartBeat(w, isReconnect, func() (*application2.LogEntry, error) { return logs.Recv() }, err) -} - -func (impl ArgoApplicationRestHandlerImpl) GetResourceTree(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - query := application2.ResourcesQuery{ - ApplicationName: &name, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.ResourceTree(ctx, &query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) ListResourceEvents(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - v := r.URL.Query() - resourceNameSpace := v.Get("resourceNamespace") - resourceUID := v.Get("resourceUID") - resourceName := v.Get("resourceName") - query := &application2.ApplicationResourceEventsQuery{ - Name: &name, - ResourceNamespace: &resourceNameSpace, - ResourceUID: &resourceUID, - ResourceName: &resourceName, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.ListResourceEvents(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) GetResource(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - v := r.URL.Query() - nameSpace := v.Get("namespace") - version := v.Get("version") - group := v.Get("group") - kind := v.Get("kind") - resourceName := v.Get("resourceName") - query := &application2.ApplicationResourceRequest{ - Name: &name, - Version: &version, - Group: &group, - Kind: &kind, - ResourceName: &resourceName, - Namespace: &nameSpace, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.GetResource(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) List(w http.ResponseWriter, r *http.Request) { - v := r.URL.Query() - name := v.Get("name") - refresh := v.Get("refresh") - project := v.Get("project") - projects := make([]string, 0) - if len(project) > 0 { - projects = strings.Split(project, ",") - } - query := &application2.ApplicationQuery{ - Name: &name, - Projects: projects, - Refresh: &refresh, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.List(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) ManagedResources(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - applicationName := vars["applicationName"] - query := &application2.ResourcesQuery{ - ApplicationName: &applicationName, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.ManagedResources(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) Rollback(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - decoder := json.NewDecoder(r.Body) - query := new(application2.ApplicationRollbackRequest) - err := decoder.Decode(query) - if err != nil { - impl.logger.Error(err) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - query.Name = &name - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.Rollback(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) GetManifests(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - v := r.URL.Query() - revision := v.Get("revision") - query := &application2.ApplicationManifestQuery{ - Name: &name, - Revision: &revision, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.GetManifests(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) Get(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - v := r.URL.Query() - refresh := v.Get("refresh") - project := v.Get("project") - projects := make([]string, 0) - if len(project) > 0 { - projects = strings.Split(project, ",") - } - query := &application2.ApplicationQuery{ - Name: &name, - Projects: projects, - Refresh: &refresh, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.Get(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) TerminateOperation(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - query := application2.OperationTerminateRequest{ - Name: &name, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.TerminateOperation(ctx, &query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) PatchResource(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - token := r.Header.Get("token") - appId := vars["appId"] - id, err := strconv.Atoi(appId) - if err != nil { - common.WriteJsonResp(w, fmt.Errorf("appId is not integer"), nil, http.StatusBadRequest) - return - } - app := impl.enforcerUtil.GetAppRBACNameByAppId(id) - if app == "" { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - if ok := impl.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionTrigger, app); !ok { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - decoder := json.NewDecoder(r.Body) - query := new(application2.ApplicationResourcePatchRequest) - err = decoder.Decode(query.Patch) - if err != nil { - impl.logger.Error(err) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - query.Name = &name - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.PatchResource(ctx, query) - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) DeleteResource(w http.ResponseWriter, r *http.Request) { - - userId, err := impl.userService.GetLoggedInUser(r) - - if err != nil { - // not returning err because userId is only needed for audit logs and not impacting delete functionality. - impl.logger.Errorw("error in getting logged in user for audit logs of k8s resource") - } - - vars := mux.Vars(r) - appNameACD := vars["appNameACD"] - name := vars["name"] - namespace := vars["namespace"] - resourceName := vars["resourceName"] - version := vars["version"] - kind := vars["kind"] - group := vars["group"] - force, err := strconv.ParseBool(vars["force"]) - if err != nil { - force = false - } - if name == "" || namespace == "" || resourceName == "" || version == "" || kind == "" { - common.WriteJsonResp(w, fmt.Errorf("missing mandatory field (name | namespace | resourceName | kind)"), nil, http.StatusBadRequest) - } - query := new(application2.ApplicationResourceDeleteRequest) - query.Name = &appNameACD - query.ResourceName = &name - query.Kind = &kind - query.Version = &version - query.Force = &force - query.Namespace = &namespace - query.Group = &group - token := r.Header.Get("token") - appId := vars["appId"] - envId := vars["envId"] - id, err := strconv.Atoi(appId) - if err != nil { - common.WriteJsonResp(w, fmt.Errorf("appId is not integer"), nil, http.StatusBadRequest) - return - } - eId, err := strconv.Atoi(envId) - if err != nil { - common.WriteJsonResp(w, fmt.Errorf("envId is not integer"), nil, http.StatusBadRequest) - return - } - appRbacObject := impl.enforcerUtil.GetAppRBACNameByAppId(id) - if appRbacObject == "" { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - envRbacObject := impl.enforcerUtil.GetEnvRBACNameByAppId(id, eId) - if envRbacObject == "" { - common.WriteJsonResp(w, fmt.Errorf("envId is incorrect"), nil, http.StatusBadRequest) - return - } - if ok := impl.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionTrigger, appRbacObject); !ok { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - if ok := impl.enforcer.Enforce(token, casbin.ResourceEnvironment, casbin.ActionTrigger, envRbacObject); !ok { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.DeleteResource(ctx, query) - - if err == nil { - ResourceHistoryErr := impl.K8sResourceHistoryService.SaveArgoCdAppsResourceDeleteHistory(query, id, eId, userId) - if ResourceHistoryErr != nil { - impl.logger.Errorw("error in saving audit logs of delete resource request for argo cd apps", "err", ResourceHistoryErr) - } - } - - impl.pump.StartMessage(w, recv, err) -} - -func (impl ArgoApplicationRestHandlerImpl) GetServiceLink(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - v := r.URL.Query() - revision := v.Get("revision") - query := &application2.ApplicationManifestQuery{ - Name: &name, - Revision: &revision, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - recv, err := impl.client.GetManifests(ctx, query) - - manifests := recv.GetManifests() - var topMap []map[string]interface{} - serviceCounter := 0 - //port := "" - for _, manifest := range manifests { - lowMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(manifest), &lowMap) - //if val, ok := lowMap["kind"]; ok { - if lowMap["kind"] == "Service" { - serviceCounter = serviceCounter + 1 - } - topMap = append(topMap, lowMap) - } - - var activeService string - var serviceName string - var serviceNamespace string - var port string - var serviceLink string - if serviceCounter > 1 { - for _, lowMap := range topMap { - if lowMap["kind"] == "Rollout" { - specObj := lowMap["spec"].(map[string]interface{}) - strategyObj := specObj["strategy"].(map[string]interface{}) - blueGreenObj := strategyObj["blueGreen"].(map[string]interface{}) - activeService = blueGreenObj["activeService"].(string) - break - } - } - } - for _, lowMap := range topMap { - if lowMap["kind"] == "Service" { - metaObj := lowMap["metadata"].(map[string]interface{}) - specObj := lowMap["spec"].(map[string]interface{}) - portArr := specObj["ports"].([]interface{}) - - serviceName = metaObj["name"].(string) - serviceNamespace = metaObj["namespace"].(string) - if serviceCounter == 1 { - for _, item := range portArr { - itemObj := item.(map[string]interface{}) - if itemObj["name"] == name { - portF := itemObj["port"].(float64) - portI := int(portF) - port = strconv.Itoa(portI) - break - } - } - serviceLink = "http://" + serviceName + "." + serviceNamespace + ":" + port - break - } else if serviceCounter > 1 && serviceName == activeService { - for _, item := range portArr { - itemObj := item.(map[string]interface{}) - if itemObj["name"] == name { - portF := itemObj["port"].(float64) - portI := int(portF) - port = strconv.Itoa(portI) - break - } - } - serviceLink = "http://" + serviceName + "." + serviceNamespace + ":" + port - break - } else { - continue - } - } - } - common.WriteJsonResp(w, err, serviceLink, 200) -} diff --git a/api/restHandler/CDRestHandler.go b/api/restHandler/CDRestHandler.go deleted file mode 100644 index e305cebc1b..0000000000 --- a/api/restHandler/CDRestHandler.go +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package restHandler - -import ( - "encoding/json" - "github.com/devtron-labs/devtron/internal/util/ArgoUtil" - "github.com/gorilla/mux" - "go.uber.org/zap" - "net/http" -) - -type CDRestHandler interface { - FetchResourceTree(w http.ResponseWriter, r *http.Request) - - FetchPodContainerLogs(w http.ResponseWriter, r *http.Request) -} - -type CDRestHandlerImpl struct { - logger *zap.SugaredLogger - resourceService ArgoUtil.ResourceService -} - -func NewCDRestHandlerImpl(logger *zap.SugaredLogger, resourceService ArgoUtil.ResourceService) *CDRestHandlerImpl { - cdRestHandler := &CDRestHandlerImpl{logger: logger, resourceService: resourceService} - return cdRestHandler -} - -func (handler CDRestHandlerImpl) FetchResourceTree(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - appName := vars["app-name"] - - res, err := handler.resourceService.FetchResourceTree(appName) - if err != nil { - handler.logger.Errorw("request err, FetchResourceTree", "err", err, "appName", appName) - } - resJson, err := json.Marshal(res) - _, err = w.Write(resJson) - if err != nil { - handler.logger.Errorw("request err, FetchResourceTree", "err", err, "appName", appName, "response", res) - } -} - -func (handler CDRestHandlerImpl) FetchPodContainerLogs(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - appName := vars["app-name"] - podName := vars["pod-name"] - - res, err := handler.resourceService.FetchPodContainerLogs(appName, podName, ArgoUtil.PodContainerLogReq{}) - if err != nil { - handler.logger.Errorw("service err, FetchPodContainerLogs", "err", err, "appName", appName, "podName", podName) - } - resJson, err := json.Marshal(res) - _, err = w.Write(resJson) - if err != nil { - handler.logger.Errorw("service err, FetchPodContainerLogs", "err", err, "appName", appName, "podName", podName) - } -} diff --git a/api/restHandler/CoreAppRestHandler.go b/api/restHandler/CoreAppRestHandler.go index 5cd951d7d8..a25979cc09 100644 --- a/api/restHandler/CoreAppRestHandler.go +++ b/api/restHandler/CoreAppRestHandler.go @@ -22,13 +22,13 @@ import ( "encoding/json" "errors" "fmt" + app2 "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/configure" "net/http" "strconv" "strings" "time" appBean "github.com/devtron-labs/devtron/api/appbean" - app2 "github.com/devtron-labs/devtron/api/restHandler/app" "github.com/devtron-labs/devtron/api/restHandler/common" "github.com/devtron-labs/devtron/internal/sql/models" "github.com/devtron-labs/devtron/internal/sql/repository" @@ -63,7 +63,6 @@ const ( APP_DELETE_FAILED_RESP = "App deletion failed, please try deleting from Devtron UI" APP_CREATE_SUCCESSFUL_RESP = "App created successfully." APP_WORKFLOW_CREATE_SUCCESSFUL_RESP = "App workflow created successfully." - WORKFLOW_NAME_EMPTY = "" ) type CoreAppRestHandler interface { diff --git a/api/restHandler/ExternalCiRestHandler.go b/api/restHandler/ExternalCiRestHandler.go index a02d2a34cd..7dbe9b8b68 100644 --- a/api/restHandler/ExternalCiRestHandler.go +++ b/api/restHandler/ExternalCiRestHandler.go @@ -19,6 +19,7 @@ package restHandler import ( "encoding/json" + util3 "github.com/devtron-labs/devtron/api/util" "net/http" "strconv" @@ -63,7 +64,7 @@ func NewExternalCiRestHandlerImpl(logger *zap.SugaredLogger, webhookService pipe } func (impl ExternalCiRestHandlerImpl) HandleExternalCiWebhook(w http.ResponseWriter, r *http.Request) { - setupResponse(&w, r) + util3.SetupCorsOriginHeader(&w) vars := mux.Vars(r) token := r.Header.Get("api-token") userId, err := impl.userService.GetLoggedInUser(r) diff --git a/api/restHandler/PipelineStatusTimelineRestHandler.go b/api/restHandler/PipelineStatusTimelineRestHandler.go deleted file mode 100644 index 76e936240d..0000000000 --- a/api/restHandler/PipelineStatusTimelineRestHandler.go +++ /dev/null @@ -1,84 +0,0 @@ -package restHandler - -import ( - "fmt" - "net/http" - "strconv" - - "github.com/devtron-labs/devtron/api/restHandler/common" - "github.com/devtron-labs/devtron/pkg/app/status" - "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" - "github.com/devtron-labs/devtron/util/rbac" - "github.com/gorilla/mux" - "go.uber.org/zap" -) - -type PipelineStatusTimelineRestHandler interface { - FetchTimelines(w http.ResponseWriter, r *http.Request) -} - -type PipelineStatusTimelineRestHandlerImpl struct { - logger *zap.SugaredLogger - pipelineStatusTimelineService status.PipelineStatusTimelineService - enforcerUtil rbac.EnforcerUtil - enforcer casbin.Enforcer -} - -func NewPipelineStatusTimelineRestHandlerImpl(logger *zap.SugaredLogger, - pipelineStatusTimelineService status.PipelineStatusTimelineService, enforcerUtil rbac.EnforcerUtil, - enforcer casbin.Enforcer) *PipelineStatusTimelineRestHandlerImpl { - return &PipelineStatusTimelineRestHandlerImpl{ - logger: logger, - pipelineStatusTimelineService: pipelineStatusTimelineService, - enforcerUtil: enforcerUtil, - enforcer: enforcer, - } -} - -func (handler *PipelineStatusTimelineRestHandlerImpl) FetchTimelines(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - appId, err := strconv.Atoi(vars["appId"]) - if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - envId, err := strconv.Atoi(vars["envId"]) - if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - wfrId := 0 - wfrIdParam := r.URL.Query().Get("wfrId") - if len(wfrIdParam) != 0 { - wfrId, err = strconv.Atoi(wfrIdParam) - if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - } - showTimeline := false - showTimelineParam := r.URL.Query().Get("showTimeline") - if len(showTimelineParam) > 0 { - showTimeline, err = strconv.ParseBool(showTimelineParam) - if err != nil { - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - } - - resourceName := handler.enforcerUtil.GetAppRBACNameByAppId(appId) - token := r.Header.Get("token") - if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, resourceName); !ok { - common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) - return - } - - timelines, err := handler.pipelineStatusTimelineService.FetchTimelines(appId, envId, wfrId, showTimeline) - if err != nil { - handler.logger.Errorw("error in getting cd pipeline status timelines by wfrId", "err", err, "wfrId", wfrId) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - common.WriteJsonResp(w, err, timelines, http.StatusOK) - return -} diff --git a/api/restHandler/AppRestHandler.go b/api/restHandler/app/appInfo/AppInfoRestHandler.go similarity index 93% rename from api/restHandler/AppRestHandler.go rename to api/restHandler/app/appInfo/AppInfoRestHandler.go index ed0b6ab4e0..f71b9475d2 100644 --- a/api/restHandler/AppRestHandler.go +++ b/api/restHandler/app/appInfo/AppInfoRestHandler.go @@ -15,7 +15,7 @@ * */ -package restHandler +package appInfo import ( "encoding/json" @@ -38,7 +38,7 @@ import ( "gopkg.in/go-playground/validator.v9" ) -type AppRestHandler interface { +type AppInfoRestHandler interface { GetAllLabels(w http.ResponseWriter, r *http.Request) GetAppMetaInfo(w http.ResponseWriter, r *http.Request) GetHelmAppMetaInfo(w http.ResponseWriter, r *http.Request) @@ -48,7 +48,7 @@ type AppRestHandler interface { UpdateAppNote(w http.ResponseWriter, r *http.Request) } -type AppRestHandlerImpl struct { +type AppInfoRestHandlerImpl struct { logger *zap.SugaredLogger appService app.AppCrudOperationService userAuthService user.UserService @@ -60,11 +60,11 @@ type AppRestHandlerImpl struct { genericNoteService genericNotes.GenericNoteService } -func NewAppRestHandlerImpl(logger *zap.SugaredLogger, appService app.AppCrudOperationService, +func NewAppInfoRestHandlerImpl(logger *zap.SugaredLogger, appService app.AppCrudOperationService, userAuthService user.UserService, validator *validator.Validate, enforcerUtil rbac.EnforcerUtil, enforcer casbin.Enforcer, helmAppService client.HelmAppService, enforcerUtilHelm rbac.EnforcerUtilHelm, - genericNoteService genericNotes.GenericNoteService) *AppRestHandlerImpl { - handler := &AppRestHandlerImpl{ + genericNoteService genericNotes.GenericNoteService) *AppInfoRestHandlerImpl { + handler := &AppInfoRestHandlerImpl{ logger: logger, appService: appService, userAuthService: userAuthService, @@ -78,7 +78,7 @@ func NewAppRestHandlerImpl(logger *zap.SugaredLogger, appService app.AppCrudOper return handler } -func (handler AppRestHandlerImpl) GetAllLabels(w http.ResponseWriter, r *http.Request) { +func (handler AppInfoRestHandlerImpl) GetAllLabels(w http.ResponseWriter, r *http.Request) { userId, err := handler.userAuthService.GetLoggedInUser(r) if userId == 0 || err != nil { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) @@ -102,7 +102,7 @@ func (handler AppRestHandlerImpl) GetAllLabels(w http.ResponseWriter, r *http.Re common.WriteJsonResp(w, nil, results, http.StatusOK) } -func (handler AppRestHandlerImpl) GetAppMetaInfo(w http.ResponseWriter, r *http.Request) { +func (handler AppInfoRestHandlerImpl) GetAppMetaInfo(w http.ResponseWriter, r *http.Request) { userId, err := handler.userAuthService.GetLoggedInUser(r) if userId == 0 || err != nil { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) @@ -135,7 +135,7 @@ func (handler AppRestHandlerImpl) GetAppMetaInfo(w http.ResponseWriter, r *http. common.WriteJsonResp(w, nil, res, http.StatusOK) } -func (handler AppRestHandlerImpl) GetHelmAppMetaInfo(w http.ResponseWriter, r *http.Request) { +func (handler AppInfoRestHandlerImpl) GetHelmAppMetaInfo(w http.ResponseWriter, r *http.Request) { userId, err := handler.userAuthService.GetLoggedInUser(r) if userId == 0 || err != nil { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) @@ -188,7 +188,7 @@ func (handler AppRestHandlerImpl) GetHelmAppMetaInfo(w http.ResponseWriter, r *h common.WriteJsonResp(w, nil, res, http.StatusOK) } -func (handler AppRestHandlerImpl) UpdateApp(w http.ResponseWriter, r *http.Request) { +func (handler AppInfoRestHandlerImpl) UpdateApp(w http.ResponseWriter, r *http.Request) { userId, err := handler.userAuthService.GetLoggedInUser(r) if userId == 0 || err != nil { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) @@ -242,7 +242,7 @@ func (handler AppRestHandlerImpl) UpdateApp(w http.ResponseWriter, r *http.Reque common.WriteJsonResp(w, nil, res, http.StatusOK) } -func (handler AppRestHandlerImpl) UpdateProjectForApps(w http.ResponseWriter, r *http.Request) { +func (handler AppInfoRestHandlerImpl) UpdateProjectForApps(w http.ResponseWriter, r *http.Request) { userId, err := handler.userAuthService.GetLoggedInUser(r) if userId == 0 || err != nil { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) @@ -286,7 +286,7 @@ func (handler AppRestHandlerImpl) UpdateProjectForApps(w http.ResponseWriter, r common.WriteJsonResp(w, nil, res, http.StatusOK) } -func (handler AppRestHandlerImpl) GetAppListByTeamIds(w http.ResponseWriter, r *http.Request) { +func (handler AppInfoRestHandlerImpl) GetAppListByTeamIds(w http.ResponseWriter, r *http.Request) { userId, err := handler.userAuthService.GetLoggedInUser(r) if userId == 0 || err != nil { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) @@ -343,7 +343,7 @@ func (handler AppRestHandlerImpl) GetAppListByTeamIds(w http.ResponseWriter, r * common.WriteJsonResp(w, err, projectWiseApps, http.StatusOK) } -func (handler AppRestHandlerImpl) UpdateAppNote(w http.ResponseWriter, r *http.Request) { +func (handler AppInfoRestHandlerImpl) UpdateAppNote(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("token") decoder := json.NewDecoder(r.Body) userId, err := handler.userAuthService.GetLoggedInUser(r) diff --git a/api/restHandler/app/appList/AppFilteringRestHandler.go b/api/restHandler/app/appList/AppFilteringRestHandler.go new file mode 100644 index 0000000000..c0e6faf87a --- /dev/null +++ b/api/restHandler/app/appList/AppFilteringRestHandler.go @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package appList + +import ( + "github.com/caarlos0/env/v6" + "github.com/devtron-labs/devtron/api/bean" + "github.com/devtron-labs/devtron/api/restHandler/common" + "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" + "github.com/devtron-labs/devtron/pkg/auth/user" + "github.com/devtron-labs/devtron/pkg/cluster" + "github.com/devtron-labs/devtron/pkg/team" + "go.uber.org/zap" + "net/http" + "strconv" + "strings" + "time" +) + +type AppFilteringRestHandler interface { + GetClusterTeamAndEnvListForAutocomplete(w http.ResponseWriter, r *http.Request) +} + +type AppFilteringRestHandlerImpl struct { + logger *zap.SugaredLogger + teamService team.TeamService + enforcer casbin.Enforcer + userService user.UserService + clusterService cluster.ClusterService + environmentClusterMappingsService cluster.EnvironmentService + cfg *bean.Config +} + +func NewAppFilteringRestHandlerImpl(logger *zap.SugaredLogger, + teamService team.TeamService, + enforcer casbin.Enforcer, + userService user.UserService, + clusterService cluster.ClusterService, + environmentClusterMappingsService cluster.EnvironmentService, +) *AppFilteringRestHandlerImpl { + cfg := &bean.Config{} + err := env.Parse(cfg) + if err != nil { + logger.Errorw("error occurred while parsing config ", "err", err) + cfg.IgnoreAuthCheck = false + } + logger.Infow("app listing rest handler initialized", "ignoreAuthCheckValue", cfg.IgnoreAuthCheck) + appFilteringRestHandler := &AppFilteringRestHandlerImpl{ + logger: logger, + teamService: teamService, + enforcer: enforcer, + userService: userService, + clusterService: clusterService, + environmentClusterMappingsService: environmentClusterMappingsService, + cfg: cfg, + } + return appFilteringRestHandler +} + +func (handler AppFilteringRestHandlerImpl) GetClusterTeamAndEnvListForAutocomplete(w http.ResponseWriter, r *http.Request) { + userId, err := handler.userService.GetLoggedInUser(r) + if userId == 0 || err != nil { + common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) + return + } + clusterMapping := make(map[string]cluster.ClusterBean) + start := time.Now() + clusterList, err := handler.clusterService.FindAllForAutoComplete() + dbOperationTime := time.Since(start) + if err != nil { + handler.logger.Errorw("service err, FindAllForAutoComplete in clusterService layer", "error", err) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + var granterClusters []cluster.ClusterBean + v := r.URL.Query() + authEnabled := true + auth := v.Get("auth") + if len(auth) > 0 { + authEnabled, err = strconv.ParseBool(auth) + if err != nil { + authEnabled = true + err = nil + //ignore error, apply rbac by default + } + } + // RBAC enforcer applying + token := r.Header.Get("token") + start = time.Now() + for _, item := range clusterList { + clusterMapping[strings.ToLower(item.ClusterName)] = item + if authEnabled == true { + if ok := handler.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionGet, item.ClusterName); ok { + granterClusters = append(granterClusters, item) + } + } else { + granterClusters = append(granterClusters, item) + } + + } + handler.logger.Infow("Cluster elapsed Time for enforcer", "dbElapsedTime", dbOperationTime, "enforcerTime", time.Since(start), "envSize", len(granterClusters)) + //RBAC enforcer Ends + + if len(granterClusters) == 0 { + granterClusters = make([]cluster.ClusterBean, 0) + } + + //getting environment for autocomplete + start = time.Now() + environments, err := handler.environmentClusterMappingsService.GetEnvironmentOnlyListForAutocomplete() + if err != nil { + handler.logger.Errorw("service err, GetEnvironmentListForAutocomplete at environmentClusterMappingsService layer", "err", err) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + dbElapsedTime := time.Since(start) + var grantedEnvironment = environments + start = time.Now() + println(dbElapsedTime, grantedEnvironment) + if !handler.cfg.IgnoreAuthCheck { + grantedEnvironment = make([]cluster.EnvironmentBean, 0) + // RBAC enforcer applying + var envIdentifierList []string + for index, item := range environments { + clusterName := strings.ToLower(strings.Split(item.EnvironmentIdentifier, "__")[0]) + if clusterMapping[clusterName].Id != 0 { + environments[index].CdArgoSetup = clusterMapping[clusterName].IsCdArgoSetup + environments[index].ClusterName = clusterMapping[clusterName].ClusterName + } + envIdentifierList = append(envIdentifierList, strings.ToLower(item.EnvironmentIdentifier)) + } + + result := handler.enforcer.EnforceInBatch(token, casbin.ResourceGlobalEnvironment, casbin.ActionGet, envIdentifierList) + for _, item := range environments { + + var hasAccess bool + EnvironmentIdentifier := item.ClusterName + "__" + item.Namespace + if item.EnvironmentIdentifier != EnvironmentIdentifier { + // fix for futuristic case + hasAccess = result[strings.ToLower(EnvironmentIdentifier)] || result[strings.ToLower(item.EnvironmentIdentifier)] + } else { + hasAccess = result[strings.ToLower(item.EnvironmentIdentifier)] + } + if hasAccess { + grantedEnvironment = append(grantedEnvironment, item) + } + } + //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 + start = time.Now() + teams, err := handler.teamService.FetchForAutocomplete() + if err != nil { + handler.logger.Errorw("service err, FetchForAutocomplete at teamService layer", "err", err) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + dbElapsedTime = time.Since(start) + var grantedTeams = teams + start = time.Now() + if !handler.cfg.IgnoreAuthCheck { + grantedTeams = make([]team.TeamRequest, 0) + // RBAC enforcer applying + var teamNameList []string + for _, item := range teams { + teamNameList = append(teamNameList, strings.ToLower(item.Name)) + } + + result := handler.enforcer.EnforceInBatch(token, casbin.ResourceTeam, casbin.ActionGet, teamNameList) + + for _, item := range teams { + if hasAccess := result[strings.ToLower(item.Name)]; hasAccess { + grantedTeams = append(grantedTeams, item) + } + } + } + handler.logger.Infow("Team elapsed Time for enforcer", "dbElapsedTime", dbElapsedTime, "elapsedTime", time.Since(start), + "envSize", len(grantedTeams)) + + //RBAC enforcer Ends + resp := &AppAutocomplete{ + Teams: grantedTeams, + Environments: grantedEnvironment, + Clusters: granterClusters, + } + common.WriteJsonResp(w, nil, resp, http.StatusOK) + +} diff --git a/api/restHandler/AppListingRestHandler.go b/api/restHandler/app/appList/AppListingRestHandler.go similarity index 79% rename from api/restHandler/AppListingRestHandler.go rename to api/restHandler/app/appList/AppListingRestHandler.go index 870f54bae6..6d6fd78336 100644 --- a/api/restHandler/AppListingRestHandler.go +++ b/api/restHandler/app/appList/AppListingRestHandler.go @@ -15,12 +15,14 @@ * */ -package restHandler +package appList import ( "context" "encoding/json" "fmt" + util3 "github.com/devtron-labs/devtron/api/util" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "net/http" "strconv" "strings" @@ -28,7 +30,6 @@ import ( application2 "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/caarlos0/env/v6" k8sCommonBean "github.com/devtron-labs/common-lib/utils/k8s/commonBean" "github.com/devtron-labs/common-lib/utils/k8s/health" k8sObjectUtils "github.com/devtron-labs/common-lib/utils/k8sObjectsUtil" @@ -73,7 +74,6 @@ type AppListingRestHandler interface { FetchAppDetailsV2(w http.ResponseWriter, r *http.Request) FetchResourceTree(w http.ResponseWriter, r *http.Request) FetchAllDevtronManagedApps(w http.ResponseWriter, r *http.Request) - FetchAppTriggerView(w http.ResponseWriter, r *http.Request) FetchAppStageStatus(w http.ResponseWriter, r *http.Request) FetchOtherEnvironment(w http.ResponseWriter, r *http.Request) @@ -81,8 +81,6 @@ type AppListingRestHandler interface { RedirectToLinkouts(w http.ResponseWriter, r *http.Request) GetHostUrlsByBatch(w http.ResponseWriter, r *http.Request) - 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) @@ -90,30 +88,26 @@ type AppListingRestHandler interface { } type AppListingRestHandlerImpl struct { - application application.ServiceClient - appListingService app.AppListingService - teamService team.TeamService - enforcer casbin.Enforcer - pipeline pipeline.PipelineBuilder - logger *zap.SugaredLogger - enforcerUtil rbac.EnforcerUtil - deploymentGroupService deploymentGroup.DeploymentGroupService - userService user.UserService - helmAppClient client.HelmAppClient - clusterService cluster.ClusterService - helmAppService client.HelmAppService - argoUserService argo.ArgoUserService - k8sCommonService k8s.K8sCommonService - installedAppService service1.InstalledAppService - cdApplicationStatusUpdateHandler cron.CdApplicationStatusUpdateHandler - pipelineRepository pipelineConfig.PipelineRepository - appStatusService appStatus.AppStatusService - installedAppRepository repository.InstalledAppRepository - environmentClusterMappingsService cluster.EnvironmentService - genericNoteService genericNotes.GenericNoteService - cfg *bean.Config - k8sApplicationService application3.K8sApplicationService - deploymentTemplateService generateManifest.DeploymentTemplateService + application application.ServiceClient + appListingService app.AppListingService + enforcer casbin.Enforcer + pipeline pipeline.PipelineBuilder + logger *zap.SugaredLogger + enforcerUtil rbac.EnforcerUtil + deploymentGroupService deploymentGroup.DeploymentGroupService + userService user.UserService + helmAppClient client.HelmAppClient + helmAppService client.HelmAppService + argoUserService argo.ArgoUserService + k8sCommonService k8s.K8sCommonService + installedAppService service1.InstalledAppService + cdApplicationStatusUpdateHandler cron.CdApplicationStatusUpdateHandler + pipelineRepository pipelineConfig.PipelineRepository + appStatusService appStatus.AppStatusService + installedAppRepository repository.InstalledAppRepository + genericNoteService genericNotes.GenericNoteService + k8sApplicationService application3.K8sApplicationService + deploymentTemplateService generateManifest.DeploymentTemplateService } type AppStatus struct { @@ -132,62 +126,44 @@ type AppAutocomplete struct { func NewAppListingRestHandlerImpl(application application.ServiceClient, appListingService app.AppListingService, - teamService team.TeamService, enforcer casbin.Enforcer, pipeline pipeline.PipelineBuilder, logger *zap.SugaredLogger, enforcerUtil rbac.EnforcerUtil, deploymentGroupService deploymentGroup.DeploymentGroupService, userService user.UserService, - helmAppClient client.HelmAppClient, clusterService cluster.ClusterService, helmAppService client.HelmAppService, - argoUserService argo.ArgoUserService, k8sCommonService k8s.K8sCommonService, installedAppService service1.InstalledAppService, + helmAppClient client.HelmAppClient, helmAppService client.HelmAppService, + argoUserService argo.ArgoUserService, k8sCommonService k8s.K8sCommonService, + installedAppService service1.InstalledAppService, cdApplicationStatusUpdateHandler cron.CdApplicationStatusUpdateHandler, pipelineRepository pipelineConfig.PipelineRepository, appStatusService appStatus.AppStatusService, installedAppRepository repository.InstalledAppRepository, - environmentClusterMappingsService cluster.EnvironmentService, genericNoteService genericNotes.GenericNoteService, k8sApplicationService application3.K8sApplicationService, deploymentTemplateService generateManifest.DeploymentTemplateService, ) *AppListingRestHandlerImpl { - cfg := &bean.Config{} - err := env.Parse(cfg) - if err != nil { - logger.Errorw("error occurred while parsing config ", "err", err) - cfg.IgnoreAuthCheck = false - } - logger.Infow("app listing rest handler initialized", "ignoreAuthCheckValue", cfg.IgnoreAuthCheck) appListingHandler := &AppListingRestHandlerImpl{ - application: application, - appListingService: appListingService, - logger: logger, - teamService: teamService, - pipeline: pipeline, - enforcer: enforcer, - enforcerUtil: enforcerUtil, - deploymentGroupService: deploymentGroupService, - userService: userService, - helmAppClient: helmAppClient, - clusterService: clusterService, - helmAppService: helmAppService, - argoUserService: argoUserService, - k8sCommonService: k8sCommonService, - installedAppService: installedAppService, - cdApplicationStatusUpdateHandler: cdApplicationStatusUpdateHandler, - pipelineRepository: pipelineRepository, - appStatusService: appStatusService, - installedAppRepository: installedAppRepository, - environmentClusterMappingsService: environmentClusterMappingsService, - genericNoteService: genericNoteService, - cfg: cfg, - k8sApplicationService: k8sApplicationService, - deploymentTemplateService: deploymentTemplateService, + application: application, + appListingService: appListingService, + logger: logger, + pipeline: pipeline, + enforcer: enforcer, + enforcerUtil: enforcerUtil, + deploymentGroupService: deploymentGroupService, + userService: userService, + helmAppClient: helmAppClient, + helmAppService: helmAppService, + argoUserService: argoUserService, + k8sCommonService: k8sCommonService, + installedAppService: installedAppService, + cdApplicationStatusUpdateHandler: cdApplicationStatusUpdateHandler, + pipelineRepository: pipelineRepository, + appStatusService: appStatusService, + installedAppRepository: installedAppRepository, + genericNoteService: genericNoteService, + k8sApplicationService: k8sApplicationService, + deploymentTemplateService: deploymentTemplateService, } return appListingHandler } -func setupResponse(w *http.ResponseWriter, req *http.Request) { - (*w).Header().Set("Access-Control-Allow-Origin", "*") - (*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") - (*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") - (*w).Header().Set("Content-Type", "text/html; charset=utf-8") -} func (handler AppListingRestHandlerImpl) FetchAllDevtronManagedApps(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("token") userId, err := handler.userService.GetLoggedInUser(r) @@ -206,6 +182,7 @@ func (handler AppListingRestHandlerImpl) FetchAllDevtronManagedApps(w http.Respo res, err := handler.appListingService.FetchAllDevtronManagedApps() common.WriteJsonResp(w, err, res, http.StatusOK) } + func (handler AppListingRestHandlerImpl) FetchJobs(w http.ResponseWriter, r *http.Request) { userId, err := handler.userService.GetLoggedInUser(r) if userId == 0 || err != nil { @@ -278,6 +255,7 @@ func (handler AppListingRestHandlerImpl) FetchJobs(w http.ResponseWriter, r *htt common.WriteJsonResp(w, err, jobContainerResponse, http.StatusOK) } + func (handler AppListingRestHandlerImpl) FetchJobOverviewCiPipelines(w http.ResponseWriter, r *http.Request) { userId, err := handler.userService.GetLoggedInUser(r) if userId == 0 || err != nil { @@ -316,6 +294,7 @@ 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"] @@ -328,9 +307,10 @@ func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentVersioned(w http. return } } + func (handler AppListingRestHandlerImpl) FetchAppsByEnvironment(w http.ResponseWriter, r *http.Request) { //Allow CORS here By * or specific origin - setupResponse(&w, r) + util3.SetupCorsOriginHeader(&w) token := r.Header.Get("token") t0 := time.Now() t1 := time.Now() @@ -508,9 +488,10 @@ func (handler AppListingRestHandlerImpl) FetchAppsByEnvironment(w http.ResponseW 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) + util3.SetupCorsOriginHeader(&w) token := r.Header.Get("token") t0 := time.Now() t1 := time.Now() @@ -688,9 +669,10 @@ func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentV1(w http.Respons 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 - setupResponse(&w, r) + util3.SetupCorsOriginHeader(&w) token := r.Header.Get("token") t0 := time.Now() t1 := time.Now() @@ -815,6 +797,7 @@ func (handler AppListingRestHandlerImpl) FetchAppsByEnvironmentV2(w http.Respons common.WriteJsonResp(w, err, appContainerResponse, http.StatusOK) } +// TODO refactoring: use schema.NewDecoder().Decode(&queryStruct, r.URL.Query()) func (handler AppListingRestHandlerImpl) FetchOverviewAppsByEnvironment(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) userId, err := handler.userService.GetLoggedInUser(r) @@ -1056,136 +1039,6 @@ func (handler AppListingRestHandlerImpl) handleResourceTreeErrAndDeletePipelineI }, nil, http.StatusInternalServerError) } -func (handler AppListingRestHandlerImpl) FetchAppTriggerView(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - token := r.Header.Get("token") - appId, err := strconv.Atoi(vars["app-id"]) - if err != nil { - handler.logger.Errorw("request err, FetchAppTriggerView", "err", err, "appId", appId) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - handler.logger.Debugw("request payload, FetchAppTriggerView", "appId", appId) - - triggerView, err := handler.appListingService.FetchAppTriggerView(appId) - if err != nil { - handler.logger.Errorw("service err, FetchAppTriggerView", "err", err, "appId", appId) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - - //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) - if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, object); !ok { - common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden) - return - } - } - //RBAC enforcer Ends - - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - acdToken, err := handler.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - handler.logger.Errorw("error in getting acd token", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - ctx = context.WithValue(ctx, "token", acdToken) - defer cancel() - - response := make(chan AppStatus) - qCount := len(triggerView) - responses := map[string]AppStatus{} - - for i := 0; i < len(triggerView); i++ { - acdAppName := triggerView[i].AppName + "-" + triggerView[i].EnvironmentName - go func(pipelineName string) { - ctxt, cancel := context.WithTimeout(ctx, 60*time.Second) - defer cancel() - query := application2.ApplicationQuery{Name: &pipelineName} - app, conn, err := handler.application.Watch(ctxt, &query) - defer conn.Close() - if err != nil { - response <- AppStatus{name: pipelineName, status: "", message: "", err: err, conditions: make([]v1alpha1.ApplicationCondition, 0)} - return - } - if app != nil { - resp, err := app.Recv() - if err != nil { - response <- AppStatus{name: pipelineName, status: "", message: "", err: err, conditions: make([]v1alpha1.ApplicationCondition, 0)} - return - } - if resp != nil { - healthStatus := resp.Application.Status.Health.Status - status := AppStatus{ - name: pipelineName, - status: string(healthStatus), - message: resp.Application.Status.Health.Message, - err: nil, - conditions: resp.Application.Status.Conditions, - } - response <- status - return - } - response <- AppStatus{name: pipelineName, status: "", message: "", err: fmt.Errorf("Missing Application"), conditions: make([]v1alpha1.ApplicationCondition, 0)} - return - } - response <- AppStatus{name: pipelineName, status: "", message: "", err: fmt.Errorf("Connection Closed by Client"), conditions: make([]v1alpha1.ApplicationCondition, 0)} - - }(acdAppName) - } - rCount := 0 - - for { - select { - case msg, ok := <-response: - if ok { - if msg.err == nil { - responses[msg.name] = msg - } - } - rCount++ - } - if qCount == rCount { - break - } - } - - for i := 0; i < len(triggerView); i++ { - acdAppName := triggerView[i].AppName + "-" + triggerView[i].EnvironmentName - if val, ok := responses[acdAppName]; ok { - status := val.status - conditions := val.conditions - for _, condition := range conditions { - if condition.Type != v1alpha1.ApplicationConditionSharedResourceWarning { - status = "Degraded" - } - } - triggerView[i].Status = status - triggerView[i].StatusMessage = val.message - triggerView[i].Conditions = val.conditions - } - if triggerView[i].Status == "" { - triggerView[i].Status = "Unknown" - } - if triggerView[i].Status == string(health.HealthStatusDegraded) { - triggerView[i].Status = "Not Deployed" - } - } - common.WriteJsonResp(w, err, triggerView, http.StatusOK) -} - func (handler AppListingRestHandlerImpl) FetchAppStageStatus(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) appId, err := strconv.Atoi(vars["app-id"]) @@ -1547,7 +1400,7 @@ func (handler AppListingRestHandlerImpl) fetchResourceTree(w http.ResponseWriter if err != nil { handler.logger.Errorw("service err, FetchAppDetailsV2", "err", err, "app", appId, "env", envId) } else if status { - resp.Status = application.HIBERNATING + resp.Status = argoApplication.HIBERNATING } } if resp.Status == string(health.HealthStatusDegraded) { @@ -1593,12 +1446,12 @@ func (handler AppListingRestHandlerImpl) fetchResourceTree(w http.ResponseWriter applicationStatus := detail.ApplicationStatus resourceTree["releaseStatus"] = releaseStatus resourceTree["status"] = applicationStatus - if applicationStatus == application.Healthy { + if applicationStatus == argoApplication.Healthy { status, err := handler.appListingService.ISLastReleaseStopType(appId, envId) if err != nil { handler.logger.Errorw("service err, FetchAppDetailsV2", "err", err, "app", appId, "env", envId) } else if status { - resourceTree["status"] = application.HIBERNATING + resourceTree["status"] = argoApplication.HIBERNATING } } handler.logger.Warnw("appName and envName not found - avoiding resource tree call", "app", cdPipeline.DeploymentAppName, "env", cdPipeline.Environment.Name) @@ -1630,184 +1483,3 @@ func (handler AppListingRestHandlerImpl) fetchResourceTree(w http.ResponseWriter newResourceTree := handler.k8sCommonService.PortNumberExtraction(resp, resourceTree) return newResourceTree, nil } -func (handler AppListingRestHandlerImpl) ManualSyncAcdPipelineDeploymentStatus(w http.ResponseWriter, r *http.Request) { - token := r.Header.Get("token") - vars := mux.Vars(r) - userId, err := handler.userService.GetLoggedInUser(r) - if userId == 0 || err != nil { - common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) - return - } - appId, err := strconv.Atoi(vars["appId"]) - if err != nil { - handler.logger.Errorw("request err, ManualSyncAcdPipelineDeploymentStatus", "err", err, "appId", appId) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - envId, err := strconv.Atoi(vars["envId"]) - if err != nil { - handler.logger.Errorw("request err, ManualSyncAcdPipelineDeploymentStatus", "err", err, "envId", envId) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - - app, err := handler.pipeline.GetApp(appId) - if err != nil { - handler.logger.Errorw("bad request", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusBadRequest) - return - } - // RBAC enforcer applying - object := handler.enforcerUtil.GetAppRBACName(app.AppName) - if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, object); !ok { - common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden) - return - } - //RBAC enforcer Ends - if app.AppType == helper.ChartStoreApp { - err = handler.cdApplicationStatusUpdateHandler.ManualSyncPipelineStatus(appId, 0, userId) - } else { - err = handler.cdApplicationStatusUpdateHandler.ManualSyncPipelineStatus(appId, envId, userId) - } - - if err != nil { - handler.logger.Errorw("service err, ManualSyncAcdPipelineDeploymentStatus", "err", err, "appId", appId, "envId", envId) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - common.WriteJsonResp(w, nil, "App synced successfully.", http.StatusOK) -} - -func (handler AppListingRestHandlerImpl) GetClusterTeamAndEnvListForAutocomplete(w http.ResponseWriter, r *http.Request) { - userId, err := handler.userService.GetLoggedInUser(r) - if userId == 0 || err != nil { - common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) - return - } - clusterMapping := make(map[string]cluster.ClusterBean) - start := time.Now() - clusterList, err := handler.clusterService.FindAllForAutoComplete() - dbOperationTime := time.Since(start) - if err != nil { - handler.logger.Errorw("service err, FindAllForAutoComplete in clusterService layer", "error", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - var granterClusters []cluster.ClusterBean - v := r.URL.Query() - authEnabled := true - auth := v.Get("auth") - if len(auth) > 0 { - authEnabled, err = strconv.ParseBool(auth) - if err != nil { - authEnabled = true - err = nil - //ignore error, apply rbac by default - } - } - // RBAC enforcer applying - token := r.Header.Get("token") - start = time.Now() - for _, item := range clusterList { - clusterMapping[strings.ToLower(item.ClusterName)] = item - if authEnabled == true { - if ok := handler.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionGet, item.ClusterName); ok { - granterClusters = append(granterClusters, item) - } - } else { - granterClusters = append(granterClusters, item) - } - - } - handler.logger.Infow("Cluster elapsed Time for enforcer", "dbElapsedTime", dbOperationTime, "enforcerTime", time.Since(start), "envSize", len(granterClusters)) - //RBAC enforcer Ends - - if len(granterClusters) == 0 { - granterClusters = make([]cluster.ClusterBean, 0) - } - - //getting environment for autocomplete - start = time.Now() - environments, err := handler.environmentClusterMappingsService.GetEnvironmentOnlyListForAutocomplete() - if err != nil { - handler.logger.Errorw("service err, GetEnvironmentListForAutocomplete at environmentClusterMappingsService layer", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - dbElapsedTime := time.Since(start) - var grantedEnvironment = environments - start = time.Now() - println(dbElapsedTime, grantedEnvironment) - if !handler.cfg.IgnoreAuthCheck { - grantedEnvironment = make([]cluster.EnvironmentBean, 0) - // RBAC enforcer applying - var envIdentifierList []string - for index, item := range environments { - clusterName := strings.ToLower(strings.Split(item.EnvironmentIdentifier, "__")[0]) - if clusterMapping[clusterName].Id != 0 { - environments[index].CdArgoSetup = clusterMapping[clusterName].IsCdArgoSetup - environments[index].ClusterName = clusterMapping[clusterName].ClusterName - } - envIdentifierList = append(envIdentifierList, strings.ToLower(item.EnvironmentIdentifier)) - } - - result := handler.enforcer.EnforceInBatch(token, casbin.ResourceGlobalEnvironment, casbin.ActionGet, envIdentifierList) - for _, item := range environments { - - var hasAccess bool - EnvironmentIdentifier := item.ClusterName + "__" + item.Namespace - if item.EnvironmentIdentifier != EnvironmentIdentifier { - // fix for futuristic case - hasAccess = result[strings.ToLower(EnvironmentIdentifier)] || result[strings.ToLower(item.EnvironmentIdentifier)] - } else { - hasAccess = result[strings.ToLower(item.EnvironmentIdentifier)] - } - if hasAccess { - grantedEnvironment = append(grantedEnvironment, item) - } - } - //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 - start = time.Now() - teams, err := handler.teamService.FetchForAutocomplete() - if err != nil { - handler.logger.Errorw("service err, FetchForAutocomplete at teamService layer", "err", err) - common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) - return - } - dbElapsedTime = time.Since(start) - var grantedTeams = teams - start = time.Now() - if !handler.cfg.IgnoreAuthCheck { - grantedTeams = make([]team.TeamRequest, 0) - // RBAC enforcer applying - var teamNameList []string - for _, item := range teams { - teamNameList = append(teamNameList, strings.ToLower(item.Name)) - } - - result := handler.enforcer.EnforceInBatch(token, casbin.ResourceTeam, casbin.ActionGet, teamNameList) - - for _, item := range teams { - if hasAccess := result[strings.ToLower(item.Name)]; hasAccess { - grantedTeams = append(grantedTeams, item) - } - } - } - handler.logger.Infow("Team elapsed Time for enforcer", "dbElapsedTime", dbElapsedTime, "elapsedTime", time.Since(start), - "envSize", len(grantedTeams)) - - //RBAC enforcer Ends - resp := &AppAutocomplete{ - Teams: grantedTeams, - Environments: grantedEnvironment, - Clusters: granterClusters, - } - common.WriteJsonResp(w, nil, resp, http.StatusOK) - -} diff --git a/api/restHandler/app/AutoCompleteRestHandler.go b/api/restHandler/app/pipeline/AutoCompleteRestHandler.go similarity index 77% rename from api/restHandler/app/AutoCompleteRestHandler.go rename to api/restHandler/app/pipeline/AutoCompleteRestHandler.go index 116f88b391..ac03a3d052 100644 --- a/api/restHandler/app/AutoCompleteRestHandler.go +++ b/api/restHandler/app/pipeline/AutoCompleteRestHandler.go @@ -1,8 +1,13 @@ -package app +package pipeline import ( "context" "fmt" + "github.com/devtron-labs/devtron/pkg/auth/user" + "github.com/devtron-labs/devtron/pkg/cluster" + "github.com/devtron-labs/devtron/pkg/team" + "github.com/devtron-labs/devtron/util/rbac" + "go.uber.org/zap" "net/http" "strconv" @@ -17,14 +22,49 @@ import ( ) type DevtronAppAutoCompleteRestHandler interface { + GetAppListForAutocomplete(w http.ResponseWriter, r *http.Request) + EnvironmentListAutocomplete(w http.ResponseWriter, r *http.Request) GitListAutocomplete(w http.ResponseWriter, r *http.Request) RegistriesListAutocomplete(w http.ResponseWriter, r *http.Request) TeamListAutocomplete(w http.ResponseWriter, r *http.Request) - EnvironmentListAutocomplete(w http.ResponseWriter, r *http.Request) - GetAppListForAutocomplete(w http.ResponseWriter, r *http.Request) } -func (handler PipelineConfigRestHandlerImpl) GetAppListForAutocomplete(w http.ResponseWriter, r *http.Request) { +type DevtronAppAutoCompleteRestHandlerImpl struct { + Logger *zap.SugaredLogger + userAuthService user.UserService + teamService team.TeamService + enforcer casbin.Enforcer + enforcerUtil rbac.EnforcerUtil + devtronAppConfigService pipeline.DevtronAppConfigService + envService cluster.EnvironmentService + gitRegistryConfig pipeline.GitRegistryConfig + dockerRegistryConfig pipeline.DockerRegistryConfig +} + +func NewDevtronAppAutoCompleteRestHandlerImpl( + Logger *zap.SugaredLogger, + userAuthService user.UserService, + teamService team.TeamService, + enforcer casbin.Enforcer, + enforcerUtil rbac.EnforcerUtil, + devtronAppConfigService pipeline.DevtronAppConfigService, + envService cluster.EnvironmentService, + gitRegistryConfig pipeline.GitRegistryConfig, + dockerRegistryConfig pipeline.DockerRegistryConfig) *DevtronAppAutoCompleteRestHandlerImpl { + return &DevtronAppAutoCompleteRestHandlerImpl{ + Logger: Logger, + userAuthService: userAuthService, + teamService: teamService, + enforcer: enforcer, + enforcerUtil: enforcerUtil, + devtronAppConfigService: devtronAppConfigService, + envService: envService, + gitRegistryConfig: gitRegistryConfig, + dockerRegistryConfig: dockerRegistryConfig, + } +} + +func (handler DevtronAppAutoCompleteRestHandlerImpl) GetAppListForAutocomplete(w http.ResponseWriter, r *http.Request) { userId, err := handler.userAuthService.GetLoggedInUser(r) if userId == 0 || err != nil { common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) @@ -53,7 +93,7 @@ func (handler PipelineConfigRestHandlerImpl) GetAppListForAutocomplete(w http.Re handler.Logger.Infow("request payload, GetAppListForAutocomplete", "teamId", teamId) var apps []*pipeline.AppBean if len(teamId) == 0 { - apps, err = handler.pipelineBuilder.FindAllMatchesByAppName(appName, helper.AppType(appType)) + apps, err = handler.devtronAppConfigService.FindAllMatchesByAppName(appName, helper.AppType(appType)) if err != nil { handler.Logger.Errorw("service err, GetAppListForAutocomplete", "err", err, "teamId", teamId) common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) @@ -65,7 +105,7 @@ func (handler PipelineConfigRestHandlerImpl) GetAppListForAutocomplete(w http.Re common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } else { - apps, err = handler.pipelineBuilder.FindAppsByTeamId(teamIdInt) + apps, err = handler.devtronAppConfigService.FindAppsByTeamId(teamIdInt) if err != nil { handler.Logger.Errorw("service err, GetAppListForAutocomplete", "err", err, "teamId", teamId) common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) @@ -107,7 +147,7 @@ func (handler PipelineConfigRestHandlerImpl) GetAppListForAutocomplete(w http.Re common.WriteJsonResp(w, err, accessedApps, http.StatusOK) } -func (handler PipelineConfigRestHandlerImpl) EnvironmentListAutocomplete(w http.ResponseWriter, r *http.Request) { +func (handler DevtronAppAutoCompleteRestHandlerImpl) EnvironmentListAutocomplete(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("token") vars := mux.Vars(r) appId, err := strconv.Atoi(vars["appId"]) @@ -137,7 +177,7 @@ func (handler PipelineConfigRestHandlerImpl) EnvironmentListAutocomplete(w http. common.WriteJsonResp(w, err, result, http.StatusOK) } -func (handler PipelineConfigRestHandlerImpl) GitListAutocomplete(w http.ResponseWriter, r *http.Request) { +func (handler DevtronAppAutoCompleteRestHandlerImpl) GitListAutocomplete(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("token") vars := mux.Vars(r) appId, err := strconv.Atoi(vars["appId"]) @@ -164,7 +204,7 @@ func (handler PipelineConfigRestHandlerImpl) GitListAutocomplete(w http.Response common.WriteJsonResp(w, err, res, http.StatusOK) } -func (handler PipelineConfigRestHandlerImpl) RegistriesListAutocomplete(w http.ResponseWriter, r *http.Request) { +func (handler DevtronAppAutoCompleteRestHandlerImpl) RegistriesListAutocomplete(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("token") vars := mux.Vars(r) appId, err := strconv.Atoi(vars["appId"]) @@ -208,7 +248,7 @@ func (handler PipelineConfigRestHandlerImpl) RegistriesListAutocomplete(w http.R common.WriteJsonResp(w, err, res, http.StatusOK) } -func (handler PipelineConfigRestHandlerImpl) TeamListAutocomplete(w http.ResponseWriter, r *http.Request) { +func (handler DevtronAppAutoCompleteRestHandlerImpl) TeamListAutocomplete(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("token") vars := mux.Vars(r) appId, err := strconv.Atoi(vars["appId"]) diff --git a/api/restHandler/app/BuildPipelineRestHandler.go b/api/restHandler/app/pipeline/configure/BuildPipelineRestHandler.go similarity index 99% rename from api/restHandler/app/BuildPipelineRestHandler.go rename to api/restHandler/app/pipeline/configure/BuildPipelineRestHandler.go index cd7b6b1e5e..95ced7033b 100644 --- a/api/restHandler/app/BuildPipelineRestHandler.go +++ b/api/restHandler/app/pipeline/configure/BuildPipelineRestHandler.go @@ -1,4 +1,4 @@ -package app +package configure import ( "context" diff --git a/api/restHandler/app/BuildPipelineRestHandler_test.go b/api/restHandler/app/pipeline/configure/BuildPipelineRestHandler_test.go similarity index 99% rename from api/restHandler/app/BuildPipelineRestHandler_test.go rename to api/restHandler/app/pipeline/configure/BuildPipelineRestHandler_test.go index 01a01735fb..13cbe791e5 100644 --- a/api/restHandler/app/BuildPipelineRestHandler_test.go +++ b/api/restHandler/app/pipeline/configure/BuildPipelineRestHandler_test.go @@ -1,4 +1,4 @@ -package app +package configure import ( "bytes" diff --git a/api/restHandler/app/DeploymentPipelineRestHandler.go b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go similarity index 99% rename from api/restHandler/app/DeploymentPipelineRestHandler.go rename to api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go index e7dfcac719..1a71ddc892 100644 --- a/api/restHandler/app/DeploymentPipelineRestHandler.go +++ b/api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go @@ -1,4 +1,4 @@ -package app +package configure import ( "context" diff --git a/api/restHandler/app/PipelineConfigRestHandler.go b/api/restHandler/app/pipeline/configure/PipelineConfigRestHandler.go similarity index 98% rename from api/restHandler/app/PipelineConfigRestHandler.go rename to api/restHandler/app/pipeline/configure/PipelineConfigRestHandler.go index 71eeeade08..4ac7c2cd02 100644 --- a/api/restHandler/app/PipelineConfigRestHandler.go +++ b/api/restHandler/app/pipeline/configure/PipelineConfigRestHandler.go @@ -15,7 +15,7 @@ * */ -package app +package configure import ( "bufio" @@ -50,7 +50,6 @@ import ( "github.com/devtron-labs/devtron/pkg/appClone" "github.com/devtron-labs/devtron/pkg/appWorkflow" "github.com/devtron-labs/devtron/pkg/bean" - request "github.com/devtron-labs/devtron/pkg/cluster" "github.com/devtron-labs/devtron/pkg/pipeline" security2 "github.com/devtron-labs/devtron/pkg/security" "github.com/devtron-labs/devtron/pkg/team" @@ -86,7 +85,6 @@ type DevtronAppWorkflowRestHandler interface { } type PipelineConfigRestHandler interface { - DevtronAppAutoCompleteRestHandler DevtronAppRestHandler DevtronAppWorkflowRestHandler DevtronAppBuildRestHandler @@ -117,8 +115,6 @@ type PipelineConfigRestHandlerImpl struct { pipelineRepository pipelineConfig.PipelineRepository appWorkflowService appWorkflow.AppWorkflowService enforcerUtil rbac.EnforcerUtil - envService request.EnvironmentService - gitRegistryConfig pipeline.GitRegistryConfig dockerRegistryConfig pipeline.DockerRegistryConfig cdHandler pipeline.CdHandler appCloneService appClone.AppCloneService @@ -144,8 +140,8 @@ func NewPipelineRestHandlerImpl(pipelineBuilder pipeline.PipelineBuilder, Logger validator *validator.Validate, gitSensorClient gitSensor.Client, ciPipelineRepository pipelineConfig.CiPipelineRepository, pipelineRepository pipelineConfig.PipelineRepository, - enforcerUtil rbac.EnforcerUtil, envService request.EnvironmentService, - gitRegistryConfig pipeline.GitRegistryConfig, dockerRegistryConfig pipeline.DockerRegistryConfig, + enforcerUtil rbac.EnforcerUtil, + dockerRegistryConfig pipeline.DockerRegistryConfig, cdHandler pipeline.CdHandler, appCloneService appClone.AppCloneService, deploymentTemplateService generateManifest.DeploymentTemplateService, @@ -175,8 +171,6 @@ func NewPipelineRestHandlerImpl(pipelineBuilder pipeline.PipelineBuilder, Logger ciPipelineRepository: ciPipelineRepository, pipelineRepository: pipelineRepository, enforcerUtil: enforcerUtil, - envService: envService, - gitRegistryConfig: gitRegistryConfig, dockerRegistryConfig: dockerRegistryConfig, cdHandler: cdHandler, appCloneService: appCloneService, diff --git a/api/restHandler/PipelineHistoryRestHandler.go b/api/restHandler/app/pipeline/history/PipelineHistoryRestHandler.go similarity index 99% rename from api/restHandler/PipelineHistoryRestHandler.go rename to api/restHandler/app/pipeline/history/PipelineHistoryRestHandler.go index ebf9f75a73..01ada568f3 100644 --- a/api/restHandler/PipelineHistoryRestHandler.go +++ b/api/restHandler/app/pipeline/history/PipelineHistoryRestHandler.go @@ -1,4 +1,4 @@ -package restHandler +package history import ( "fmt" diff --git a/api/restHandler/app/pipeline/status/PipelineStatusTimelineRestHandler.go b/api/restHandler/app/pipeline/status/PipelineStatusTimelineRestHandler.go new file mode 100644 index 0000000000..c3b7c931e5 --- /dev/null +++ b/api/restHandler/app/pipeline/status/PipelineStatusTimelineRestHandler.go @@ -0,0 +1,140 @@ +package status + +import ( + "fmt" + "github.com/devtron-labs/devtron/client/cron" + "github.com/devtron-labs/devtron/internal/sql/repository/helper" + "github.com/devtron-labs/devtron/pkg/auth/user" + "github.com/devtron-labs/devtron/pkg/pipeline" + "net/http" + "strconv" + + "github.com/devtron-labs/devtron/api/restHandler/common" + "github.com/devtron-labs/devtron/pkg/app/status" + "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" + "github.com/devtron-labs/devtron/util/rbac" + "github.com/gorilla/mux" + "go.uber.org/zap" +) + +type PipelineStatusTimelineRestHandler interface { + FetchTimelines(w http.ResponseWriter, r *http.Request) + ManualSyncAcdPipelineDeploymentStatus(w http.ResponseWriter, r *http.Request) +} + +type PipelineStatusTimelineRestHandlerImpl struct { + logger *zap.SugaredLogger + userService user.UserService + pipelineStatusTimelineService status.PipelineStatusTimelineService + enforcerUtil rbac.EnforcerUtil + enforcer casbin.Enforcer + pipeline pipeline.PipelineBuilder + cdApplicationStatusUpdateHandler cron.CdApplicationStatusUpdateHandler +} + +func NewPipelineStatusTimelineRestHandlerImpl(logger *zap.SugaredLogger, + pipelineStatusTimelineService status.PipelineStatusTimelineService, enforcerUtil rbac.EnforcerUtil, + enforcer casbin.Enforcer) *PipelineStatusTimelineRestHandlerImpl { + return &PipelineStatusTimelineRestHandlerImpl{ + logger: logger, + pipelineStatusTimelineService: pipelineStatusTimelineService, + enforcerUtil: enforcerUtil, + enforcer: enforcer, + } +} + +func (handler *PipelineStatusTimelineRestHandlerImpl) FetchTimelines(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + appId, err := strconv.Atoi(vars["appId"]) + if err != nil { + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + envId, err := strconv.Atoi(vars["envId"]) + if err != nil { + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + wfrId := 0 + wfrIdParam := r.URL.Query().Get("wfrId") + if len(wfrIdParam) != 0 { + wfrId, err = strconv.Atoi(wfrIdParam) + if err != nil { + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + } + showTimeline := false + showTimelineParam := r.URL.Query().Get("showTimeline") + if len(showTimelineParam) > 0 { + showTimeline, err = strconv.ParseBool(showTimelineParam) + if err != nil { + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + } + + resourceName := handler.enforcerUtil.GetAppRBACNameByAppId(appId) + token := r.Header.Get("token") + if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, resourceName); !ok { + common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) + return + } + + timelines, err := handler.pipelineStatusTimelineService.FetchTimelines(appId, envId, wfrId, showTimeline) + if err != nil { + handler.logger.Errorw("error in getting cd pipeline status timelines by wfrId", "err", err, "wfrId", wfrId) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + common.WriteJsonResp(w, err, timelines, http.StatusOK) + return +} + +func (handler *PipelineStatusTimelineRestHandlerImpl) ManualSyncAcdPipelineDeploymentStatus(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("token") + vars := mux.Vars(r) + userId, err := handler.userService.GetLoggedInUser(r) + if userId == 0 || err != nil { + common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) + return + } + appId, err := strconv.Atoi(vars["appId"]) + if err != nil { + handler.logger.Errorw("request err, ManualSyncAcdPipelineDeploymentStatus", "err", err, "appId", appId) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + envId, err := strconv.Atoi(vars["envId"]) + if err != nil { + handler.logger.Errorw("request err, ManualSyncAcdPipelineDeploymentStatus", "err", err, "envId", envId) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + + app, err := handler.pipeline.GetApp(appId) + if err != nil { + handler.logger.Errorw("bad request", "err", err) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + // RBAC enforcer applying + object := handler.enforcerUtil.GetAppRBACName(app.AppName) + if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, object); !ok { + common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden) + return + } + //RBAC enforcer Ends + if app.AppType == helper.ChartStoreApp { + err = handler.cdApplicationStatusUpdateHandler.ManualSyncPipelineStatus(appId, 0, userId) + } else { + err = handler.cdApplicationStatusUpdateHandler.ManualSyncPipelineStatus(appId, envId, userId) + } + + if err != nil { + handler.logger.Errorw("service err, ManualSyncAcdPipelineDeploymentStatus", "err", err, "appId", appId, "envId", envId) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + common.WriteJsonResp(w, nil, "App synced successfully.", http.StatusOK) +} diff --git a/api/restHandler/PipelineTriggerRestHandler.go b/api/restHandler/app/pipeline/trigger/PipelineTriggerRestHandler.go similarity index 99% rename from api/restHandler/PipelineTriggerRestHandler.go rename to api/restHandler/app/pipeline/trigger/PipelineTriggerRestHandler.go index f019462e65..695ee95f44 100644 --- a/api/restHandler/PipelineTriggerRestHandler.go +++ b/api/restHandler/app/pipeline/trigger/PipelineTriggerRestHandler.go @@ -15,7 +15,7 @@ * */ -package restHandler +package trigger import ( "context" diff --git a/api/restHandler/WebhookDataRestHandler.go b/api/restHandler/app/pipeline/webhook/WebhookDataRestHandler.go similarity index 99% rename from api/restHandler/WebhookDataRestHandler.go rename to api/restHandler/app/pipeline/webhook/WebhookDataRestHandler.go index 4a4463d06a..c0dd12c85b 100644 --- a/api/restHandler/WebhookDataRestHandler.go +++ b/api/restHandler/app/pipeline/webhook/WebhookDataRestHandler.go @@ -15,7 +15,7 @@ * */ -package restHandler +package webhook import ( "context" diff --git a/api/restHandler/AppWorkflowRestHandler.go b/api/restHandler/app/workflow/AppWorkflowRestHandler.go similarity index 99% rename from api/restHandler/AppWorkflowRestHandler.go rename to api/restHandler/app/workflow/AppWorkflowRestHandler.go index ee99852e51..f0b2016bc8 100644 --- a/api/restHandler/AppWorkflowRestHandler.go +++ b/api/restHandler/app/workflow/AppWorkflowRestHandler.go @@ -15,7 +15,7 @@ * */ -package restHandler +package workflow import ( "encoding/json" diff --git a/api/router/AppListingRouter.go b/api/router/AppListingRouter.go deleted file mode 100644 index affdb15823..0000000000 --- a/api/router/AppListingRouter.go +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package router - -import ( - "github.com/devtron-labs/devtron/api/restHandler" - "github.com/gorilla/mux" -) - -type AppListingRouter interface { - initAppListingRouter(helmRouter *mux.Router) -} - -type AppListingRouterImpl struct { - appListingRestHandler restHandler.AppListingRestHandler -} - -func NewAppListingRouterImpl(appListingRestHandler restHandler.AppListingRestHandler) *AppListingRouterImpl { - router := &AppListingRouterImpl{ - appListingRestHandler: appListingRestHandler, - } - return router -} - -func (router AppListingRouterImpl) initAppListingRouter(appListingRouter *mux.Router) { - appListingRouter.Path("/allApps").HandlerFunc(router.appListingRestHandler.FetchAllDevtronManagedApps). - Methods("GET") - - appListingRouter.Path("/resource/urls").Queries("envId", "{envId}"). - HandlerFunc(router.appListingRestHandler.GetHostUrlsByBatch).Methods("GET") - - appListingRouter.Path("/list"). - HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironment). - Methods("POST") - - appListingRouter.Path("/list/{version}"). - HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironmentVersioned). - Methods("POST") - - appListingRouter.Path("/list/group/{env-id}"). - HandlerFunc(router.appListingRestHandler.FetchOverviewAppsByEnvironment). - Methods("GET") - - appListingRouter.Path("/list/group/{env-id}"). - Queries("size", "{size}", "offset", "{offset}"). - HandlerFunc(router.appListingRestHandler.FetchOverviewAppsByEnvironment). - Methods("GET") - //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") - - appListingRouter.Path("/detail/v2").Queries("app-id", "{app-id}").Queries("env-id", "{env-id}"). - HandlerFunc(router.appListingRestHandler.FetchAppDetailsV2). - Methods("GET") - - appListingRouter.Path("/detail/resource-tree").Queries("app-id", "{app-id}").Queries("env-id", "{env-id}"). - HandlerFunc(router.appListingRestHandler.FetchResourceTree). - Methods("GET") - - appListingRouter.Path("/vsm").Queries("app-id", "{app-id}"). - HandlerFunc(router.appListingRestHandler.FetchAppTriggerView). - Methods("GET") - - appListingRouter.Path("/stage/status").Queries("app-id", "{app-id}"). - HandlerFunc(router.appListingRestHandler.FetchAppStageStatus). - Methods("GET") - - appListingRouter.Path("/other-env").Queries("app-id", "{app-id}"). - HandlerFunc(router.appListingRestHandler.FetchOtherEnvironment). - Methods("GET") - - appListingRouter.Path("/other-env/min").Queries("app-id", "{app-id}"). - HandlerFunc(router.appListingRestHandler.FetchMinDetailOtherEnvironment).Methods("GET") - - appListingRouter.Path("/linkouts/{Id}/{appId}/{envId}").Queries("podName", "{podName}"). - Queries("containerName", "{containerName}"). - HandlerFunc(router.appListingRestHandler.RedirectToLinkouts). - Methods("GET") - - appListingRouter.Path("/deployment-status/manual-sync/{appId}/{envId}"). - HandlerFunc(router.appListingRestHandler.ManualSyncAcdPipelineDeploymentStatus). - Methods("GET") - - appListingRouter.Path("/app-listing/autocomplete"). - HandlerFunc(router.appListingRestHandler.GetClusterTeamAndEnvListForAutocomplete).Methods("GET") - -} diff --git a/api/router/ApplicationRouter.go b/api/router/ApplicationRouter.go deleted file mode 100644 index 729f7f5242..0000000000 --- a/api/router/ApplicationRouter.go +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package router - -import ( - "github.com/devtron-labs/devtron/api/restHandler" - "github.com/devtron-labs/devtron/pkg/terminal" - "github.com/gorilla/mux" - "go.uber.org/zap" -) - -type ApplicationRouter interface { - initApplicationRouter(router *mux.Router) -} - -type ApplicationRouterImpl struct { - handler restHandler.ArgoApplicationRestHandler - logger *zap.SugaredLogger -} - -func NewApplicationRouterImpl(handler restHandler.ArgoApplicationRestHandler, logger *zap.SugaredLogger) *ApplicationRouterImpl { - return &ApplicationRouterImpl{ - handler: handler, - logger: logger, - } -} - -func (r ApplicationRouterImpl) initApplicationRouter(router *mux.Router) { - router.Path("/stream"). - Queries("name", "{name}"). - Methods("GET"). - HandlerFunc(r.handler.Watch) - - router.Path("/{name}/pods/{podName}/logs"). - Queries("container", "{container}", "namespace", "{namespace}"). - Queries("follow", "{follow}"). - Queries("sinceSeconds", "{sinceSeconds}"). - Queries("sinceTime.seconds", "{sinceTime.seconds}"). - Queries("sinceTime.nanos", "{sinceTime.nanos}"). - Queries("tailLines", "{tailLines}"). - Methods("GET"). - HandlerFunc(r.handler.GetPodLogs) - router.Path("/{name}/pods/{podName}/logs"). - Methods("GET"). - HandlerFunc(r.handler.GetPodLogs) - router.Path("/{name}/resource-tree"). - Methods("GET"). - HandlerFunc(r.handler.GetResourceTree) - router.Path("/{name}/resource"). - Queries("version", "{version}", "namespace", "{namespace}", "group", "{group}", "kind", "{kind}", "resourceName", "{resourceName}"). - Methods("GET"). - HandlerFunc(r.handler.GetResource) - router.Path("/{name}/events"). - Queries("resourceNamespace", "{resourceNamespace}", "resourceUID", "{resourceUID}", "resourceName", "{resourceName}"). - Methods("GET"). - HandlerFunc(r.handler.ListResourceEvents) - router.Path("/{name}/events"). - Methods("GET"). - HandlerFunc(r.handler.ListResourceEvents) - router.Path("/"). - Queries("name", "{name}", "refresh", "{refresh}", "project", "{project}"). - Methods("GET"). - HandlerFunc(r.handler.List) - router.Path("/{applicationName}/managed-resources"). - Methods("GET"). - HandlerFunc(r.handler.ManagedResources) - router.Path("/{name}" + - "/rollback"). - Methods("GET"). - HandlerFunc(r.handler.Rollback) - - router.Path("/{name}/manifests"). - Methods("GET"). - HandlerFunc(r.handler.GetManifests) - router.Path("/{name}"). - Methods("GET"). - HandlerFunc(r.handler.Get) - router.Path("/{appName}/operation"). - Methods("DELETE"). - HandlerFunc(r.handler.TerminateOperation) - router.Path("/{name}/resource"). - Methods("POST"). - HandlerFunc(r.handler.PatchResource) - router.Path("/{appNameACD}/resource"). - Queries("name", "{name}", "namespace", "{namespace}", "resourceName", "{resourceName}", "version", "{version}", - "force", "{force}", "appId", "{appId}", "envId", "{envId}", "group", "{group}", "kind", "{kind}"). - Methods("DELETE"). - HandlerFunc(r.handler.DeleteResource) - - router.Path("/{name}/service-link"). - Methods("GET"). - HandlerFunc(r.handler.GetServiceLink) - router.Path("/pod/exec/session/{appId}/{environmentId}/{namespace}/{pod}/{shell}/{container}"). - Methods("GET"). - HandlerFunc(r.handler.GetTerminalSession) - router.Path("/pod/exec/sockjs/ws/").Handler(terminal.CreateAttachHandler("/api/v1/applications/pod/exec/sockjs/ws/")) -} diff --git a/api/router/CDRouter.go b/api/router/CDRouter.go deleted file mode 100644 index 7cf9ae9fe9..0000000000 --- a/api/router/CDRouter.go +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package router - -import ( - "github.com/devtron-labs/devtron/api/restHandler" - "github.com/gorilla/mux" - "go.uber.org/zap" - "net/http" -) - -type CDRouter interface { - initCDRouter(helmRouter *mux.Router) -} - -type CDRouterImpl struct { - logger *zap.SugaredLogger - cdRestHandler restHandler.CDRestHandler -} - -func NewCDRouterImpl(logger *zap.SugaredLogger, cdRestHandler restHandler.CDRestHandler) *CDRouterImpl { - router := &CDRouterImpl{ - logger: logger, - cdRestHandler: cdRestHandler, - } - return router -} - -func (router CDRouterImpl) initCDRouter(cdRouter *mux.Router) { - cdRouter.Path("/"). - HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - router.writeSuccess("Welcome @Devtron", writer) - }).Methods("GET") - - cdRouter.Path("/tree/{app-name}"). - HandlerFunc(router.cdRestHandler.FetchResourceTree). - Methods("GET") - - cdRouter.Path("/logs/{app-name}/pods/{pod-name}"). - HandlerFunc(router.cdRestHandler.FetchPodContainerLogs). - Methods("GET") -} - -func (router CDRouterImpl) writeSuccess(message string, w http.ResponseWriter) { - w.WriteHeader(http.StatusOK) - _, err := w.Write([]byte(message)) - if err != nil { - router.logger.Error(err) - } -} diff --git a/api/router/JobsRouter.go b/api/router/JobsRouter.go index e6130ae93e..08fb268d4b 100644 --- a/api/router/JobsRouter.go +++ b/api/router/JobsRouter.go @@ -1,8 +1,8 @@ package router import ( - "github.com/devtron-labs/devtron/api/restHandler" - "github.com/devtron-labs/devtron/api/restHandler/app" + "github.com/devtron-labs/devtron/api/restHandler/app/appList" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/configure" "github.com/gorilla/mux" ) @@ -10,11 +10,11 @@ type JobRouter interface { InitJobRouter(router *mux.Router) } type JobRouterImpl struct { - pipelineConfigRestHandler app.PipelineConfigRestHandler - appListingRestHandler restHandler.AppListingRestHandler + pipelineConfigRestHandler configure.PipelineConfigRestHandler + appListingRestHandler appList.AppListingRestHandler } -func NewJobRouterImpl(pipelineConfigRestHandler app.PipelineConfigRestHandler, appListingRestHandler restHandler.AppListingRestHandler) *JobRouterImpl { +func NewJobRouterImpl(pipelineConfigRestHandler configure.PipelineConfigRestHandler, appListingRestHandler appList.AppListingRestHandler) *JobRouterImpl { return &JobRouterImpl{ appListingRestHandler: appListingRestHandler, pipelineConfigRestHandler: pipelineConfigRestHandler, diff --git a/api/router/ResourceGroupingRouter.go b/api/router/ResourceGroupingRouter.go index 94a72a1acd..252d2d225a 100644 --- a/api/router/ResourceGroupingRouter.go +++ b/api/router/ResourceGroupingRouter.go @@ -2,7 +2,8 @@ package router import ( "github.com/devtron-labs/devtron/api/restHandler" - "github.com/devtron-labs/devtron/api/restHandler/app" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/configure" + "github.com/devtron-labs/devtron/api/restHandler/app/workflow" "github.com/gorilla/mux" ) @@ -10,13 +11,13 @@ type ResourceGroupingRouter interface { InitResourceGroupingRouter(router *mux.Router) } type ResourceGroupingRouterImpl struct { - pipelineConfigRestHandler app.PipelineConfigRestHandler - appWorkflowRestHandler restHandler.AppWorkflowRestHandler + pipelineConfigRestHandler configure.PipelineConfigRestHandler + appWorkflowRestHandler workflow.AppWorkflowRestHandler resourceGroupRestHandler restHandler.ResourceGroupRestHandler } -func NewResourceGroupingRouterImpl(restHandler app.PipelineConfigRestHandler, - appWorkflowRestHandler restHandler.AppWorkflowRestHandler, +func NewResourceGroupingRouterImpl(restHandler configure.PipelineConfigRestHandler, + appWorkflowRestHandler workflow.AppWorkflowRestHandler, resourceGroupRestHandler restHandler.ResourceGroupRestHandler) *ResourceGroupingRouterImpl { return &ResourceGroupingRouterImpl{ pipelineConfigRestHandler: restHandler, diff --git a/api/router/WebhookRouter.go b/api/router/WebhookRouter.go index 4fa1ea0ae8..9b852150fa 100644 --- a/api/router/WebhookRouter.go +++ b/api/router/WebhookRouter.go @@ -19,7 +19,7 @@ package router import ( "github.com/devtron-labs/devtron/api/restHandler" - "github.com/devtron-labs/devtron/api/restHandler/app" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/configure" "github.com/gorilla/mux" ) @@ -29,13 +29,13 @@ type WebhookRouter interface { type WebhookRouterImpl struct { gitWebhookRestHandler restHandler.GitWebhookRestHandler - pipelineRestHandler app.PipelineConfigRestHandler + pipelineRestHandler configure.PipelineConfigRestHandler externalCiRestHandler restHandler.ExternalCiRestHandler pubSubClientRestHandler restHandler.PubSubClientRestHandler } func NewWebhookRouterImpl(gitWebhookRestHandler restHandler.GitWebhookRestHandler, - pipelineRestHandler app.PipelineConfigRestHandler, externalCiRestHandler restHandler.ExternalCiRestHandler, + pipelineRestHandler configure.PipelineConfigRestHandler, externalCiRestHandler restHandler.ExternalCiRestHandler, pubSubClientRestHandler restHandler.PubSubClientRestHandler) *WebhookRouterImpl { return &WebhookRouterImpl{ gitWebhookRestHandler: gitWebhookRestHandler, diff --git a/api/router/app/AppRouter.go b/api/router/app/AppRouter.go new file mode 100644 index 0000000000..9a55f865b7 --- /dev/null +++ b/api/router/app/AppRouter.go @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package app + +import ( + "github.com/devtron-labs/devtron/api/restHandler/app/appList" + workflow2 "github.com/devtron-labs/devtron/api/restHandler/app/workflow" + "github.com/devtron-labs/devtron/api/router/app/appInfo" + appList2 "github.com/devtron-labs/devtron/api/router/app/appList" + pipeline2 "github.com/devtron-labs/devtron/api/router/app/pipeline" + "github.com/devtron-labs/devtron/api/router/app/pipeline/configure" + "github.com/devtron-labs/devtron/api/router/app/pipeline/history" + "github.com/devtron-labs/devtron/api/router/app/pipeline/status" + "github.com/devtron-labs/devtron/api/router/app/pipeline/trigger" + "github.com/devtron-labs/devtron/api/router/app/workflow" + "github.com/gorilla/mux" +) + +type AppRouter interface { + InitAppRouter(helmRouter *mux.Router) +} + +type AppRouterImpl struct { + appFilteringRouter appList2.AppFilteringRouter + appListingRouter appList2.AppListingRouter + appInfoRouter appInfo.AppInfoRouter + helmRouter trigger.PipelineTriggerRouter + pipelineConfigRouter configure.PipelineConfigRouter + pipelineHistoryRouter history.PipelineHistoryRouter + pipelineStatusRouter status.PipelineStatusRouter + appWorkflowRouter workflow.AppWorkflowRouter + devtronAppAutoCompleteRouter pipeline2.DevtronAppAutoCompleteRouter + + // TODO remove these dependencies after migration + appWorkflowRestHandler workflow2.AppWorkflowRestHandler + appListingRestHandler appList.AppListingRestHandler + appFilteringRestHandler appList.AppFilteringRestHandler +} + +func NewAppRouterImpl(appFilteringRouter appList2.AppFilteringRouter, + appListingRouter appList2.AppListingRouter, + appInfoRouter appInfo.AppInfoRouter, + helmRouter trigger.PipelineTriggerRouter, + pipelineConfigRouter configure.PipelineConfigRouter, + pipelineHistoryRouter history.PipelineHistoryRouter, + pipelineStatusRouter status.PipelineStatusRouter, + appWorkflowRouter workflow.AppWorkflowRouter, + devtronAppAutoCompleteRouter pipeline2.DevtronAppAutoCompleteRouter, + appWorkflowRestHandler workflow2.AppWorkflowRestHandler, + appListingRestHandler appList.AppListingRestHandler, + appFilteringRestHandler appList.AppFilteringRestHandler) *AppRouterImpl { + router := &AppRouterImpl{ + appInfoRouter: appInfoRouter, + helmRouter: helmRouter, + appFilteringRouter: appFilteringRouter, + appListingRouter: appListingRouter, + pipelineConfigRouter: pipelineConfigRouter, + pipelineHistoryRouter: pipelineHistoryRouter, + pipelineStatusRouter: pipelineStatusRouter, + appWorkflowRouter: appWorkflowRouter, + devtronAppAutoCompleteRouter: devtronAppAutoCompleteRouter, + appWorkflowRestHandler: appWorkflowRestHandler, + appListingRestHandler: appListingRestHandler, + appFilteringRestHandler: appFilteringRestHandler, + } + return router +} + +func (router AppRouterImpl) InitAppRouter(AppRouter *mux.Router) { + router.appInfoRouter.InitAppInfoRouter(AppRouter) + router.pipelineConfigRouter.InitPipelineConfigRouter(AppRouter) + router.helmRouter.InitPipelineTriggerRouter(AppRouter) + router.devtronAppAutoCompleteRouter.InitDevtronAppAutoCompleteRouter(AppRouter) + + appFilterRouter := AppRouter.PathPrefix("/filter").Subrouter() + router.appFilteringRouter.InitAppFilteringRouter(appFilterRouter) + + appListRouter := AppRouter.PathPrefix("/list").Subrouter() + router.appListingRouter.InitAppListingRouter(appListRouter) + + pipelineHistoryRouter := AppRouter.PathPrefix("/history").Subrouter() + router.pipelineHistoryRouter.InitPipelineHistoryRouter(pipelineHistoryRouter) + + deploymentStatusRouter := AppRouter.PathPrefix("/deployment-status").Subrouter() + router.pipelineStatusRouter.InitPipelineStatusRouter(deploymentStatusRouter) + + appWorkflowRouter := AppRouter.PathPrefix("/app-wf").Subrouter() + router.appWorkflowRouter.InitAppWorkflowRouter(appWorkflowRouter) + + // TODO refactoring: categorise and move to respective folders + AppRouter.Path("/allApps"). + HandlerFunc(router.appListingRestHandler.FetchAllDevtronManagedApps). + Methods("GET") + + AppRouter.Path("/resource/urls"). + Queries("envId", "{envId}"). + HandlerFunc(router.appListingRestHandler.GetHostUrlsByBatch). + Methods("GET") + + //This API used for fetch app details, not deployment details + AppRouter.Path("/detail"). + Queries("app-id", "{app-id}"). + Queries("env-id", "{env-id}"). + HandlerFunc(router.appListingRestHandler.FetchAppDetails). + Methods("GET") + + AppRouter.Path("/detail/v2").Queries("app-id", "{app-id}"). + Queries("env-id", "{env-id}"). + HandlerFunc(router.appListingRestHandler.FetchAppDetailsV2). + Methods("GET") + + AppRouter.Path("/detail/resource-tree").Queries("app-id", "{app-id}"). + Queries("env-id", "{env-id}"). + HandlerFunc(router.appListingRestHandler.FetchResourceTree). + Methods("GET") + + AppRouter.Path("/stage/status").Queries("app-id", "{app-id}"). + HandlerFunc(router.appListingRestHandler.FetchAppStageStatus). + Methods("GET") + + AppRouter.Path("/other-env").Queries("app-id", "{app-id}"). + HandlerFunc(router.appListingRestHandler.FetchOtherEnvironment). + Methods("GET") + + AppRouter.Path("/other-env/min").Queries("app-id", "{app-id}"). + HandlerFunc(router.appListingRestHandler.FetchMinDetailOtherEnvironment). + Methods("GET") + + AppRouter.Path("/linkouts/{Id}/{appId}/{envId}").Queries("podName", "{podName}"). + Queries("containerName", "{containerName}"). + HandlerFunc(router.appListingRestHandler.RedirectToLinkouts). + Methods("GET") + + // TODO refactoring: migrate + AppRouter.Path("/app-listing/autocomplete"). + HandlerFunc(router.appFilteringRestHandler.GetClusterTeamAndEnvListForAutocomplete). + Methods("GET") // deprecated; use filter/autocomplete instead. + + // TODO refactoring: migrate + AppRouter.Path("/wf/all/component-names/{appId}"). + HandlerFunc(router.appWorkflowRestHandler.FindAllWorkflows). + Methods("GET") // deprecated; use /app-wf/all/component-names/{appId} instead. +} diff --git a/api/router/app/AppRouterEAMode.go b/api/router/app/AppRouterEAMode.go new file mode 100644 index 0000000000..cebef3f989 --- /dev/null +++ b/api/router/app/AppRouterEAMode.go @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package app + +import ( + "github.com/devtron-labs/devtron/api/router/app/appInfo" + "github.com/devtron-labs/devtron/api/router/app/appList" + "github.com/gorilla/mux" +) + +type AppRouterEAMode interface { + InitAppRouterEAMode(helmRouter *mux.Router) +} + +type AppRouterEAModeImpl struct { + appInfoRouter appInfo.AppInfoRouter + appFilteringRouter appList.AppFilteringRouter +} + +func NewAppRouterEAModeImpl(appInfoRouter appInfo.AppInfoRouter, appFilteringRouter appList.AppFilteringRouter) *AppRouterEAModeImpl { + router := &AppRouterEAModeImpl{ + appInfoRouter: appInfoRouter, + appFilteringRouter: appFilteringRouter, + } + return router +} + +func (router AppRouterEAModeImpl) InitAppRouterEAMode(AppRouterEAMode *mux.Router) { + router.appInfoRouter.InitAppInfoRouter(AppRouterEAMode) + appFilterRouter := AppRouterEAMode.PathPrefix("/filter").Subrouter() + router.appFilteringRouter.InitAppFilteringRouter(appFilterRouter) +} diff --git a/api/router/AppRouter.go b/api/router/app/appInfo/AppInfoRouter.go similarity index 76% rename from api/router/AppRouter.go rename to api/router/app/appInfo/AppInfoRouter.go index 2f6f146ea4..175d0f8ff4 100644 --- a/api/router/AppRouter.go +++ b/api/router/app/appInfo/AppInfoRouter.go @@ -15,32 +15,32 @@ * */ -package router +package appInfo import ( - "github.com/devtron-labs/devtron/api/restHandler" + "github.com/devtron-labs/devtron/api/restHandler/app/appInfo" "github.com/gorilla/mux" "go.uber.org/zap" ) -type AppRouter interface { - InitAppRouter(router *mux.Router) +type AppInfoRouter interface { + InitAppInfoRouter(router *mux.Router) } -type AppRouterImpl struct { +type AppInfoRouterImpl struct { logger *zap.SugaredLogger - handler restHandler.AppRestHandler + handler appInfo.AppInfoRestHandler } -func NewAppRouterImpl(logger *zap.SugaredLogger, handler restHandler.AppRestHandler) *AppRouterImpl { - router := &AppRouterImpl{ +func NewAppInfoRouterImpl(logger *zap.SugaredLogger, handler appInfo.AppInfoRestHandler) *AppInfoRouterImpl { + router := &AppInfoRouterImpl{ logger: logger, handler: handler, } return router } -func (router AppRouterImpl) InitAppRouter(appRouter *mux.Router) { +func (router AppInfoRouterImpl) InitAppInfoRouter(appRouter *mux.Router) { appRouter.Path("/labels/list"). HandlerFunc(router.handler.GetAllLabels).Methods("GET") appRouter.Path("/meta/info/{appId}"). diff --git a/api/router/app/appList/AppFilteringRouter.go b/api/router/app/appList/AppFilteringRouter.go new file mode 100644 index 0000000000..3e56c0a74f --- /dev/null +++ b/api/router/app/appList/AppFilteringRouter.go @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package appList + +import ( + "github.com/devtron-labs/devtron/api/restHandler/app/appList" + "github.com/gorilla/mux" +) + +type AppFilteringRouter interface { + InitAppFilteringRouter(helmRouter *mux.Router) +} + +type AppFilteringRouterImpl struct { + appFilteringRestHandler appList.AppFilteringRestHandler +} + +func NewAppFilteringRouterImpl(appFilteringRestHandler appList.AppFilteringRestHandler) *AppFilteringRouterImpl { + router := &AppFilteringRouterImpl{ + appFilteringRestHandler: appFilteringRestHandler, + } + return router +} + +func (router AppFilteringRouterImpl) InitAppFilteringRouter(AppFilteringRouter *mux.Router) { + AppFilteringRouter.Path("/autocomplete"). + HandlerFunc(router.appFilteringRestHandler.GetClusterTeamAndEnvListForAutocomplete).Methods("GET") +} diff --git a/api/router/app/appList/AppListingRouter.go b/api/router/app/appList/AppListingRouter.go new file mode 100644 index 0000000000..2f5590ead1 --- /dev/null +++ b/api/router/app/appList/AppListingRouter.go @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package appList + +import ( + "github.com/devtron-labs/devtron/api/restHandler/app/appList" + "github.com/gorilla/mux" +) + +type AppListingRouter interface { + InitAppListingRouter(helmRouter *mux.Router) +} + +type AppListingRouterImpl struct { + appListingRestHandler appList.AppListingRestHandler +} + +func NewAppListingRouterImpl(appListingRestHandler appList.AppListingRestHandler) *AppListingRouterImpl { + router := &AppListingRouterImpl{ + appListingRestHandler: appListingRestHandler, + } + return router +} + +func (router AppListingRouterImpl) InitAppListingRouter(appListingRouter *mux.Router) { + + appListingRouter.Path(""). + HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironment). + Methods("POST") + + appListingRouter.Path("/{version}"). + HandlerFunc(router.appListingRestHandler.FetchAppsByEnvironmentVersioned). + Methods("POST") + + appListingRouter.Path("/group/{env-id}"). + Queries("size", "{size}", "offset", "{offset}"). + HandlerFunc(router.appListingRestHandler.FetchOverviewAppsByEnvironment). + Methods("GET") +} diff --git a/api/router/app/pipeline/DevtronAppAutoCompleteRouter.go b/api/router/app/pipeline/DevtronAppAutoCompleteRouter.go new file mode 100644 index 0000000000..2b4a8f49b0 --- /dev/null +++ b/api/router/app/pipeline/DevtronAppAutoCompleteRouter.go @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package pipeline + +import ( + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline" + "github.com/gorilla/mux" +) + +type DevtronAppAutoCompleteRouter interface { + InitDevtronAppAutoCompleteRouter(configRouter *mux.Router) +} +type DevtronAppAutoCompleteRouterImpl struct { + devtronAppAutoCompleteRestHandler pipeline.DevtronAppAutoCompleteRestHandler +} + +func NewDevtronAppAutoCompleteRouterImpl( + devtronAppAutoCompleteRestHandler pipeline.DevtronAppAutoCompleteRestHandler, +) *DevtronAppAutoCompleteRouterImpl { + return &DevtronAppAutoCompleteRouterImpl{ + devtronAppAutoCompleteRestHandler: devtronAppAutoCompleteRestHandler, + } +} + +func (router DevtronAppAutoCompleteRouterImpl) InitDevtronAppAutoCompleteRouter(configRouter *mux.Router) { + configRouter.Path("/autocomplete").HandlerFunc(router.devtronAppAutoCompleteRestHandler.GetAppListForAutocomplete).Methods("GET") + configRouter.Path("/{appId}/autocomplete/environment").HandlerFunc(router.devtronAppAutoCompleteRestHandler.EnvironmentListAutocomplete).Methods("GET") + configRouter.Path("/{appId}/autocomplete/git").HandlerFunc(router.devtronAppAutoCompleteRestHandler.GitListAutocomplete).Methods("GET") + configRouter.Path("/{appId}/autocomplete/docker").HandlerFunc(router.devtronAppAutoCompleteRestHandler.RegistriesListAutocomplete).Methods("GET") + configRouter.Path("/{appId}/autocomplete/team").HandlerFunc(router.devtronAppAutoCompleteRestHandler.TeamListAutocomplete).Methods("GET") +} diff --git a/api/router/PipelineConfigRouter.go b/api/router/app/pipeline/configure/PipelineConfigRouter.go similarity index 74% rename from api/router/PipelineConfigRouter.go rename to api/router/app/pipeline/configure/PipelineConfigRouter.go index 1f1339645b..3c67db207c 100644 --- a/api/router/PipelineConfigRouter.go +++ b/api/router/app/pipeline/configure/PipelineConfigRouter.go @@ -15,40 +15,31 @@ * */ -package router +package configure import ( - "github.com/devtron-labs/devtron/api/restHandler" - "github.com/devtron-labs/devtron/api/restHandler/app" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/configure" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/webhook" "github.com/gorilla/mux" ) type PipelineConfigRouter interface { - initPipelineConfigRouter(configRouter *mux.Router) + InitPipelineConfigRouter(configRouter *mux.Router) } type PipelineConfigRouterImpl struct { - restHandler app.PipelineConfigRestHandler - appWorkflowRestHandler restHandler.AppWorkflowRestHandler - webhookDataRestHandler restHandler.WebhookDataRestHandler - pipelineHistoryRestHandler restHandler.PipelineHistoryRestHandler - pipelineStatusTimelineRestHandler restHandler.PipelineStatusTimelineRestHandler + restHandler configure.PipelineConfigRestHandler + webhookDataRestHandler webhook.WebhookDataRestHandler } -func NewPipelineRouterImpl(restHandler app.PipelineConfigRestHandler, - appWorkflowRestHandler restHandler.AppWorkflowRestHandler, - webhookDataRestHandler restHandler.WebhookDataRestHandler, - pipelineHistoryRestHandler restHandler.PipelineHistoryRestHandler, - pipelineStatusTimelineRestHandler restHandler.PipelineStatusTimelineRestHandler) *PipelineConfigRouterImpl { +func NewPipelineRouterImpl(restHandler configure.PipelineConfigRestHandler, + webhookDataRestHandler webhook.WebhookDataRestHandler) *PipelineConfigRouterImpl { return &PipelineConfigRouterImpl{ - restHandler: restHandler, - appWorkflowRestHandler: appWorkflowRestHandler, - webhookDataRestHandler: webhookDataRestHandler, - pipelineHistoryRestHandler: pipelineHistoryRestHandler, - pipelineStatusTimelineRestHandler: pipelineStatusTimelineRestHandler, + restHandler: restHandler, + webhookDataRestHandler: webhookDataRestHandler, } } -func (router PipelineConfigRouterImpl) initPipelineConfigRouter(configRouter *mux.Router) { +func (router PipelineConfigRouterImpl) InitPipelineConfigRouter(configRouter *mux.Router) { configRouter.Path("").HandlerFunc(router.restHandler.CreateApp).Methods("POST") configRouter.Path("/{appId}").HandlerFunc(router.restHandler.DeleteApp).Methods("DELETE") configRouter.Path("/delete/{appId}/{envId}/non-cascade").HandlerFunc(router.restHandler.DeleteACDAppWithNonCascade).Methods("DELETE") @@ -56,7 +47,6 @@ func (router PipelineConfigRouterImpl) initPipelineConfigRouter(configRouter *mu configRouter.Path("/material").HandlerFunc(router.restHandler.UpdateMaterial).Methods("PUT") configRouter.Path("/material/delete").HandlerFunc(router.restHandler.DeleteMaterial).Methods("DELETE") configRouter.Path("/get/{appId}").HandlerFunc(router.restHandler.GetApp).Methods("GET") - configRouter.Path("/autocomplete").HandlerFunc(router.restHandler.GetAppListForAutocomplete).Methods("GET") //Deprecated configRouter.Path("/template/{appId}/default/{chartRefId}").HandlerFunc(router.restHandler.GetAppOverrideForDefaultTemplate).Methods("GET") @@ -116,11 +106,6 @@ func (router PipelineConfigRouterImpl) initPipelineConfigRouter(configRouter *mu configRouter.Path("/ci-pipeline/{pipelineId}/workflow/{workflowId}").HandlerFunc(router.restHandler.CancelWorkflow).Methods("DELETE") configRouter.Path("/cd-pipeline/{pipelineId}/workflowRunner/{workflowRunnerId}").HandlerFunc(router.restHandler.CancelStage).Methods("DELETE") - configRouter.Path("/{appId}/autocomplete/environment").HandlerFunc(router.restHandler.EnvironmentListAutocomplete).Methods("GET") - configRouter.Path("/{appId}/autocomplete/git").HandlerFunc(router.restHandler.GitListAutocomplete).Methods("GET") - configRouter.Path("/{appId}/autocomplete/docker").HandlerFunc(router.restHandler.RegistriesListAutocomplete).Methods("GET") - configRouter.Path("/{appId}/autocomplete/team").HandlerFunc(router.restHandler.TeamListAutocomplete).Methods("GET") - configRouter.Path("/cd-pipeline/defaultStrategy/{appId}/{envId}").HandlerFunc(router.restHandler.GetDefaultDeploymentPipelineStrategy).Methods("GET") configRouter.Path("/cd-pipeline/{appId}/{envId}/{pipelineId}").HandlerFunc(router.restHandler.IsReadyToTrigger).Methods("GET") configRouter.Path("/cd-pipeline/strategies/{appId}").HandlerFunc(router.restHandler.GetDeploymentPipelineStrategy).Methods("GET") @@ -133,24 +118,6 @@ func (router PipelineConfigRouterImpl) initPipelineConfigRouter(configRouter *mu configRouter.Path("/template/metrics/{appId}").HandlerFunc(router.restHandler.AppMetricsEnableDisable).Methods("POST") configRouter.Path("/env/metrics/{appId}/{environmentId}").HandlerFunc(router.restHandler.EnvMetricsEnableDisable).Methods("POST") - configRouter.Path("/app-wf"). - HandlerFunc(router.appWorkflowRestHandler.CreateAppWorkflow).Methods("POST") - - configRouter.Path("/app-wf/{app-id}"). - HandlerFunc(router.appWorkflowRestHandler.FindAppWorkflow).Methods("GET") - - configRouter.Path("/app-wf/view/{app-id}"). - HandlerFunc(router.appWorkflowRestHandler.GetWorkflowsViewData).Methods("GET") - - configRouter.Path("/app-wf/{app-id}/{app-wf-id}"). - HandlerFunc(router.appWorkflowRestHandler.DeleteAppWorkflow).Methods("DELETE") - - configRouter.Path("/app-wf/all"). - HandlerFunc(router.appWorkflowRestHandler.FindAllWorkflowsForApps).Methods("POST") - - configRouter.Path("/wf/all/component-names/{appId}"). - HandlerFunc(router.appWorkflowRestHandler.FindAllWorkflows).Methods("GET") - configRouter.Path("/cd-pipeline/workflow/history/{appId}/{environmentId}/{pipelineId}").HandlerFunc(router.restHandler.ListDeploymentHistory).Methods("GET") configRouter.Path("/cd-pipeline/workflow/logs/{appId}/{environmentId}/{pipelineId}/{workflowId}").HandlerFunc(router.restHandler.GetPrePostDeploymentLogs).Methods("GET") configRouter.Path("/cd-pipeline/workflow/trigger-info/{appId}/{environmentId}/{pipelineId}/{workflowRunnerId}").HandlerFunc(router.restHandler.FetchCdWorkflowDetails).Methods("GET") @@ -173,29 +140,8 @@ func (router PipelineConfigRouterImpl) initPipelineConfigRouter(configRouter *mu configRouter.Path("/pipeline/suggest/{type}/{appId}"). HandlerFunc(router.restHandler.PipelineNameSuggestion).Methods("GET") - configRouter.Path("/history/deployed-configuration/{appId}/{pipelineId}/{wfrId}"). - HandlerFunc(router.pipelineHistoryRestHandler.FetchDeployedConfigurationsForWorkflow). - Methods("GET") - - configRouter.Path("/history/deployed-component/list/{appId}/{pipelineId}"). - HandlerFunc(router.pipelineHistoryRestHandler.FetchDeployedHistoryComponentList). - Methods("GET") - - configRouter.Path("/history/deployed-component/detail/{appId}/{pipelineId}/{id}"). - HandlerFunc(router.pipelineHistoryRestHandler.FetchDeployedHistoryComponentDetail). - Methods("GET") - - configRouter.Path("/history/deployed-configuration/latest/deployed/{appId}/{pipelineId}"). - HandlerFunc(router.pipelineHistoryRestHandler.GetAllDeployedConfigurationHistoryForLatestWfrIdForPipeline). - Methods("GET") - - configRouter.Path("/history/deployed-configuration/all/{appId}/{pipelineId}/{wfrId}"). - HandlerFunc(router.pipelineHistoryRestHandler.GetAllDeployedConfigurationHistoryForSpecificWfrIdForPipeline). - Methods("GET") - configRouter.Path("/commit-info/{ciPipelineMaterialId}/{gitHash}").HandlerFunc(router.restHandler.GetCommitMetadataForPipelineMaterial).Methods("GET") - configRouter.Path("/deployment-status/timeline/{appId}/{envId}").HandlerFunc(router.pipelineStatusTimelineRestHandler.FetchTimelines).Methods("GET") configRouter.Path("/image-tagging/{ciPipelineId}/{artifactId}").HandlerFunc(router.restHandler.CreateUpdateImageTagging).Methods("POST") configRouter.Path("/image-tagging/{ciPipelineId}/{artifactId}").HandlerFunc(router.restHandler.GetImageTaggingData).Methods("GET") } diff --git a/api/router/app/pipeline/history/PipelineHistoryRouter.go b/api/router/app/pipeline/history/PipelineHistoryRouter.go new file mode 100644 index 0000000000..74da1b2a8f --- /dev/null +++ b/api/router/app/pipeline/history/PipelineHistoryRouter.go @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package history + +import ( + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/history" + "github.com/gorilla/mux" +) + +type PipelineHistoryRouter interface { + InitPipelineHistoryRouter(appRouter *mux.Router) +} +type PipelineHistoryRouterImpl struct { + pipelineHistoryRestHandler history.PipelineHistoryRestHandler +} + +func NewPipelineHistoryRouterImpl(pipelineHistoryRestHandler history.PipelineHistoryRestHandler) *PipelineHistoryRouterImpl { + return &PipelineHistoryRouterImpl{ + pipelineHistoryRestHandler: pipelineHistoryRestHandler, + } +} + +func (router PipelineHistoryRouterImpl) InitPipelineHistoryRouter(appRouter *mux.Router) { + appRouter.Path("/deployed-configuration/{appId}/{pipelineId}/{wfrId}"). + HandlerFunc(router.pipelineHistoryRestHandler.FetchDeployedConfigurationsForWorkflow). + Methods("GET") + + appRouter.Path("/deployed-component/list/{appId}/{pipelineId}"). + HandlerFunc(router.pipelineHistoryRestHandler.FetchDeployedHistoryComponentList). + Methods("GET") + + appRouter.Path("/deployed-component/detail/{appId}/{pipelineId}/{id}"). + HandlerFunc(router.pipelineHistoryRestHandler.FetchDeployedHistoryComponentDetail). + Methods("GET") + + appRouter.Path("/deployed-configuration/latest/deployed/{appId}/{pipelineId}"). + HandlerFunc(router.pipelineHistoryRestHandler.GetAllDeployedConfigurationHistoryForLatestWfrIdForPipeline). + Methods("GET") + + appRouter.Path("/deployed-configuration/all/{appId}/{pipelineId}/{wfrId}"). + HandlerFunc(router.pipelineHistoryRestHandler.GetAllDeployedConfigurationHistoryForSpecificWfrIdForPipeline). + Methods("GET") +} diff --git a/api/router/app/pipeline/status/PipelineStatusRouter.go b/api/router/app/pipeline/status/PipelineStatusRouter.go new file mode 100644 index 0000000000..cb0c84d22f --- /dev/null +++ b/api/router/app/pipeline/status/PipelineStatusRouter.go @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package status + +import ( + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/status" + "github.com/gorilla/mux" +) + +type PipelineStatusRouter interface { + InitPipelineStatusRouter(appRouter *mux.Router) +} +type PipelineStatusRouterImpl struct { + pipelineStatusTimelineRestHandler status.PipelineStatusTimelineRestHandler +} + +func NewPipelineStatusRouterImpl(pipelineStatusTimelineRestHandler status.PipelineStatusTimelineRestHandler) *PipelineStatusRouterImpl { + return &PipelineStatusRouterImpl{ + pipelineStatusTimelineRestHandler: pipelineStatusTimelineRestHandler, + } +} + +func (router PipelineStatusRouterImpl) InitPipelineStatusRouter(appRouter *mux.Router) { + appRouter.Path("/timeline/{appId}/{envId}"). + HandlerFunc(router.pipelineStatusTimelineRestHandler.FetchTimelines). + Methods("GET") + + appRouter.Path("/manual-sync/{appId}/{envId}"). + HandlerFunc(router.pipelineStatusTimelineRestHandler.ManualSyncAcdPipelineDeploymentStatus). + Methods("GET") +} diff --git a/api/router/PipelineTriggerRouter.go b/api/router/app/pipeline/trigger/PipelineTriggerRouter.go similarity index 86% rename from api/router/PipelineTriggerRouter.go rename to api/router/app/pipeline/trigger/PipelineTriggerRouter.go index 6d40fe9b6b..8678550185 100644 --- a/api/router/PipelineTriggerRouter.go +++ b/api/router/app/pipeline/trigger/PipelineTriggerRouter.go @@ -15,10 +15,10 @@ * */ -package router +package trigger import ( - "github.com/devtron-labs/devtron/api/restHandler" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/trigger" sse2 "github.com/devtron-labs/devtron/api/sse" "github.com/gorilla/mux" "github.com/juju/errors" @@ -31,7 +31,7 @@ import ( var sse *sse2.SSE type PipelineTriggerRouter interface { - initPipelineTriggerRouter(pipelineTriggerRouter *mux.Router) + InitPipelineTriggerRouter(pipelineTriggerRouter *mux.Router) } func PollTopic(r *http.Request) (string, error) { @@ -46,17 +46,17 @@ func PollTopic(r *http.Request) (string, error) { return "/" + name, nil } -func NewPipelineTriggerRouter(pipelineRestHandler restHandler.PipelineTriggerRestHandler, sseChannel *sse2.SSE) *PipelineTriggerRouterImpl { +func NewPipelineTriggerRouter(pipelineRestHandler trigger.PipelineTriggerRestHandler, sseChannel *sse2.SSE) *PipelineTriggerRouterImpl { routerImpl := &PipelineTriggerRouterImpl{restHandler: pipelineRestHandler} sse = sseChannel return routerImpl } type PipelineTriggerRouterImpl struct { - restHandler restHandler.PipelineTriggerRestHandler + restHandler trigger.PipelineTriggerRestHandler } -func (router PipelineTriggerRouterImpl) initPipelineTriggerRouter(pipelineTriggerRouter *mux.Router) { +func (router PipelineTriggerRouterImpl) InitPipelineTriggerRouter(pipelineTriggerRouter *mux.Router) { pipelineTriggerRouter.Path("/cd-pipeline/trigger").HandlerFunc(router.restHandler.OverrideConfig).Methods("POST") pipelineTriggerRouter.Path("/update-release-status").HandlerFunc(router.restHandler.ReleaseStatusUpdate).Methods("POST") pipelineTriggerRouter.Path("/rotate-pods").HandlerFunc(router.restHandler.RotatePods).Methods("POST") diff --git a/api/router/app/workflow/AppWorkflowRouter.go b/api/router/app/workflow/AppWorkflowRouter.go new file mode 100644 index 0000000000..1bc932d04d --- /dev/null +++ b/api/router/app/workflow/AppWorkflowRouter.go @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 Devtron Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package workflow + +import ( + "github.com/devtron-labs/devtron/api/restHandler/app/workflow" + "github.com/gorilla/mux" +) + +type AppWorkflowRouter interface { + InitAppWorkflowRouter(appRouter *mux.Router) +} +type AppWorkflowRouterImpl struct { + appWorkflowRestHandler workflow.AppWorkflowRestHandler +} + +func NewAppWorkflowRouterImpl(appWorkflowRestHandler workflow.AppWorkflowRestHandler) *AppWorkflowRouterImpl { + return &AppWorkflowRouterImpl{ + appWorkflowRestHandler: appWorkflowRestHandler, + } +} + +func (router AppWorkflowRouterImpl) InitAppWorkflowRouter(appRouter *mux.Router) { + appRouter.Path(""). + HandlerFunc(router.appWorkflowRestHandler.CreateAppWorkflow).Methods("POST") + + appRouter.Path("/{app-id}"). + HandlerFunc(router.appWorkflowRestHandler.FindAppWorkflow).Methods("GET") + + appRouter.Path("/view/{app-id}"). + HandlerFunc(router.appWorkflowRestHandler.GetWorkflowsViewData).Methods("GET") + + appRouter.Path("/{app-id}/{app-wf-id}"). + HandlerFunc(router.appWorkflowRestHandler.DeleteAppWorkflow).Methods("DELETE") + + appRouter.Path("/all"). + HandlerFunc(router.appWorkflowRestHandler.FindAllWorkflowsForApps).Methods("POST") + + appRouter.Path("/all/component-names/{appId}"). + HandlerFunc(router.appWorkflowRestHandler.FindAllWorkflows).Methods("GET") +} diff --git a/api/router/router.go b/api/router/router.go index 58375546ce..57440bf749 100644 --- a/api/router/router.go +++ b/api/router/router.go @@ -36,6 +36,7 @@ import ( "github.com/devtron-labs/devtron/api/k8s/capacity" "github.com/devtron-labs/devtron/api/module" "github.com/devtron-labs/devtron/api/restHandler/common" + "github.com/devtron-labs/devtron/api/router/app" "github.com/devtron-labs/devtron/api/router/pubsub" "github.com/devtron-labs/devtron/api/server" "github.com/devtron-labs/devtron/api/team" @@ -56,16 +57,11 @@ import ( type MuxRouter struct { logger *zap.SugaredLogger Router *mux.Router - HelmRouter PipelineTriggerRouter - PipelineConfigRouter PipelineConfigRouter JobRouter JobRouter EnvironmentClusterMappingsRouter cluster.EnvironmentRouter - AppListingRouter AppListingRouter ClusterRouter cluster.ClusterRouter WebHookRouter WebhookRouter UserAuthRouter user.UserAuthRouter - ApplicationRouter ApplicationRouter - CDRouter CDRouter GitProviderRouter GitProviderRouter GitHostRouter GitHostRouter DockerRegRouter DockerRegRouter @@ -99,7 +95,7 @@ type MuxRouter struct { telemetryWatcher telemetry.TelemetryEventClient bulkUpdateRouter BulkUpdateRouter WebhookListenerRouter WebhookListenerRouter - appRouter AppRouter + appRouter app.AppRouter coreAppRouter CoreAppRouter helmAppRouter client.HelmAppRouter k8sApplicationRouter application.K8sApplicationRouter @@ -124,11 +120,9 @@ type MuxRouter struct { ciTriggerCron cron.CiTriggerCron } -func NewMuxRouter(logger *zap.SugaredLogger, HelmRouter PipelineTriggerRouter, PipelineConfigRouter PipelineConfigRouter, - AppListingRouter AppListingRouter, +func NewMuxRouter(logger *zap.SugaredLogger, EnvironmentClusterMappingsRouter cluster.EnvironmentRouter, ClusterRouter cluster.ClusterRouter, - WebHookRouter WebhookRouter, UserAuthRouter user.UserAuthRouter, ApplicationRouter ApplicationRouter, - CDRouter CDRouter, + WebHookRouter WebhookRouter, UserAuthRouter user.UserAuthRouter, GitProviderRouter GitProviderRouter, GitHostRouter GitHostRouter, DockerRegRouter DockerRegRouter, NotificationRouter NotificationRouter, @@ -141,7 +135,7 @@ func NewMuxRouter(logger *zap.SugaredLogger, HelmRouter PipelineTriggerRouter, P ReleaseMetricsRouter ReleaseMetricsRouter, deploymentGroupRouter DeploymentGroupRouter, batchOperationRouter BatchOperationRouter, chartGroupRouter chartGroup.ChartGroupRouter, imageScanRouter ImageScanRouter, policyRouter PolicyRouter, gitOpsConfigRouter GitOpsConfigRouter, dashboardRouter dashboard.DashboardRouter, attributesRouter AttributesRouter, userAttributesRouter UserAttributesRouter, - commonRouter CommonRouter, grafanaRouter GrafanaRouter, ssoLoginRouter sso.SsoLoginRouter, telemetryRouter TelemetryRouter, telemetryWatcher telemetry.TelemetryEventClient, bulkUpdateRouter BulkUpdateRouter, webhookListenerRouter WebhookListenerRouter, appRouter AppRouter, + commonRouter CommonRouter, grafanaRouter GrafanaRouter, ssoLoginRouter sso.SsoLoginRouter, telemetryRouter TelemetryRouter, telemetryWatcher telemetry.TelemetryEventClient, bulkUpdateRouter BulkUpdateRouter, webhookListenerRouter WebhookListenerRouter, appRouter app.AppRouter, coreAppRouter CoreAppRouter, helmAppRouter client.HelmAppRouter, k8sApplicationRouter application.K8sApplicationRouter, pProfRouter PProfRouter, deploymentConfigRouter deployment.DeploymentConfigRouter, dashboardTelemetryRouter dashboardEvent.DashboardTelemetryRouter, commonDeploymentRouter appStoreDeployment.CommonDeploymentRouter, externalLinkRouter externalLink.ExternalLinkRouter, @@ -157,15 +151,10 @@ func NewMuxRouter(logger *zap.SugaredLogger, HelmRouter PipelineTriggerRouter, P proxyRouter proxy.ProxyRouter) *MuxRouter { r := &MuxRouter{ Router: mux.NewRouter(), - HelmRouter: HelmRouter, - PipelineConfigRouter: PipelineConfigRouter, EnvironmentClusterMappingsRouter: EnvironmentClusterMappingsRouter, - AppListingRouter: AppListingRouter, ClusterRouter: ClusterRouter, WebHookRouter: WebHookRouter, UserAuthRouter: UserAuthRouter, - ApplicationRouter: ApplicationRouter, - CDRouter: CDRouter, DockerRegRouter: DockerRegRouter, GitProviderRouter: GitProviderRouter, GitHostRouter: GitHostRouter, @@ -265,11 +254,8 @@ func (r MuxRouter) Init() { coreAppRouter := r.Router.PathPrefix("/orchestrator/core").Subrouter() r.coreAppRouter.initCoreAppRouter(coreAppRouter) - pipelineConfigRouter := r.Router.PathPrefix("/orchestrator/app").Subrouter() - r.PipelineConfigRouter.initPipelineConfigRouter(pipelineConfigRouter) - r.AppListingRouter.initAppListingRouter(pipelineConfigRouter) - r.HelmRouter.initPipelineTriggerRouter(pipelineConfigRouter) - r.appRouter.InitAppRouter(pipelineConfigRouter) + appSubRouter := r.Router.PathPrefix("/orchestrator/app").Subrouter() + r.appRouter.InitAppRouter(appSubRouter) jobConfigRouter := r.Router.PathPrefix("/orchestrator/job").Subrouter() r.JobRouter.InitJobRouter(jobConfigRouter) @@ -284,9 +270,6 @@ func (r MuxRouter) Init() { webHookRouter := r.Router.PathPrefix("/orchestrator/webhook").Subrouter() r.WebHookRouter.intWebhookRouter(webHookRouter) - applicationRouter := r.Router.PathPrefix("/orchestrator/api/v1/applications").Subrouter() - r.ApplicationRouter.initApplicationRouter(applicationRouter) - rootRouter := r.Router.PathPrefix("/orchestrator").Subrouter() r.UserAuthRouter.InitUserAuthRouter(rootRouter) diff --git a/api/util/apiHeader.go b/api/util/apiHeader.go new file mode 100644 index 0000000000..60d0f1ae08 --- /dev/null +++ b/api/util/apiHeader.go @@ -0,0 +1,10 @@ +package util + +import "net/http" + +func SetupCorsOriginHeader(w *http.ResponseWriter) { + (*w).Header().Set("Access-Control-Allow-Origin", "*") + (*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") + (*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") + (*w).Header().Set("Content-Type", "text/html; charset=utf-8") +} diff --git a/client/argocdServer/application/Application.go b/client/argocdServer/application/Application.go index dfb9dea97b..e58eb87655 100644 --- a/client/argocdServer/application/Application.go +++ b/client/argocdServer/application/Application.go @@ -21,146 +21,53 @@ import ( "context" "encoding/json" "errors" - "fmt" - k8sObjectUtils "github.com/devtron-labs/common-lib/utils/k8sObjectsUtil" - "github.com/devtron-labs/devtron/client/argocdServer/connection" - "strings" - "time" - "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" + "github.com/devtron-labs/devtron/client/argocdServer/connection" "github.com/devtron-labs/devtron/util" "go.uber.org/zap" - "google.golang.org/grpc" - v12 "k8s.io/api/apps/v1" - v1 "k8s.io/api/core/v1" -) - -const ( - Degraded = "Degraded" - Healthy = "Healthy" - Progressing = "Progressing" - Suspended = "Suspended" - TimeoutFast = 10 * time.Second - TimeoutSlow = 30 * time.Second - TimeoutLazy = 60 * time.Second - HIBERNATING = "HIBERNATING" - SUCCEEDED = "Succeeded" ) type ServiceClient interface { - List(ctxt context.Context, query *application.ApplicationQuery) (*v1alpha1.ApplicationList, error) - PodLogs(ctxt context.Context, query *application.ApplicationPodLogsQuery) (application.ApplicationService_PodLogsClient, *grpc.ClientConn, error) - ListResourceEvents(ctx context.Context, query *application.ApplicationResourceEventsQuery) (*v1.EventList, error) - ResourceTree(ctx context.Context, query *application.ResourcesQuery) (*ResourceTreeResponse, error) - // Watch returns stream of application change events. - Watch(ctx context.Context, in *application.ApplicationQuery) (application.ApplicationService_WatchClient, *grpc.ClientConn, error) - ManagedResources(ctx context.Context, query *application.ResourcesQuery) (*application.ManagedResourcesResponse, error) - // Rollback syncs an application to its target state - Rollback(ctx context.Context, query *application.ApplicationRollbackRequest) (*v1alpha1.Application, error) - // Patch patch an application + // ResourceTree returns the status for all Apps deployed via ArgoCd + ResourceTree(ctx context.Context, query *application.ResourcesQuery) (*argoApplication.ResourceTreeResponse, error) + + // Patch an ArgoCd application Patch(ctx context.Context, query *application.ApplicationPatchRequest) (*v1alpha1.Application, error) - // GetManifests returns application manifests - GetManifests(ctx context.Context, query *application.ApplicationManifestQuery) (*apiclient.ManifestResponse, error) + // GetResource returns single application resource GetResource(ctxt context.Context, query *application.ApplicationResourceRequest) (*application.ApplicationResourceResponse, error) + // Get returns an application by name Get(ctx context.Context, query *application.ApplicationQuery) (*v1alpha1.Application, error) - // Create creates an application - Create(ctx context.Context, query *application.ApplicationCreateRequest) (*v1alpha1.Application, error) + // Update updates an application Update(ctx context.Context, query *application.ApplicationUpdateRequest) (*v1alpha1.Application, error) + // Sync syncs an application to its target state Sync(ctx context.Context, query *application.ApplicationSyncRequest) (*v1alpha1.Application, error) - // TerminateOperation terminates the currently running operation - TerminateOperation(ctx context.Context, query *application.OperationTerminateRequest) (*application.OperationTerminateResponse, error) - // PatchResource patch single application resource - PatchResource(ctx context.Context, query *application.ApplicationResourcePatchRequest) (*application.ApplicationResourceResponse, error) - // DeleteResource deletes a single application resource - DeleteResource(ctx context.Context, query *application.ApplicationResourceDeleteRequest) (*application.ApplicationResponse, error) + // Delete deletes an application Delete(ctx context.Context, query *application.ApplicationDeleteRequest) (*application.ApplicationResponse, error) } -type Result struct { - Response *application.ApplicationResourceResponse - Error error - Request *application.ApplicationResourceRequest -} - -type ResourceTreeResponse struct { - *v1alpha1.ApplicationTree - NewGenerationReplicaSets []string `json:"newGenerationReplicaSets"` - Status string `json:"status"` - RevisionHash string `json:"revisionHash"` - PodMetadata []*PodMetadata `json:"podMetadata"` - Conditions []v1alpha1.ApplicationCondition `json:"conditions"` -} - -type PodMetadata struct { - Name string `json:"name"` - UID string `json:"uid"` - Containers []*string `json:"containers"` - InitContainers []*string `json:"initContainers"` - IsNew bool `json:"isNew"` - // EphemeralContainers are set for Pod kind manifest response only - // will always contain running ephemeral containers - // +optional - EphemeralContainers []*k8sObjectUtils.EphemeralContainerData `json:"ephemeralContainers"` -} - -type Manifests struct { - rolloutManifest map[string]interface{} - deploymentManifest map[string]interface{} - replicaSetManifests []map[string]interface{} - serviceManifests []map[string]interface{} -} - type ServiceClientImpl struct { logger *zap.SugaredLogger argoCDConnectionManager connection.ArgoCDConnectionManager } func NewApplicationClientImpl( - logger *zap.SugaredLogger, argoCDConnectionManager connection.ArgoCDConnectionManager, -) *ServiceClientImpl { + logger *zap.SugaredLogger, + argoCDConnectionManager connection.ArgoCDConnectionManager) *ServiceClientImpl { return &ServiceClientImpl{ logger: logger, argoCDConnectionManager: argoCDConnectionManager, } } -func (c ServiceClientImpl) ManagedResources(ctxt context.Context, query *application.ResourcesQuery) (*application.ManagedResourcesResponse, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.ManagedResources(ctx, query) - return resp, err -} - -func (c ServiceClientImpl) Rollback(ctxt context.Context, query *application.ApplicationRollbackRequest) (*v1alpha1.Application, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.Rollback(ctx, query) - return resp, err -} - func (c ServiceClientImpl) Patch(ctxt context.Context, query *application.ApplicationPatchRequest) (*v1alpha1.Application, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutLazy) + ctx, cancel := context.WithTimeout(ctxt, argoApplication.TimeoutLazy) defer cancel() token, ok := ctxt.Value("token").(string) if !ok { @@ -173,22 +80,8 @@ func (c ServiceClientImpl) Patch(ctxt context.Context, query *application.Applic return resp, err } -func (c ServiceClientImpl) GetManifests(ctxt context.Context, query *application.ApplicationManifestQuery) (*apiclient.ManifestResponse, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.GetManifests(ctx, query) - return resp, err -} - func (c ServiceClientImpl) Get(ctxt context.Context, query *application.ApplicationQuery) (*v1alpha1.Application, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) + ctx, cancel := context.WithTimeout(ctxt, argoApplication.TimeoutFast) defer cancel() token, ok := ctxt.Value("token").(string) if !ok { @@ -202,7 +95,7 @@ func (c ServiceClientImpl) Get(ctxt context.Context, query *application.Applicat } func (c ServiceClientImpl) Update(ctxt context.Context, query *application.ApplicationUpdateRequest) (*v1alpha1.Application, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) + ctx, cancel := context.WithTimeout(ctxt, argoApplication.TimeoutFast) defer cancel() token, ok := ctxt.Value("token").(string) if !ok { @@ -215,25 +108,12 @@ func (c ServiceClientImpl) Update(ctxt context.Context, query *application.Appli return resp, err } -type ErrUnauthorized struct { - message string -} - -func NewErrUnauthorized(message string) *ErrUnauthorized { - return &ErrUnauthorized{ - message: message, - } -} -func (e *ErrUnauthorized) Error() string { - return e.message -} - func (c ServiceClientImpl) Sync(ctxt context.Context, query *application.ApplicationSyncRequest) (*v1alpha1.Application, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) + ctx, cancel := context.WithTimeout(ctxt, argoApplication.TimeoutFast) defer cancel() token, ok := ctxt.Value("token").(string) if !ok { - return nil, NewErrUnauthorized("Unauthorized") + return nil, argoApplication.NewErrUnauthorized("Unauthorized") } conn := c.argoCDConnectionManager.GetConnection(token) defer util.Close(conn, c.logger) @@ -242,82 +122,8 @@ func (c ServiceClientImpl) Sync(ctxt context.Context, query *application.Applica return resp, err } -func (c ServiceClientImpl) TerminateOperation(ctxt context.Context, query *application.OperationTerminateRequest) (*application.OperationTerminateResponse, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutSlow) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.TerminateOperation(ctx, query) - return resp, err -} - -func (c ServiceClientImpl) PatchResource(ctxt context.Context, query *application.ApplicationResourcePatchRequest) (*application.ApplicationResourceResponse, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.PatchResource(ctx, query) - return resp, err -} - -func (c ServiceClientImpl) DeleteResource(ctxt context.Context, query *application.ApplicationResourceDeleteRequest) (*application.ApplicationResponse, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutSlow) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.DeleteResource(ctx, query) - return resp, err -} - -func (c ServiceClientImpl) List(ctxt context.Context, query *application.ApplicationQuery) (*v1alpha1.ApplicationList, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.List(ctx, query) - return resp, err -} - -func (c ServiceClientImpl) PodLogs(ctx context.Context, query *application.ApplicationPodLogsQuery) (application.ApplicationService_PodLogsClient, *grpc.ClientConn, error) { - token, _ := ctx.Value("token").(string) - conn := c.argoCDConnectionManager.GetConnection(token) - //defer conn.Close() - asc := application.NewApplicationServiceClient(conn) - logs, err := asc.PodLogs(ctx, query) - return logs, conn, err -} - -func (c ServiceClientImpl) Watch(ctx context.Context, query *application.ApplicationQuery) (application.ApplicationService_WatchClient, *grpc.ClientConn, error) { - token, _ := ctx.Value("token").(string) - conn := c.argoCDConnectionManager.GetConnection(token) - //defer conn.Close() - asc := application.NewApplicationServiceClient(conn) - logs, err := asc.Watch(ctx, query) - return logs, conn, err -} - func (c ServiceClientImpl) GetResource(ctxt context.Context, query *application.ApplicationResourceRequest) (*application.ApplicationResourceResponse, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) + ctx, cancel := context.WithTimeout(ctxt, argoApplication.TimeoutFast) defer cancel() token, ok := ctxt.Value("token").(string) if !ok { @@ -330,7 +136,7 @@ func (c ServiceClientImpl) GetResource(ctxt context.Context, query *application. } func (c ServiceClientImpl) Delete(ctxt context.Context, query *application.ApplicationDeleteRequest) (*application.ApplicationResponse, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutSlow) + ctx, cancel := context.WithTimeout(ctxt, argoApplication.TimeoutSlow) defer cancel() token, ok := ctxt.Value("token").(string) if !ok { @@ -342,37 +148,9 @@ func (c ServiceClientImpl) Delete(ctxt context.Context, query *application.Appli return asc.Delete(ctx, query) } -func (c ServiceClientImpl) ListResourceEvents(ctxt context.Context, query *application.ApplicationResourceEventsQuery) (*v1.EventList, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutFast) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.ListResourceEvents(ctx, query) - return resp, err -} - -func (c ServiceClientImpl) Create(ctxt context.Context, query *application.ApplicationCreateRequest) (*v1alpha1.Application, error) { - ctx, cancel := context.WithTimeout(ctxt, TimeoutSlow) - defer cancel() - token, ok := ctxt.Value("token").(string) - if !ok { - return nil, errors.New("Unauthorized") - } - conn := c.argoCDConnectionManager.GetConnection(token) - defer util.Close(conn, c.logger) - asc := application.NewApplicationServiceClient(conn) - resp, err := asc.Create(ctx, query) - return resp, err -} - -func (c ServiceClientImpl) ResourceTree(ctxt context.Context, query *application.ResourcesQuery) (*ResourceTreeResponse, error) { +func (c ServiceClientImpl) ResourceTree(ctxt context.Context, query *application.ResourcesQuery) (*argoApplication.ResourceTreeResponse, error) { //all the apps deployed via argo are fetching status from here - ctx, cancel := context.WithTimeout(ctxt, TimeoutSlow) + ctx, cancel := context.WithTimeout(ctxt, argoApplication.TimeoutSlow) defer cancel() token, ok := ctxt.Value("token").(string) if !ok { @@ -399,7 +177,7 @@ func (c ServiceClientImpl) ResourceTree(ctxt context.Context, query *application appResp, err := app.Recv() if err == nil { // https://github.com/argoproj/argo-cd/issues/11234 workaround - c.updateNodeHealthStatus(resp, appResp) + updateNodeHealthStatus(resp, appResp) status = string(appResp.Application.Status.Health.Status) hash = appResp.Application.Status.Sync.Revision @@ -414,40 +192,10 @@ func (c ServiceClientImpl) ResourceTree(ctxt context.Context, query *application } } } - return &ResourceTreeResponse{resp, newReplicaSets, status, hash, podMetadata, conditions}, err -} - -// fill the health status in node from app resources -func (c ServiceClientImpl) updateNodeHealthStatus(resp *v1alpha1.ApplicationTree, appResp *v1alpha1.ApplicationWatchEvent) { - if resp == nil || len(resp.Nodes) == 0 || appResp == nil || len(appResp.Application.Status.Resources) == 0 { - return - } - - for index, node := range resp.Nodes { - if node.Health != nil { - continue - } - for _, resource := range appResp.Application.Status.Resources { - if node.Group != resource.Group || node.Version != resource.Version || node.Kind != resource.Kind || - node.Name != resource.Name || node.Namespace != resource.Namespace { - continue - } - resourceHealth := resource.Health - if resourceHealth != nil { - node.Health = &v1alpha1.HealthStatus{ - Message: resourceHealth.Message, - Status: resourceHealth.Status, - } - // updating the element in slice - // https://medium.com/@xcoulon/3-ways-to-update-elements-in-a-slice-d5df54c9b2f8 - resp.Nodes[index] = node - } - break - } - } + return &argoApplication.ResourceTreeResponse{resp, newReplicaSets, status, hash, podMetadata, conditions}, err } -func (c ServiceClientImpl) buildPodMetadata(resp *v1alpha1.ApplicationTree, responses []*Result) (podMetaData []*PodMetadata, newReplicaSets []string) { +func (c ServiceClientImpl) buildPodMetadata(resp *v1alpha1.ApplicationTree, responses []*argoApplication.Result) (podMetaData []*argoApplication.PodMetadata, newReplicaSets []string) { rolloutManifests := make([]map[string]interface{}, 0) statefulSetManifest := make(map[string]interface{}) deploymentManifests := make([]map[string]interface{}, 0) @@ -520,7 +268,7 @@ func (c ServiceClientImpl) buildPodMetadata(resp *v1alpha1.ApplicationTree, resp // for rollout we compare pod hash for _, rolloutManifest := range rolloutManifests { if _, ok := rolloutManifest["kind"]; ok { - newReplicaSet := c.getRolloutNewReplicaSetName(rolloutManifest, replicaSetManifests) + newReplicaSet := getRolloutNewReplicaSetName(rolloutManifest, replicaSetManifests) if len(newReplicaSet) > 0 { newReplicaSets = append(newReplicaSets, newReplicaSet) } @@ -529,7 +277,7 @@ func (c ServiceClientImpl) buildPodMetadata(resp *v1alpha1.ApplicationTree, resp for _, deploymentManifest := range deploymentManifests { if _, ok := deploymentManifest["kind"]; ok { - newReplicaSet := c.getDeploymentNewReplicaSetName(deploymentManifest, replicaSetManifests) + newReplicaSet := getDeploymentNewReplicaSetName(deploymentManifest, replicaSetManifests) if len(newReplicaSet) > 0 { newReplicaSets = append(newReplicaSets, newReplicaSet) } @@ -537,15 +285,15 @@ func (c ServiceClientImpl) buildPodMetadata(resp *v1alpha1.ApplicationTree, resp } if _, ok := statefulSetManifest["kind"]; ok { - newPodNames = c.getStatefulSetNewPods(statefulSetManifest, podManifests) + newPodNames = getStatefulSetNewPods(statefulSetManifest, podManifests) } if _, ok := daemonSetManifest["kind"]; ok { - newPodNames = c.getDaemonSetNewPods(daemonSetManifest, podManifests, controllerRevisionManifests) + newPodNames = getDaemonSetNewPods(daemonSetManifest, podManifests, controllerRevisionManifests) } if _, ok := jobsManifest["kind"]; ok { - newPodNames = c.getJobsNewPods(jobsManifest, podManifests) + newPodNames = getJobsNewPods(jobsManifest, podManifests) } for _, node := range resp.Nodes { @@ -565,7 +313,7 @@ func (c ServiceClientImpl) buildPodMetadata(resp *v1alpha1.ApplicationTree, resp //podMetaData := make([]*PodMetadata, 0) duplicateCheck := make(map[string]bool) if len(newReplicaSets) > 0 { - results := c.buildPodMetadataFromReplicaSet(resp, newReplicaSets, replicaSetManifests) + results := buildPodMetadataFromReplicaSet(resp, newReplicaSets, replicaSetManifests) for _, meta := range results { duplicateCheck[meta.Name] = true podMetaData = append(podMetaData, meta) @@ -581,471 +329,3 @@ func (c ServiceClientImpl) buildPodMetadata(resp *v1alpha1.ApplicationTree, resp } return } - -func parseResult(resp *v1alpha1.ApplicationTree, query *application.ResourcesQuery, ctx context.Context, asc application.ApplicationServiceClient, err error, c ServiceClientImpl) []*Result { - var responses = make([]*Result, 0) - qCount := 0 - response := make(chan Result) - if err != nil || resp == nil || len(resp.Nodes) == 0 { - return responses - } - needPods := false - queryNodes := make([]v1alpha1.ResourceNode, 0) - podParents := make([]string, 0) - for _, node := range resp.Nodes { - if node.Kind == "Pod" { - for _, pr := range node.ParentRefs { - podParents = append(podParents, pr.Name) - } - } - } - for _, node := range resp.Nodes { - if node.Kind == "Rollout" || node.Kind == "Deployment" || node.Kind == "StatefulSet" || node.Kind == "DaemonSet" { - queryNodes = append(queryNodes, node) - } - if node.Kind == "ReplicaSet" { - for _, pr := range podParents { - if pr == node.Name { - queryNodes = append(queryNodes, node) - break - } - } - } - if node.Kind == "StatefulSet" || node.Kind == "DaemonSet" || node.Kind == "Workflow" { - needPods = true - } - - if node.Kind == "CronJob" || node.Kind == "Job" { - queryNodes = append(queryNodes, node) - needPods = true - } - } - - c.logger.Debugw("needPods", "pods", needPods) - - if needPods { - for _, node := range resp.Nodes { - if node.Kind == "Pod" { - queryNodes = append(queryNodes, node) - } - } - } - - relevantCR := make(map[string]bool) - for _, node := range resp.Nodes { - prefix := "" - if len(node.ParentRefs) > 0 { - for _, p := range node.ParentRefs { - if p.Kind == "DaemonSet" { - prefix = p.Name - } - } - } - if node.Kind == "Pod" { - relevantCR[prefix+"-"+node.NetworkingInfo.Labels["controller-revision-hash"]] = true - } - } - - for _, node := range resp.Nodes { - if node.Kind == "ControllerRevision" { - if ok := relevantCR[node.Name]; ok { - queryNodes = append(queryNodes, node) - } - } - } - - for _, node := range queryNodes { - rQuery := transform(node, query.ApplicationName) - qCount++ - go func(request application.ApplicationResourceRequest) { - ctx, cancel := context.WithTimeout(ctx, 60*time.Second) - defer cancel() - startTime := time.Now() - res, err := asc.GetResource(ctx, &request) - if err != nil { - c.logger.Errorw("GRPC_GET_RESOURCE", "data", request, "timeTaken", time.Since(startTime), "err", err) - } else { - c.logger.Debugw("GRPC_GET_RESOURCE", "data", request, "timeTaken", time.Since(startTime)) - } - if res != nil || err != nil { - response <- Result{Response: res, Error: err, Request: &request} - } else { - response <- Result{Response: nil, Error: fmt.Errorf("connection closed by client"), Request: &request} - } - }(*rQuery) - } - - if qCount == 0 { - return responses - } - - rCount := 0 - for { - select { - case msg, ok := <-response: - if ok { - if msg.Error == nil { - responses = append(responses, &msg) - } - } - rCount++ - } - if qCount == rCount { - break - } - } - return responses -} - -func (c ServiceClientImpl) getDeploymentNewReplicaSetName(deploymentManifest map[string]interface{}, replicaSetManifests []map[string]interface{}) (newReplicaSet string) { - d, err := json.Marshal(deploymentManifest) - if err != nil { - return - } - deployment := &v12.Deployment{} - err = json.Unmarshal(d, deployment) - if err != nil { - return - } - dPodHash := util.ComputeHash(&deployment.Spec.Template, deployment.Status.CollisionCount) - for _, rs := range replicaSetManifests { - r, err := json.Marshal(rs) - if err != nil { - return - } - replicaset := &v12.ReplicaSet{} - err = json.Unmarshal(r, replicaset) - if err != nil { - continue - } - rsCopy := replicaset.Spec.DeepCopy() - labels := make(map[string]string) - for k, v := range rsCopy.Template.Labels { - if k != "pod-template-hash" { - labels[k] = v - } - } - rsCopy.Template.Labels = labels - podHash := util.ComputeHash(&rsCopy.Template, deployment.Status.CollisionCount) - if podHash == dPodHash { - newReplicaSet = getResourceName(rs) - } - } - return -} - -func (c ServiceClientImpl) getDaemonSetNewPods(daemonSetManifest map[string]interface{}, podManifests []map[string]interface{}, controllerRevisionManifests []map[string]interface{}) (newPodNames map[string]bool) { - d, err := json.Marshal(daemonSetManifest) - if err != nil { - return - } - daemonSet := &v12.DaemonSet{} - err = json.Unmarshal(d, daemonSet) - if err != nil { - return - } - latestRevision := "" - latestGen := 0 - newPodNames = make(map[string]bool, 0) - for _, crm := range controllerRevisionManifests { - rev := int(crm["revision"].(float64)) - if latestGen < rev { - latestGen = rev - latestRevision = getDaemonSetPodControllerRevisionHash(crm) - } - } - for _, pod := range podManifests { - podRevision := getDaemonSetPodControllerRevisionHash(pod) - if latestRevision == podRevision { - newPodNames[getResourceName(pod)] = true - } - } - return -} - -func getDaemonSetPodControllerRevisionHash(pod map[string]interface{}) string { - if md, ok := pod["metadata"]; ok { - if mdm, ok := md.(map[string]interface{}); ok { - if l, ok := mdm["labels"]; ok { - if lm, ok := l.(map[string]interface{}); ok { - if h, ok := lm["controller-revision-hash"]; ok { - if hs, ok := h.(string); ok { - return hs - } - } - } - } - } - } - return "" -} - -func (c ServiceClientImpl) getStatefulSetNewPods(statefulSetManifest map[string]interface{}, podManifests []map[string]interface{}) (newPodNames map[string]bool) { - newPodNames = make(map[string]bool, 0) - updateRevision := getStatefulSetUpdateRevision(statefulSetManifest) - for _, pod := range podManifests { - podRevision := getStatefulSetPodControllerRevisionHash(pod) - if updateRevision == podRevision { - newPodNames[getResourceName(pod)] = true - } - } - return -} - -func getStatefulSetUpdateRevision(statefulSet map[string]interface{}) string { - if s, ok := statefulSet["status"]; ok { - if sm, ok := s.(map[string]interface{}); ok { - if cph, ok := sm["updateRevision"]; ok { - if cphs, ok := cph.(string); ok { - return cphs - } - } - } - } - return "" -} - -func getStatefulSetPodControllerRevisionHash(pod map[string]interface{}) string { - if md, ok := pod["metadata"]; ok { - if mdm, ok := md.(map[string]interface{}); ok { - if l, ok := mdm["labels"]; ok { - if lm, ok := l.(map[string]interface{}); ok { - if h, ok := lm["controller-revision-hash"]; ok { - if hs, ok := h.(string); ok { - return hs - } - } - } - } - } - } - return "" -} - -func (c ServiceClientImpl) getRolloutNewReplicaSetName(rManifest map[string]interface{}, replicaSetManifests []map[string]interface{}) (newReplicaSet string) { - rPodHash := getRolloutPodHash(rManifest) - for _, rs := range replicaSetManifests { - podHash := getRolloutPodTemplateHash(rs) - if podHash == rPodHash { - newReplicaSet = getResourceName(rs) - } - } - return newReplicaSet -} - -func getRolloutPodHash(rollout map[string]interface{}) string { - if s, ok := rollout["status"]; ok { - if sm, ok := s.(map[string]interface{}); ok { - if cph, ok := sm["currentPodHash"]; ok { - if cphs, ok := cph.(string); ok { - return cphs - } - } - } - } - return "" -} - -func getRolloutPodTemplateHash(pod map[string]interface{}) string { - if md, ok := pod["metadata"]; ok { - if mdm, ok := md.(map[string]interface{}); ok { - if l, ok := mdm["labels"]; ok { - if lm, ok := l.(map[string]interface{}); ok { - if h, ok := lm["rollouts-pod-template-hash"]; ok { - if hs, ok := h.(string); ok { - return hs - } - } - } - } - } - } - return "" -} - -func buildPodMetadataFromPod(resp *v1alpha1.ApplicationTree, podManifests []map[string]interface{}, newPodNames map[string]bool) (podMetadata []*PodMetadata) { - containerMapping := make(map[string][]*string) - initContainerMapping := make(map[string][]*string) - for _, pod := range podManifests { - containerMapping[getResourceName(pod)] = getPodContainers(pod) - } - - for _, pod := range podManifests { - initContainerMapping[getResourceName(pod)] = getPodInitContainers(pod) - } - - for _, node := range resp.Nodes { - if node.Kind == "Pod" { - isNew := newPodNames[node.Name] - metadata := PodMetadata{Name: node.Name, UID: node.UID, Containers: containerMapping[node.Name], InitContainers: initContainerMapping[node.Name], IsNew: isNew} - podMetadata = append(podMetadata, &metadata) - } - } - return -} - -func contains(elems []string, v string) bool { - for _, s := range elems { - if strings.HasPrefix(v, s) { - return true - } - } - return false -} - -func getPodContainers(resource map[string]interface{}) []*string { - containers := make([]*string, 0) - if s, ok := resource["spec"]; ok { - if sm, ok := s.(map[string]interface{}); ok { - if c, ok := sm["containers"]; ok { - if cas, ok := c.([]interface{}); ok { - for _, ca := range cas { - if cam, ok := ca.(map[string]interface{}); ok { - if n, ok := cam["name"]; ok { - if cn, ok := n.(string); ok { - containers = append(containers, &cn) - } - } - } - } - } - } - } - } - return containers -} -func getPodInitContainers(resource map[string]interface{}) []*string { - containers := make([]*string, 0) - if s, ok := resource["spec"]; ok { - if sm, ok := s.(map[string]interface{}); ok { - if c, ok := sm["initContainers"]; ok { - if cas, ok := c.([]interface{}); ok { - for _, ca := range cas { - if cam, ok := ca.(map[string]interface{}); ok { - if n, ok := cam["name"]; ok { - if cn, ok := n.(string); ok { - containers = append(containers, &cn) - } - } - } - } - } - } - } - } - return containers -} - -func (c ServiceClientImpl) buildPodMetadataFromReplicaSet(resp *v1alpha1.ApplicationTree, newReplicaSets []string, replicaSetManifests []map[string]interface{}) (podMetadata []*PodMetadata) { - replicaSets := make(map[string]map[string]interface{}) - for _, replicaSet := range replicaSetManifests { - replicaSets[getResourceName(replicaSet)] = replicaSet - } - for _, node := range resp.Nodes { - if node.Kind == "Pod" { - parentName := "" - for _, p := range node.ParentRefs { - if p.Kind == "ReplicaSet" { - parentName = p.Name - } - } - if parentName != "" { - isNew := false - for _, newReplicaSet := range newReplicaSets { - if parentName == newReplicaSet { - isNew = true - break - } - } - replicaSet := replicaSets[parentName] - containers, intContainers := getReplicaSetContainers(replicaSet) - metadata := PodMetadata{Name: node.Name, UID: node.UID, Containers: containers, InitContainers: intContainers, IsNew: isNew} - podMetadata = append(podMetadata, &metadata) - } - } - } - return -} - -func getReplicaSetContainers(resource map[string]interface{}) (containers []*string, intContainers []*string) { - if s, ok := resource["spec"]; ok { - if sm, ok := s.(map[string]interface{}); ok { - if t, ok := sm["template"]; ok { - if tm, ok := t.(map[string]interface{}); ok { - if tms, ok := tm["spec"]; ok { - if tmsm, ok := tms.(map[string]interface{}); ok { - if c, ok := tmsm["containers"]; ok { - if cas, ok := c.([]interface{}); ok { - for _, ca := range cas { - if cam, ok := ca.(map[string]interface{}); ok { - if n, ok := cam["name"]; ok { - if cn, ok := n.(string); ok { - containers = append(containers, &cn) - } - } - } - } - } - } - ///initContainers.name - if c, ok := tmsm["initContainers"]; ok { - if cas, ok := c.([]interface{}); ok { - for _, ca := range cas { - if cam, ok := ca.(map[string]interface{}); ok { - if n, ok := cam["name"]; ok { - if cn, ok := n.(string); ok { - intContainers = append(intContainers, &cn) - } - } - } - } - } - } - } - } - } - } - } - } - return containers, intContainers -} - -func getResourceName(resource map[string]interface{}) string { - if md, ok := resource["metadata"]; ok { - if mdm, ok := md.(map[string]interface{}); ok { - if h, ok := mdm["name"]; ok { - if hs, ok := h.(string); ok { - return hs - } - } - } - } - return "" -} - -func transform(resource v1alpha1.ResourceNode, name *string) *application.ApplicationResourceRequest { - resourceName := resource.Name - kind := resource.Kind - group := resource.Group - version := resource.Version - namespace := resource.Namespace - request := &application.ApplicationResourceRequest{ - Name: name, - ResourceName: &resourceName, - Kind: &kind, - Group: &group, - Version: &version, - Namespace: &namespace, - } - return request -} - -func (c ServiceClientImpl) getJobsNewPods(jobManifest map[string]interface{}, podManifests []map[string]interface{}) (newPodNames map[string]bool) { - newPodNames = make(map[string]bool, 0) - for _, pod := range podManifests { - newPodNames[getResourceName(pod)] = true - } - - //TODO - new or old logic - return -} diff --git a/client/argocdServer/application/ApplicationUtil.go b/client/argocdServer/application/ApplicationUtil.go new file mode 100644 index 0000000000..cbf7df2b6b --- /dev/null +++ b/client/argocdServer/application/ApplicationUtil.go @@ -0,0 +1,513 @@ +package application + +import ( + "context" + "encoding/json" + "fmt" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" + "github.com/devtron-labs/devtron/util" + v12 "k8s.io/api/apps/v1" + "strings" + "time" +) + +// fill the health status in node from app resources +func updateNodeHealthStatus(resp *v1alpha1.ApplicationTree, appResp *v1alpha1.ApplicationWatchEvent) { + if resp == nil || len(resp.Nodes) == 0 || appResp == nil || len(appResp.Application.Status.Resources) == 0 { + return + } + + for index, node := range resp.Nodes { + if node.Health != nil { + continue + } + for _, resource := range appResp.Application.Status.Resources { + if node.Group != resource.Group || node.Version != resource.Version || node.Kind != resource.Kind || + node.Name != resource.Name || node.Namespace != resource.Namespace { + continue + } + resourceHealth := resource.Health + if resourceHealth != nil { + node.Health = &v1alpha1.HealthStatus{ + Message: resourceHealth.Message, + Status: resourceHealth.Status, + } + // updating the element in slice + // https://medium.com/@xcoulon/3-ways-to-update-elements-in-a-slice-d5df54c9b2f8 + resp.Nodes[index] = node + } + break + } + } +} + +func parseResult(resp *v1alpha1.ApplicationTree, query *application.ResourcesQuery, ctx context.Context, asc application.ApplicationServiceClient, err error, c ServiceClientImpl) []*argoApplication.Result { + var responses = make([]*argoApplication.Result, 0) + qCount := 0 + response := make(chan argoApplication.Result) + if err != nil || resp == nil || len(resp.Nodes) == 0 { + return responses + } + needPods := false + queryNodes := make([]v1alpha1.ResourceNode, 0) + podParents := make([]string, 0) + for _, node := range resp.Nodes { + if node.Kind == "Pod" { + for _, pr := range node.ParentRefs { + podParents = append(podParents, pr.Name) + } + } + } + for _, node := range resp.Nodes { + if node.Kind == "Rollout" || node.Kind == "Deployment" || node.Kind == "StatefulSet" || node.Kind == "DaemonSet" { + queryNodes = append(queryNodes, node) + } + if node.Kind == "ReplicaSet" { + for _, pr := range podParents { + if pr == node.Name { + queryNodes = append(queryNodes, node) + break + } + } + } + if node.Kind == "StatefulSet" || node.Kind == "DaemonSet" || node.Kind == "Workflow" { + needPods = true + } + + if node.Kind == "CronJob" || node.Kind == "Job" { + queryNodes = append(queryNodes, node) + needPods = true + } + } + + c.logger.Debugw("needPods", "pods", needPods) + + if needPods { + for _, node := range resp.Nodes { + if node.Kind == "Pod" { + queryNodes = append(queryNodes, node) + } + } + } + + relevantCR := make(map[string]bool) + for _, node := range resp.Nodes { + prefix := "" + if len(node.ParentRefs) > 0 { + for _, p := range node.ParentRefs { + if p.Kind == "DaemonSet" { + prefix = p.Name + } + } + } + if node.Kind == "Pod" { + relevantCR[prefix+"-"+node.NetworkingInfo.Labels["controller-revision-hash"]] = true + } + } + + for _, node := range resp.Nodes { + if node.Kind == "ControllerRevision" { + if ok := relevantCR[node.Name]; ok { + queryNodes = append(queryNodes, node) + } + } + } + + for _, node := range queryNodes { + rQuery := transform(node, query.ApplicationName) + qCount++ + go func(request application.ApplicationResourceRequest) { + ctx, cancel := context.WithTimeout(ctx, 60*time.Second) + defer cancel() + startTime := time.Now() + res, err := asc.GetResource(ctx, &request) + if err != nil { + c.logger.Errorw("GRPC_GET_RESOURCE", "data", request, "timeTaken", time.Since(startTime), "err", err) + } else { + c.logger.Debugw("GRPC_GET_RESOURCE", "data", request, "timeTaken", time.Since(startTime)) + } + if res != nil || err != nil { + response <- argoApplication.Result{Response: res, Error: err, Request: &request} + } else { + response <- argoApplication.Result{Response: nil, Error: fmt.Errorf("connection closed by client"), Request: &request} + } + }(*rQuery) + } + + if qCount == 0 { + return responses + } + + rCount := 0 + for { + select { + case msg, ok := <-response: + if ok { + if msg.Error == nil { + responses = append(responses, &msg) + } + } + rCount++ + } + if qCount == rCount { + break + } + } + return responses +} + +func getDeploymentNewReplicaSetName(deploymentManifest map[string]interface{}, replicaSetManifests []map[string]interface{}) (newReplicaSet string) { + d, err := json.Marshal(deploymentManifest) + if err != nil { + return + } + deployment := &v12.Deployment{} + err = json.Unmarshal(d, deployment) + if err != nil { + return + } + dPodHash := util.ComputeHash(&deployment.Spec.Template, deployment.Status.CollisionCount) + for _, rs := range replicaSetManifests { + r, err := json.Marshal(rs) + if err != nil { + return + } + replicaset := &v12.ReplicaSet{} + err = json.Unmarshal(r, replicaset) + if err != nil { + continue + } + rsCopy := replicaset.Spec.DeepCopy() + labels := make(map[string]string) + for k, v := range rsCopy.Template.Labels { + if k != "pod-template-hash" { + labels[k] = v + } + } + rsCopy.Template.Labels = labels + podHash := util.ComputeHash(&rsCopy.Template, deployment.Status.CollisionCount) + if podHash == dPodHash { + newReplicaSet = getResourceName(rs) + } + } + return +} + +func getDaemonSetNewPods(daemonSetManifest map[string]interface{}, podManifests []map[string]interface{}, controllerRevisionManifests []map[string]interface{}) (newPodNames map[string]bool) { + d, err := json.Marshal(daemonSetManifest) + if err != nil { + return + } + daemonSet := &v12.DaemonSet{} + err = json.Unmarshal(d, daemonSet) + if err != nil { + return + } + latestRevision := "" + latestGen := 0 + newPodNames = make(map[string]bool, 0) + for _, crm := range controllerRevisionManifests { + rev := int(crm["revision"].(float64)) + if latestGen < rev { + latestGen = rev + latestRevision = getDaemonSetPodControllerRevisionHash(crm) + } + } + for _, pod := range podManifests { + podRevision := getDaemonSetPodControllerRevisionHash(pod) + if latestRevision == podRevision { + newPodNames[getResourceName(pod)] = true + } + } + return +} + +func getDaemonSetPodControllerRevisionHash(pod map[string]interface{}) string { + if md, ok := pod["metadata"]; ok { + if mdm, ok := md.(map[string]interface{}); ok { + if l, ok := mdm["labels"]; ok { + if lm, ok := l.(map[string]interface{}); ok { + if h, ok := lm["controller-revision-hash"]; ok { + if hs, ok := h.(string); ok { + return hs + } + } + } + } + } + } + return "" +} + +func getStatefulSetNewPods(statefulSetManifest map[string]interface{}, podManifests []map[string]interface{}) (newPodNames map[string]bool) { + newPodNames = make(map[string]bool, 0) + updateRevision := getStatefulSetUpdateRevision(statefulSetManifest) + for _, pod := range podManifests { + podRevision := getStatefulSetPodControllerRevisionHash(pod) + if updateRevision == podRevision { + newPodNames[getResourceName(pod)] = true + } + } + return +} + +func getStatefulSetUpdateRevision(statefulSet map[string]interface{}) string { + if s, ok := statefulSet["status"]; ok { + if sm, ok := s.(map[string]interface{}); ok { + if cph, ok := sm["updateRevision"]; ok { + if cphs, ok := cph.(string); ok { + return cphs + } + } + } + } + return "" +} + +func getStatefulSetPodControllerRevisionHash(pod map[string]interface{}) string { + if md, ok := pod["metadata"]; ok { + if mdm, ok := md.(map[string]interface{}); ok { + if l, ok := mdm["labels"]; ok { + if lm, ok := l.(map[string]interface{}); ok { + if h, ok := lm["controller-revision-hash"]; ok { + if hs, ok := h.(string); ok { + return hs + } + } + } + } + } + } + return "" +} + +func getRolloutNewReplicaSetName(rManifest map[string]interface{}, replicaSetManifests []map[string]interface{}) (newReplicaSet string) { + rPodHash := getRolloutPodHash(rManifest) + for _, rs := range replicaSetManifests { + podHash := getRolloutPodTemplateHash(rs) + if podHash == rPodHash { + newReplicaSet = getResourceName(rs) + } + } + return newReplicaSet +} + +func getRolloutPodHash(rollout map[string]interface{}) string { + if s, ok := rollout["status"]; ok { + if sm, ok := s.(map[string]interface{}); ok { + if cph, ok := sm["currentPodHash"]; ok { + if cphs, ok := cph.(string); ok { + return cphs + } + } + } + } + return "" +} + +func getRolloutPodTemplateHash(pod map[string]interface{}) string { + if md, ok := pod["metadata"]; ok { + if mdm, ok := md.(map[string]interface{}); ok { + if l, ok := mdm["labels"]; ok { + if lm, ok := l.(map[string]interface{}); ok { + if h, ok := lm["rollouts-pod-template-hash"]; ok { + if hs, ok := h.(string); ok { + return hs + } + } + } + } + } + } + return "" +} + +func buildPodMetadataFromPod(resp *v1alpha1.ApplicationTree, podManifests []map[string]interface{}, newPodNames map[string]bool) (podMetadata []*argoApplication.PodMetadata) { + containerMapping := make(map[string][]*string) + initContainerMapping := make(map[string][]*string) + for _, pod := range podManifests { + containerMapping[getResourceName(pod)] = getPodContainers(pod) + } + + for _, pod := range podManifests { + initContainerMapping[getResourceName(pod)] = getPodInitContainers(pod) + } + + for _, node := range resp.Nodes { + if node.Kind == "Pod" { + isNew := newPodNames[node.Name] + metadata := argoApplication.PodMetadata{Name: node.Name, UID: node.UID, Containers: containerMapping[node.Name], InitContainers: initContainerMapping[node.Name], IsNew: isNew} + podMetadata = append(podMetadata, &metadata) + } + } + return +} + +func contains(elems []string, v string) bool { + for _, s := range elems { + if strings.HasPrefix(v, s) { + return true + } + } + return false +} + +func getPodContainers(resource map[string]interface{}) []*string { + containers := make([]*string, 0) + if s, ok := resource["spec"]; ok { + if sm, ok := s.(map[string]interface{}); ok { + if c, ok := sm["containers"]; ok { + if cas, ok := c.([]interface{}); ok { + for _, ca := range cas { + if cam, ok := ca.(map[string]interface{}); ok { + if n, ok := cam["name"]; ok { + if cn, ok := n.(string); ok { + containers = append(containers, &cn) + } + } + } + } + } + } + } + } + return containers +} + +func getPodInitContainers(resource map[string]interface{}) []*string { + containers := make([]*string, 0) + if s, ok := resource["spec"]; ok { + if sm, ok := s.(map[string]interface{}); ok { + if c, ok := sm["initContainers"]; ok { + if cas, ok := c.([]interface{}); ok { + for _, ca := range cas { + if cam, ok := ca.(map[string]interface{}); ok { + if n, ok := cam["name"]; ok { + if cn, ok := n.(string); ok { + containers = append(containers, &cn) + } + } + } + } + } + } + } + } + return containers +} + +func buildPodMetadataFromReplicaSet(resp *v1alpha1.ApplicationTree, newReplicaSets []string, replicaSetManifests []map[string]interface{}) (podMetadata []*argoApplication.PodMetadata) { + replicaSets := make(map[string]map[string]interface{}) + for _, replicaSet := range replicaSetManifests { + replicaSets[getResourceName(replicaSet)] = replicaSet + } + for _, node := range resp.Nodes { + if node.Kind == "Pod" { + parentName := "" + for _, p := range node.ParentRefs { + if p.Kind == "ReplicaSet" { + parentName = p.Name + } + } + if parentName != "" { + isNew := false + for _, newReplicaSet := range newReplicaSets { + if parentName == newReplicaSet { + isNew = true + break + } + } + replicaSet := replicaSets[parentName] + containers, intContainers := getReplicaSetContainers(replicaSet) + metadata := argoApplication.PodMetadata{Name: node.Name, UID: node.UID, Containers: containers, InitContainers: intContainers, IsNew: isNew} + podMetadata = append(podMetadata, &metadata) + } + } + } + return +} + +func getReplicaSetContainers(resource map[string]interface{}) (containers []*string, intContainers []*string) { + if s, ok := resource["spec"]; ok { + if sm, ok := s.(map[string]interface{}); ok { + if t, ok := sm["template"]; ok { + if tm, ok := t.(map[string]interface{}); ok { + if tms, ok := tm["spec"]; ok { + if tmsm, ok := tms.(map[string]interface{}); ok { + if c, ok := tmsm["containers"]; ok { + if cas, ok := c.([]interface{}); ok { + for _, ca := range cas { + if cam, ok := ca.(map[string]interface{}); ok { + if n, ok := cam["name"]; ok { + if cn, ok := n.(string); ok { + containers = append(containers, &cn) + } + } + } + } + } + } + ///initContainers.name + if c, ok := tmsm["initContainers"]; ok { + if cas, ok := c.([]interface{}); ok { + for _, ca := range cas { + if cam, ok := ca.(map[string]interface{}); ok { + if n, ok := cam["name"]; ok { + if cn, ok := n.(string); ok { + intContainers = append(intContainers, &cn) + } + } + } + } + } + } + } + } + } + } + } + } + return containers, intContainers +} + +func getResourceName(resource map[string]interface{}) string { + if md, ok := resource["metadata"]; ok { + if mdm, ok := md.(map[string]interface{}); ok { + if h, ok := mdm["name"]; ok { + if hs, ok := h.(string); ok { + return hs + } + } + } + } + return "" +} + +func transform(resource v1alpha1.ResourceNode, name *string) *application.ApplicationResourceRequest { + resourceName := resource.Name + kind := resource.Kind + group := resource.Group + version := resource.Version + namespace := resource.Namespace + request := &application.ApplicationResourceRequest{ + Name: name, + ResourceName: &resourceName, + Kind: &kind, + Group: &group, + Version: &version, + Namespace: &namespace, + } + return request +} + +func getJobsNewPods(jobManifest map[string]interface{}, podManifests []map[string]interface{}) (newPodNames map[string]bool) { + newPodNames = make(map[string]bool, 0) + for _, pod := range podManifests { + newPodNames[getResourceName(pod)] = true + } + + //TODO - new or old logic + return +} diff --git a/client/argocdServer/application/Application_test.go b/client/argocdServer/application/Application_test.go index 5cab0e0001..eb2c26e726 100644 --- a/client/argocdServer/application/Application_test.go +++ b/client/argocdServer/application/Application_test.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "testing" "go.uber.org/zap" @@ -60,7 +61,7 @@ func TestServiceClientImpl_getRolloutStatus(t *testing.T) { resp: data1.respTree, }, wantNewReplicaSet: "app-deployment-9-7c797c6d54", - wantStatus: Healthy, + wantStatus: argoApplication.Healthy, }, { name: "test2", @@ -74,7 +75,7 @@ func TestServiceClientImpl_getRolloutStatus(t *testing.T) { resp: data2.respTree, }, wantNewReplicaSet: "app-deployment-9-7c797c6d54", - wantStatus: Degraded, + wantStatus: argoApplication.Degraded, }, { name: "test3", @@ -88,7 +89,7 @@ func TestServiceClientImpl_getRolloutStatus(t *testing.T) { resp: data3.respTree, }, wantNewReplicaSet: "app-deployment-9-7c797c6d54", - wantStatus: Suspended, + wantStatus: argoApplication.Suspended, }, { name: "test4", @@ -102,7 +103,7 @@ func TestServiceClientImpl_getRolloutStatus(t *testing.T) { resp: data4.respTree, }, wantNewReplicaSet: "app-deployment-9-7c797c6d54", - wantStatus: Degraded, + wantStatus: argoApplication.Degraded, }, } for _, tt := range tests { diff --git a/client/argocdServer/bean/bean.go b/client/argocdServer/bean/bean.go index 1a75a5c204..c2b3093b4f 100644 --- a/client/argocdServer/bean/bean.go +++ b/client/argocdServer/bean/bean.go @@ -1,3 +1,63 @@ package bean +import ( + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/devtron-labs/common-lib/utils/k8sObjectsUtil" + "time" +) + const RefreshTypeNormal = "normal" + +const ( + Degraded = "Degraded" + Healthy = "Healthy" + Progressing = "Progressing" + Suspended = "Suspended" + TimeoutFast = 10 * time.Second + TimeoutSlow = 30 * time.Second + TimeoutLazy = 60 * time.Second + HIBERNATING = "HIBERNATING" + SUCCEEDED = "Succeeded" +) + +type Result struct { + Response *application.ApplicationResourceResponse + Error error + Request *application.ApplicationResourceRequest +} + +type ResourceTreeResponse struct { + *v1alpha1.ApplicationTree + NewGenerationReplicaSets []string `json:"newGenerationReplicaSets"` + Status string `json:"status"` + RevisionHash string `json:"revisionHash"` + PodMetadata []*PodMetadata `json:"podMetadata"` + Conditions []v1alpha1.ApplicationCondition `json:"conditions"` +} + +type PodMetadata struct { + Name string `json:"name"` + UID string `json:"uid"` + Containers []*string `json:"containers"` + InitContainers []*string `json:"initContainers"` + IsNew bool `json:"isNew"` + // EphemeralContainers are set for Pod kind manifest response only + // will always contain running ephemeral containers + // +optional + EphemeralContainers []*k8sObjectsUtil.EphemeralContainerData `json:"ephemeralContainers"` +} + +type ErrUnauthorized struct { + message string +} + +func NewErrUnauthorized(message string) *ErrUnauthorized { + return &ErrUnauthorized{ + message: message, + } +} + +func (e *ErrUnauthorized) Error() string { + return e.message +} diff --git a/client/argocdServer/repository/Repository.go b/client/argocdServer/repository/Repository.go index 7b5013f3f3..c53b720e46 100644 --- a/client/argocdServer/repository/Repository.go +++ b/client/argocdServer/repository/Repository.go @@ -23,7 +23,7 @@ import ( repository2 "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" - "github.com/devtron-labs/devtron/client/argocdServer/application" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "github.com/devtron-labs/devtron/client/argocdServer/connection" "go.uber.org/zap" ) @@ -66,7 +66,7 @@ func (r ServiceClientImpl) getService(ctx context.Context) (repository2.Reposito } func (r ServiceClientImpl) List(ctx context.Context, query *repository2.RepoQuery) (*v1alpha1.RepositoryList, error) { - ctx, cancel := context.WithTimeout(ctx, application.TimeoutFast) + ctx, cancel := context.WithTimeout(ctx, argoApplication.TimeoutFast) defer cancel() client, err := r.getService(ctx) if err != nil { @@ -76,7 +76,7 @@ func (r ServiceClientImpl) List(ctx context.Context, query *repository2.RepoQuer } func (r ServiceClientImpl) ListApps(ctx context.Context, query *repository2.RepoAppsQuery) (*repository2.RepoAppsResponse, error) { - ctx, cancel := context.WithTimeout(ctx, application.TimeoutFast) + ctx, cancel := context.WithTimeout(ctx, argoApplication.TimeoutFast) defer cancel() client, err := r.getService(ctx) if err != nil { @@ -86,7 +86,7 @@ func (r ServiceClientImpl) ListApps(ctx context.Context, query *repository2.Repo } func (r ServiceClientImpl) GetAppDetails(ctx context.Context, query *repository2.RepoAppDetailsQuery) (*apiclient.RepoAppDetailsResponse, error) { - ctx, cancel := context.WithTimeout(ctx, application.TimeoutFast) + ctx, cancel := context.WithTimeout(ctx, argoApplication.TimeoutFast) defer cancel() client, err := r.getService(ctx) if err != nil { @@ -96,7 +96,7 @@ func (r ServiceClientImpl) GetAppDetails(ctx context.Context, query *repository2 } func (r ServiceClientImpl) Create(ctx context.Context, query *repository2.RepoCreateRequest) (*v1alpha1.Repository, error) { - ctx, cancel := context.WithTimeout(ctx, application.TimeoutSlow) + ctx, cancel := context.WithTimeout(ctx, argoApplication.TimeoutSlow) defer cancel() client, err := r.getService(ctx) if err != nil { @@ -106,7 +106,7 @@ func (r ServiceClientImpl) Create(ctx context.Context, query *repository2.RepoCr } func (r ServiceClientImpl) Update(ctx context.Context, query *repository2.RepoUpdateRequest) (*v1alpha1.Repository, error) { - ctx, cancel := context.WithTimeout(ctx, application.TimeoutSlow) + ctx, cancel := context.WithTimeout(ctx, argoApplication.TimeoutSlow) defer cancel() client, err := r.getService(ctx) if err != nil { @@ -116,7 +116,7 @@ func (r ServiceClientImpl) Update(ctx context.Context, query *repository2.RepoUp } func (r ServiceClientImpl) Delete(ctx context.Context, query *repository2.RepoQuery) (*repository2.RepoResponse, error) { - ctx, cancel := context.WithTimeout(ctx, application.TimeoutSlow) + ctx, cancel := context.WithTimeout(ctx, argoApplication.TimeoutSlow) defer cancel() client, err := r.getService(ctx) if err != nil { diff --git a/cmd/external-app/router.go b/cmd/external-app/router.go index e143987a70..d5a803d256 100644 --- a/cmd/external-app/router.go +++ b/cmd/external-app/router.go @@ -19,6 +19,7 @@ import ( "github.com/devtron-labs/devtron/api/module" "github.com/devtron-labs/devtron/api/restHandler/common" "github.com/devtron-labs/devtron/api/router" + "github.com/devtron-labs/devtron/api/router/app" "github.com/devtron-labs/devtron/api/server" "github.com/devtron-labs/devtron/api/team" "github.com/devtron-labs/devtron/api/terminal" @@ -61,7 +62,7 @@ type MuxRouter struct { telemetryRouter router.TelemetryRouter userTerminalAccessRouter terminal.UserTerminalAccessRouter attributesRouter router.AttributesRouter - appRouter router.AppRouter + appRouter app.AppRouterEAMode rbacRoleRouter user.RbacRoleRouter } @@ -93,7 +94,7 @@ func NewMuxRouter( telemetryRouter router.TelemetryRouter, userTerminalAccessRouter terminal.UserTerminalAccessRouter, attributesRouter router.AttributesRouter, - appRouter router.AppRouter, + appRouter app.AppRouterEAMode, rbacRoleRouter user.RbacRoleRouter, ) *MuxRouter { r := &MuxRouter{ @@ -186,8 +187,8 @@ func (r *MuxRouter) Init() { r.helmAppRouter.InitAppListRouter(HelmApplicationSubRouter) r.commonDeploymentRouter.Init(HelmApplicationSubRouter) - ApplicationSubRouter := r.Router.PathPrefix("/orchestrator/app").Subrouter() - r.appRouter.InitAppRouter(ApplicationSubRouter) + applicationSubRouter := r.Router.PathPrefix("/orchestrator/app").Subrouter() + r.appRouter.InitAppRouterEAMode(applicationSubRouter) k8sApp := r.Router.PathPrefix("/orchestrator/k8s").Subrouter() r.k8sApplicationRouter.InitK8sApplicationRouter(k8sApp) diff --git a/cmd/external-app/wire.go b/cmd/external-app/wire.go index 1aaab3c922..73671cdbb3 100644 --- a/cmd/external-app/wire.go +++ b/cmd/external-app/wire.go @@ -23,7 +23,12 @@ import ( "github.com/devtron-labs/devtron/api/k8s" "github.com/devtron-labs/devtron/api/module" "github.com/devtron-labs/devtron/api/restHandler" + "github.com/devtron-labs/devtron/api/restHandler/app/appInfo" + appList2 "github.com/devtron-labs/devtron/api/restHandler/app/appList" "github.com/devtron-labs/devtron/api/router" + app3 "github.com/devtron-labs/devtron/api/router/app" + appInfo2 "github.com/devtron-labs/devtron/api/router/app/appInfo" + "github.com/devtron-labs/devtron/api/router/app/appList" "github.com/devtron-labs/devtron/api/server" "github.com/devtron-labs/devtron/api/team" "github.com/devtron-labs/devtron/api/terminal" @@ -101,10 +106,18 @@ func InitializeApp() (*App, error) { rbac.NewEnforcerUtilImpl, wire.Bind(new(rbac.EnforcerUtil), new(*rbac.EnforcerUtilImpl)), - router.NewAppRouterImpl, - wire.Bind(new(router.AppRouter), new(*router.AppRouterImpl)), - restHandler.NewAppRestHandlerImpl, - wire.Bind(new(restHandler.AppRestHandler), new(*restHandler.AppRestHandlerImpl)), + appInfo2.NewAppInfoRouterImpl, + wire.Bind(new(appInfo2.AppInfoRouter), new(*appInfo2.AppInfoRouterImpl)), + appInfo.NewAppInfoRestHandlerImpl, + wire.Bind(new(appInfo.AppInfoRestHandler), new(*appInfo.AppInfoRestHandlerImpl)), + + appList.NewAppFilteringRouterImpl, + wire.Bind(new(appList.AppFilteringRouter), new(*appList.AppFilteringRouterImpl)), + appList2.NewAppFilteringRestHandlerImpl, + wire.Bind(new(appList2.AppFilteringRestHandler), new(*appList2.AppFilteringRestHandlerImpl)), + + app3.NewAppRouterEAModeImpl, + wire.Bind(new(app3.AppRouterEAMode), new(*app3.AppRouterEAModeImpl)), app.NewAppCrudOperationServiceImpl, wire.Bind(new(app.AppCrudOperationService), new(*app.AppCrudOperationServiceImpl)), diff --git a/cmd/external-app/wire_gen.go b/cmd/external-app/wire_gen.go index 963c40f842..a8fecd24ba 100644 --- a/cmd/external-app/wire_gen.go +++ b/cmd/external-app/wire_gen.go @@ -29,7 +29,12 @@ import ( capacity2 "github.com/devtron-labs/devtron/api/k8s/capacity" module2 "github.com/devtron-labs/devtron/api/module" "github.com/devtron-labs/devtron/api/restHandler" + "github.com/devtron-labs/devtron/api/restHandler/app/appInfo" + "github.com/devtron-labs/devtron/api/restHandler/app/appList" "github.com/devtron-labs/devtron/api/router" + app3 "github.com/devtron-labs/devtron/api/router/app" + appInfo2 "github.com/devtron-labs/devtron/api/router/app/appInfo" + appList2 "github.com/devtron-labs/devtron/api/router/app/appList" server2 "github.com/devtron-labs/devtron/api/server" team2 "github.com/devtron-labs/devtron/api/team" terminal2 "github.com/devtron-labs/devtron/api/terminal" @@ -378,12 +383,15 @@ func InitializeApp() (*App, error) { appLabelRepositoryImpl := pipelineConfig.NewAppLabelRepositoryImpl(db) materialRepositoryImpl := pipelineConfig.NewMaterialRepositoryImpl(db) appCrudOperationServiceImpl := app2.NewAppCrudOperationServiceImpl(appLabelRepositoryImpl, sugaredLogger, appRepositoryImpl, userRepositoryImpl, installedAppRepositoryImpl, genericNoteServiceImpl, materialRepositoryImpl) - appRestHandlerImpl := restHandler.NewAppRestHandlerImpl(sugaredLogger, appCrudOperationServiceImpl, userServiceImpl, validate, enforcerUtilImpl, enforcerImpl, helmAppServiceImpl, enforcerUtilHelmImpl, genericNoteServiceImpl) - appRouterImpl := router.NewAppRouterImpl(sugaredLogger, appRestHandlerImpl) + appInfoRestHandlerImpl := appInfo.NewAppInfoRestHandlerImpl(sugaredLogger, appCrudOperationServiceImpl, userServiceImpl, validate, enforcerUtilImpl, enforcerImpl, helmAppServiceImpl, enforcerUtilHelmImpl, genericNoteServiceImpl) + appInfoRouterImpl := appInfo2.NewAppInfoRouterImpl(sugaredLogger, appInfoRestHandlerImpl) + appFilteringRestHandlerImpl := appList.NewAppFilteringRestHandlerImpl(sugaredLogger, teamServiceImpl, enforcerImpl, userServiceImpl, clusterServiceImpl, environmentServiceImpl) + appFilteringRouterImpl := appList2.NewAppFilteringRouterImpl(appFilteringRestHandlerImpl) + appRouterEAModeImpl := app3.NewAppRouterEAModeImpl(appInfoRouterImpl, appFilteringRouterImpl) rbacRoleServiceImpl := user.NewRbacRoleServiceImpl(sugaredLogger, rbacRoleDataRepositoryImpl) rbacRoleRestHandlerImpl := user2.NewRbacRoleHandlerImpl(sugaredLogger, validate, rbacRoleServiceImpl, userServiceImpl, enforcerImpl, enforcerUtilImpl) rbacRoleRouterImpl := user2.NewRbacRoleRouterImpl(sugaredLogger, validate, rbacRoleRestHandlerImpl) - muxRouter := NewMuxRouter(sugaredLogger, ssoLoginRouterImpl, teamRouterImpl, userAuthRouterImpl, userRouterImpl, clusterRouterImpl, dashboardRouterImpl, helmAppRouterImpl, environmentRouterImpl, k8sApplicationRouterImpl, chartRepositoryRouterImpl, appStoreDiscoverRouterImpl, appStoreValuesRouterImpl, appStoreDeploymentRouterImpl, chartProviderRouterImpl, dockerRegRouterImpl, dashboardTelemetryRouterImpl, commonDeploymentRouterImpl, externalLinkRouterImpl, moduleRouterImpl, serverRouterImpl, apiTokenRouterImpl, k8sCapacityRouterImpl, webhookHelmRouterImpl, userAttributesRouterImpl, telemetryRouterImpl, userTerminalAccessRouterImpl, attributesRouterImpl, appRouterImpl, rbacRoleRouterImpl) + muxRouter := NewMuxRouter(sugaredLogger, ssoLoginRouterImpl, teamRouterImpl, userAuthRouterImpl, userRouterImpl, clusterRouterImpl, dashboardRouterImpl, helmAppRouterImpl, environmentRouterImpl, k8sApplicationRouterImpl, chartRepositoryRouterImpl, appStoreDiscoverRouterImpl, appStoreValuesRouterImpl, appStoreDeploymentRouterImpl, chartProviderRouterImpl, dockerRegRouterImpl, dashboardTelemetryRouterImpl, commonDeploymentRouterImpl, externalLinkRouterImpl, moduleRouterImpl, serverRouterImpl, apiTokenRouterImpl, k8sCapacityRouterImpl, webhookHelmRouterImpl, userAttributesRouterImpl, telemetryRouterImpl, userTerminalAccessRouterImpl, attributesRouterImpl, appRouterEAModeImpl, rbacRoleRouterImpl) mainApp := NewApp(db, sessionManager, muxRouter, telemetryEventClientImpl, posthogClient, sugaredLogger) return mainApp, nil } diff --git a/internal/sql/repository/AppListingRepository.go b/internal/sql/repository/AppListingRepository.go index ecff1f94c2..1f981f8a62 100644 --- a/internal/sql/repository/AppListingRepository.go +++ b/internal/sql/repository/AppListingRepository.go @@ -81,9 +81,6 @@ type LastDeployed struct { LastDeployedImage string `sql:"last_deployed_image"` } -const NewDeployment string = "Deployment Initiated" -const Hibernating string = "HIBERNATING" - type AppListingRepositoryImpl struct { dbConnection *pg.DB Logger *zap.SugaredLogger @@ -111,6 +108,7 @@ func (impl AppListingRepositoryImpl) FetchJobs(appIds []int, statuses []string, jobContainers = impl.extractEnvironmentNameFromId(jobContainers) return jobContainers, nil } + func (impl AppListingRepositoryImpl) FetchOverviewCiPipelines(jobId int) ([]*bean.JobListingContainer, error) { var jobContainers []*bean.JobListingContainer jobsQuery := impl.appListingRepositoryQueryBuilder.OverviewCiPipelineQuery() diff --git a/internal/sql/repository/chartConfig/PipelineOverrideRepository.go b/internal/sql/repository/chartConfig/PipelineOverrideRepository.go index e617efafae..81548f1a07 100644 --- a/internal/sql/repository/chartConfig/PipelineOverrideRepository.go +++ b/internal/sql/repository/chartConfig/PipelineOverrideRepository.go @@ -19,12 +19,13 @@ package chartConfig import ( "github.com/devtron-labs/devtron/api/bean" - "github.com/devtron-labs/devtron/client/argocdServer/application" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "github.com/devtron-labs/devtron/internal/sql/models" "github.com/devtron-labs/devtron/internal/sql/repository" "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig" "github.com/devtron-labs/devtron/internal/util" "github.com/devtron-labs/devtron/pkg/sql" + deploymentStatus "github.com/devtron-labs/devtron/util" "github.com/go-pg/pg" "github.com/juju/errors" "time" @@ -231,7 +232,7 @@ func (impl PipelineOverrideRepositoryImpl) FetchHelmTypePipelineOverridesForStat Join("inner join cd_workflow cdwf on cdwf.pipeline_id = p.id"). Join("inner join cd_workflow_runner cdwfr on cdwfr.cd_workflow_id = cdwf.id"). Where("p.deployment_app_type = ?", util.PIPELINE_DEPLOYMENT_TYPE_HELM). - Where("cdwfr.status not in (?)", pg.In([]string{application.Degraded, application.HIBERNATING, application.Healthy, "Failed", "Aborted"})). + Where("cdwfr.status not in (?)", pg.In([]string{argoApplication.Degraded, argoApplication.HIBERNATING, argoApplication.Healthy, deploymentStatus.WorkflowFailed, deploymentStatus.WorkflowAborted})). Where("cdwfr.workflow_type = ?", bean.CD_WORKFLOW_TYPE_DEPLOY). Where("p.deleted = ?", false). Select() diff --git a/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go b/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go index ed6be1c69f..e0f3001b19 100644 --- a/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go +++ b/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go @@ -23,7 +23,7 @@ import ( "fmt" "github.com/devtron-labs/common-lib/utils/k8s/health" "github.com/devtron-labs/devtron/api/bean" - "github.com/devtron-labs/devtron/client/argocdServer/application" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "github.com/devtron-labs/devtron/client/gitSensor" "github.com/devtron-labs/devtron/internal/sql/repository" repository2 "github.com/devtron-labs/devtron/internal/sql/repository/imageTagging" @@ -109,7 +109,7 @@ const ( WorkflowTypePost = "POST" ) -var WfrTerminalStatusList = []string{WorkflowAborted, WorkflowFailed, WorkflowSucceeded, application.HIBERNATING, string(health.HealthStatusHealthy), string(health.HealthStatusDegraded)} +var WfrTerminalStatusList = []string{WorkflowAborted, WorkflowFailed, WorkflowSucceeded, argoApplication.HIBERNATING, string(health.HealthStatusHealthy), string(health.HealthStatusDegraded)} func (a WorkflowStatus) String() string { return [...]string{"WF_UNKNOWN", "REQUEST_ACCEPTED", "ENQUEUED", "QUE_ERROR", "WF_STARTED", "DROPPED_STALE", "DEQUE_ERROR", "TRIGGER_ERROR"}[a] diff --git a/internal/util/ArgoUtil/ApplicationService.go b/internal/util/ArgoUtil/ApplicationService.go deleted file mode 100644 index 0b818a5ccd..0000000000 --- a/internal/util/ArgoUtil/ApplicationService.go +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package ArgoUtil - -import ( - "context" - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" -) - -type ApplicationService interface { - GetAll(ctx context.Context) (*v1alpha1.ApplicationList, error) - CreateApplication(appRequest *v1alpha1.Application, ctx context.Context) (appResponse *v1alpha1.Application, err error) - Delete(appName string, ctx context.Context) error -} -type ApplicationServiceImpl struct { - *ArgoSession - location string -} - -func NewApplicationServiceImpl(session *ArgoSession) *ApplicationServiceImpl { - return &ApplicationServiceImpl{ - ArgoSession: session, - location: "/api/v1/applications", - } -} - -func (impl *ApplicationServiceImpl) GetAll(ctx context.Context) (*v1alpha1.ApplicationList, error) { - res := &v1alpha1.ApplicationList{} - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: res, Path: impl.location, Method: "GET"}) - if err != nil { - return nil, err - } - return res, nil -} - -func (impl *ApplicationServiceImpl) CreateApplication(appRequest *v1alpha1.Application, ctx context.Context) (appResponse *v1alpha1.Application, err error) { - res := &v1alpha1.Application{} - _, _, err = impl.DoRequest(&ClientRequest{ResponseBody: res, Path: impl.location, Method: "POST", RequestBody: appRequest}) - if err != nil { - return nil, err - } - return res, nil -} - -func (impl *ApplicationServiceImpl) Delete(appName string, ctx context.Context) error { - res := &v1alpha1.Application{} - _, _, err := impl.DoRequest(&ClientRequest{ - ResponseBody: res, - Method: "DELETE", - Path: impl.location + "/" + appName, - }) - return err -} diff --git a/internal/util/ArgoUtil/ArgoClient.go b/internal/util/ArgoUtil/ArgoClient.go deleted file mode 100644 index d6d3af4cc1..0000000000 --- a/internal/util/ArgoUtil/ArgoClient.go +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package ArgoUtil - -import ( - "bytes" - "encoding/json" - "fmt" - "github.com/caarlos0/env" - "go.uber.org/zap" - "io" - "io/ioutil" - "net/http" - "net/url" - "reflect" -) - -type ArgoConfig struct { - Url string `env:"ACD_URL" envDefault:""` - UserName string `env:"ACD_USER" ` - Password string `env:"ACD_PASSWORD" ` - Timeout int `env:"ACD_TIMEOUT" envDefault:"0"` // in seconds - InsecureSkipVerify bool `env:"ACD_SKIP_VERIFY" envDefault:"true"` //ignore ssl verification -} - -type ArgoSession struct { - httpClient *http.Client - logger *zap.SugaredLogger - baseUrl *url.URL -} -type StatusCode int - -func (code StatusCode) IsSuccess() bool { - return code >= 200 && code <= 299 -} - -type ClientRequest struct { - Method string - Path string - RequestBody interface{} - ResponseBody interface{} -} - -func GetArgoConfig() (*ArgoConfig, error) { - cfg := &ArgoConfig{} - err := env.Parse(cfg) - return cfg, err -} - -func (session *ArgoSession) DoRequest(clientRequest *ClientRequest) (resBody []byte, resCode *StatusCode, err error) { - if clientRequest.ResponseBody == nil { - return nil, nil, fmt.Errorf("response body cant be nil") - } - if reflect.ValueOf(clientRequest.ResponseBody).Kind() != reflect.Ptr { - return nil, nil, fmt.Errorf("responsebody non pointer") - } - rel, err := session.baseUrl.Parse(clientRequest.Path) - if err != nil { - return nil, nil, err - } - var body io.Reader - if clientRequest.RequestBody != nil { - if req, err := json.Marshal(clientRequest.RequestBody); err != nil { - return nil, nil, err - } else { - session.logger.Debugw("argo req with body", "body", string(req)) - body = bytes.NewBuffer(req) - } - - } - httpReq, err := http.NewRequest(clientRequest.Method, rel.String(), body) - if err != nil { - return nil, nil, err - } - httpRes, err := session.httpClient.Do(httpReq) - if err != nil { - return nil, nil, err - } - defer httpRes.Body.Close() - resBody, err = ioutil.ReadAll(httpRes.Body) - if err != nil { - session.logger.Errorw("error in argocd communication ", "err", err) - return nil, nil, err - } - status := StatusCode(httpRes.StatusCode) - if status.IsSuccess() { - err = json.Unmarshal(resBody, clientRequest.ResponseBody) - } else { - session.logger.Errorw("api err", "res", string(resBody)) - return resBody, &status, fmt.Errorf("res not success, code: %d ", status) - } - return resBody, &status, err -} - -func NewArgoSession(config *ArgoConfig, logger *zap.SugaredLogger) (session *ArgoSession, err error) { - /*location := "/api/v1/session" - baseUrl, err := url.Parse(config.RedirectionUrl) - if err != nil { - return nil, err - } - rel, err := baseUrl.Parse(location) - param := map[string]string{} - param["username"] = "admin" - param["password"] = "argocd-server-6cd5bcffd4-j6kcx" - paramJson, err := json.Marshal(param) - if err != nil { - return nil, err - } - req, _ := http.NewRequest("POST", rel.String(), bytes.NewBuffer(paramJson)) - transCfg := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}, - } - cookieJar, err := cookiejar.New(nil) - if err != nil { - return nil, err - } - client := &http.Client{Transport: transCfg, Jar: cookieJar, Timeout: time.Duration(config.Timeout)} - res, err := client.Do(req) - defer res.Body.Close() - if res.StatusCode != http.StatusOK { - return nil, err - }*/ - return &ArgoSession{}, nil -} diff --git a/internal/util/ArgoUtil/ClusterService.go b/internal/util/ArgoUtil/ClusterService.go deleted file mode 100644 index bd04b5eaf2..0000000000 --- a/internal/util/ArgoUtil/ClusterService.go +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package ArgoUtil - -import ( - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" -) - -type ClusterService interface { - GetClusterByServer(server string) (*v1alpha1.Cluster, error) - ClusterList() (*v1alpha1.ClusterList, error) - CreateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) - UpdateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) - DeleteCluster(server string) (string, error) -} - -type ClusterServiceImpl struct { - *ArgoSession - id int - location string -} - -func NewClusterServiceImpl(session *ArgoSession) *ClusterServiceImpl { - return &ClusterServiceImpl{ - ArgoSession: session, - location: "/api/v1/clusters", - } -} - -func (impl *ClusterServiceImpl) GetClusterByServer(server string) (*v1alpha1.Cluster, error) { - - path := impl.location + "/" + server - res := &v1alpha1.Cluster{} - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: res, Path: path, Method: "GET"}) - if err != nil { - return nil, err - } - return res, nil -} - -func (impl *ClusterServiceImpl) ClusterList() (*v1alpha1.ClusterList, error) { - - path := impl.location - res := &v1alpha1.ClusterList{} - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: res, Path: path, Method: "GET"}) - if err != nil { - return nil, err - } - return res, nil -} - -func (impl *ClusterServiceImpl) CreateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) { - - path := impl.location - res := &v1alpha1.Cluster{} - - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: res, Path: path, RequestBody: cluster, Method: "POST"}) - if err != nil { - return nil, err - } - return res, nil -} - -func (impl *ClusterServiceImpl) UpdateCluster(cluster v1alpha1.Cluster) (*v1alpha1.Cluster, error) { - - path := impl.location + "/" + cluster.Server - res := &v1alpha1.Cluster{} - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: res, Path: path, RequestBody: cluster, Method: "PUT"}) - if err != nil { - return nil, err - } - return res, nil -} - -func (impl *ClusterServiceImpl) DeleteCluster(server string) (string, error) { - res := "" - path := impl.location + "/" + server - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: &res, Path: path, Method: "DELETE"}) - if err != nil { - return "", err - } - return res, nil -} - -type CubeConfigCreate struct { - Context string `json:"context"` - InCluster bool `json:"inCluster"` - Kubeconfig string `json:"kubeconfig"` - Upsert bool `json:"upsert"` -} diff --git a/internal/util/ArgoUtil/ClusterService_test.go b/internal/util/ArgoUtil/ClusterService_test.go deleted file mode 100644 index fcefb1cc71..0000000000 --- a/internal/util/ArgoUtil/ClusterService_test.go +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package ArgoUtil - -import "testing" - -var clusterServiceImpl *ClusterServiceImpl - -func init() { - session, _ := GetTestClient() - clusterServiceImpl = NewClusterServiceImpl(session) -} -func TestClusterServiceImpl_DeleteCluster(t *testing.T) { - type args struct { - server string - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "abc", - args: args{server: "88888888devtron9.smartflow.k8s.local"}, - wantErr: false, - }, - // TODO: Add test cases. - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - impl := clusterServiceImpl - if _, err := impl.DeleteCluster(tt.args.server); (err != nil) != tt.wantErr { - t.Errorf("ClusterServiceImpl.DeleteCluster() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} diff --git a/internal/util/ArgoUtil/RepositoryService.go b/internal/util/ArgoUtil/RepositoryService.go deleted file mode 100644 index 8de7f23c99..0000000000 --- a/internal/util/ArgoUtil/RepositoryService.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package ArgoUtil - -import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - -type RepositoryService interface { - Create(repositoryRequest *v1alpha1.Repository) (repository *v1alpha1.Repository, err error) -} - -type RepositoryServiceImpl struct { - *ArgoSession - location string -} - -func NewRepositoryService(session *ArgoSession) *RepositoryServiceImpl { - return &RepositoryServiceImpl{ - ArgoSession: session, - location: "/api/v1/repositories", - } -} - -func (impl RepositoryServiceImpl) Create(repositoryRequest *v1alpha1.Repository) (repository *v1alpha1.Repository, err error) { - res := &v1alpha1.Repository{} - _, _, err = impl.DoRequest(&ClientRequest{ResponseBody: res, Path: impl.location, Method: "POST", RequestBody: repositoryRequest}) - if err != nil { - return nil, err - } - return res, nil -} diff --git a/internal/util/ArgoUtil/ResourceService.go b/internal/util/ArgoUtil/ResourceService.go deleted file mode 100644 index a8d7782fec..0000000000 --- a/internal/util/ArgoUtil/ResourceService.go +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package ArgoUtil - -import ( - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" -) - -type ResourceService interface { - FetchResourceTree(appName string) (*Items, error) - FetchPodContainerLogs(appName string, podName string, req PodContainerLogReq) (*Items, error) -} -type ResourceServiceImpl struct { - *ArgoSession - id int - location string -} - -func NewResourceServiceImpl(session *ArgoSession) *ResourceServiceImpl { - return &ResourceServiceImpl{ - ArgoSession: session, - location: "/api/v1/applications", - } -} - -func (impl *ResourceServiceImpl) FetchResourceTree(appName string) (*Items, error) { - - path := impl.location + "/" + appName + "/resource-tree" - res := &Items{} - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: res, Path: path, Method: "GET"}) - if err != nil { - return nil, err - } - //writeJsonResp(w, err, resJson, http.StatusOK) - return res, nil -} - -func (impl *ResourceServiceImpl) FetchPodContainerLogs(appName string, podName string, req PodContainerLogReq) (*Items, error) { - - path := impl.location + "/" + appName + "/pods/" + podName + "/logs" - req2 := &PodContainerLogReq{ - Namespace: "dont-use", - Container: "application", - Follow: true, - } - _, _, err := impl.DoRequest(&ClientRequest{ResponseBody: nil, Path: path, RequestBody: req2, Method: "GET"}) - if err != nil { - return nil, err - } - //writeJsonResp(w, err, resJson, http.StatusOK) - return nil, nil -} - -type Items struct { - Items []Resource `json:"items"` -} - -type Resource struct { - v1alpha1.ResourceNode `json:",inline" protobuf:"bytes,1,opt,name=resourceNode"` - //Children []v1alpha1.ResourceRef `json:"children,omitempty" protobuf:"bytes,3,opt,name=children"` -} - -type PodContainerLogReq struct { - Namespace string `json:"namespace,omitempty"` - Container string `json:"container,omitempty"` - SinceSeconds string `json:"sinceSeconds,omitempty"` - TailLines string `json:"tailLines,omitempty"` - Follow bool `json:"follow,omitempty"` -} diff --git a/internal/util/ArgoUtil/TestUtil.go b/internal/util/ArgoUtil/TestUtil.go deleted file mode 100644 index 6096348a91..0000000000 --- a/internal/util/ArgoUtil/TestUtil.go +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package ArgoUtil - -func GetTestClient() (session *ArgoSession, err error) { - config, err := GetArgoConfig() - if err != nil { - return nil, err - } - session, err = NewArgoSession(config, nil) - return session, err -} diff --git a/pkg/app/AppListingService.go b/pkg/app/AppListingService.go index f93bd4408a..cb391c1da8 100644 --- a/pkg/app/AppListingService.go +++ b/pkg/app/AppListingService.go @@ -19,8 +19,8 @@ package app import ( "context" - "encoding/json" "fmt" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "net/http" "strconv" "strings" @@ -38,20 +38,15 @@ import ( "go.opentelemetry.io/otel" "golang.org/x/exp/slices" - "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" "github.com/devtron-labs/devtron/api/bean" application2 "github.com/devtron-labs/devtron/client/argocdServer/application" - "github.com/devtron-labs/devtron/internal/constants" "github.com/devtron-labs/devtron/internal/sql/models" "github.com/devtron-labs/devtron/internal/sql/repository" "github.com/devtron-labs/devtron/internal/sql/repository/chartConfig" "github.com/devtron-labs/devtron/internal/sql/repository/helper" "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig" "github.com/devtron-labs/devtron/internal/util" - "github.com/devtron-labs/devtron/pkg/prometheus" "github.com/go-pg/pg" - "github.com/pkg/errors" - v1 "github.com/prometheus/client_golang/api/prometheus/v1" "go.uber.org/zap" ) @@ -64,25 +59,7 @@ type AppListingService interface { FetchAllDevtronManagedApps() ([]AppNameTypeIdContainer, error) FetchAppDetails(ctx context.Context, appId int, envId int) (bean.AppDetailContainer, error) - PodCountByAppLabel(appLabel string, namespace string, env string, proEndpoint string) int - PodListByAppLabel(appLabel string, namespace string, env string, proEndpoint string) map[string]string - - // below 4 functions used for pod level cpu and memory usage - CpuUsageGroupByPod(namespace string, env string, proEndpoint string) map[string]string - CpuRequestGroupByPod(namespace string, env string, proEndpoint string) map[string]string - MemoryUsageGroupByPod(namespace string, env string, proEndpoint string) map[string]string - MemoryRequestGroupByPod(namespace string, env string, proEndpoint string) map[string]string - - //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) - 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 + //------------------ FetchAppTriggerView(appId int) ([]bean.TriggerView, error) FetchAppStageStatus(appId int, appType int) ([]bean.AppStageStatus, error) @@ -99,10 +76,8 @@ type AppListingService interface { } const ( - Initiate string = "Initiate" - ScalingReplicaSetDown string = "ScalingReplicaSetDown" - APIVersionV1 string = "v1" - APIVersionV2 string = "v2" + APIVersionV1 string = "v1" + APIVersionV2 string = "v2" ) type FetchAppListingRequest struct { @@ -129,6 +104,7 @@ type AppNameTypeIdContainer struct { func (req FetchAppListingRequest) GetNamespaceClusterMapping() (namespaceClusterPair []*repository2.ClusterNamespacePair, clusterIds []int, err error) { for _, ns := range req.Namespaces { items := strings.Split(ns, "_") + // TODO refactoring: invalid condition; always false if len(items) < 1 && len(items) > 2 { return nil, nil, fmt.Errorf("invalid namespaceds") } @@ -765,7 +741,7 @@ func (impl AppListingServiceImpl) fetchACDAppStatus(fetchAppListingRequest Fetch if status == string(health.HealthStatusHealthy) { stopType := releaseMap[pipeline.Id] if stopType { - status = application2.HIBERNATING + status = argoApplication.HIBERNATING env.Status = status } } @@ -813,55 +789,6 @@ func (impl AppListingServiceImpl) fetchACDAppStatusV2(fetchAppListingRequest Fet return appEnvMapping, nil } -func (impl AppListingServiceImpl) getAppACDStatus(env bean.AppEnvironmentContainer, w http.ResponseWriter, r *http.Request, token string) (string, error) { - //not being used now - if len(env.AppName) > 0 && len(env.EnvironmentName) > 0 { - acdAppName := env.AppName + "-" + env.EnvironmentName - query := &application.ResourcesQuery{ - ApplicationName: &acdAppName, - } - ctx, cancel := context.WithCancel(r.Context()) - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - defer cancel() - acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken() - if err != nil { - impl.Logger.Errorw("error in getting acd token", "err", err) - return "", err - } - ctx = context.WithValue(ctx, "token", acdToken) - impl.Logger.Debugf("Getting status for app %s in env %s", env.AppId, env.EnvironmentId) - start := time.Now() - resp, err := impl.application.ResourceTree(ctx, query) - elapsed := time.Since(start) - impl.Logger.Debugf("Time elapsed %s in fetching application %s for environment %s", elapsed, env.AppId, env.EnvironmentId) - if err != nil { - impl.Logger.Errorw("error fetching resource tree", "error", err) - err = &util.ApiError{ - Code: constants.AppDetailResourceTreeNotFound, - InternalMessage: "app detail fetched, failed to get resource tree from acd", - UserMessage: "app detail fetched, failed to get resource tree from acd", - } - return "", err - } - return resp.Status, nil - } - impl.Logger.Error("invalid acd app name and env ", env.AppName, " - ", env.EnvironmentName) - return "", errors.New(AcdInvalidAppErr) -} - -// TODO: Status mapping -func (impl AppListingServiceImpl) adaptStatusForView(status string) string { - return status -} - func (impl AppListingServiceImpl) FetchAppDetails(ctx context.Context, appId int, envId int) (bean.AppDetailContainer, error) { appDetailContainer, err := impl.appListingRepository.FetchAppDetail(ctx, appId, envId) if err != nil { @@ -962,745 +889,6 @@ func (impl AppListingServiceImpl) setIpAccessProvidedData(ctx context.Context, a return appDetailContainer, nil } -// Return only a integer value pod count, aggregated of all the pod inside a app -// (includes all the pods running different cd pipeline for same app) -func (impl AppListingServiceImpl) PodCountByAppLabel(appLabel string, namespace string, env string, proEndpoint string) int { - if appLabel == "" || namespace == "" || proEndpoint == "" || env == "" { - impl.Logger.Warnw("not a complete data found for prometheus call", "missing", "AppName or namespace or prometheus url or env") - return 0 - } - - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return 0 - } - - podCountQuery := "count(kube_pod_labels{label_app='" + appLabel + "', namespace='" + namespace + "'})" - out, _, err := prometheusAPI.Query(context.Background(), podCountQuery, time.Now()) - if err != nil { - impl.Logger.Errorw("pod count query failed in prometheus:", "error", err) - return 0 - } - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("pod count data marshal failed:", "error", err) - return 0 - } - - podCount := 0 - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("pod count data unmarshal failed: ", "error", err) - return 0 - } - for _, value := range resultMap { - data := value.([]interface{}) - - for _, item := range data { - - ito := item - for k, v := range ito.(map[string]interface{}) { - if k == "value" { - vArr := v.([]interface{}) - //t := (vArr[1].(string)) - feetInt, err := strconv.Atoi(vArr[1].(string)) - if err != nil { - feetInt = 0 - impl.Logger.Errorw("casting error", "err", err) - } - podCount = feetInt - } - } - } - } - return podCount -} - -// Returns map of running pod names -func (impl AppListingServiceImpl) PodListByAppLabel(appLabel string, namespace string, env string, proEndpoint string) map[string]string { - response := make(map[string]interface{}) - podList := make(map[string]string) - resultMap := make(map[string]interface{}) - if appLabel == "" || namespace == "" || proEndpoint == "" || env == "" { - impl.Logger.Warnw("not a complete data found for prometheus call", "missing", "AppName or namespace or prometheus url or env") - return podList - } - - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return podList - } - - podCountQuery := "kube_pod_labels{label_app='" + appLabel + "', namespace='" + namespace + "'}" - out, _, err := prometheusAPI.Query(context.Background(), podCountQuery, time.Now()) - if err != nil { - impl.Logger.Errorw("pod list query failed in prometheus:", "error", err) - return podList - } - - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("pod count data unmarshal failed:", "error", err) - return podList - } - - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("pod count data unmarshal failed:", "error", err) - return podList - } - for _, value := range resultMap { - if value != nil { - data := value.([]interface{}) - - for _, item := range data { - - ito := item - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod"].(string) - podList[key] = "1" - } - if k == "value" { - } - } - } - } - } - return podList -} - -func (impl AppListingServiceImpl) CpuUsageGroupByPod(namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing cpuUsageGroupByPod:") - cpuUsageMetric := make(map[string]string) - - if namespace == "" || proEndpoint == "" || env == "" { - impl.Logger.Warnw("not a complete data found for prometheus call", "missing", "AppName or namespace or prometheus url or env") - return cpuUsageMetric - } - - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return cpuUsageMetric - } - - query := "sum(rate (container_cpu_usage_seconds_total{image!='',pod_name!='',container_name!='POD',namespace='" + namespace + "'}[1m])) by (pod_name)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in getting CpuUsageGroupByPod:", "error", err) - return cpuUsageMetric - } - - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal CpuUsageGroupByPod:", "error", err) - return cpuUsageMetric - } - - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal CpuUsageGroupByPod:", "error", err) - return cpuUsageMetric - } - - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod_name"].(string) - cpuUsageMetric[key] = "1.0" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := cpuUsageMetric[temp]; ok { - cpuUsageMetric[temp] = vArr[1].(string) - } - } - } - } - } - return cpuUsageMetric -} - -func (impl AppListingServiceImpl) CpuRequestGroupByPod(namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing cpuUsageGroupByPod:") - cpuRequestMetric := make(map[string]string) - - if namespace == "" || proEndpoint == "" || env == "" { - impl.Logger.Warnw("not a complete data found for prometheus call", "missing", "AppName or namespace or prometheus url or env") - return cpuRequestMetric - } - - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return cpuRequestMetric - } - - query := "sum(kube_pod_container_resource_requests_cpu_cores{namespace='" + namespace + "'}) by (pod)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return cpuRequestMetric - } - - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return cpuRequestMetric - } - - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return cpuRequestMetric - } - for _, value := range resultMap { - data := value.([]interface{}) - - for _, item := range data { - - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod"].(string) - cpuRequestMetric[key] = "1" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := cpuRequestMetric[temp]; ok { - cpuRequestMetric[temp] = vArr[1].(string) - } - } - } - } - } - return cpuRequestMetric -} - -func (impl AppListingServiceImpl) MemoryUsageGroupByPod(namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing memoryUsageGroupByPod") - memoryUsageMetric := make(map[string]string) - - if namespace == "" || proEndpoint == "" || env == "" { - impl.Logger.Warnw("not a complete data found for prometheus call", "missing", "AppName or namespace or prometheus url or env") - return memoryUsageMetric - } - - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return memoryUsageMetric - } - - query := "sum(container_memory_usage_bytes{container_name!='POD', container_name!='', namespace='" + namespace + "'}) by (pod_name)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return memoryUsageMetric - } - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return memoryUsageMetric - } - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return memoryUsageMetric - } - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod_name"].(string) - memoryUsageMetric[key] = "1" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := memoryUsageMetric[temp]; ok { - memoryUsageMetric[temp] = vArr[1].(string) - } - } - } - } - } - return memoryUsageMetric -} - -func (impl AppListingServiceImpl) MemoryRequestGroupByPod(namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing memoryRequestGroupByPod") - memoryRequestMetric := make(map[string]string) - if namespace == "" || proEndpoint == "" || env == "" { - impl.Logger.Warnw("not a complete data found for prometheus call", "missing", "AppName or namespace or prometheus url or env") - return memoryRequestMetric - } - - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return memoryRequestMetric - } - - query := "sum(kube_pod_container_resource_requests_memory_bytes{container!='POD', container!='', namespace='" + namespace + "'}) by (pod)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return memoryRequestMetric - } - - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return memoryRequestMetric - } - - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return memoryRequestMetric - } - - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod"].(string) - memoryRequestMetric[key] = "1" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := memoryRequestMetric[temp]; ok { - memoryRequestMetric[temp] = vArr[1].(string) - } - } - } - } - } - return memoryRequestMetric -} - -// Deprecated: Currently not in use -func (impl AppListingServiceImpl) CpuUsageGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing cpuUsageGroupByPod:") - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - cpuUsageMetric := make(map[string]string) - - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return cpuUsageMetric - } - - query := "sum(rate(container_cpu_usage_seconds_total{image!='', pod_name='" + podName + "',container_name!='POD', namespace='" + podName + "'}[1m])) by (container_name)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return cpuUsageMetric - } - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return cpuUsageMetric - } - - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return cpuUsageMetric - } - - for _, value := range resultMap { - data := value.([]interface{}) - - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod_name"].(string) - cpuUsageMetric[key] = "1" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := cpuUsageMetric[temp]; ok { - cpuUsageMetric[temp] = vArr[1].(string) - } - } - } - } - } - - return cpuUsageMetric -} - -// Deprecated: Currently not in use -func (impl AppListingServiceImpl) CpuRequestGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing cpuUsageGroupByPod:") - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - cpuRequestMetric := make(map[string]string) - - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return cpuRequestMetric - } - - query := "sum(kube_pod_container_resource_requests_cpu_cores{namespace='" + namespace + "',pod='" + podName + "'}) by (container)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return cpuRequestMetric - } - - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return cpuRequestMetric - } - - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return cpuRequestMetric - } - - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod"].(string) - cpuRequestMetric[key] = "1" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := cpuRequestMetric[temp]; ok { - cpuRequestMetric[temp] = vArr[1].(string) - } - } - } - } - } - return cpuRequestMetric -} - -// Deprecated: Currently not in use -func (impl AppListingServiceImpl) MemoryUsageGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing memoryUsageGroupByPod") - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - memoryUsageMetric := make(map[string]string) - - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return memoryUsageMetric - } - - query := "sum(container_memory_usage_bytes{container_name!='POD', container_name!='',pod_name='" + podName + "', namespace='" + namespace + "'}) by (container_name)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return memoryUsageMetric - } - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return memoryUsageMetric - } - - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return memoryUsageMetric - } - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod_name"].(string) - memoryUsageMetric[key] = "1" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := memoryUsageMetric[temp]; ok { - memoryUsageMetric[temp] = vArr[1].(string) - } - } - } - } - } - return memoryUsageMetric -} - -// Deprecated: Currently not in use -func (impl AppListingServiceImpl) MemoryRequestGroupByContainer(podName string, namespace string, env string, proEndpoint string) map[string]string { - impl.Logger.Debug("executing memoryRequestGroupByPod") - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - memoryRequestMetric := make(map[string]string) - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return memoryRequestMetric - } - - query := "sum(kube_pod_container_resource_requests_memory_bytes{container!='POD', container!='',pod='" + podName + "', namespace='" + namespace + "'}) by (container)" - out, _, err := prometheusAPI.Query(context.Background(), query, time.Now()) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return memoryRequestMetric - } - - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return memoryRequestMetric - } - - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return memoryRequestMetric - } - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod"].(string) - memoryRequestMetric[key] = "1" - temp = key - } - if k == "value" { - vArr := v.([]interface{}) - if _, ok := memoryRequestMetric[temp]; ok { - memoryRequestMetric[temp] = vArr[1].(string) - } - } - } - } - } - return memoryRequestMetric -} - -// Deprecated: Currently not in use (intent to fetch graph data from prometheus) -func (impl AppListingServiceImpl) CpuUsageGroupByPodGraph(podName string, namespace string, env string, proEndpoint string, r v1.Range) map[string][]interface{} { - impl.Logger.Debug("executing CpuUsageGroupByPodGraph:") - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - cpuUsageMetric := make(map[string][]interface{}) - - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return cpuUsageMetric - } - - query := "sum(rate(container_cpu_usage_seconds_total{namespace='" + namespace + "', container_name!='POD'}[1m])) by (pod_name)" - time1 := time.Now() - r1 := v1.Range{ - Start: time1.Add(-time.Hour), - End: time1, - Step: time.Minute, - } - out, _, err := prometheusAPI.QueryRange(context.Background(), query, r1) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return cpuUsageMetric - } - - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return cpuUsageMetric - } - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return cpuUsageMetric - } - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod_name"].(string) - cpuUsageMetric[key] = nil - temp = key - } - if k == "values" { - vArr := v.([]interface{}) - if _, ok := cpuUsageMetric[temp]; ok { - cpuUsageMetric[temp] = vArr - } - } - } - } - } - return cpuUsageMetric -} - -// Deprecated: Currently not in use (intent to fetch graph data from prometheus) -func (impl AppListingServiceImpl) MemoryUsageGroupByPodGraph(podName string, namespace string, env string, proEndpoint string, r v1.Range) map[string][]interface{} { - impl.Logger.Debug("executing MemoryUsageGroupByPodGraph") - prometheusAPI, err := prometheus.ContextByEnv(env, proEndpoint) - memoryUsageMetric := make(map[string][]interface{}) - - if err != nil { - impl.Logger.Errorw("error in getting prometheus api client:", "error", err) - return memoryUsageMetric - } - - query := "sum(container_memory_usage_bytes{namespace='" + namespace + "', container_name!='POD', container_name!=''}) by (pod_name)" - time1 := time.Now() - r1 := v1.Range{ - Start: time1.Add(-time.Hour), - End: time1, - Step: time.Minute, - } - out, _, err := prometheusAPI.QueryRange(context.Background(), query, r1) - if err != nil { - impl.Logger.Errorw("error in prometheus query:", "error", err) - return memoryUsageMetric - } - response := make(map[string]interface{}) - response["data"] = out - resJson, err := json.Marshal(response) - if err != nil { - impl.Logger.Errorw("error in marshal:", "error", err) - return memoryUsageMetric - } - resultMap := make(map[string]interface{}) - err = json.Unmarshal([]byte(resJson), &resultMap) - if err != nil { - impl.Logger.Errorw("error in unmarshal:", "error", err) - return memoryUsageMetric - } - for _, value := range resultMap { - data := value.([]interface{}) - for _, item := range data { - ito := item - temp := "" - for k, v := range ito.(map[string]interface{}) { - if k == "metric" { - vMap := v.(map[string]interface{}) - key := vMap["pod_name"].(string) - memoryUsageMetric[key] = nil - temp = key - } - if k == "values" { - vArr := v.([]interface{}) - if _, ok := memoryUsageMetric[temp]; ok { - memoryUsageMetric[temp] = vArr - } - } - } - } - } - return memoryUsageMetric -} - -// Deprecated: Currently not in use (intent to fetch graph data from prometheus) -func (impl AppListingServiceImpl) GraphAPI(appId int, envId int) error { - impl.Logger.Debug("reached at GraphAPI:") - /* - appDetailView, err := impl.appListingRepository.FetchAppDetail(appId, envId) - if err != nil { - impl.Logger.Errorw("Exception", err) - return err - } - - //calculating cpu and memory usage percent - appLabel := appDetailView.AppName - namespace := appDetailView.Namespace - proEndpoint := appDetailView.PrometheusEndpoint - env := appDetailView.EnvironmentName - podList := impl.PodListByAppLabel(appLabel, namespace, env, proEndpoint) - - //TODO - Pod List By Label- Release - - time1 := time.Time{} - r1 := v1.Range{ - Start: time1.Add(-time.Minute), - End: time1, - Step: time.Minute, - } - podName := "prometheus-monitoring-prometheus-oper-prometheus-0" - impl.CpuUsageGroupByPodGraph(podName, namespace, env, proEndpoint, r1) - //data := impl.MemoryUsageGroupByPodGraph(podName, "monitoring", env, proEndpoint, r1) - - for fKey, _ := range podList { - fmt.Println(fKey) - } - */ - return nil -} - func (impl AppListingServiceImpl) FetchAppTriggerView(appId int) ([]bean.TriggerView, error) { return impl.appListingRepository.FetchAppTriggerView(appId) } diff --git a/pkg/app/AppService.go b/pkg/app/AppService.go index 05c7ddf332..dd72cde9fb 100644 --- a/pkg/app/AppService.go +++ b/pkg/app/AppService.go @@ -21,6 +21,7 @@ import ( "context" "encoding/json" "fmt" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "io/ioutil" "net/url" "os" @@ -650,7 +651,7 @@ func (impl *AppServiceImpl) UpdateDeploymentStatusForPipeline(app *v1alpha1.Appl impl.logger.Errorw("error on update cd workflow runner", "CdWorkflowId", pipelineOverride.CdWorkflowId, "app", app, "err", err) return isSucceeded, err } - if application.Healthy == app.Status.Health.Status { + if argoApplication.Healthy == app.Status.Health.Status { isSucceeded = true } return isSucceeded, nil @@ -664,7 +665,7 @@ func (impl *AppServiceImpl) UpdateDeploymentStatusForAppStore(app *v1alpha1.Appl impl.logger.Errorw("error on update installed version history", "installedVersionHistoryId", installedVersionHistoryId, "app", app, "err", err) return isSucceeded, err } - if application.Healthy == app.Status.Health.Status { + if argoApplication.Healthy == app.Status.Health.Status { isSucceeded = true } return isSucceeded, nil diff --git a/pkg/app/DeploymentEventHandler.go b/pkg/app/DeploymentEventHandler.go index adbaa688fd..c931a526b6 100644 --- a/pkg/app/DeploymentEventHandler.go +++ b/pkg/app/DeploymentEventHandler.go @@ -18,11 +18,11 @@ package app import ( + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "strings" "time" "github.com/devtron-labs/devtron/api/bean" - "github.com/devtron-labs/devtron/client/argocdServer/application" client "github.com/devtron-labs/devtron/client/events" "github.com/devtron-labs/devtron/internal/sql/repository" util "github.com/devtron-labs/devtron/util/event" @@ -71,5 +71,5 @@ func (impl *DeploymentEventHandlerImpl) BuildPayload(appName string, deploymentF } func (impl *DeploymentEventHandlerImpl) isDeploymentFailed(ds repository.DeploymentStatus) bool { - return ds.Status == application.Degraded && time.Since(ds.UpdatedOn) > 5*time.Minute + return ds.Status == argoApplication.Degraded && time.Since(ds.UpdatedOn) > 5*time.Minute } diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index e10ab30e90..356e4f9d8a 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -20,6 +20,8 @@ package service import ( "bytes" "context" + bean3 "github.com/devtron-labs/devtron/client/argocdServer/bean" + /* #nosec */ "crypto/sha1" "encoding/json" @@ -944,7 +946,7 @@ func (impl InstalledAppServiceImpl) UpdateInstalledAppVersionStatus(application impl.logger.Errorw("error while fetching installed version history", "error", err) return isHealthy, err } - if versionHistory.Status != (application2.Healthy) { + if versionHistory.Status != (bean3.Healthy) { versionHistory.Status = string(application.Status.Health.Status) versionHistory.UpdatedOn = time.Now() versionHistory.UpdatedBy = 1 diff --git a/pkg/bulkAction/BulkUpdateService.go b/pkg/bulkAction/BulkUpdateService.go index d696620d5a..e49aca835b 100644 --- a/pkg/bulkAction/BulkUpdateService.go +++ b/pkg/bulkAction/BulkUpdateService.go @@ -11,7 +11,7 @@ import ( "github.com/devtron-labs/devtron/api/bean" client "github.com/devtron-labs/devtron/api/helm-app" openapi "github.com/devtron-labs/devtron/api/helm-app/openapiClient" - "github.com/devtron-labs/devtron/client/argocdServer/application" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "github.com/devtron-labs/devtron/client/argocdServer/repository" "github.com/devtron-labs/devtron/internal/sql/models" repository3 "github.com/devtron-labs/devtron/internal/sql/repository" @@ -1054,7 +1054,7 @@ func (impl BulkUpdateServiceImpl) BulkHibernate(request *BulkApplicationForEnvir impl.logger.Infow("application already hibernated", "app_id", pipeline.AppId) pipelineResponse := response[appKey] pipelineResponse[pipelineKey] = false - if deploymentHistory.Status == application.HIBERNATING { + if deploymentHistory.Status == argoApplication.HIBERNATING { pipelineResponse[Skipped] = "Application is already hibernated" } else { pipelineResponse[Skipped] = "Hibernation already in progress" @@ -1213,7 +1213,7 @@ func (impl BulkUpdateServiceImpl) BulkUnHibernate(request *BulkApplicationForEnv impl.logger.Infow("application already UnHibernated", "app_id", pipeline.AppId) pipelineResponse := response[appKey] pipelineResponse[pipelineKey] = false - if deploymentHistory.Status == application.Healthy { + if deploymentHistory.Status == argoApplication.Healthy { pipelineResponse[Skipped] = "Application is already un-hibernated" } else { pipelineResponse[Skipped] = "Un-hibernation already in progress" diff --git a/pkg/pipeline/AppArtifactManager.go b/pkg/pipeline/AppArtifactManager.go index 7ec6f4d57d..994143bfe4 100644 --- a/pkg/pipeline/AppArtifactManager.go +++ b/pkg/pipeline/AppArtifactManager.go @@ -18,11 +18,11 @@ package pipeline import ( + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "sort" "strings" "github.com/devtron-labs/devtron/api/bean" - "github.com/devtron-labs/devtron/client/argocdServer/application" "github.com/devtron-labs/devtron/internal/sql/repository" dockerArtifactStoreRegistry "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry" "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig" @@ -135,7 +135,7 @@ func (impl *AppArtifactManagerImpl) BuildArtifactsForCdStage(pipelineId int, sta deploymentArtifactId = wfr.CdWorkflow.CiArtifact.Id deploymentArtifactStatus = wfr.Status } - if wfr.Status == application.Healthy || wfr.Status == application.SUCCEEDED { + if wfr.Status == argoApplication.Healthy || wfr.Status == argoApplication.SUCCEEDED { lastSuccessfulTriggerOnParent := parent && index == 0 latest := !parent && index == 0 runningOnParentCd := parentCdRunningArtifactId == wfr.CdWorkflow.CiArtifact.Id @@ -360,7 +360,7 @@ func (impl *AppArtifactManagerImpl) BuildRollbackArtifactsList(artifactListingFi totalCount := 0 //1)get current deployed artifact on this pipeline - latestWf, err := impl.cdWorkflowRepository.FindArtifactByPipelineIdAndRunnerType(artifactListingFilterOpts.PipelineId, artifactListingFilterOpts.StageType, 1, []string{application.Healthy, application.SUCCEEDED, application.Progressing}) + latestWf, err := impl.cdWorkflowRepository.FindArtifactByPipelineIdAndRunnerType(artifactListingFilterOpts.PipelineId, artifactListingFilterOpts.StageType, 1, []string{argoApplication.Healthy, argoApplication.SUCCEEDED, argoApplication.Progressing}) if err != nil && err != pg.ErrNoRows { impl.logger.Errorw("error in getting latest workflow by pipelineId", "pipelineId", artifactListingFilterOpts.PipelineId, "currentStageType", artifactListingFilterOpts.StageType) return deployedCiArtifacts, nil, totalCount, err @@ -776,7 +776,7 @@ func (impl *AppArtifactManagerImpl) BuildArtifactsList(listingFilterOpts *bean.A var ciArtifacts []*bean2.CiArtifactBean totalCount := 0 //1)get current deployed artifact on this pipeline - latestWf, err := impl.cdWorkflowRepository.FindArtifactByPipelineIdAndRunnerType(listingFilterOpts.PipelineId, listingFilterOpts.StageType, 1, []string{application.Healthy, application.SUCCEEDED, application.Progressing}) + latestWf, err := impl.cdWorkflowRepository.FindArtifactByPipelineIdAndRunnerType(listingFilterOpts.PipelineId, listingFilterOpts.StageType, 1, []string{argoApplication.Healthy, argoApplication.SUCCEEDED, argoApplication.Progressing}) if err != nil && err != pg.ErrNoRows { impl.logger.Errorw("error in getting latest workflow by pipelineId", "pipelineId", listingFilterOpts.PipelineId, "currentStageType", listingFilterOpts.StageType) return ciArtifacts, 0, "", totalCount, err @@ -864,7 +864,7 @@ func (impl *AppArtifactManagerImpl) BuildArtifactsForCdStageV2(listingFilterOpts artifactRunningOnParentCd := 0 if listingFilterOpts.ParentCdId > 0 { //TODO: check if we can fetch LastSuccessfulTriggerOnParent wfr along with last running wf - parentCdWfrList, err := impl.cdWorkflowRepository.FindArtifactByPipelineIdAndRunnerType(listingFilterOpts.ParentCdId, bean.CD_WORKFLOW_TYPE_DEPLOY, 1, []string{application.Healthy, application.SUCCEEDED, application.Progressing}) + parentCdWfrList, err := impl.cdWorkflowRepository.FindArtifactByPipelineIdAndRunnerType(listingFilterOpts.ParentCdId, bean.CD_WORKFLOW_TYPE_DEPLOY, 1, []string{argoApplication.Healthy, argoApplication.SUCCEEDED, argoApplication.Progressing}) if err != nil { impl.logger.Errorw("error in getting artifact for parent cd", "parentCdPipelineId", listingFilterOpts.ParentCdId) return ciArtifacts, totalCount, err diff --git a/pkg/pipeline/WorkflowDagExecutor.go b/pkg/pipeline/WorkflowDagExecutor.go index 375121e825..f79c75ada9 100644 --- a/pkg/pipeline/WorkflowDagExecutor.go +++ b/pkg/pipeline/WorkflowDagExecutor.go @@ -22,6 +22,7 @@ import ( "encoding/json" errors3 "errors" "fmt" + argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean" "path" "strconv" "strings" @@ -37,7 +38,6 @@ import ( "github.com/devtron-labs/common-lib/utils/k8s/health" client2 "github.com/devtron-labs/devtron/api/helm-app" "github.com/devtron-labs/devtron/client/argocdServer" - "github.com/devtron-labs/devtron/client/argocdServer/application" application2 "github.com/devtron-labs/devtron/client/argocdServer/application" gitSensorClient "github.com/devtron-labs/devtron/client/gitSensor" "github.com/devtron-labs/devtron/internal/middleware" @@ -541,7 +541,7 @@ func (impl *WorkflowDagExecutorImpl) UpdateWorkflowRunnerStatusForDeployment(app return false } - if helmInstalledDevtronApp.GetApplicationStatus() == application.Healthy { + if helmInstalledDevtronApp.GetApplicationStatus() == argoApplication.Healthy { // mark the deployment as succeed wfr.Status = pipelineConfig.WorkflowSucceeded wfr.FinishedOn = time.Now() diff --git a/pkg/prometheus/prometheus_client.go b/pkg/prometheus/prometheus_client.go deleted file mode 100644 index 341f816f37..0000000000 --- a/pkg/prometheus/prometheus_client.go +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020 Devtron Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package prometheus - -import ( - "fmt" - "github.com/prometheus/client_golang/api" - "github.com/prometheus/client_golang/api/prometheus/v1" -) - -var prometheusAPI v1.API -var prometheusAPIMap map[string]v1.API - -func Context(prometheusUrl string) (v1.API, error) { - - if prometheusAPI != nil { - return prometheusAPI, nil - } - - client, err := api.NewClient(api.Config{Address: prometheusUrl}) - if err != nil { - fmt.Println("Error creating client") - fmt.Println(err) - return nil, err - } - prometheusAPI = v1.NewAPI(client) - - return prometheusAPI, nil -} - -func ContextByEnv(env string, prometheusUrl string) (v1.API, error) { - if prometheusAPIMap == nil { - prometheusAPIMap = make(map[string]v1.API) - } - if _, ok := prometheusAPIMap[env]; ok { - prometheusAPI = prometheusAPIMap[env] - } else { - client, err := api.NewClient(api.Config{Address: prometheusUrl}) - if err != nil { - fmt.Println("Error creating client") - fmt.Println(err) - return nil, err - } - prometheusAPI = v1.NewAPI(client) - prometheusAPIMap[env] = prometheusAPI - } - return prometheusAPI, nil -} diff --git a/wire_gen.go b/wire_gen.go index 88874c0c5b..92e6560b19 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -8,7 +8,7 @@ package main import ( "github.com/devtron-labs/authenticator/apiToken" - client2 "github.com/devtron-labs/authenticator/client" + "github.com/devtron-labs/authenticator/client" "github.com/devtron-labs/authenticator/middleware" "github.com/devtron-labs/common-lib/cloud-provider-identifier" "github.com/devtron-labs/common-lib/pubsub-lib" @@ -28,14 +28,31 @@ import ( "github.com/devtron-labs/devtron/api/dashboardEvent" "github.com/devtron-labs/devtron/api/deployment" externalLink2 "github.com/devtron-labs/devtron/api/externalLink" - client3 "github.com/devtron-labs/devtron/api/helm-app" + client2 "github.com/devtron-labs/devtron/api/helm-app" application3 "github.com/devtron-labs/devtron/api/k8s/application" capacity2 "github.com/devtron-labs/devtron/api/k8s/capacity" module2 "github.com/devtron-labs/devtron/api/module" "github.com/devtron-labs/devtron/api/restHandler" - app3 "github.com/devtron-labs/devtron/api/restHandler/app" + "github.com/devtron-labs/devtron/api/restHandler/app/appInfo" + "github.com/devtron-labs/devtron/api/restHandler/app/appList" + pipeline2 "github.com/devtron-labs/devtron/api/restHandler/app/pipeline" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/configure" + history2 "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/history" + status2 "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/status" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/trigger" + "github.com/devtron-labs/devtron/api/restHandler/app/pipeline/webhook" + "github.com/devtron-labs/devtron/api/restHandler/app/workflow" "github.com/devtron-labs/devtron/api/restHandler/scopedVariable" "github.com/devtron-labs/devtron/api/router" + app3 "github.com/devtron-labs/devtron/api/router/app" + appInfo2 "github.com/devtron-labs/devtron/api/router/app/appInfo" + appList2 "github.com/devtron-labs/devtron/api/router/app/appList" + pipeline3 "github.com/devtron-labs/devtron/api/router/app/pipeline" + configure2 "github.com/devtron-labs/devtron/api/router/app/pipeline/configure" + history3 "github.com/devtron-labs/devtron/api/router/app/pipeline/history" + status3 "github.com/devtron-labs/devtron/api/router/app/pipeline/status" + trigger2 "github.com/devtron-labs/devtron/api/router/app/pipeline/trigger" + workflow2 "github.com/devtron-labs/devtron/api/router/app/workflow" "github.com/devtron-labs/devtron/api/router/pubsub" server2 "github.com/devtron-labs/devtron/api/server" "github.com/devtron-labs/devtron/api/sse" @@ -47,16 +64,16 @@ import ( "github.com/devtron-labs/devtron/client/argocdServer/application" "github.com/devtron-labs/devtron/client/argocdServer/cluster" "github.com/devtron-labs/devtron/client/argocdServer/connection" - repository9 "github.com/devtron-labs/devtron/client/argocdServer/repository" + repository10 "github.com/devtron-labs/devtron/client/argocdServer/repository" "github.com/devtron-labs/devtron/client/cron" "github.com/devtron-labs/devtron/client/dashboard" - "github.com/devtron-labs/devtron/client/events" + client3 "github.com/devtron-labs/devtron/client/events" "github.com/devtron-labs/devtron/client/gitSensor" "github.com/devtron-labs/devtron/client/grafana" "github.com/devtron-labs/devtron/client/lens" "github.com/devtron-labs/devtron/client/proxy" "github.com/devtron-labs/devtron/client/telemetry" - "github.com/devtron-labs/devtron/internal/sql/repository" + repository2 "github.com/devtron-labs/devtron/internal/sql/repository" "github.com/devtron-labs/devtron/internal/sql/repository/app" "github.com/devtron-labs/devtron/internal/sql/repository/appStatus" "github.com/devtron-labs/devtron/internal/sql/repository/appWorkflow" @@ -69,7 +86,6 @@ import ( "github.com/devtron-labs/devtron/internal/sql/repository/resourceGroup" "github.com/devtron-labs/devtron/internal/sql/repository/security" "github.com/devtron-labs/devtron/internal/util" - "github.com/devtron-labs/devtron/internal/util/ArgoUtil" "github.com/devtron-labs/devtron/pkg/apiToken" app2 "github.com/devtron-labs/devtron/pkg/app" "github.com/devtron-labs/devtron/pkg/app/status" @@ -101,18 +117,18 @@ import ( "github.com/devtron-labs/devtron/pkg/chartRepo" "github.com/devtron-labs/devtron/pkg/chartRepo/repository" cluster2 "github.com/devtron-labs/devtron/pkg/cluster" - repository2 "github.com/devtron-labs/devtron/pkg/cluster/repository" + "github.com/devtron-labs/devtron/pkg/cluster/repository" "github.com/devtron-labs/devtron/pkg/clusterTerminalAccess" "github.com/devtron-labs/devtron/pkg/commonService" delete2 "github.com/devtron-labs/devtron/pkg/delete" "github.com/devtron-labs/devtron/pkg/deploymentGroup" "github.com/devtron-labs/devtron/pkg/devtronResource" - repository8 "github.com/devtron-labs/devtron/pkg/devtronResource/repository" + repository9 "github.com/devtron-labs/devtron/pkg/devtronResource/repository" "github.com/devtron-labs/devtron/pkg/dockerRegistry" "github.com/devtron-labs/devtron/pkg/externalLink" "github.com/devtron-labs/devtron/pkg/generateManifest" "github.com/devtron-labs/devtron/pkg/genericNotes" - repository10 "github.com/devtron-labs/devtron/pkg/genericNotes/repository" + repository6 "github.com/devtron-labs/devtron/pkg/genericNotes/repository" "github.com/devtron-labs/devtron/pkg/git" "github.com/devtron-labs/devtron/pkg/gitops" k8s2 "github.com/devtron-labs/devtron/pkg/k8s" @@ -128,7 +144,7 @@ import ( "github.com/devtron-labs/devtron/pkg/pipeline" "github.com/devtron-labs/devtron/pkg/pipeline/executors" "github.com/devtron-labs/devtron/pkg/pipeline/history" - repository6 "github.com/devtron-labs/devtron/pkg/pipeline/history/repository" + repository7 "github.com/devtron-labs/devtron/pkg/pipeline/history/repository" repository12 "github.com/devtron-labs/devtron/pkg/pipeline/repository" "github.com/devtron-labs/devtron/pkg/pipeline/types" "github.com/devtron-labs/devtron/pkg/plugin" @@ -145,7 +161,7 @@ import ( util2 "github.com/devtron-labs/devtron/pkg/util" "github.com/devtron-labs/devtron/pkg/variables" "github.com/devtron-labs/devtron/pkg/variables/parsers" - repository7 "github.com/devtron-labs/devtron/pkg/variables/repository" + repository8 "github.com/devtron-labs/devtron/pkg/variables/repository" "github.com/devtron-labs/devtron/pkg/webhook/helm" util3 "github.com/devtron-labs/devtron/util" "github.com/devtron-labs/devtron/util/argo" @@ -173,38 +189,19 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - envConfigOverrideRepositoryImpl := chartConfig.NewEnvConfigOverrideRepository(db) - pipelineOverrideRepositoryImpl := chartConfig.NewPipelineOverrideRepository(db) - mergeUtil := &util.MergeUtil{ - Logger: sugaredLogger, - } - ciArtifactRepositoryImpl := repository.NewCiArtifactRepositoryImpl(db, sugaredLogger) - pipelineRepositoryImpl := pipelineConfig.NewPipelineRepositoryImpl(db, sugaredLogger) - httpClient := util.NewHttpClient() - eventClientConfig, err := client.GetEventClientConfig() - if err != nil { - return nil, err - } - pubSubClientServiceImpl := pubsub_lib.NewPubSubClientServiceImpl(sugaredLogger) - ciPipelineRepositoryImpl := pipelineConfig.NewCiPipelineRepositoryImpl(db, sugaredLogger) - attributesRepositoryImpl := repository.NewAttributesRepositoryImpl(db) - serverEnvConfigServerEnvConfig, err := serverEnvConfig.ParseServerEnvConfig() - if err != nil { - return nil, err - } - moduleRepositoryImpl := moduleRepo.NewModuleRepositoryImpl(db) - moduleActionAuditLogRepositoryImpl := module.NewModuleActionAuditLogRepositoryImpl(db) - clusterRepositoryImpl := repository2.NewClusterRepositoryImpl(db, sugaredLogger) appStatusRepositoryImpl := appStatus.NewAppStatusRepositoryImpl(db, sugaredLogger) - environmentRepositoryImpl := repository2.NewEnvironmentRepositoryImpl(db, sugaredLogger, appStatusRepositoryImpl) + environmentRepositoryImpl := repository.NewEnvironmentRepositoryImpl(db, sugaredLogger, appStatusRepositoryImpl) + clusterRepositoryImpl := repository.NewClusterRepositoryImpl(db, sugaredLogger) + httpClient := util.NewHttpClient() grafanaClientConfig, err := grafana.GetGrafanaClientConfig() if err != nil { return nil, err } + attributesRepositoryImpl := repository2.NewAttributesRepositoryImpl(db) attributesServiceImpl := attributes.NewAttributesServiceImpl(sugaredLogger, attributesRepositoryImpl) grafanaClientImpl := grafana.NewGrafanaClientImpl(sugaredLogger, httpClient, grafanaClientConfig, attributesServiceImpl) installedAppRepositoryImpl := repository3.NewInstalledAppRepositoryImpl(sugaredLogger, db) - runtimeConfig, err := client2.GetRuntimeConfig() + runtimeConfig, err := client.GetRuntimeConfig() if err != nil { return nil, err } @@ -217,6 +214,7 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } + moduleRepositoryImpl := moduleRepo.NewModuleRepositoryImpl(db) argoCDConnectionManagerImpl, err := connection.NewArgoCDConnectionManagerImpl(sugaredLogger, settingsManager, moduleRepositoryImpl) if err != nil { return nil, err @@ -224,33 +222,22 @@ func InitializeApp() (*App, error) { serviceClientImpl := cluster.NewServiceClientImpl(sugaredLogger, argoCDConnectionManagerImpl) v := informer.NewGlobalMapClusterNamespace() k8sInformerFactoryImpl := informer.NewK8sInformerFactoryImpl(sugaredLogger, v, runtimeConfig, k8sServiceImpl) - gitOpsConfigRepositoryImpl := repository.NewGitOpsConfigRepositoryImpl(sugaredLogger, db) + gitOpsConfigRepositoryImpl := repository2.NewGitOpsConfigRepositoryImpl(sugaredLogger, db) defaultAuthPolicyRepositoryImpl := repository4.NewDefaultAuthPolicyRepositoryImpl(db, sugaredLogger) defaultAuthRoleRepositoryImpl := repository4.NewDefaultAuthRoleRepositoryImpl(db, sugaredLogger) userAuthRepositoryImpl := repository4.NewUserAuthRepositoryImpl(db, sugaredLogger, defaultAuthPolicyRepositoryImpl, defaultAuthRoleRepositoryImpl) userRepositoryImpl := repository4.NewUserRepositoryImpl(db, sugaredLogger) roleGroupRepositoryImpl := repository4.NewRoleGroupRepositoryImpl(db, sugaredLogger) clusterServiceImplExtended := cluster2.NewClusterServiceImplExtended(clusterRepositoryImpl, environmentRepositoryImpl, grafanaClientImpl, sugaredLogger, installedAppRepositoryImpl, k8sServiceImpl, serviceClientImpl, k8sInformerFactoryImpl, gitOpsConfigRepositoryImpl, userAuthRepositoryImpl, userRepositoryImpl, roleGroupRepositoryImpl) - helmClientConfig, err := client3.GetConfig() + k8sClient, err := client.NewK8sClient(runtimeConfig) if err != nil { return nil, err } - helmAppClientImpl := client3.NewHelmAppClientImpl(sugaredLogger, helmClientConfig) - pumpImpl := connector.NewPumpImpl(sugaredLogger) - teamRepositoryImpl := team.NewTeamRepositoryImpl(db) - appRepositoryImpl := app.NewAppRepositoryImpl(db, sugaredLogger) - enforcerUtilHelmImpl := rbac.NewEnforcerUtilHelmImpl(sugaredLogger, clusterRepositoryImpl, teamRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, installedAppRepositoryImpl) - serverDataStoreServerDataStore := serverDataStore.InitServerDataStore() - appStoreApplicationVersionRepositoryImpl := appStoreDiscoverRepository.NewAppStoreApplicationVersionRepositoryImpl(sugaredLogger, db) - k8sClient, err := client2.NewK8sClient(runtimeConfig) + dexConfig, err := client.BuildDexConfig(k8sClient) if err != nil { return nil, err } - dexConfig, err := client2.BuildDexConfig(k8sClient) - if err != nil { - return nil, err - } - settings, err := client2.GetSettings(dexConfig) + settings, err := client.GetSettings(dexConfig) if err != nil { return nil, err } @@ -266,17 +253,88 @@ func InitializeApp() (*App, error) { userServiceImpl := user.NewUserServiceImpl(userAuthRepositoryImpl, sugaredLogger, userRepositoryImpl, roleGroupRepositoryImpl, sessionManager, userCommonServiceImpl, userAuditServiceImpl) userAuthServiceImpl := user.NewUserAuthServiceImpl(userAuthRepositoryImpl, sessionManager, loginService, sugaredLogger, userRepositoryImpl, roleGroupRepositoryImpl, userServiceImpl) environmentServiceImpl := cluster2.NewEnvironmentServiceImpl(environmentRepositoryImpl, clusterServiceImplExtended, sugaredLogger, k8sServiceImpl, k8sInformerFactoryImpl, userAuthServiceImpl, attributesRepositoryImpl) - helmReleaseConfig, err := client3.GetHelmReleaseConfig() + validate, err := util.IntValidator() if err != nil { return nil, err } - helmAppServiceImpl := client3.NewHelmAppServiceImpl(sugaredLogger, clusterServiceImplExtended, helmAppClientImpl, pumpImpl, enforcerUtilHelmImpl, serverDataStoreServerDataStore, serverEnvConfigServerEnvConfig, appStoreApplicationVersionRepositoryImpl, environmentServiceImpl, pipelineRepositoryImpl, installedAppRepositoryImpl, appRepositoryImpl, clusterRepositoryImpl, k8sServiceImpl, helmReleaseConfig) + syncedEnforcer := casbin.Create() + enforcerImpl := casbin.NewEnforcerImpl(syncedEnforcer, sessionManager, sugaredLogger) + teamRepositoryImpl := team.NewTeamRepositoryImpl(db) + teamServiceImpl := team.NewTeamServiceImpl(sugaredLogger, teamRepositoryImpl, userAuthServiceImpl) + appRepositoryImpl := app.NewAppRepositoryImpl(db, sugaredLogger) + pipelineRepositoryImpl := pipelineConfig.NewPipelineRepositoryImpl(db, sugaredLogger) + chartRepoRepositoryImpl := chartRepoRepository.NewChartRepoRepositoryImpl(db) + acdAuthConfig, err := util2.GetACDAuthConfig() + if err != nil { + return nil, err + } + serverEnvConfigServerEnvConfig, err := serverEnvConfig.ParseServerEnvConfig() + if err != nil { + return nil, err + } + chartRepositoryServiceImpl := chartRepo.NewChartRepositoryServiceImpl(sugaredLogger, chartRepoRepositoryImpl, k8sServiceImpl, clusterServiceImplExtended, acdAuthConfig, httpClient, serverEnvConfigServerEnvConfig) + helmClientConfig, err := client2.GetConfig() + if err != nil { + return nil, err + } + helmAppClientImpl := client2.NewHelmAppClientImpl(sugaredLogger, helmClientConfig) + pumpImpl := connector.NewPumpImpl(sugaredLogger) + enforcerUtilHelmImpl := rbac.NewEnforcerUtilHelmImpl(sugaredLogger, clusterRepositoryImpl, teamRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, installedAppRepositoryImpl) + serverDataStoreServerDataStore := serverDataStore.InitServerDataStore() + appStoreApplicationVersionRepositoryImpl := appStoreDiscoverRepository.NewAppStoreApplicationVersionRepositoryImpl(sugaredLogger, db) + helmReleaseConfig, err := client2.GetHelmReleaseConfig() + if err != nil { + return nil, err + } + helmAppServiceImpl := client2.NewHelmAppServiceImpl(sugaredLogger, clusterServiceImplExtended, helmAppClientImpl, pumpImpl, enforcerUtilHelmImpl, serverDataStoreServerDataStore, serverEnvConfigServerEnvConfig, appStoreApplicationVersionRepositoryImpl, environmentServiceImpl, pipelineRepositoryImpl, installedAppRepositoryImpl, appRepositoryImpl, clusterRepositoryImpl, k8sServiceImpl, helmReleaseConfig) + dockerArtifactStoreRepositoryImpl := repository5.NewDockerArtifactStoreRepositoryImpl(db) + dockerRegistryIpsConfigRepositoryImpl := repository5.NewDockerRegistryIpsConfigRepositoryImpl(db) + ociRegistryConfigRepositoryImpl := repository5.NewOCIRegistryConfigRepositoryImpl(db) + dockerRegistryConfigImpl := pipeline.NewDockerRegistryConfigImpl(sugaredLogger, helmAppServiceImpl, dockerArtifactStoreRepositoryImpl, dockerRegistryIpsConfigRepositoryImpl, ociRegistryConfigRepositoryImpl) + deleteServiceExtendedImpl := delete2.NewDeleteServiceExtendedImpl(sugaredLogger, teamServiceImpl, clusterServiceImplExtended, environmentServiceImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineRepositoryImpl, chartRepositoryServiceImpl, installedAppRepositoryImpl, dockerRegistryConfigImpl, dockerArtifactStoreRepositoryImpl) + k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sServiceImpl, clusterServiceImplExtended) + environmentRestHandlerImpl := cluster3.NewEnvironmentRestHandlerImpl(environmentServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceExtendedImpl, k8sServiceImpl, k8sCommonServiceImpl) + environmentRouterImpl := cluster3.NewEnvironmentRouterImpl(environmentRestHandlerImpl) + genericNoteRepositoryImpl := repository6.NewGenericNoteRepositoryImpl(db) + genericNoteHistoryRepositoryImpl := repository6.NewGenericNoteHistoryRepositoryImpl(db) + genericNoteHistoryServiceImpl := genericNotes.NewGenericNoteHistoryServiceImpl(genericNoteHistoryRepositoryImpl, sugaredLogger) + genericNoteServiceImpl := genericNotes.NewGenericNoteServiceImpl(genericNoteRepositoryImpl, genericNoteHistoryServiceImpl, userRepositoryImpl, sugaredLogger) + clusterDescriptionRepositoryImpl := repository.NewClusterDescriptionRepositoryImpl(db, sugaredLogger) + clusterDescriptionServiceImpl := cluster2.NewClusterDescriptionServiceImpl(clusterDescriptionRepositoryImpl, userRepositoryImpl, sugaredLogger) + devtronSecretConfig, err := util3.GetDevtronSecretName() + if err != nil { + return nil, err + } + versionServiceImpl := argocdServer.NewVersionServiceImpl(sugaredLogger, argoCDConnectionManagerImpl) + argoUserServiceImpl, err := argo.NewArgoUserServiceImpl(sugaredLogger, clusterServiceImplExtended, devtronSecretConfig, runtimeConfig, gitOpsConfigRepositoryImpl, argoCDConnectionManagerImpl, versionServiceImpl, k8sServiceImpl) + if err != nil { + return nil, err + } + clusterRbacServiceImpl := cluster2.NewClusterRbacServiceImpl(environmentServiceImpl, enforcerImpl, clusterServiceImplExtended, sugaredLogger, userServiceImpl) + clusterRestHandlerImpl := cluster3.NewClusterRestHandlerImpl(clusterServiceImplExtended, genericNoteServiceImpl, clusterDescriptionServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceExtendedImpl, argoUserServiceImpl, environmentServiceImpl, clusterRbacServiceImpl) + clusterRouterImpl := cluster3.NewClusterRouterImpl(clusterRestHandlerImpl) + ciCdConfig, err := types.GetCiCdConfig() + if err != nil { + return nil, err + } + envConfigOverrideRepositoryImpl := chartConfig.NewEnvConfigOverrideRepository(db) + pipelineOverrideRepositoryImpl := chartConfig.NewPipelineOverrideRepository(db) + mergeUtil := &util.MergeUtil{ + Logger: sugaredLogger, + } + ciArtifactRepositoryImpl := repository2.NewCiArtifactRepositoryImpl(db, sugaredLogger) + eventClientConfig, err := client3.GetEventClientConfig() + if err != nil { + return nil, err + } + pubSubClientServiceImpl := pubsub_lib.NewPubSubClientServiceImpl(sugaredLogger) + ciPipelineRepositoryImpl := pipelineConfig.NewCiPipelineRepositoryImpl(db, sugaredLogger) + moduleActionAuditLogRepositoryImpl := module.NewModuleActionAuditLogRepositoryImpl(db) serverCacheServiceImpl := server.NewServerCacheServiceImpl(sugaredLogger, serverEnvConfigServerEnvConfig, serverDataStoreServerDataStore, helmAppServiceImpl) moduleEnvConfig, err := module.ParseModuleEnvConfig() if err != nil { return nil, err } - teamServiceImpl := team.NewTeamServiceImpl(sugaredLogger, teamRepositoryImpl, userAuthServiceImpl) moduleCacheServiceImpl := module.NewModuleCacheServiceImpl(sugaredLogger, k8sServiceImpl, moduleEnvConfig, serverEnvConfigServerEnvConfig, serverDataStoreServerDataStore, moduleRepositoryImpl, teamServiceImpl) moduleServiceHelperImpl := module.NewModuleServiceHelperImpl(serverEnvConfigServerEnvConfig) moduleResourceStatusRepositoryImpl := moduleRepo.NewModuleResourceStatusRepositoryImpl(db) @@ -287,29 +345,22 @@ func InitializeApp() (*App, error) { } scanToolMetadataRepositoryImpl := security.NewScanToolMetadataRepositoryImpl(db, sugaredLogger) moduleServiceImpl := module.NewModuleServiceImpl(sugaredLogger, serverEnvConfigServerEnvConfig, moduleRepositoryImpl, moduleActionAuditLogRepositoryImpl, helmAppServiceImpl, serverDataStoreServerDataStore, serverCacheServiceImpl, moduleCacheServiceImpl, moduleCronServiceImpl, moduleServiceHelperImpl, moduleResourceStatusRepositoryImpl, scanToolMetadataRepositoryImpl) - eventRESTClientImpl := client.NewEventRESTClientImpl(sugaredLogger, httpClient, eventClientConfig, pubSubClientServiceImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, attributesRepositoryImpl, moduleServiceImpl) + eventRESTClientImpl := client3.NewEventRESTClientImpl(sugaredLogger, httpClient, eventClientConfig, pubSubClientServiceImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, attributesRepositoryImpl, moduleServiceImpl) cdWorkflowRepositoryImpl := pipelineConfig.NewCdWorkflowRepositoryImpl(db, sugaredLogger) ciWorkflowRepositoryImpl := pipelineConfig.NewCiWorkflowRepositoryImpl(db, sugaredLogger) ciPipelineMaterialRepositoryImpl := pipelineConfig.NewCiPipelineMaterialRepositoryImpl(db, sugaredLogger) - eventSimpleFactoryImpl := client.NewEventSimpleFactoryImpl(sugaredLogger, cdWorkflowRepositoryImpl, pipelineOverrideRepositoryImpl, ciWorkflowRepositoryImpl, ciPipelineMaterialRepositoryImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, userRepositoryImpl, ciArtifactRepositoryImpl) + eventSimpleFactoryImpl := client3.NewEventSimpleFactoryImpl(sugaredLogger, cdWorkflowRepositoryImpl, pipelineOverrideRepositoryImpl, ciWorkflowRepositoryImpl, ciPipelineMaterialRepositoryImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, userRepositoryImpl, ciArtifactRepositoryImpl) applicationServiceClientImpl := application.NewApplicationClientImpl(sugaredLogger, argoCDConnectionManagerImpl) - acdAuthConfig, err := util2.GetACDAuthConfig() - if err != nil { - return nil, err - } tokenCache := util2.NewTokenCache(sugaredLogger, acdAuthConfig, userAuthServiceImpl) - syncedEnforcer := casbin.Create() - enforcerImpl := casbin.NewEnforcerImpl(syncedEnforcer, sessionManager, sugaredLogger) enforcerUtilImpl := rbac.NewEnforcerUtilImpl(sugaredLogger, teamRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineRepositoryImpl, ciPipelineRepositoryImpl, clusterRepositoryImpl, enforcerImpl) appListingRepositoryQueryBuilder := helper.NewAppListingRepositoryQueryBuilder(sugaredLogger) - appListingRepositoryImpl := repository.NewAppListingRepositoryImpl(sugaredLogger, db, appListingRepositoryQueryBuilder, environmentRepositoryImpl) + appListingRepositoryImpl := repository2.NewAppListingRepositoryImpl(sugaredLogger, db, appListingRepositoryQueryBuilder, environmentRepositoryImpl) pipelineConfigRepositoryImpl := chartConfig.NewPipelineConfigRepository(db) configMapRepositoryImpl := chartConfig.NewConfigMapRepositoryImpl(sugaredLogger, db) - appLevelMetricsRepositoryImpl := repository.NewAppLevelMetricsRepositoryImpl(db, sugaredLogger) - envLevelAppMetricsRepositoryImpl := repository.NewEnvLevelAppMetricsRepositoryImpl(db, sugaredLogger) + appLevelMetricsRepositoryImpl := repository2.NewAppLevelMetricsRepositoryImpl(db, sugaredLogger) + envLevelAppMetricsRepositoryImpl := repository2.NewEnvLevelAppMetricsRepositoryImpl(db, sugaredLogger) chartRepositoryImpl := chartRepoRepository.NewChartRepository(db) - dockerArtifactStoreRepositoryImpl := repository5.NewDockerArtifactStoreRepositoryImpl(db) - gitProviderRepositoryImpl := repository.NewGitProviderRepositoryImpl(db) + gitProviderRepositoryImpl := repository2.NewGitProviderRepositoryImpl(db) commonServiceImpl := commonService.NewCommonServiceImpl(sugaredLogger, chartRepositoryImpl, envConfigOverrideRepositoryImpl, gitOpsConfigRepositoryImpl, dockerArtifactStoreRepositoryImpl, attributesRepositoryImpl, gitProviderRepositoryImpl, environmentRepositoryImpl, teamRepositoryImpl, appRepositoryImpl) imageScanDeployInfoRepositoryImpl := security.NewImageScanDeployInfoRepositoryImpl(db, sugaredLogger) imageScanHistoryRepositoryImpl := security.NewImageScanHistoryRepositoryImpl(db, sugaredLogger) @@ -319,15 +370,15 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - pipelineStrategyHistoryRepositoryImpl := repository6.NewPipelineStrategyHistoryRepositoryImpl(sugaredLogger, db) + pipelineStrategyHistoryRepositoryImpl := repository7.NewPipelineStrategyHistoryRepositoryImpl(sugaredLogger, db) pipelineStrategyHistoryServiceImpl := history.NewPipelineStrategyHistoryServiceImpl(sugaredLogger, pipelineStrategyHistoryRepositoryImpl, userServiceImpl) - configMapHistoryRepositoryImpl := repository6.NewConfigMapHistoryRepositoryImpl(sugaredLogger, db) - scopedVariableRepositoryImpl := repository7.NewScopedVariableRepository(db, sugaredLogger) + configMapHistoryRepositoryImpl := repository7.NewConfigMapHistoryRepositoryImpl(sugaredLogger, db) + scopedVariableRepositoryImpl := repository8.NewScopedVariableRepository(db, sugaredLogger) qualifiersMappingRepositoryImpl, err := resourceQualifiers.NewQualifiersMappingRepositoryImpl(db, sugaredLogger) if err != nil { return nil, err } - devtronResourceSearchableKeyRepositoryImpl := repository8.NewDevtronResourceSearchableKeyRepositoryImpl(sugaredLogger, db) + devtronResourceSearchableKeyRepositoryImpl := repository9.NewDevtronResourceSearchableKeyRepositoryImpl(sugaredLogger, db) devtronResourceSearchableKeyServiceImpl, err := devtronResource.NewDevtronResourceSearchableKeyServiceImpl(sugaredLogger, devtronResourceSearchableKeyRepositoryImpl) if err != nil { return nil, err @@ -340,9 +391,9 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - variableEntityMappingRepositoryImpl := repository7.NewVariableEntityMappingRepository(sugaredLogger, db) + variableEntityMappingRepositoryImpl := repository8.NewVariableEntityMappingRepository(sugaredLogger, db) variableEntityMappingServiceImpl := variables.NewVariableEntityMappingServiceImpl(variableEntityMappingRepositoryImpl, sugaredLogger) - variableSnapshotHistoryRepositoryImpl := repository7.NewVariableSnapshotHistoryRepository(sugaredLogger, db) + variableSnapshotHistoryRepositoryImpl := repository8.NewVariableSnapshotHistoryRepository(sugaredLogger, db) variableSnapshotHistoryServiceImpl := variables.NewVariableSnapshotHistoryServiceImpl(variableSnapshotHistoryRepositoryImpl, sugaredLogger) variableTemplateParserImpl, err := parsers.NewVariableTemplateParserImpl(sugaredLogger) if err != nil { @@ -353,7 +404,7 @@ func InitializeApp() (*App, error) { return nil, err } configMapHistoryServiceImpl := history.NewConfigMapHistoryServiceImpl(sugaredLogger, configMapHistoryRepositoryImpl, pipelineRepositoryImpl, configMapRepositoryImpl, userServiceImpl, scopedVariableCMCSManagerImpl) - deploymentTemplateHistoryRepositoryImpl := repository6.NewDeploymentTemplateHistoryRepositoryImpl(sugaredLogger, db) + deploymentTemplateHistoryRepositoryImpl := repository7.NewDeploymentTemplateHistoryRepositoryImpl(sugaredLogger, db) chartRefRepositoryImpl := chartRepoRepository.NewChartRefRepositoryImpl(db) scopedVariableManagerImpl, err := variables.NewScopedVariableManagerImpl(sugaredLogger, scopedVariableServiceImpl, variableEntityMappingServiceImpl, variableSnapshotHistoryServiceImpl, variableTemplateParserImpl) if err != nil { @@ -367,31 +418,16 @@ func InitializeApp() (*App, error) { } chartTemplateServiceImpl := util.NewChartTemplateServiceImpl(sugaredLogger, chartWorkingDir, httpClient, gitFactory, globalEnvVariables, gitOpsConfigRepositoryImpl, userRepositoryImpl, chartRepositoryImpl) refChartDir := _wireRefChartDirValue - chartRepoRepositoryImpl := chartRepoRepository.NewChartRepoRepositoryImpl(db) defaultChart := _wireDefaultChartValue utilMergeUtil := util.MergeUtil{ Logger: sugaredLogger, } - repositoryServiceClientImpl := repository9.NewServiceClientImpl(sugaredLogger, argoCDConnectionManagerImpl) + repositoryServiceClientImpl := repository10.NewServiceClientImpl(sugaredLogger, argoCDConnectionManagerImpl) chartServiceImpl := chart.NewChartServiceImpl(chartRepositoryImpl, sugaredLogger, chartTemplateServiceImpl, chartRepoRepositoryImpl, appRepositoryImpl, refChartDir, defaultChart, utilMergeUtil, repositoryServiceClientImpl, chartRefRepositoryImpl, envConfigOverrideRepositoryImpl, pipelineConfigRepositoryImpl, configMapRepositoryImpl, environmentRepositoryImpl, pipelineRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, httpClient, deploymentTemplateHistoryServiceImpl, scopedVariableManagerImpl) - devtronSecretConfig, err := util3.GetDevtronSecretName() - if err != nil { - return nil, err - } - versionServiceImpl := argocdServer.NewVersionServiceImpl(sugaredLogger, argoCDConnectionManagerImpl) - argoUserServiceImpl, err := argo.NewArgoUserServiceImpl(sugaredLogger, clusterServiceImplExtended, devtronSecretConfig, runtimeConfig, gitOpsConfigRepositoryImpl, argoCDConnectionManagerImpl, versionServiceImpl, k8sServiceImpl) - if err != nil { - return nil, err - } pipelineStatusTimelineRepositoryImpl := pipelineConfig.NewPipelineStatusTimelineRepositoryImpl(db, sugaredLogger) appLabelRepositoryImpl := pipelineConfig.NewAppLabelRepositoryImpl(db) - genericNoteRepositoryImpl := repository10.NewGenericNoteRepositoryImpl(db) - genericNoteHistoryRepositoryImpl := repository10.NewGenericNoteHistoryRepositoryImpl(db) - genericNoteHistoryServiceImpl := genericNotes.NewGenericNoteHistoryServiceImpl(genericNoteHistoryRepositoryImpl, sugaredLogger) - genericNoteServiceImpl := genericNotes.NewGenericNoteServiceImpl(genericNoteRepositoryImpl, genericNoteHistoryServiceImpl, userRepositoryImpl, sugaredLogger) materialRepositoryImpl := pipelineConfig.NewMaterialRepositoryImpl(db) appCrudOperationServiceImpl := app2.NewAppCrudOperationServiceImpl(appLabelRepositoryImpl, sugaredLogger, appRepositoryImpl, userRepositoryImpl, installedAppRepositoryImpl, genericNoteServiceImpl, materialRepositoryImpl) - dockerRegistryIpsConfigRepositoryImpl := repository5.NewDockerRegistryIpsConfigRepositoryImpl(db) ciTemplateOverrideRepositoryImpl := pipelineConfig.NewCiTemplateOverrideRepositoryImpl(db, sugaredLogger) dockerRegistryIpsConfigServiceImpl := dockerRegistry.NewDockerRegistryIpsConfigServiceImpl(sugaredLogger, dockerRegistryIpsConfigRepositoryImpl, k8sServiceImpl, clusterServiceImplExtended, ciPipelineRepositoryImpl, dockerArtifactStoreRepositoryImpl, ciTemplateOverrideRepositoryImpl) pipelineStatusTimelineResourcesRepositoryImpl := pipelineConfig.NewPipelineStatusTimelineResourcesRepositoryImpl(db, sugaredLogger) @@ -409,7 +445,6 @@ func InitializeApp() (*App, error) { clusterInstalledAppsRepositoryImpl := repository3.NewClusterInstalledAppsRepositoryImpl(db, sugaredLogger) refChartProxyDir := _wireRefChartProxyDirValue appStoreDeploymentCommonServiceImpl := appStoreDeploymentCommon.NewAppStoreDeploymentCommonServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, chartTemplateServiceImpl, refChartProxyDir, gitFactory, gitOpsConfigRepositoryImpl) - ociRegistryConfigRepositoryImpl := repository5.NewOCIRegistryConfigRepositoryImpl(db) appStoreDeploymentHelmServiceImpl := appStoreDeploymentTool.NewAppStoreDeploymentHelmServiceImpl(sugaredLogger, helmAppServiceImpl, appStoreApplicationVersionRepositoryImpl, helmAppClientImpl, installedAppRepositoryImpl, appStoreDeploymentCommonServiceImpl, ociRegistryConfigRepositoryImpl) acdConfig, err := argocdServer.GetACDDeploymentConfig() if err != nil { @@ -423,19 +458,10 @@ func InitializeApp() (*App, error) { return nil, err } appStoreDeploymentServiceImpl := service.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, chartGroupDeploymentRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, clusterInstalledAppsRepositoryImpl, appRepositoryImpl, appStoreDeploymentHelmServiceImpl, appStoreDeploymentArgoCdServiceImpl, environmentServiceImpl, clusterServiceImplExtended, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, installedAppVersionHistoryRepositoryImpl, gitOpsConfigRepositoryImpl, attributesServiceImpl, deploymentServiceTypeConfig, chartTemplateServiceImpl, acdConfig) - k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sServiceImpl, clusterServiceImplExtended) manifestPushConfigRepositoryImpl := repository12.NewManifestPushConfigRepository(sugaredLogger, db) gitOpsManifestPushServiceImpl := app2.NewGitOpsManifestPushServiceImpl(sugaredLogger, chartTemplateServiceImpl, chartServiceImpl, gitOpsConfigRepositoryImpl, gitFactory, pipelineStatusTimelineServiceImpl, pipelineStatusTimelineRepositoryImpl, acdConfig) appServiceImpl := app2.NewAppService(envConfigOverrideRepositoryImpl, pipelineOverrideRepositoryImpl, mergeUtil, sugaredLogger, ciArtifactRepositoryImpl, pipelineRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, applicationServiceClientImpl, tokenCache, acdAuthConfig, enforcerImpl, enforcerUtilImpl, userServiceImpl, appListingRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineConfigRepositoryImpl, configMapRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, chartRepositoryImpl, ciPipelineMaterialRepositoryImpl, cdWorkflowRepositoryImpl, commonServiceImpl, imageScanDeployInfoRepositoryImpl, imageScanHistoryRepositoryImpl, argoK8sClientImpl, gitFactory, pipelineStrategyHistoryServiceImpl, configMapHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, chartTemplateServiceImpl, refChartDir, chartRefRepositoryImpl, chartServiceImpl, helmAppClientImpl, argoUserServiceImpl, pipelineStatusTimelineRepositoryImpl, appCrudOperationServiceImpl, configMapHistoryRepositoryImpl, pipelineStrategyHistoryRepositoryImpl, deploymentTemplateHistoryRepositoryImpl, dockerRegistryIpsConfigServiceImpl, pipelineStatusTimelineResourcesServiceImpl, pipelineStatusSyncDetailServiceImpl, pipelineStatusTimelineServiceImpl, appServiceConfig, gitOpsConfigRepositoryImpl, appStatusServiceImpl, installedAppRepositoryImpl, appStoreDeploymentServiceImpl, k8sCommonServiceImpl, installedAppVersionHistoryRepositoryImpl, globalEnvVariables, helmAppServiceImpl, manifestPushConfigRepositoryImpl, gitOpsManifestPushServiceImpl, argoClientWrapperServiceImpl, scopedVariableCMCSManagerImpl, acdConfig) - validate, err := util.IntValidator() - if err != nil { - return nil, err - } - ciCdConfig, err := types.GetCiCdConfig() - if err != nil { - return nil, err - } - globalCMCSRepositoryImpl := repository.NewGlobalCMCSRepositoryImpl(sugaredLogger, db) + globalCMCSRepositoryImpl := repository2.NewGlobalCMCSRepositoryImpl(sugaredLogger, db) globalCMCSServiceImpl := pipeline.NewGlobalCMCSServiceImpl(sugaredLogger, globalCMCSRepositoryImpl) argoWorkflowExecutorImpl := executors.NewArgoWorkflowExecutorImpl(sugaredLogger) systemWorkflowExecutorImpl := executors.NewSystemWorkflowExecutorImpl(sugaredLogger, k8sServiceImpl) @@ -443,13 +469,20 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - deploymentGroupRepositoryImpl := repository.NewDeploymentGroupRepositoryImpl(sugaredLogger, db) - cvePolicyRepositoryImpl := security.NewPolicyRepositoryImpl(db) - imageScanResultRepositoryImpl := security.NewImageScanResultRepositoryImpl(db, sugaredLogger) - appWorkflowRepositoryImpl := appWorkflow.NewAppWorkflowRepositoryImpl(sugaredLogger, db) - prePostCdScriptHistoryRepositoryImpl := repository6.NewPrePostCdScriptHistoryRepositoryImpl(sugaredLogger, db) - prePostCdScriptHistoryServiceImpl := history.NewPrePostCdScriptHistoryServiceImpl(sugaredLogger, prePostCdScriptHistoryRepositoryImpl, configMapRepositoryImpl, configMapHistoryServiceImpl) + prePostCiScriptHistoryRepositoryImpl := repository7.NewPrePostCiScriptHistoryRepositoryImpl(sugaredLogger, db) + prePostCiScriptHistoryServiceImpl := history.NewPrePostCiScriptHistoryServiceImpl(sugaredLogger, prePostCiScriptHistoryRepositoryImpl) + pipelineStageRepositoryImpl := repository12.NewPipelineStageRepository(sugaredLogger, db) + globalPluginRepositoryImpl := repository13.NewGlobalPluginRepository(sugaredLogger, db) + pipelineStageServiceImpl := pipeline.NewPipelineStageService(sugaredLogger, pipelineStageRepositoryImpl, globalPluginRepositoryImpl, pipelineRepositoryImpl, scopedVariableManagerImpl) + ciBuildConfigRepositoryImpl := pipelineConfig.NewCiBuildConfigRepositoryImpl(db, sugaredLogger) + ciBuildConfigServiceImpl := pipeline.NewCiBuildConfigServiceImpl(sugaredLogger, ciBuildConfigRepositoryImpl) ciTemplateRepositoryImpl := pipelineConfig.NewCiTemplateRepositoryImpl(db, sugaredLogger) + ciTemplateServiceImpl := pipeline.NewCiTemplateServiceImpl(sugaredLogger, ciBuildConfigServiceImpl, ciTemplateRepositoryImpl, ciTemplateOverrideRepositoryImpl) + imageTagRepositoryImpl := repository2.NewImageTagRepository(db, sugaredLogger) + customTagServiceImpl := pipeline.NewCustomTagService(sugaredLogger, imageTagRepositoryImpl) + pluginInputVariableParserImpl := pipeline.NewPluginInputVariableParserImpl(sugaredLogger, dockerRegistryConfigImpl, customTagServiceImpl) + globalPluginServiceImpl := plugin.NewGlobalPluginService(sugaredLogger, globalPluginRepositoryImpl, pipelineStageRepositoryImpl) + ciServiceImpl := pipeline.NewCiServiceImpl(sugaredLogger, workflowServiceImpl, ciPipelineMaterialRepositoryImpl, ciWorkflowRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, mergeUtil, ciPipelineRepositoryImpl, prePostCiScriptHistoryServiceImpl, pipelineStageServiceImpl, userServiceImpl, ciTemplateServiceImpl, appCrudOperationServiceImpl, environmentRepositoryImpl, appRepositoryImpl, scopedVariableManagerImpl, customTagServiceImpl, pluginInputVariableParserImpl, globalPluginServiceImpl) clientConfig, err := gitSensor.GetConfig() if err != nil { return nil, err @@ -458,120 +491,70 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - pipelineStageRepositoryImpl := repository12.NewPipelineStageRepository(sugaredLogger, db) - globalPluginRepositoryImpl := repository13.NewGlobalPluginRepository(sugaredLogger, db) - pipelineStageServiceImpl := pipeline.NewPipelineStageService(sugaredLogger, pipelineStageRepositoryImpl, globalPluginRepositoryImpl, pipelineRepositoryImpl, scopedVariableManagerImpl) - globalPluginServiceImpl := plugin.NewGlobalPluginService(sugaredLogger, globalPluginRepositoryImpl, pipelineStageRepositoryImpl) - dockerRegistryConfigImpl := pipeline.NewDockerRegistryConfigImpl(sugaredLogger, helmAppServiceImpl, dockerArtifactStoreRepositoryImpl, dockerRegistryIpsConfigRepositoryImpl, ociRegistryConfigRepositoryImpl) - imageTagRepositoryImpl := repository.NewImageTagRepository(db, sugaredLogger) - customTagServiceImpl := pipeline.NewCustomTagService(sugaredLogger, imageTagRepositoryImpl) - pluginInputVariableParserImpl := pipeline.NewPluginInputVariableParserImpl(sugaredLogger, dockerRegistryConfigImpl, customTagServiceImpl) - pipelineConfigListenerServiceImpl := pipeline.NewPipelineConfigListenerServiceImpl(sugaredLogger) - workflowDagExecutorImpl := pipeline.NewWorkflowDagExecutorImpl(sugaredLogger, pipelineRepositoryImpl, cdWorkflowRepositoryImpl, pubSubClientServiceImpl, appServiceImpl, workflowServiceImpl, ciArtifactRepositoryImpl, ciPipelineRepositoryImpl, materialRepositoryImpl, pipelineOverrideRepositoryImpl, userServiceImpl, deploymentGroupRepositoryImpl, environmentRepositoryImpl, enforcerImpl, enforcerUtilImpl, eventSimpleFactoryImpl, eventRESTClientImpl, cvePolicyRepositoryImpl, imageScanResultRepositoryImpl, appWorkflowRepositoryImpl, prePostCdScriptHistoryServiceImpl, argoUserServiceImpl, pipelineStatusTimelineRepositoryImpl, pipelineStatusTimelineServiceImpl, ciTemplateRepositoryImpl, ciWorkflowRepositoryImpl, appLabelRepositoryImpl, clientImpl, pipelineStageServiceImpl, k8sCommonServiceImpl, globalPluginServiceImpl, pluginInputVariableParserImpl, scopedVariableCMCSManagerImpl, deploymentTemplateHistoryServiceImpl, configMapHistoryServiceImpl, pipelineStrategyHistoryServiceImpl, manifestPushConfigRepositoryImpl, gitOpsManifestPushServiceImpl, ciPipelineMaterialRepositoryImpl, imageScanHistoryRepositoryImpl, imageScanDeployInfoRepositoryImpl, appCrudOperationServiceImpl, pipelineConfigRepositoryImpl, dockerRegistryIpsConfigServiceImpl, chartRepositoryImpl, chartTemplateServiceImpl, pipelineStrategyHistoryRepositoryImpl, appRepositoryImpl, deploymentTemplateHistoryRepositoryImpl, argoK8sClientImpl, configMapRepositoryImpl, configMapHistoryRepositoryImpl, refChartDir, helmAppServiceImpl, helmAppClientImpl, chartRefRepositoryImpl, envConfigOverrideRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, mergeUtil, gitOpsConfigRepositoryImpl, gitFactory, applicationServiceClientImpl, argoClientWrapperServiceImpl, pipelineConfigListenerServiceImpl, customTagServiceImpl, acdConfig) - deploymentGroupAppRepositoryImpl := repository.NewDeploymentGroupAppRepositoryImpl(sugaredLogger, db) - deploymentGroupServiceImpl := deploymentGroup.NewDeploymentGroupServiceImpl(appRepositoryImpl, sugaredLogger, pipelineRepositoryImpl, ciPipelineRepositoryImpl, deploymentGroupRepositoryImpl, environmentRepositoryImpl, deploymentGroupAppRepositoryImpl, ciArtifactRepositoryImpl, appWorkflowRepositoryImpl, workflowDagExecutorImpl) - deploymentConfigServiceImpl := pipeline.NewDeploymentConfigServiceImpl(sugaredLogger, envConfigOverrideRepositoryImpl, chartRepositoryImpl, pipelineRepositoryImpl, envLevelAppMetricsRepositoryImpl, appLevelMetricsRepositoryImpl, pipelineConfigRepositoryImpl, configMapRepositoryImpl, configMapHistoryServiceImpl, chartRefRepositoryImpl, scopedVariableCMCSManagerImpl) - pipelineTriggerRestHandlerImpl := restHandler.NewPipelineRestHandler(appServiceImpl, userServiceImpl, validate, enforcerImpl, teamServiceImpl, sugaredLogger, enforcerUtilImpl, workflowDagExecutorImpl, deploymentGroupServiceImpl, argoUserServiceImpl, deploymentConfigServiceImpl) - sseSSE := sse.NewSSE() - pipelineTriggerRouterImpl := router.NewPipelineTriggerRouter(pipelineTriggerRestHandlerImpl, sseSSE) - prePostCiScriptHistoryRepositoryImpl := repository6.NewPrePostCiScriptHistoryRepositoryImpl(sugaredLogger, db) - prePostCiScriptHistoryServiceImpl := history.NewPrePostCiScriptHistoryServiceImpl(sugaredLogger, prePostCiScriptHistoryRepositoryImpl) - gitMaterialHistoryRepositoryImpl := repository6.NewGitMaterialHistoryRepositoyImpl(db) + ciLogServiceImpl, err := pipeline.NewCiLogServiceImpl(sugaredLogger, ciServiceImpl, k8sServiceImpl) + if err != nil { + return nil, err + } + resourceGroupRepositoryImpl := resourceGroup.NewResourceGroupRepositoryImpl(db) + resourceGroupMappingRepositoryImpl := resourceGroup.NewResourceGroupMappingRepositoryImpl(db) + resourceGroupServiceImpl := resourceGroup2.NewResourceGroupServiceImpl(sugaredLogger, resourceGroupRepositoryImpl, resourceGroupMappingRepositoryImpl, enforcerUtilImpl, devtronResourceSearchableKeyServiceImpl, appStatusRepositoryImpl) + imageTaggingRepositoryImpl := repository14.NewImageTaggingRepositoryImpl(db) + imageTaggingServiceImpl := pipeline.NewImageTaggingServiceImpl(imageTaggingRepositoryImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, environmentRepositoryImpl, sugaredLogger) + blobStorageConfigServiceImpl := pipeline.NewBlobStorageConfigServiceImpl(sugaredLogger, k8sServiceImpl, ciCdConfig) + appWorkflowRepositoryImpl := appWorkflow.NewAppWorkflowRepositoryImpl(sugaredLogger, db) + ciHandlerImpl := pipeline.NewCiHandlerImpl(sugaredLogger, ciServiceImpl, ciPipelineMaterialRepositoryImpl, clientImpl, ciWorkflowRepositoryImpl, workflowServiceImpl, ciLogServiceImpl, ciArtifactRepositoryImpl, userServiceImpl, eventRESTClientImpl, eventSimpleFactoryImpl, ciPipelineRepositoryImpl, appListingRepositoryImpl, k8sServiceImpl, pipelineRepositoryImpl, enforcerUtilImpl, resourceGroupServiceImpl, environmentRepositoryImpl, imageTaggingServiceImpl, k8sCommonServiceImpl, clusterServiceImplExtended, blobStorageConfigServiceImpl, appWorkflowRepositoryImpl, customTagServiceImpl, environmentServiceImpl) + gitWebhookRepositoryImpl := repository2.NewGitWebhookRepositoryImpl(db) + gitWebhookServiceImpl := git.NewGitWebhookServiceImpl(sugaredLogger, ciHandlerImpl, gitWebhookRepositoryImpl) + gitWebhookRestHandlerImpl := restHandler.NewGitWebhookRestHandlerImpl(sugaredLogger, gitWebhookServiceImpl) + prePostCdScriptHistoryRepositoryImpl := repository7.NewPrePostCdScriptHistoryRepositoryImpl(sugaredLogger, db) + prePostCdScriptHistoryServiceImpl := history.NewPrePostCdScriptHistoryServiceImpl(sugaredLogger, prePostCdScriptHistoryRepositoryImpl, configMapRepositoryImpl, configMapHistoryServiceImpl) + gitMaterialHistoryRepositoryImpl := repository7.NewGitMaterialHistoryRepositoyImpl(db) gitMaterialHistoryServiceImpl := history.NewGitMaterialHistoryServiceImpl(gitMaterialHistoryRepositoryImpl, sugaredLogger) - ciPipelineHistoryRepositoryImpl := repository6.NewCiPipelineHistoryRepositoryImpl(db, sugaredLogger) + ciPipelineHistoryRepositoryImpl := repository7.NewCiPipelineHistoryRepositoryImpl(db, sugaredLogger) ciPipelineHistoryServiceImpl := history.NewCiPipelineHistoryServiceImpl(ciPipelineHistoryRepositoryImpl, sugaredLogger, ciPipelineRepositoryImpl) - ciBuildConfigRepositoryImpl := pipelineConfig.NewCiBuildConfigRepositoryImpl(db, sugaredLogger) - ciBuildConfigServiceImpl := pipeline.NewCiBuildConfigServiceImpl(sugaredLogger, ciBuildConfigRepositoryImpl) - ciTemplateServiceImpl := pipeline.NewCiTemplateServiceImpl(sugaredLogger, ciBuildConfigServiceImpl, ciTemplateRepositoryImpl, ciTemplateOverrideRepositoryImpl) configMapServiceImpl := pipeline.NewConfigMapServiceImpl(chartRepositoryImpl, sugaredLogger, chartRepoRepositoryImpl, utilMergeUtil, pipelineConfigRepositoryImpl, configMapRepositoryImpl, envConfigOverrideRepositoryImpl, commonServiceImpl, appRepositoryImpl, configMapHistoryServiceImpl, environmentRepositoryImpl, scopedVariableCMCSManagerImpl) ciCdPipelineOrchestratorImpl := pipeline.NewCiCdPipelineOrchestrator(appRepositoryImpl, sugaredLogger, materialRepositoryImpl, pipelineRepositoryImpl, ciPipelineRepositoryImpl, ciPipelineMaterialRepositoryImpl, clientImpl, ciCdConfig, appWorkflowRepositoryImpl, environmentRepositoryImpl, attributesServiceImpl, appListingRepositoryImpl, appCrudOperationServiceImpl, userAuthServiceImpl, prePostCdScriptHistoryServiceImpl, prePostCiScriptHistoryServiceImpl, pipelineStageServiceImpl, ciTemplateOverrideRepositoryImpl, gitMaterialHistoryServiceImpl, ciPipelineHistoryServiceImpl, ciTemplateServiceImpl, dockerArtifactStoreRepositoryImpl, ciArtifactRepositoryImpl, configMapServiceImpl, customTagServiceImpl, genericNoteServiceImpl) ecrConfig, err := pipeline.GetEcrConfig() if err != nil { return nil, err } - ciTemplateHistoryRepositoryImpl := repository6.NewCiTemplateHistoryRepositoryImpl(db, sugaredLogger) + ciTemplateHistoryRepositoryImpl := repository7.NewCiTemplateHistoryRepositoryImpl(db, sugaredLogger) ciTemplateHistoryServiceImpl := history.NewCiTemplateHistoryServiceImpl(ciTemplateHistoryRepositoryImpl, sugaredLogger) - resourceGroupRepositoryImpl := resourceGroup.NewResourceGroupRepositoryImpl(db) - resourceGroupMappingRepositoryImpl := resourceGroup.NewResourceGroupMappingRepositoryImpl(db) - resourceGroupServiceImpl := resourceGroup2.NewResourceGroupServiceImpl(sugaredLogger, resourceGroupRepositoryImpl, resourceGroupMappingRepositoryImpl, enforcerUtilImpl, devtronResourceSearchableKeyServiceImpl, appStatusRepositoryImpl) buildPipelineSwitchServiceImpl := pipeline.NewBuildPipelineSwitchServiceImpl(sugaredLogger, ciPipelineRepositoryImpl, ciCdPipelineOrchestratorImpl, pipelineRepositoryImpl, ciWorkflowRepositoryImpl, appWorkflowRepositoryImpl, ciPipelineHistoryServiceImpl, ciTemplateOverrideRepositoryImpl, ciPipelineMaterialRepositoryImpl) ciPipelineConfigServiceImpl := pipeline.NewCiPipelineConfigServiceImpl(sugaredLogger, ciCdPipelineOrchestratorImpl, dockerArtifactStoreRepositoryImpl, materialRepositoryImpl, appRepositoryImpl, pipelineRepositoryImpl, ciPipelineRepositoryImpl, ecrConfig, appWorkflowRepositoryImpl, ciCdConfig, attributesServiceImpl, pipelineStageServiceImpl, ciPipelineMaterialRepositoryImpl, ciTemplateServiceImpl, ciTemplateOverrideRepositoryImpl, ciTemplateHistoryServiceImpl, enforcerUtilImpl, ciWorkflowRepositoryImpl, resourceGroupServiceImpl, customTagServiceImpl, ciPipelineHistoryServiceImpl, cdWorkflowRepositoryImpl, buildPipelineSwitchServiceImpl) ciMaterialConfigServiceImpl := pipeline.NewCiMaterialConfigServiceImpl(sugaredLogger, materialRepositoryImpl, ciTemplateServiceImpl, ciCdPipelineOrchestratorImpl, ciPipelineRepositoryImpl, gitMaterialHistoryServiceImpl, pipelineRepositoryImpl, ciPipelineMaterialRepositoryImpl) - imageTaggingRepositoryImpl := repository14.NewImageTaggingRepositoryImpl(db) - imageTaggingServiceImpl := pipeline.NewImageTaggingServiceImpl(imageTaggingRepositoryImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, environmentRepositoryImpl, sugaredLogger) + deploymentGroupRepositoryImpl := repository2.NewDeploymentGroupRepositoryImpl(sugaredLogger, db) chartDeploymentServiceImpl := util.NewChartDeploymentServiceImpl(sugaredLogger, repositoryServiceClientImpl) propertiesConfigServiceImpl := pipeline.NewPropertiesConfigServiceImpl(sugaredLogger, envConfigOverrideRepositoryImpl, chartRepositoryImpl, chartRefRepositoryImpl, utilMergeUtil, environmentRepositoryImpl, ciCdPipelineOrchestratorImpl, applicationServiceClientImpl, envLevelAppMetricsRepositoryImpl, appLevelMetricsRepositoryImpl, deploymentTemplateHistoryServiceImpl, scopedVariableManagerImpl) pipelineDeploymentServiceTypeConfig, err := pipeline.GetDeploymentServiceTypeConfig() if err != nil { return nil, err } + pipelineConfigListenerServiceImpl := pipeline.NewPipelineConfigListenerServiceImpl(sugaredLogger) devtronAppCMCSServiceImpl := pipeline.NewDevtronAppCMCSServiceImpl(sugaredLogger, appServiceImpl, attributesRepositoryImpl) cdPipelineConfigServiceImpl := pipeline.NewCdPipelineConfigServiceImpl(sugaredLogger, pipelineRepositoryImpl, environmentRepositoryImpl, pipelineConfigRepositoryImpl, appWorkflowRepositoryImpl, pipelineStageServiceImpl, appRepositoryImpl, appServiceImpl, deploymentGroupRepositoryImpl, ciCdPipelineOrchestratorImpl, appStatusRepositoryImpl, ciPipelineRepositoryImpl, prePostCdScriptHistoryServiceImpl, clusterRepositoryImpl, helmAppServiceImpl, enforcerUtilImpl, gitOpsConfigRepositoryImpl, pipelineStrategyHistoryServiceImpl, chartRepositoryImpl, resourceGroupServiceImpl, chartDeploymentServiceImpl, chartTemplateServiceImpl, propertiesConfigServiceImpl, appLevelMetricsRepositoryImpl, deploymentTemplateHistoryServiceImpl, scopedVariableManagerImpl, pipelineDeploymentServiceTypeConfig, applicationServiceClientImpl, customTagServiceImpl, pipelineConfigListenerServiceImpl, devtronAppCMCSServiceImpl, ciPipelineConfigServiceImpl, buildPipelineSwitchServiceImpl) appArtifactManagerImpl := pipeline.NewAppArtifactManagerImpl(sugaredLogger, cdWorkflowRepositoryImpl, userServiceImpl, imageTaggingServiceImpl, ciArtifactRepositoryImpl, ciWorkflowRepositoryImpl, pipelineStageServiceImpl, cdPipelineConfigServiceImpl, dockerArtifactStoreRepositoryImpl, ciPipelineRepositoryImpl, ciTemplateServiceImpl) globalStrategyMetadataChartRefMappingRepositoryImpl := chartRepoRepository.NewGlobalStrategyMetadataChartRefMappingRepositoryImpl(db, sugaredLogger) devtronAppStrategyServiceImpl := pipeline.NewDevtronAppStrategyServiceImpl(sugaredLogger, chartRepositoryImpl, globalStrategyMetadataChartRefMappingRepositoryImpl, ciCdPipelineOrchestratorImpl, cdPipelineConfigServiceImpl) + cvePolicyRepositoryImpl := security.NewPolicyRepositoryImpl(db) + imageScanResultRepositoryImpl := security.NewImageScanResultRepositoryImpl(db, sugaredLogger) + workflowDagExecutorImpl := pipeline.NewWorkflowDagExecutorImpl(sugaredLogger, pipelineRepositoryImpl, cdWorkflowRepositoryImpl, pubSubClientServiceImpl, appServiceImpl, workflowServiceImpl, ciArtifactRepositoryImpl, ciPipelineRepositoryImpl, materialRepositoryImpl, pipelineOverrideRepositoryImpl, userServiceImpl, deploymentGroupRepositoryImpl, environmentRepositoryImpl, enforcerImpl, enforcerUtilImpl, eventSimpleFactoryImpl, eventRESTClientImpl, cvePolicyRepositoryImpl, imageScanResultRepositoryImpl, appWorkflowRepositoryImpl, prePostCdScriptHistoryServiceImpl, argoUserServiceImpl, pipelineStatusTimelineRepositoryImpl, pipelineStatusTimelineServiceImpl, ciTemplateRepositoryImpl, ciWorkflowRepositoryImpl, appLabelRepositoryImpl, clientImpl, pipelineStageServiceImpl, k8sCommonServiceImpl, globalPluginServiceImpl, pluginInputVariableParserImpl, scopedVariableCMCSManagerImpl, deploymentTemplateHistoryServiceImpl, configMapHistoryServiceImpl, pipelineStrategyHistoryServiceImpl, manifestPushConfigRepositoryImpl, gitOpsManifestPushServiceImpl, ciPipelineMaterialRepositoryImpl, imageScanHistoryRepositoryImpl, imageScanDeployInfoRepositoryImpl, appCrudOperationServiceImpl, pipelineConfigRepositoryImpl, dockerRegistryIpsConfigServiceImpl, chartRepositoryImpl, chartTemplateServiceImpl, pipelineStrategyHistoryRepositoryImpl, appRepositoryImpl, deploymentTemplateHistoryRepositoryImpl, argoK8sClientImpl, configMapRepositoryImpl, configMapHistoryRepositoryImpl, refChartDir, helmAppServiceImpl, helmAppClientImpl, chartRefRepositoryImpl, envConfigOverrideRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, mergeUtil, gitOpsConfigRepositoryImpl, gitFactory, applicationServiceClientImpl, argoClientWrapperServiceImpl, pipelineConfigListenerServiceImpl, customTagServiceImpl, acdConfig) appDeploymentTypeChangeManagerImpl := pipeline.NewAppDeploymentTypeChangeManagerImpl(sugaredLogger, pipelineRepositoryImpl, workflowDagExecutorImpl, appServiceImpl, chartTemplateServiceImpl, appStatusRepositoryImpl, helmAppServiceImpl, applicationServiceClientImpl, appArtifactManagerImpl, cdPipelineConfigServiceImpl) devtronAppConfigServiceImpl := pipeline.NewDevtronAppConfigServiceImpl(sugaredLogger, ciCdPipelineOrchestratorImpl, appRepositoryImpl, pipelineRepositoryImpl, resourceGroupServiceImpl, enforcerUtilImpl, ciMaterialConfigServiceImpl) pipelineBuilderImpl := pipeline.NewPipelineBuilderImpl(sugaredLogger, materialRepositoryImpl, chartRepositoryImpl, ciPipelineConfigServiceImpl, ciMaterialConfigServiceImpl, appArtifactManagerImpl, devtronAppCMCSServiceImpl, devtronAppStrategyServiceImpl, appDeploymentTypeChangeManagerImpl, cdPipelineConfigServiceImpl, devtronAppConfigServiceImpl) - ciServiceImpl := pipeline.NewCiServiceImpl(sugaredLogger, workflowServiceImpl, ciPipelineMaterialRepositoryImpl, ciWorkflowRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, mergeUtil, ciPipelineRepositoryImpl, prePostCiScriptHistoryServiceImpl, pipelineStageServiceImpl, userServiceImpl, ciTemplateServiceImpl, appCrudOperationServiceImpl, environmentRepositoryImpl, appRepositoryImpl, scopedVariableManagerImpl, customTagServiceImpl, pluginInputVariableParserImpl, globalPluginServiceImpl) - ciLogServiceImpl, err := pipeline.NewCiLogServiceImpl(sugaredLogger, ciServiceImpl, k8sServiceImpl) - if err != nil { - return nil, err - } - blobStorageConfigServiceImpl := pipeline.NewBlobStorageConfigServiceImpl(sugaredLogger, k8sServiceImpl, ciCdConfig) - ciHandlerImpl := pipeline.NewCiHandlerImpl(sugaredLogger, ciServiceImpl, ciPipelineMaterialRepositoryImpl, clientImpl, ciWorkflowRepositoryImpl, workflowServiceImpl, ciLogServiceImpl, ciArtifactRepositoryImpl, userServiceImpl, eventRESTClientImpl, eventSimpleFactoryImpl, ciPipelineRepositoryImpl, appListingRepositoryImpl, k8sServiceImpl, pipelineRepositoryImpl, enforcerUtilImpl, resourceGroupServiceImpl, environmentRepositoryImpl, imageTaggingServiceImpl, k8sCommonServiceImpl, clusterServiceImplExtended, blobStorageConfigServiceImpl, appWorkflowRepositoryImpl, customTagServiceImpl, environmentServiceImpl) - gitRegistryConfigImpl := pipeline.NewGitRegistryConfigImpl(sugaredLogger, gitProviderRepositoryImpl, clientImpl) appListingViewBuilderImpl := app2.NewAppListingViewBuilderImpl(sugaredLogger) - linkoutsRepositoryImpl := repository.NewLinkoutsRepositoryImpl(sugaredLogger, db) + linkoutsRepositoryImpl := repository2.NewLinkoutsRepositoryImpl(sugaredLogger, db) appListingServiceImpl := app2.NewAppListingServiceImpl(sugaredLogger, appListingRepositoryImpl, applicationServiceClientImpl, appRepositoryImpl, appListingViewBuilderImpl, pipelineRepositoryImpl, linkoutsRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, cdWorkflowRepositoryImpl, pipelineOverrideRepositoryImpl, environmentRepositoryImpl, argoUserServiceImpl, envConfigOverrideRepositoryImpl, chartRepositoryImpl, ciPipelineRepositoryImpl, dockerRegistryIpsConfigServiceImpl, userRepositoryImpl) deploymentEventHandlerImpl := app2.NewDeploymentEventHandlerImpl(sugaredLogger, appListingServiceImpl, eventRESTClientImpl, eventSimpleFactoryImpl) cdHandlerImpl := pipeline.NewCdHandlerImpl(sugaredLogger, userServiceImpl, cdWorkflowRepositoryImpl, ciLogServiceImpl, ciArtifactRepositoryImpl, ciPipelineMaterialRepositoryImpl, pipelineRepositoryImpl, environmentRepositoryImpl, ciWorkflowRepositoryImpl, helmAppServiceImpl, pipelineOverrideRepositoryImpl, workflowDagExecutorImpl, appListingServiceImpl, appListingRepositoryImpl, pipelineStatusTimelineRepositoryImpl, applicationServiceClientImpl, argoUserServiceImpl, deploymentEventHandlerImpl, eventRESTClientImpl, pipelineStatusTimelineResourcesServiceImpl, pipelineStatusSyncDetailServiceImpl, pipelineStatusTimelineServiceImpl, appServiceImpl, appStatusServiceImpl, enforcerUtilImpl, installedAppRepositoryImpl, installedAppVersionHistoryRepositoryImpl, appRepositoryImpl, resourceGroupServiceImpl, imageTaggingServiceImpl, k8sServiceImpl, workflowServiceImpl, clusterServiceImplExtended, blobStorageConfigServiceImpl, customTagServiceImpl, argoClientWrapperServiceImpl, appServiceConfig, acdConfig) appWorkflowServiceImpl := appWorkflow2.NewAppWorkflowServiceImpl(sugaredLogger, appWorkflowRepositoryImpl, ciCdPipelineOrchestratorImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, enforcerUtilImpl, resourceGroupServiceImpl, appRepositoryImpl, userAuthServiceImpl) appCloneServiceImpl := appClone.NewAppCloneServiceImpl(sugaredLogger, pipelineBuilderImpl, materialRepositoryImpl, chartServiceImpl, configMapServiceImpl, appWorkflowServiceImpl, appListingServiceImpl, propertiesConfigServiceImpl, ciTemplateOverrideRepositoryImpl, pipelineStageServiceImpl, ciTemplateServiceImpl, appRepositoryImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, appWorkflowRepositoryImpl, ciPipelineConfigServiceImpl) - deploymentTemplateRepositoryImpl := repository.NewDeploymentTemplateRepositoryImpl(db, sugaredLogger) + deploymentTemplateRepositoryImpl := repository2.NewDeploymentTemplateRepositoryImpl(db, sugaredLogger) deploymentTemplateServiceImpl := generateManifest.NewDeploymentTemplateServiceImpl(sugaredLogger, chartServiceImpl, appListingServiceImpl, appListingRepositoryImpl, deploymentTemplateRepositoryImpl, helmAppServiceImpl, chartRepositoryImpl, chartTemplateServiceImpl, helmAppClientImpl, k8sServiceImpl, propertiesConfigServiceImpl, deploymentTemplateHistoryServiceImpl, environmentRepositoryImpl, appRepositoryImpl, scopedVariableManagerImpl) imageScanObjectMetaRepositoryImpl := security.NewImageScanObjectMetaRepositoryImpl(db, sugaredLogger) cveStoreRepositoryImpl := security.NewCveStoreRepositoryImpl(db, sugaredLogger) policyServiceImpl := security2.NewPolicyServiceImpl(environmentServiceImpl, sugaredLogger, appRepositoryImpl, pipelineOverrideRepositoryImpl, cvePolicyRepositoryImpl, clusterServiceImplExtended, pipelineRepositoryImpl, imageScanResultRepositoryImpl, imageScanDeployInfoRepositoryImpl, imageScanObjectMetaRepositoryImpl, httpClient, ciArtifactRepositoryImpl, ciCdConfig, imageScanHistoryRepositoryImpl, cveStoreRepositoryImpl, ciTemplateRepositoryImpl) - pipelineConfigRestHandlerImpl := app3.NewPipelineRestHandlerImpl(pipelineBuilderImpl, sugaredLogger, chartServiceImpl, propertiesConfigServiceImpl, applicationServiceClientImpl, userServiceImpl, teamServiceImpl, enforcerImpl, ciHandlerImpl, validate, clientImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, enforcerUtilImpl, environmentServiceImpl, gitRegistryConfigImpl, dockerRegistryConfigImpl, cdHandlerImpl, appCloneServiceImpl, deploymentTemplateServiceImpl, appWorkflowServiceImpl, materialRepositoryImpl, policyServiceImpl, imageScanResultRepositoryImpl, gitProviderRepositoryImpl, argoUserServiceImpl, ciPipelineMaterialRepositoryImpl, imageTaggingServiceImpl, ciArtifactRepositoryImpl) - appWorkflowRestHandlerImpl := restHandler.NewAppWorkflowRestHandlerImpl(sugaredLogger, userServiceImpl, appWorkflowServiceImpl, teamServiceImpl, enforcerImpl, pipelineBuilderImpl, appRepositoryImpl, enforcerUtilImpl) - webhookEventDataRepositoryImpl := repository.NewWebhookEventDataRepositoryImpl(db) - webhookEventDataConfigImpl := pipeline.NewWebhookEventDataConfigImpl(sugaredLogger, webhookEventDataRepositoryImpl) - webhookDataRestHandlerImpl := restHandler.NewWebhookDataRestHandlerImpl(sugaredLogger, userServiceImpl, ciPipelineMaterialRepositoryImpl, enforcerUtilImpl, enforcerImpl, clientImpl, webhookEventDataConfigImpl) - deployedConfigurationHistoryServiceImpl := history.NewDeployedConfigurationHistoryServiceImpl(sugaredLogger, userServiceImpl, deploymentTemplateHistoryServiceImpl, pipelineStrategyHistoryServiceImpl, configMapHistoryServiceImpl, cdWorkflowRepositoryImpl) - pipelineHistoryRestHandlerImpl := restHandler.NewPipelineHistoryRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, pipelineStrategyHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, configMapHistoryServiceImpl, prePostCiScriptHistoryServiceImpl, prePostCdScriptHistoryServiceImpl, enforcerUtilImpl, deployedConfigurationHistoryServiceImpl) - pipelineStatusTimelineRestHandlerImpl := restHandler.NewPipelineStatusTimelineRestHandlerImpl(sugaredLogger, pipelineStatusTimelineServiceImpl, enforcerUtilImpl, enforcerImpl) - pipelineConfigRouterImpl := router.NewPipelineRouterImpl(pipelineConfigRestHandlerImpl, appWorkflowRestHandlerImpl, webhookDataRestHandlerImpl, pipelineHistoryRestHandlerImpl, pipelineStatusTimelineRestHandlerImpl) - appStoreVersionValuesRepositoryImpl := appStoreValuesRepository.NewAppStoreVersionValuesRepositoryImpl(sugaredLogger, db) - appStoreValuesServiceImpl := service2.NewAppStoreValuesServiceImpl(sugaredLogger, appStoreApplicationVersionRepositoryImpl, installedAppRepositoryImpl, appStoreVersionValuesRepositoryImpl, userServiceImpl) - k8sResourceHistoryRepositoryImpl := repository15.NewK8sResourceHistoryRepositoryImpl(db, sugaredLogger) - k8sResourceHistoryServiceImpl := kubernetesResourceAuditLogs.Newk8sResourceHistoryServiceImpl(k8sResourceHistoryRepositoryImpl, sugaredLogger, appRepositoryImpl, environmentRepositoryImpl) - ephemeralContainersRepositoryImpl := repository2.NewEphemeralContainersRepositoryImpl(db) - ephemeralContainerServiceImpl := cluster2.NewEphemeralContainerServiceImpl(ephemeralContainersRepositoryImpl, sugaredLogger) - terminalSessionHandlerImpl := terminal.NewTerminalSessionHandlerImpl(environmentServiceImpl, clusterServiceImplExtended, sugaredLogger, k8sServiceImpl, ephemeralContainerServiceImpl) - k8sApplicationServiceImpl, err := application2.NewK8sApplicationServiceImpl(sugaredLogger, clusterServiceImplExtended, pumpImpl, helmAppServiceImpl, k8sServiceImpl, acdAuthConfig, k8sResourceHistoryServiceImpl, k8sCommonServiceImpl, terminalSessionHandlerImpl, ephemeralContainerServiceImpl, ephemeralContainersRepositoryImpl) - if err != nil { - return nil, err - } - installedAppServiceImpl, err := service.NewInstalledAppServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, teamRepositoryImpl, appRepositoryImpl, applicationServiceClientImpl, appStoreValuesServiceImpl, pubSubClientServiceImpl, chartGroupDeploymentRepositoryImpl, environmentServiceImpl, gitFactory, acdAuthConfig, gitOpsConfigRepositoryImpl, userServiceImpl, appStoreDeploymentFullModeServiceImpl, appStoreDeploymentServiceImpl, installedAppVersionHistoryRepositoryImpl, argoUserServiceImpl, helmAppClientImpl, helmAppServiceImpl, appStatusServiceImpl, k8sServiceImpl, pipelineStatusTimelineServiceImpl, appStoreDeploymentCommonServiceImpl, k8sCommonServiceImpl, k8sApplicationServiceImpl, acdConfig) - if err != nil { - return nil, err - } - cdApplicationStatusUpdateHandlerImpl := cron.NewCdApplicationStatusUpdateHandlerImpl(sugaredLogger, appServiceImpl, workflowDagExecutorImpl, installedAppServiceImpl, cdHandlerImpl, appServiceConfig, pubSubClientServiceImpl, pipelineStatusTimelineRepositoryImpl, eventRESTClientImpl, appListingRepositoryImpl, cdWorkflowRepositoryImpl, pipelineRepositoryImpl, installedAppVersionHistoryRepositoryImpl, installedAppRepositoryImpl) - appListingRestHandlerImpl := restHandler.NewAppListingRestHandlerImpl(applicationServiceClientImpl, appListingServiceImpl, teamServiceImpl, enforcerImpl, pipelineBuilderImpl, sugaredLogger, enforcerUtilImpl, deploymentGroupServiceImpl, userServiceImpl, helmAppClientImpl, clusterServiceImplExtended, helmAppServiceImpl, argoUserServiceImpl, k8sCommonServiceImpl, installedAppServiceImpl, cdApplicationStatusUpdateHandlerImpl, pipelineRepositoryImpl, appStatusServiceImpl, installedAppRepositoryImpl, environmentServiceImpl, genericNoteServiceImpl, k8sApplicationServiceImpl, deploymentTemplateServiceImpl) - appListingRouterImpl := router.NewAppListingRouterImpl(appListingRestHandlerImpl) - chartRepositoryServiceImpl := chartRepo.NewChartRepositoryServiceImpl(sugaredLogger, chartRepoRepositoryImpl, k8sServiceImpl, clusterServiceImplExtended, acdAuthConfig, httpClient, serverEnvConfigServerEnvConfig) - deleteServiceExtendedImpl := delete2.NewDeleteServiceExtendedImpl(sugaredLogger, teamServiceImpl, clusterServiceImplExtended, environmentServiceImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineRepositoryImpl, chartRepositoryServiceImpl, installedAppRepositoryImpl, dockerRegistryConfigImpl, dockerArtifactStoreRepositoryImpl) - environmentRestHandlerImpl := cluster3.NewEnvironmentRestHandlerImpl(environmentServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceExtendedImpl, k8sServiceImpl, k8sCommonServiceImpl) - environmentRouterImpl := cluster3.NewEnvironmentRouterImpl(environmentRestHandlerImpl) - clusterDescriptionRepositoryImpl := repository2.NewClusterDescriptionRepositoryImpl(db, sugaredLogger) - clusterDescriptionServiceImpl := cluster2.NewClusterDescriptionServiceImpl(clusterDescriptionRepositoryImpl, userRepositoryImpl, sugaredLogger) - clusterRbacServiceImpl := cluster2.NewClusterRbacServiceImpl(environmentServiceImpl, enforcerImpl, clusterServiceImplExtended, sugaredLogger, userServiceImpl) - clusterRestHandlerImpl := cluster3.NewClusterRestHandlerImpl(clusterServiceImplExtended, genericNoteServiceImpl, clusterDescriptionServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceExtendedImpl, argoUserServiceImpl, environmentServiceImpl, clusterRbacServiceImpl) - clusterRouterImpl := cluster3.NewClusterRouterImpl(clusterRestHandlerImpl) - gitWebhookRepositoryImpl := repository.NewGitWebhookRepositoryImpl(db) - gitWebhookServiceImpl := git.NewGitWebhookServiceImpl(sugaredLogger, ciHandlerImpl, gitWebhookRepositoryImpl) - gitWebhookRestHandlerImpl := restHandler.NewGitWebhookRestHandlerImpl(sugaredLogger, gitWebhookServiceImpl) + pipelineConfigRestHandlerImpl := configure.NewPipelineRestHandlerImpl(pipelineBuilderImpl, sugaredLogger, chartServiceImpl, propertiesConfigServiceImpl, applicationServiceClientImpl, userServiceImpl, teamServiceImpl, enforcerImpl, ciHandlerImpl, validate, clientImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, enforcerUtilImpl, dockerRegistryConfigImpl, cdHandlerImpl, appCloneServiceImpl, deploymentTemplateServiceImpl, appWorkflowServiceImpl, materialRepositoryImpl, policyServiceImpl, imageScanResultRepositoryImpl, gitProviderRepositoryImpl, argoUserServiceImpl, ciPipelineMaterialRepositoryImpl, imageTaggingServiceImpl, ciArtifactRepositoryImpl) webhookServiceImpl := pipeline.NewWebhookServiceImpl(ciArtifactRepositoryImpl, sugaredLogger, ciPipelineRepositoryImpl, appServiceImpl, eventRESTClientImpl, eventSimpleFactoryImpl, ciWorkflowRepositoryImpl, workflowDagExecutorImpl, ciHandlerImpl, pipelineStageRepositoryImpl, globalPluginRepositoryImpl, customTagServiceImpl) ciEventConfig, err := pubsub.GetCiEventConfig() if err != nil { @@ -589,35 +572,23 @@ func InitializeApp() (*App, error) { return nil, err } userAuthRouterImpl := user2.NewUserAuthRouterImpl(sugaredLogger, userAuthHandlerImpl, userAuthOidcHelperImpl) - argoApplicationRestHandlerImpl := restHandler.NewArgoApplicationRestHandlerImpl(applicationServiceClientImpl, pumpImpl, enforcerImpl, teamServiceImpl, environmentServiceImpl, sugaredLogger, enforcerUtilImpl, terminalSessionHandlerImpl, argoUserServiceImpl, k8sResourceHistoryServiceImpl, userServiceImpl) - applicationRouterImpl := router.NewApplicationRouterImpl(argoApplicationRestHandlerImpl, sugaredLogger) - argoConfig, err := ArgoUtil.GetArgoConfig() - if err != nil { - return nil, err - } - argoSession, err := ArgoUtil.NewArgoSession(argoConfig, sugaredLogger) - if err != nil { - return nil, err - } - resourceServiceImpl := ArgoUtil.NewResourceServiceImpl(argoSession) - cdRestHandlerImpl := restHandler.NewCDRestHandlerImpl(sugaredLogger, resourceServiceImpl) - cdRouterImpl := router.NewCDRouterImpl(sugaredLogger, cdRestHandlerImpl) + gitRegistryConfigImpl := pipeline.NewGitRegistryConfigImpl(sugaredLogger, gitProviderRepositoryImpl, clientImpl) deleteServiceFullModeImpl := delete2.NewDeleteServiceFullModeImpl(sugaredLogger, materialRepositoryImpl, gitRegistryConfigImpl, ciTemplateRepositoryImpl, dockerRegistryConfigImpl, dockerArtifactStoreRepositoryImpl) gitProviderRestHandlerImpl := restHandler.NewGitProviderRestHandlerImpl(dockerRegistryConfigImpl, sugaredLogger, gitRegistryConfigImpl, userServiceImpl, validate, enforcerImpl, teamServiceImpl, deleteServiceFullModeImpl) gitProviderRouterImpl := router.NewGitProviderRouterImpl(gitProviderRestHandlerImpl) - gitHostRepositoryImpl := repository.NewGitHostRepositoryImpl(db) + gitHostRepositoryImpl := repository2.NewGitHostRepositoryImpl(db) gitHostConfigImpl := pipeline.NewGitHostConfigImpl(gitHostRepositoryImpl, sugaredLogger, attributesServiceImpl) gitHostRestHandlerImpl := restHandler.NewGitHostRestHandlerImpl(sugaredLogger, gitHostConfigImpl, userServiceImpl, validate, enforcerImpl, clientImpl, gitRegistryConfigImpl) gitHostRouterImpl := router.NewGitHostRouterImpl(gitHostRestHandlerImpl) chartProviderServiceImpl := chartProvider.NewChartProviderServiceImpl(sugaredLogger, chartRepoRepositoryImpl, chartRepositoryServiceImpl, dockerArtifactStoreRepositoryImpl, ociRegistryConfigRepositoryImpl) dockerRegRestHandlerExtendedImpl := restHandler.NewDockerRegRestHandlerExtendedImpl(dockerRegistryConfigImpl, sugaredLogger, chartProviderServiceImpl, userServiceImpl, validate, enforcerImpl, teamServiceImpl, deleteServiceExtendedImpl, deleteServiceFullModeImpl) dockerRegRouterImpl := router.NewDockerRegRouterImpl(dockerRegRestHandlerExtendedImpl) - notificationSettingsRepositoryImpl := repository.NewNotificationSettingsRepositoryImpl(db) + notificationSettingsRepositoryImpl := repository2.NewNotificationSettingsRepositoryImpl(db) notificationConfigBuilderImpl := notifier.NewNotificationConfigBuilderImpl(sugaredLogger) - slackNotificationRepositoryImpl := repository.NewSlackNotificationRepositoryImpl(db) - webhookNotificationRepositoryImpl := repository.NewWebhookNotificationRepositoryImpl(db) - sesNotificationRepositoryImpl := repository.NewSESNotificationRepositoryImpl(db) - smtpNotificationRepositoryImpl := repository.NewSMTPNotificationRepositoryImpl(db) + slackNotificationRepositoryImpl := repository2.NewSlackNotificationRepositoryImpl(db) + webhookNotificationRepositoryImpl := repository2.NewWebhookNotificationRepositoryImpl(db) + sesNotificationRepositoryImpl := repository2.NewSESNotificationRepositoryImpl(db) + smtpNotificationRepositoryImpl := repository2.NewSMTPNotificationRepositoryImpl(db) notificationConfigServiceImpl := notifier.NewNotificationConfigServiceImpl(sugaredLogger, notificationSettingsRepositoryImpl, notificationConfigBuilderImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, slackNotificationRepositoryImpl, webhookNotificationRepositoryImpl, sesNotificationRepositoryImpl, smtpNotificationRepositoryImpl, teamRepositoryImpl, environmentRepositoryImpl, appRepositoryImpl, userRepositoryImpl, ciPipelineMaterialRepositoryImpl) slackNotificationServiceImpl := notifier.NewSlackNotificationServiceImpl(sugaredLogger, slackNotificationRepositoryImpl, webhookNotificationRepositoryImpl, teamServiceImpl, userRepositoryImpl, notificationSettingsRepositoryImpl) webhookNotificationServiceImpl := notifier.NewWebhookNotificationServiceImpl(sugaredLogger, webhookNotificationRepositoryImpl, teamServiceImpl, userRepositoryImpl, notificationSettingsRepositoryImpl) @@ -629,6 +600,21 @@ func InitializeApp() (*App, error) { teamRouterImpl := team2.NewTeamRouterImpl(teamRestHandlerImpl) gitWebhookHandlerImpl := pubsub.NewGitWebhookHandler(sugaredLogger, pubSubClientServiceImpl, gitWebhookServiceImpl) workflowStatusUpdateHandlerImpl := pubsub.NewWorkflowStatusUpdateHandlerImpl(sugaredLogger, pubSubClientServiceImpl, ciHandlerImpl, cdHandlerImpl, eventSimpleFactoryImpl, eventRESTClientImpl, cdWorkflowRepositoryImpl) + appStoreVersionValuesRepositoryImpl := appStoreValuesRepository.NewAppStoreVersionValuesRepositoryImpl(sugaredLogger, db) + appStoreValuesServiceImpl := service2.NewAppStoreValuesServiceImpl(sugaredLogger, appStoreApplicationVersionRepositoryImpl, installedAppRepositoryImpl, appStoreVersionValuesRepositoryImpl, userServiceImpl) + k8sResourceHistoryRepositoryImpl := repository15.NewK8sResourceHistoryRepositoryImpl(db, sugaredLogger) + k8sResourceHistoryServiceImpl := kubernetesResourceAuditLogs.Newk8sResourceHistoryServiceImpl(k8sResourceHistoryRepositoryImpl, sugaredLogger, appRepositoryImpl, environmentRepositoryImpl) + ephemeralContainersRepositoryImpl := repository.NewEphemeralContainersRepositoryImpl(db) + ephemeralContainerServiceImpl := cluster2.NewEphemeralContainerServiceImpl(ephemeralContainersRepositoryImpl, sugaredLogger) + terminalSessionHandlerImpl := terminal.NewTerminalSessionHandlerImpl(environmentServiceImpl, clusterServiceImplExtended, sugaredLogger, k8sServiceImpl, ephemeralContainerServiceImpl) + k8sApplicationServiceImpl, err := application2.NewK8sApplicationServiceImpl(sugaredLogger, clusterServiceImplExtended, pumpImpl, helmAppServiceImpl, k8sServiceImpl, acdAuthConfig, k8sResourceHistoryServiceImpl, k8sCommonServiceImpl, terminalSessionHandlerImpl, ephemeralContainerServiceImpl, ephemeralContainersRepositoryImpl) + if err != nil { + return nil, err + } + installedAppServiceImpl, err := service.NewInstalledAppServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, teamRepositoryImpl, appRepositoryImpl, applicationServiceClientImpl, appStoreValuesServiceImpl, pubSubClientServiceImpl, chartGroupDeploymentRepositoryImpl, environmentServiceImpl, gitFactory, acdAuthConfig, gitOpsConfigRepositoryImpl, userServiceImpl, appStoreDeploymentFullModeServiceImpl, appStoreDeploymentServiceImpl, installedAppVersionHistoryRepositoryImpl, argoUserServiceImpl, helmAppClientImpl, helmAppServiceImpl, appStatusServiceImpl, k8sServiceImpl, pipelineStatusTimelineServiceImpl, appStoreDeploymentCommonServiceImpl, k8sCommonServiceImpl, k8sApplicationServiceImpl, acdConfig) + if err != nil { + return nil, err + } applicationStatusHandlerImpl := pubsub.NewApplicationStatusHandlerImpl(sugaredLogger, pubSubClientServiceImpl, appServiceImpl, workflowDagExecutorImpl, installedAppServiceImpl, appStoreDeploymentServiceImpl, pipelineBuilderImpl, pipelineRepositoryImpl, installedAppRepositoryImpl) roleGroupServiceImpl := user.NewRoleGroupServiceImpl(userAuthRepositoryImpl, sugaredLogger, userRepositoryImpl, roleGroupRepositoryImpl, userCommonServiceImpl) userRestHandlerImpl := user2.NewUserRestHandlerImpl(userServiceImpl, validate, sugaredLogger, enforcerImpl, roleGroupServiceImpl, userCommonServiceImpl) @@ -637,6 +623,7 @@ func InitializeApp() (*App, error) { chartRefRouterImpl := router.NewChartRefRouterImpl(chartRefRestHandlerImpl) configMapRestHandlerImpl := restHandler.NewConfigMapRestHandlerImpl(pipelineBuilderImpl, sugaredLogger, chartServiceImpl, userServiceImpl, teamServiceImpl, enforcerImpl, pipelineRepositoryImpl, enforcerUtilImpl, configMapServiceImpl) configMapRouterImpl := router.NewConfigMapRouterImpl(configMapRestHandlerImpl) + cdApplicationStatusUpdateHandlerImpl := cron.NewCdApplicationStatusUpdateHandlerImpl(sugaredLogger, appServiceImpl, workflowDagExecutorImpl, installedAppServiceImpl, cdHandlerImpl, appServiceConfig, pubSubClientServiceImpl, pipelineStatusTimelineRepositoryImpl, eventRESTClientImpl, appListingRepositoryImpl, cdWorkflowRepositoryImpl, pipelineRepositoryImpl, installedAppVersionHistoryRepositoryImpl, installedAppRepositoryImpl) installedAppRestHandlerImpl := appStore.NewInstalledAppRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, enforcerUtilImpl, enforcerUtilHelmImpl, installedAppServiceImpl, validate, clusterServiceImplExtended, applicationServiceClientImpl, appStoreDeploymentServiceImpl, helmAppClientImpl, argoUserServiceImpl, cdApplicationStatusUpdateHandlerImpl, installedAppRepositoryImpl, appCrudOperationServiceImpl) appStoreValuesRestHandlerImpl := appStoreValues.NewAppStoreValuesRestHandlerImpl(sugaredLogger, userServiceImpl, appStoreValuesServiceImpl) appStoreValuesRouterImpl := appStoreValues.NewAppStoreValuesRouterImpl(appStoreValuesRestHandlerImpl) @@ -662,6 +649,8 @@ func InitializeApp() (*App, error) { releaseDataServiceImpl := app2.NewReleaseDataServiceImpl(pipelineOverrideRepositoryImpl, sugaredLogger, ciPipelineMaterialRepositoryImpl, eventRESTClientImpl, lensClientImpl) releaseMetricsRestHandlerImpl := restHandler.NewReleaseMetricsRestHandlerImpl(sugaredLogger, enforcerImpl, releaseDataServiceImpl, userServiceImpl, teamServiceImpl, pipelineRepositoryImpl, enforcerUtilImpl) releaseMetricsRouterImpl := router.NewReleaseMetricsRouterImpl(sugaredLogger, releaseMetricsRestHandlerImpl) + deploymentGroupAppRepositoryImpl := repository2.NewDeploymentGroupAppRepositoryImpl(sugaredLogger, db) + deploymentGroupServiceImpl := deploymentGroup.NewDeploymentGroupServiceImpl(appRepositoryImpl, sugaredLogger, pipelineRepositoryImpl, ciPipelineRepositoryImpl, deploymentGroupRepositoryImpl, environmentRepositoryImpl, deploymentGroupAppRepositoryImpl, ciArtifactRepositoryImpl, appWorkflowRepositoryImpl, workflowDagExecutorImpl) deploymentGroupRestHandlerImpl := restHandler.NewDeploymentGroupRestHandlerImpl(deploymentGroupServiceImpl, sugaredLogger, validate, enforcerImpl, teamServiceImpl, userServiceImpl, enforcerUtilImpl) deploymentGroupRouterImpl := router.NewDeploymentGroupRouterImpl(deploymentGroupRestHandlerImpl) buildActionImpl := batch.NewBuildActionImpl(pipelineBuilderImpl, sugaredLogger, appRepositoryImpl, appWorkflowRepositoryImpl, ciPipelineRepositoryImpl, materialRepositoryImpl) @@ -692,7 +681,7 @@ func InitializeApp() (*App, error) { dashboardRouterImpl := dashboard.NewDashboardRouterImpl(sugaredLogger, dashboardConfig) attributesRestHandlerImpl := restHandler.NewAttributesRestHandlerImpl(sugaredLogger, enforcerImpl, userServiceImpl, attributesServiceImpl) attributesRouterImpl := router.NewAttributesRouterImpl(attributesRestHandlerImpl) - userAttributesRepositoryImpl := repository.NewUserAttributesRepositoryImpl(db) + userAttributesRepositoryImpl := repository2.NewUserAttributesRepositoryImpl(db) userAttributesServiceImpl := attributes.NewUserAttributesServiceImpl(sugaredLogger, userAttributesRepositoryImpl) userAttributesRestHandlerImpl := restHandler.NewUserAttributesRestHandlerImpl(sugaredLogger, enforcerImpl, userServiceImpl, userAttributesServiceImpl) userAttributesRouterImpl := router.NewUserAttributesRouterImpl(userAttributesRestHandlerImpl) @@ -726,14 +715,36 @@ func InitializeApp() (*App, error) { bulkUpdateRestHandlerImpl := restHandler.NewBulkUpdateRestHandlerImpl(pipelineBuilderImpl, sugaredLogger, bulkUpdateServiceImpl, chartServiceImpl, propertiesConfigServiceImpl, applicationServiceClientImpl, userServiceImpl, teamServiceImpl, enforcerImpl, ciHandlerImpl, validate, clientImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, enforcerUtilImpl, environmentServiceImpl, gitRegistryConfigImpl, dockerRegistryConfigImpl, cdHandlerImpl, appCloneServiceImpl, appWorkflowServiceImpl, materialRepositoryImpl, policyServiceImpl, imageScanResultRepositoryImpl, argoUserServiceImpl) bulkUpdateRouterImpl := router.NewBulkUpdateRouterImpl(bulkUpdateRestHandlerImpl) webhookSecretValidatorImpl := git.NewWebhookSecretValidatorImpl(sugaredLogger) + webhookEventDataRepositoryImpl := repository2.NewWebhookEventDataRepositoryImpl(db) + webhookEventDataConfigImpl := pipeline.NewWebhookEventDataConfigImpl(sugaredLogger, webhookEventDataRepositoryImpl) webhookEventHandlerImpl := restHandler.NewWebhookEventHandlerImpl(sugaredLogger, gitHostConfigImpl, eventRESTClientImpl, webhookSecretValidatorImpl, webhookEventDataConfigImpl) webhookListenerRouterImpl := router.NewWebhookListenerRouterImpl(webhookEventHandlerImpl) - appRestHandlerImpl := restHandler.NewAppRestHandlerImpl(sugaredLogger, appCrudOperationServiceImpl, userServiceImpl, validate, enforcerUtilImpl, enforcerImpl, helmAppServiceImpl, enforcerUtilHelmImpl, genericNoteServiceImpl) - appRouterImpl := router.NewAppRouterImpl(sugaredLogger, appRestHandlerImpl) + appFilteringRestHandlerImpl := appList.NewAppFilteringRestHandlerImpl(sugaredLogger, teamServiceImpl, enforcerImpl, userServiceImpl, clusterServiceImplExtended, environmentServiceImpl) + appFilteringRouterImpl := appList2.NewAppFilteringRouterImpl(appFilteringRestHandlerImpl) + appListingRestHandlerImpl := appList.NewAppListingRestHandlerImpl(applicationServiceClientImpl, appListingServiceImpl, enforcerImpl, pipelineBuilderImpl, sugaredLogger, enforcerUtilImpl, deploymentGroupServiceImpl, userServiceImpl, helmAppClientImpl, helmAppServiceImpl, argoUserServiceImpl, k8sCommonServiceImpl, installedAppServiceImpl, cdApplicationStatusUpdateHandlerImpl, pipelineRepositoryImpl, appStatusServiceImpl, installedAppRepositoryImpl, genericNoteServiceImpl, k8sApplicationServiceImpl, deploymentTemplateServiceImpl) + appListingRouterImpl := appList2.NewAppListingRouterImpl(appListingRestHandlerImpl) + appInfoRestHandlerImpl := appInfo.NewAppInfoRestHandlerImpl(sugaredLogger, appCrudOperationServiceImpl, userServiceImpl, validate, enforcerUtilImpl, enforcerImpl, helmAppServiceImpl, enforcerUtilHelmImpl, genericNoteServiceImpl) + appInfoRouterImpl := appInfo2.NewAppInfoRouterImpl(sugaredLogger, appInfoRestHandlerImpl) + deploymentConfigServiceImpl := pipeline.NewDeploymentConfigServiceImpl(sugaredLogger, envConfigOverrideRepositoryImpl, chartRepositoryImpl, pipelineRepositoryImpl, envLevelAppMetricsRepositoryImpl, appLevelMetricsRepositoryImpl, pipelineConfigRepositoryImpl, configMapRepositoryImpl, configMapHistoryServiceImpl, chartRefRepositoryImpl, scopedVariableCMCSManagerImpl) + pipelineTriggerRestHandlerImpl := trigger.NewPipelineRestHandler(appServiceImpl, userServiceImpl, validate, enforcerImpl, teamServiceImpl, sugaredLogger, enforcerUtilImpl, workflowDagExecutorImpl, deploymentGroupServiceImpl, argoUserServiceImpl, deploymentConfigServiceImpl) + sseSSE := sse.NewSSE() + pipelineTriggerRouterImpl := trigger2.NewPipelineTriggerRouter(pipelineTriggerRestHandlerImpl, sseSSE) + webhookDataRestHandlerImpl := webhook.NewWebhookDataRestHandlerImpl(sugaredLogger, userServiceImpl, ciPipelineMaterialRepositoryImpl, enforcerUtilImpl, enforcerImpl, clientImpl, webhookEventDataConfigImpl) + pipelineConfigRouterImpl := configure2.NewPipelineRouterImpl(pipelineConfigRestHandlerImpl, webhookDataRestHandlerImpl) + deployedConfigurationHistoryServiceImpl := history.NewDeployedConfigurationHistoryServiceImpl(sugaredLogger, userServiceImpl, deploymentTemplateHistoryServiceImpl, pipelineStrategyHistoryServiceImpl, configMapHistoryServiceImpl, cdWorkflowRepositoryImpl) + pipelineHistoryRestHandlerImpl := history2.NewPipelineHistoryRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, pipelineStrategyHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, configMapHistoryServiceImpl, prePostCiScriptHistoryServiceImpl, prePostCdScriptHistoryServiceImpl, enforcerUtilImpl, deployedConfigurationHistoryServiceImpl) + pipelineHistoryRouterImpl := history3.NewPipelineHistoryRouterImpl(pipelineHistoryRestHandlerImpl) + pipelineStatusTimelineRestHandlerImpl := status2.NewPipelineStatusTimelineRestHandlerImpl(sugaredLogger, pipelineStatusTimelineServiceImpl, enforcerUtilImpl, enforcerImpl) + pipelineStatusRouterImpl := status3.NewPipelineStatusRouterImpl(pipelineStatusTimelineRestHandlerImpl) + appWorkflowRestHandlerImpl := workflow.NewAppWorkflowRestHandlerImpl(sugaredLogger, userServiceImpl, appWorkflowServiceImpl, teamServiceImpl, enforcerImpl, pipelineBuilderImpl, appRepositoryImpl, enforcerUtilImpl) + appWorkflowRouterImpl := workflow2.NewAppWorkflowRouterImpl(appWorkflowRestHandlerImpl) + devtronAppAutoCompleteRestHandlerImpl := pipeline2.NewDevtronAppAutoCompleteRestHandlerImpl(sugaredLogger, userServiceImpl, teamServiceImpl, enforcerImpl, enforcerUtilImpl, devtronAppConfigServiceImpl, environmentServiceImpl, gitRegistryConfigImpl, dockerRegistryConfigImpl) + devtronAppAutoCompleteRouterImpl := pipeline3.NewDevtronAppAutoCompleteRouterImpl(devtronAppAutoCompleteRestHandlerImpl) + appRouterImpl := app3.NewAppRouterImpl(appFilteringRouterImpl, appListingRouterImpl, appInfoRouterImpl, pipelineTriggerRouterImpl, pipelineConfigRouterImpl, pipelineHistoryRouterImpl, pipelineStatusRouterImpl, appWorkflowRouterImpl, devtronAppAutoCompleteRouterImpl, appWorkflowRestHandlerImpl, appListingRestHandlerImpl, appFilteringRestHandlerImpl) coreAppRestHandlerImpl := restHandler.NewCoreAppRestHandlerImpl(sugaredLogger, userServiceImpl, validate, enforcerUtilImpl, enforcerImpl, appCrudOperationServiceImpl, pipelineBuilderImpl, gitRegistryConfigImpl, chartServiceImpl, configMapServiceImpl, appListingServiceImpl, propertiesConfigServiceImpl, appWorkflowServiceImpl, materialRepositoryImpl, gitProviderRepositoryImpl, appWorkflowRepositoryImpl, environmentRepositoryImpl, configMapRepositoryImpl, envConfigOverrideRepositoryImpl, chartRepositoryImpl, teamServiceImpl, argoUserServiceImpl, pipelineStageServiceImpl, ciPipelineRepositoryImpl) coreAppRouterImpl := router.NewCoreAppRouterImpl(coreAppRestHandlerImpl) - helmAppRestHandlerImpl := client3.NewHelmAppRestHandlerImpl(sugaredLogger, helmAppServiceImpl, enforcerImpl, clusterServiceImplExtended, enforcerUtilHelmImpl, appStoreDeploymentCommonServiceImpl, userServiceImpl, attributesServiceImpl, serverEnvConfigServerEnvConfig) - helmAppRouterImpl := client3.NewHelmAppRouterImpl(helmAppRestHandlerImpl) + helmAppRestHandlerImpl := client2.NewHelmAppRestHandlerImpl(sugaredLogger, helmAppServiceImpl, enforcerImpl, clusterServiceImplExtended, enforcerUtilHelmImpl, appStoreDeploymentCommonServiceImpl, userServiceImpl, attributesServiceImpl, serverEnvConfigServerEnvConfig) + helmAppRouterImpl := client2.NewHelmAppRouterImpl(helmAppRestHandlerImpl) k8sApplicationRestHandlerImpl := application3.NewK8sApplicationRestHandlerImpl(sugaredLogger, k8sApplicationServiceImpl, pumpImpl, terminalSessionHandlerImpl, enforcerImpl, enforcerUtilHelmImpl, enforcerUtilImpl, helmAppServiceImpl, userServiceImpl, k8sCommonServiceImpl, validate) k8sApplicationRouterImpl := application3.NewK8sApplicationRouterImpl(k8sApplicationRestHandlerImpl) pProfRestHandlerImpl := restHandler.NewPProfRestHandler(userServiceImpl, enforcerImpl) @@ -778,7 +789,7 @@ func InitializeApp() (*App, error) { webhookHelmRouterImpl := webhookHelm2.NewWebhookHelmRouterImpl(webhookHelmRestHandlerImpl) globalCMCSRestHandlerImpl := restHandler.NewGlobalCMCSRestHandlerImpl(sugaredLogger, userServiceImpl, validate, enforcerImpl, globalCMCSServiceImpl) globalCMCSRouterImpl := router.NewGlobalCMCSRouterImpl(globalCMCSRestHandlerImpl) - terminalAccessRepositoryImpl := repository.NewTerminalAccessRepositoryImpl(db, sugaredLogger) + terminalAccessRepositoryImpl := repository2.NewTerminalAccessRepositoryImpl(db, sugaredLogger) userTerminalSessionConfig, err := clusterTerminalAccess.GetTerminalAccessConfig() if err != nil { return nil, err @@ -812,7 +823,7 @@ func InitializeApp() (*App, error) { return nil, err } proxyRouterImpl := proxy.NewProxyRouterImpl(sugaredLogger, proxyConfig, enforcerImpl) - muxRouter := router.NewMuxRouter(sugaredLogger, pipelineTriggerRouterImpl, pipelineConfigRouterImpl, appListingRouterImpl, environmentRouterImpl, clusterRouterImpl, webhookRouterImpl, userAuthRouterImpl, applicationRouterImpl, cdRouterImpl, gitProviderRouterImpl, gitHostRouterImpl, dockerRegRouterImpl, notificationRouterImpl, teamRouterImpl, gitWebhookHandlerImpl, workflowStatusUpdateHandlerImpl, applicationStatusHandlerImpl, ciEventHandlerImpl, pubSubClientServiceImpl, userRouterImpl, chartRefRouterImpl, configMapRouterImpl, appStoreRouterImpl, chartRepositoryRouterImpl, releaseMetricsRouterImpl, deploymentGroupRouterImpl, batchOperationRouterImpl, chartGroupRouterImpl, imageScanRouterImpl, policyRouterImpl, gitOpsConfigRouterImpl, dashboardRouterImpl, attributesRouterImpl, userAttributesRouterImpl, commonRouterImpl, grafanaRouterImpl, ssoLoginRouterImpl, telemetryRouterImpl, telemetryEventClientImplExtended, bulkUpdateRouterImpl, webhookListenerRouterImpl, appRouterImpl, coreAppRouterImpl, helmAppRouterImpl, k8sApplicationRouterImpl, pProfRouterImpl, deploymentConfigRouterImpl, dashboardTelemetryRouterImpl, commonDeploymentRouterImpl, externalLinkRouterImpl, globalPluginRouterImpl, moduleRouterImpl, serverRouterImpl, apiTokenRouterImpl, cdApplicationStatusUpdateHandlerImpl, k8sCapacityRouterImpl, webhookHelmRouterImpl, globalCMCSRouterImpl, userTerminalAccessRouterImpl, jobRouterImpl, ciStatusUpdateCronImpl, resourceGroupingRouterImpl, rbacRoleRouterImpl, scopedVariableRouterImpl, ciTriggerCronImpl, proxyRouterImpl) + muxRouter := router.NewMuxRouter(sugaredLogger, environmentRouterImpl, clusterRouterImpl, webhookRouterImpl, userAuthRouterImpl, gitProviderRouterImpl, gitHostRouterImpl, dockerRegRouterImpl, notificationRouterImpl, teamRouterImpl, gitWebhookHandlerImpl, workflowStatusUpdateHandlerImpl, applicationStatusHandlerImpl, ciEventHandlerImpl, pubSubClientServiceImpl, userRouterImpl, chartRefRouterImpl, configMapRouterImpl, appStoreRouterImpl, chartRepositoryRouterImpl, releaseMetricsRouterImpl, deploymentGroupRouterImpl, batchOperationRouterImpl, chartGroupRouterImpl, imageScanRouterImpl, policyRouterImpl, gitOpsConfigRouterImpl, dashboardRouterImpl, attributesRouterImpl, userAttributesRouterImpl, commonRouterImpl, grafanaRouterImpl, ssoLoginRouterImpl, telemetryRouterImpl, telemetryEventClientImplExtended, bulkUpdateRouterImpl, webhookListenerRouterImpl, appRouterImpl, coreAppRouterImpl, helmAppRouterImpl, k8sApplicationRouterImpl, pProfRouterImpl, deploymentConfigRouterImpl, dashboardTelemetryRouterImpl, commonDeploymentRouterImpl, externalLinkRouterImpl, globalPluginRouterImpl, moduleRouterImpl, serverRouterImpl, apiTokenRouterImpl, cdApplicationStatusUpdateHandlerImpl, k8sCapacityRouterImpl, webhookHelmRouterImpl, globalCMCSRouterImpl, userTerminalAccessRouterImpl, jobRouterImpl, ciStatusUpdateCronImpl, resourceGroupingRouterImpl, rbacRoleRouterImpl, scopedVariableRouterImpl, ciTriggerCronImpl, proxyRouterImpl) loggingMiddlewareImpl := util4.NewLoggingMiddlewareImpl(userServiceImpl) mainApp := NewApp(muxRouter, sugaredLogger, sseSSE, syncedEnforcer, db, pubSubClientServiceImpl, sessionManager, posthogClient, loggingMiddlewareImpl) return mainApp, nil