From 2f2c82f9ea6b49a1d142c510e56caf2ba7f3102c Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Fri, 22 Nov 2024 19:01:40 +0530 Subject: [PATCH 01/19] secret masking initial commit,all flow complete except prepare payload part --- Wire.go | 10 +- .../DeploymentConfigurationRestHandler.go | 56 +++- api/restHandler/app/configDiff/utils.go | 20 ++ .../configDiff}/DeploymentConfigRouter.go | 15 +- api/router/router.go | 9 +- .../DeploymentConfigurationService.go | 270 +++++++++++++++++- pkg/configDiff/bean/bean.go | 73 ++++- pkg/configDiff/utils/utils.go | 87 +++++- .../read/ConfigMapHistoryReadService.go | 25 +- .../DeploymentTemplateHistoryReadService.go | 10 + .../DeploymentTemplateHistoryRepository.go | 13 + wire_gen.go | 8 +- 12 files changed, 541 insertions(+), 55 deletions(-) rename api/restHandler/{ => app/configDiff}/DeploymentConfigurationRestHandler.go (69%) create mode 100644 api/restHandler/app/configDiff/utils.go rename api/router/{ => app/configDiff}/DeploymentConfigRouter.go (54%) diff --git a/Wire.go b/Wire.go index 6b0eb099f6..58656f514f 100644 --- a/Wire.go +++ b/Wire.go @@ -49,6 +49,7 @@ import ( "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" + configDiff2 "github.com/devtron-labs/devtron/api/restHandler/app/configDiff" 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" @@ -61,6 +62,7 @@ import ( 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" + configDiff3 "github.com/devtron-labs/devtron/api/router/app/configDiff" 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" @@ -702,10 +704,10 @@ func InitializeApp() (*App, error) { scopedVariable.NewScopedVariableRestHandlerImpl, wire.Bind(new(scopedVariable.ScopedVariableRestHandler), new(*scopedVariable.ScopedVariableRestHandlerImpl)), - router.NewDeploymentConfigurationRouter, - wire.Bind(new(router.DeploymentConfigurationRouter), new(*router.DeploymentConfigurationRouterImpl)), - restHandler.NewDeploymentConfigurationRestHandlerImpl, - wire.Bind(new(restHandler.DeploymentConfigurationRestHandler), new(*restHandler.DeploymentConfigurationRestHandlerImpl)), + configDiff3.NewDeploymentConfigurationRouter, + wire.Bind(new(configDiff3.DeploymentConfigurationRouter), new(*configDiff3.DeploymentConfigurationRouterImpl)), + configDiff2.NewDeploymentConfigurationRestHandlerImpl, + wire.Bind(new(configDiff2.DeploymentConfigurationRestHandler), new(*configDiff2.DeploymentConfigurationRestHandlerImpl)), configDiff.NewDeploymentConfigurationServiceImpl, wire.Bind(new(configDiff.DeploymentConfigurationService), new(*configDiff.DeploymentConfigurationServiceImpl)), diff --git a/api/restHandler/DeploymentConfigurationRestHandler.go b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go similarity index 69% rename from api/restHandler/DeploymentConfigurationRestHandler.go rename to api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go index 7a9f467629..9b1b106da8 100644 --- a/api/restHandler/DeploymentConfigurationRestHandler.go +++ b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go @@ -1,7 +1,8 @@ -package restHandler +package configDiff import ( "context" + "encoding/json" "fmt" "github.com/devtron-labs/devtron/api/restHandler/common" "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" @@ -10,6 +11,7 @@ import ( "github.com/devtron-labs/devtron/pkg/configDiff/bean" util2 "github.com/devtron-labs/devtron/util" "github.com/devtron-labs/devtron/util/rbac" + "github.com/gorilla/mux" "github.com/gorilla/schema" "go.uber.org/zap" "gopkg.in/go-playground/validator.v9" @@ -20,6 +22,7 @@ import ( type DeploymentConfigurationRestHandler interface { ConfigAutoComplete(w http.ResponseWriter, r *http.Request) GetConfigData(w http.ResponseWriter, r *http.Request) + CompareCategoryWiseConfigData(w http.ResponseWriter, r *http.Request) } type DeploymentConfigurationRestHandlerImpl struct { logger *zap.SugaredLogger @@ -143,3 +146,54 @@ func getConfigDataQueryParams(r *http.Request) (*bean.ConfigDataQueryParams, err return &queryParams, nil } + +func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfigData(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) + return + } + vars := mux.Vars(r) + configCategory := vars["category"] + var comparisonRequestDto bean.ComparisonRequestDto + err = json.NewDecoder(r.Body).Decode(&comparisonRequestDto) + if err != nil { + handler.logger.Errorw("error in decoding request body", "err", err) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + err = validateComparisonRequest(configCategory, comparisonRequestDto) + if err != nil { + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + + comparisonRequestDto.UpdateUserIdInComparisonItems(userId) + + //RBAC START + token := r.Header.Get(common.TokenHeaderKey) + object := handler.enforcerUtil.GetAppRBACName(comparisonRequestDto.AppName) + + ok := handler.enforcerUtil.CheckAppRbacForAppOrJob(token, object, casbin.ActionGet) + if !ok { + common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), nil, http.StatusForbidden) + return + } + //RBAC END + //isSuperAdmin is required to make decision if a sensitive data(as defined by super admin) needs to be redacted + //or not while resolving scope variable. + isSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*") + //userHasAdminAccess is required to mask secrets in the response after scope resolution. + userHasAdminAccess := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionUpdate, object) + + ctx := util2.SetSuperAdminInContext(r.Context(), isSuperAdmin) + res, err := handler.deploymentConfigurationService.CompareCategoryWiseConfigData(ctx, comparisonRequestDto, userHasAdminAccess) + if err != nil { + handler.logger.Errorw("service err, GetAllConfigData ", "err", err) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + //res.IsAppAdmin = handler.enforceForAppAndEnv(configDataQueryParams.AppName, configDataQueryParams.EnvName, token, casbin.ActionUpdate) + + common.WriteJsonResp(w, nil, res, http.StatusOK) +} diff --git a/api/restHandler/app/configDiff/utils.go b/api/restHandler/app/configDiff/utils.go new file mode 100644 index 0000000000..f4c21b47e7 --- /dev/null +++ b/api/restHandler/app/configDiff/utils.go @@ -0,0 +1,20 @@ +package configDiff + +import ( + "errors" + "github.com/devtron-labs/devtron/pkg/configDiff/bean" +) + +var validConfigCategories = map[string]bool{"secret": true, "cm": true, "dt": true, "ps": true} +var ErrInvalidConfigCategory = errors.New("invalid config category provided") +var ErrInvalidComparisonItems = errors.New("invalid comparison items, only 2 items are supported for comparison") + +func validateComparisonRequest(configCategory string, comparisonRequestDto bean.ComparisonRequestDto) error { + if ok := validConfigCategories[configCategory]; !ok { + return ErrInvalidConfigCategory + } + if len(comparisonRequestDto.ComparisonItems) > 2 { + return ErrInvalidComparisonItems + } + return nil +} diff --git a/api/router/DeploymentConfigRouter.go b/api/router/app/configDiff/DeploymentConfigRouter.go similarity index 54% rename from api/router/DeploymentConfigRouter.go rename to api/router/app/configDiff/DeploymentConfigRouter.go index a8a568d604..56d1816bc4 100644 --- a/api/router/DeploymentConfigRouter.go +++ b/api/router/app/configDiff/DeploymentConfigRouter.go @@ -1,31 +1,34 @@ -package router +package configDiff import ( - "github.com/devtron-labs/devtron/api/restHandler" + "github.com/devtron-labs/devtron/api/restHandler/app/configDiff" "github.com/gorilla/mux" ) type DeploymentConfigurationRouter interface { - initDeploymentConfigurationRouter(configRouter *mux.Router) + InitDeploymentConfigurationRouter(configRouter *mux.Router) } type DeploymentConfigurationRouterImpl struct { - deploymentGroupRestHandler restHandler.DeploymentConfigurationRestHandler + deploymentGroupRestHandler configDiff.DeploymentConfigurationRestHandler } -func NewDeploymentConfigurationRouter(deploymentGroupRestHandler restHandler.DeploymentConfigurationRestHandler) *DeploymentConfigurationRouterImpl { +func NewDeploymentConfigurationRouter(deploymentGroupRestHandler configDiff.DeploymentConfigurationRestHandler) *DeploymentConfigurationRouterImpl { router := &DeploymentConfigurationRouterImpl{ deploymentGroupRestHandler: deploymentGroupRestHandler, } return router } -func (router DeploymentConfigurationRouterImpl) initDeploymentConfigurationRouter(configRouter *mux.Router) { +func (router DeploymentConfigurationRouterImpl) InitDeploymentConfigurationRouter(configRouter *mux.Router) { configRouter.Path("/autocomplete"). HandlerFunc(router.deploymentGroupRestHandler.ConfigAutoComplete). Methods("GET") configRouter.Path("/data"). HandlerFunc(router.deploymentGroupRestHandler.GetConfigData). Methods("GET") + configRouter.Path("/compare/{category}"). + HandlerFunc(router.deploymentGroupRestHandler.CompareCategoryWiseConfigData). + Methods("GET") } diff --git a/api/router/router.go b/api/router/router.go index cbee85a928..6ae82ede50 100644 --- a/api/router/router.go +++ b/api/router/router.go @@ -39,6 +39,7 @@ import ( "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/app/configDiff" "github.com/devtron-labs/devtron/api/server" "github.com/devtron-labs/devtron/api/team" terminal2 "github.com/devtron-labs/devtron/api/terminal" @@ -114,7 +115,7 @@ type MuxRouter struct { rbacRoleRouter user.RbacRoleRouter scopedVariableRouter ScopedVariableRouter ciTriggerCron cron.CiTriggerCron - deploymentConfigurationRouter DeploymentConfigurationRouter + deploymentConfigurationRouter configDiff.DeploymentConfigurationRouter infraConfigRouter infraConfig.InfraConfigRouter argoApplicationRouter argoApplication.ArgoApplicationRouter fluxApplicationRouter fluxApplication2.FluxApplicationRouter @@ -147,12 +148,12 @@ func NewMuxRouter(logger *zap.SugaredLogger, scopedVariableRouter ScopedVariableRouter, ciTriggerCron cron.CiTriggerCron, proxyRouter proxy.ProxyRouter, - deploymentConfigurationRouter DeploymentConfigurationRouter, + deploymentConfigurationRouter configDiff.DeploymentConfigurationRouter, infraConfigRouter infraConfig.InfraConfigRouter, argoApplicationRouter argoApplication.ArgoApplicationRouter, devtronResourceRouter devtronResource.DevtronResourceRouter, fluxApplicationRouter fluxApplication2.FluxApplicationRouter, - ) *MuxRouter { +) *MuxRouter { r := &MuxRouter{ Router: mux.NewRouter(), EnvironmentClusterMappingsRouter: EnvironmentClusterMappingsRouter, @@ -298,7 +299,7 @@ func (r MuxRouter) Init() { configRouter := r.Router.PathPrefix("/orchestrator/config").Subrouter() r.ConfigMapRouter.initConfigMapRouter(configRouter) - r.deploymentConfigurationRouter.initDeploymentConfigurationRouter(configRouter) + r.deploymentConfigurationRouter.InitDeploymentConfigurationRouter(configRouter) appStoreRouter := r.Router.PathPrefix("/orchestrator/app-store").Subrouter() r.AppStoreRouter.Init(appStoreRouter) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 6e671bac09..38a4479760 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -39,6 +39,7 @@ import ( type DeploymentConfigurationService interface { ConfigAutoComplete(appId int, envId int) (*bean2.ConfigDataResponse, error) GetAllConfigData(ctx context.Context, configDataQueryParams *bean2.ConfigDataQueryParams, userHasAdminAccess bool) (*bean2.DeploymentAndCmCsConfigDto, error) + CompareCategoryWiseConfigData(ctx context.Context, comparisonRequestDto bean2.ComparisonRequestDto, userHasAdminAccess bool) (*bean2.ComparisonResponseDto, error) } type DeploymentConfigurationServiceImpl struct { @@ -320,9 +321,8 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsConfigHistory(ctx context } if configType == repository3.SECRET_TYPE { - impl.encodeSecretDataFromNonAdminUsers(configData, userHasAdminAccess) - impl.encodeSecretDataFromNonAdminUsers(resolvedConfigDataList, userHasAdminAccess) - + impl.encodeSecretDataFromNonAdminUsers(configData, userHasAdminAccess, bean2.SecretMaskedValue) + impl.encodeSecretDataFromNonAdminUsers(resolvedConfigDataList, userHasAdminAccess, bean2.SecretMaskedValue) } configDataReq := &bean.ConfigDataRequest{ConfigData: configData} @@ -350,7 +350,7 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsConfigHistory(ctx context return cmConfigData, nil } -func (impl *DeploymentConfigurationServiceImpl) encodeSecretDataFromNonAdminUsers(configDataList []*bean.ConfigData, userHasAdminAccess bool) { +func (impl *DeploymentConfigurationServiceImpl) encodeSecretDataFromNonAdminUsers(configDataList []*bean.ConfigData, userHasAdminAccess bool, secretMaskedValue string) { for _, config := range configDataList { if config.Data != nil { if !userHasAdminAccess { @@ -364,7 +364,7 @@ func (impl *DeploymentConfigurationServiceImpl) encodeSecretDataFromNonAdminUser } for key, _ := range resultMap { //hard-coding values to show them as hidden to user - resultMapFinal[key] = bean2.SecretMaskedValue + resultMapFinal[key] = secretMaskedValue } config.Data, err = utils.ConvertToJsonRawMessage(resultMapFinal) if err != nil { @@ -385,8 +385,13 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsDataForPreviousDeployment impl.logger.Errorw("error in getting deployment template history", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) return nil, err } + secretConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, repository3.SECRET_TYPE, userHasAdminAccess) + if err != nil { + impl.logger.Errorw("error in getting secretData and cmData", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) + return nil, err + } - secretConfigData, cmConfigData, err := impl.configMapHistoryReadService.GetConfigmapHistoryDataByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, userHasAdminAccess) + cmConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, repository3.CONFIGMAP_TYPE, userHasAdminAccess) if err != nil { impl.logger.Errorw("error in getting secretData and cmData", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) return nil, err @@ -746,7 +751,7 @@ func (impl *DeploymentConfigurationServiceImpl) getStringifiedCmCs(resolvedCmMap resolvedSecretDataList = append(resolvedSecretDataList, adapter.ConvertConfigDataToPipelineConfigData(resolvedSecretData)) } if len(resolvedSecretMap) > 0 { - impl.encodeSecretDataFromNonAdminUsers(resolvedSecretDataList, userHasAdminAccess) + impl.encodeSecretDataFromNonAdminUsers(resolvedSecretDataList, userHasAdminAccess, bean2.SecretMaskedValue) } resolvedConfigDataReq := &bean.ConfigDataRequest{ConfigData: resolvedConfigDataList} resolvedConfigDataString, err := utils.ConvertToString(resolvedConfigDataReq) @@ -925,3 +930,254 @@ func (impl *DeploymentConfigurationServiceImpl) getConfigMapResponse(resourceNam } return impl.configMapService.CMGlobalFetch(appId) } + +func (impl *DeploymentConfigurationServiceImpl) CompareCategoryWiseConfigData(ctx context.Context, comparisonRequestDto bean2.ComparisonRequestDto, userHasAdminAccess bool) (*bean2.ComparisonResponseDto, error) { + allSecretConfigDto := make([]*bean2.DeploymentAndCmCsConfigDto, 0) + indexVsSecretConfigMetadata := make(map[int]*bean2.SecretConfigMetadata, len(comparisonRequestDto.ComparisonItems)) + allComparisonSecretsMetadata := make([]*bean2.SecretConfigMetadata, 0, len(comparisonRequestDto.ComparisonItems)) + for _, comparisonItem := range comparisonRequestDto.ComparisonItems { + secretConfigMetadata, err := impl.getSingleSecretConfigForComparison(ctx, comparisonItem) + if err != nil { + impl.logger.Errorw("error in getting single secret config for comparison", "comparisonItem", comparisonItem, "err", err) + return nil, err + } + //secretConfigDto.Index = comparisonItem.Index + if _, ok := indexVsSecretConfigMetadata[comparisonItem.Index]; !ok { + indexVsSecretConfigMetadata[comparisonItem.Index] = secretConfigMetadata + } + allComparisonSecretsMetadata = append(allComparisonSecretsMetadata, secretConfigMetadata) + } + if !userHasAdminAccess { + // compare secrets data and mask if necessary + err := impl.CompareSecretDataAndMaskIfNecessary(allComparisonSecretsMetadata) + if err != nil { + impl.logger.Errorw("error in comparing secret and masking if necessary", "err", err) + return nil, err + } + } + + //prepare response + + return bean2.DefaultComparisonResponseDto().WithComparisonItemResponse(allSecretConfigDto), nil +} + +func (impl *DeploymentConfigurationServiceImpl) prepareKeyValMapForSingleSecretAndMaskValue(secretMetadata *bean2.SecretConfigMetadata) (map[string]map[string]string, map[string]map[string]string, error) { + + keyValMapForSecretConfig, err := utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretsList.ConfigData) + if err != nil { + impl.logger.Errorw("error in getting key val map for SecretsList's config data with masking", "err", err) + return nil, nil, err + } + keyValMapForResolvedSecretConfig := make(map[string]map[string]string) + if len(secretMetadata.SecretScopeVariableMetadata.VariableSnapShot) > 0 { + //scope variable is used so mask scope variable secret data also + keyValMapForResolvedSecretConfig, err = utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretScopeVariableMetadata.ResolvedConfigData) + if err != nil { + impl.logger.Errorw("error in getting key val map for resolved config data with masking", "err", err) + return nil, nil, err + } + } + + return keyValMapForSecretConfig, keyValMapForResolvedSecretConfig, nil +} + +func (impl *DeploymentConfigurationServiceImpl) compareAndMaskOtherComparableSecretValues(secretMetadata2 *bean2.SecretConfigMetadata, keyValMapForSecretConfig1 map[string]map[string]string, + keyValMapForResolvedSecretConfig1 map[string]map[string]string) error { + + err := utils.CompareAndMaskSecretValuesInConfigData(secretMetadata2.SecretsList.ConfigData, keyValMapForSecretConfig1) + if err != nil { + impl.logger.Errorw("error in comparing and masking secretsList's secret values ", "err", err) + return err + } + if len(secretMetadata2.SecretScopeVariableMetadata.VariableSnapShot) > 0 { + err = utils.CompareAndMaskSecretValuesInConfigData(secretMetadata2.SecretScopeVariableMetadata.ResolvedConfigData, keyValMapForResolvedSecretConfig1) + if err != nil { + impl.logger.Errorw("error in comparing and masking resolvedConfigData's secret values ", "err", err) + return err + } + } + return nil +} + +func (impl *DeploymentConfigurationServiceImpl) CompareSecretDataAndMaskIfNecessary(comparisonItems []*bean2.SecretConfigMetadata) error { + if len(comparisonItems) > 1 { + secretMetadata1 := comparisonItems[0] + keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1, err := impl.prepareKeyValMapForSingleSecretAndMaskValue(secretMetadata1) + if err != nil { + impl.logger.Errorw("error in preparing key val map for secret and mask the values", "err", err) + return err + } + secretMetadata2 := comparisonItems[1] + err = impl.compareAndMaskOtherComparableSecretValues(secretMetadata2, keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1) + if err != nil { + impl.logger.Errorw("error in comparing and masking other secret's value", "err", err) + return err + } + + } + return nil +} + +func (impl *DeploymentConfigurationServiceImpl) getAppEnvClusterAndSystemMetadata(comparisonItem *bean2.ComparisonItemRequestDto) (*bean2.AppEnvAndClusterMetadata, *resourceQualifiers.SystemMetadata, error) { + var err error + var envId, appId, clusterId int + systemMetadata := &resourceQualifiers.SystemMetadata{ + AppName: comparisonItem.AppName, + } + if len(comparisonItem.EnvName) > 0 { + env, err := impl.environmentRepository.FindEnvByNameWithClusterDetails(comparisonItem.EnvName) + if err != nil { + impl.logger.Errorw("error in getting environment model by envName", "envName", comparisonItem.EnvName, "err", err) + return nil, nil, err + } + envId = env.Id + clusterId = env.ClusterId + systemMetadata.EnvironmentName = env.Name + systemMetadata.Namespace = env.Namespace + systemMetadata.ClusterName = env.Cluster.ClusterName + } + appId, err = impl.appRepository.FindAppIdByName(comparisonItem.AppName) + if err != nil { + impl.logger.Errorw("error in getting app model by appName", "appName", comparisonItem.AppName, "err", err) + return nil, nil, err + } + return &bean2.AppEnvAndClusterMetadata{AppId: appId, EnvId: envId, ClusterId: clusterId}, systemMetadata, nil +} + +func (impl *DeploymentConfigurationServiceImpl) getSingleSecretConfigForComparison(ctx context.Context, comparisonItemRequest *bean2.ComparisonItemRequestDto) (*bean2.SecretConfigMetadata, error) { + appEnvAndClusterMetadata, systemMetadata, err := impl.getAppEnvClusterAndSystemMetadata(comparisonItemRequest) + if err != nil { + impl.logger.Errorw("error in getting app, env, cluster and systemMetadata", "comparisonItemRequest", comparisonItemRequest, "err", err) + return nil, err + } + switch comparisonItemRequest.ConfigArea { + case bean2.CdRollback.ToString(), bean2.DeploymentHistory.ToString(): + return impl.getHistoricalSecretData(ctx, comparisonItemRequest) + } + // this would be the default case + return impl.getSingleSecretDataForAppConfiguration(ctx, comparisonItemRequest, appEnvAndClusterMetadata, systemMetadata) +} + +func (impl *DeploymentConfigurationServiceImpl) getHistoricalSecretData(ctx context.Context, comparisonItem *bean2.ComparisonItemRequestDto) (*bean2.SecretConfigMetadata, error) { + // wfrId is expected in this case to return the expected data + if comparisonItem.WfrId == 0 { + return nil, &util.ApiError{HttpStatusCode: http.StatusNotFound, Code: strconv.Itoa(http.StatusNotFound), InternalMessage: bean2.ExpectedWfrIdNotPassedInQueryParamErr, UserMessage: bean2.ExpectedWfrIdNotPassedInQueryParamErr} + } + secretsList, resolvedSecretsData, err := impl.getSingleSecretDataForPreviousDeployments(ctx, comparisonItem.ConfigDataQueryParams) + if err != nil { + impl.logger.Errorw("error in getting historical data for secret", "comparisonDataPayload", comparisonItem.ConfigDataQueryParams, "err", err) + return nil, err + } + secretConfigMetadata := &bean2.SecretConfigMetadata{ + SecretsList: secretsList, + SecretScopeVariableMetadata: resolvedSecretsData, + } + return secretConfigMetadata, nil +} + +func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForAppConfiguration(ctx context.Context, comparisonItem *bean2.ComparisonItemRequestDto, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, + systemMetadata *resourceQualifiers.SystemMetadata) (*bean2.SecretConfigMetadata, error) { + var secretConfigMetadata *bean2.SecretConfigMetadata + var err error + switch comparisonItem.ConfigType { + case bean2.PreviousDeployments.ToString(): + secretConfigMetadata, err = impl.getHistoricalSecretData(ctx, comparisonItem) + if err != nil { + impl.logger.Errorw("error in config data for Previous Deployments", "comparisonDataPayload", comparisonItem.ConfigDataQueryParams, "err", err) + return nil, err + } + default: // keeping default as PublishedOnly + secretConfigMetadata, err = impl.getSingleSecretDataForPublishedOnly(ctx, appEnvAndClusterMetadata, systemMetadata) + if err != nil { + impl.logger.Errorw("error in config data for PublishedOnly", "comparisonDataPayload", comparisonItem.ConfigDataQueryParams, "err", err) + return nil, err + } + } + return secretConfigMetadata, nil +} + +func (impl *DeploymentConfigurationServiceImpl) getHistoryAndSecretsListForPreviousDeployments(wfrId, pipelineId int) (*bean.SecretsList, *repository3.ConfigmapAndSecretHistory, error) { + history, err := impl.configMapHistoryRepository.GetHistoryByPipelineIdAndWfrId(pipelineId, wfrId, repository3.SECRET_TYPE) + if err != nil { + impl.logger.Errorw("error in getting if cs history exists for pipelineId and wfrId", "pipelineId", pipelineId, "wfrId", wfrId, "err", err) + return nil, nil, err + } + _, secretsList, err := impl.configMapHistoryReadService.GetCmCsListObjectFromHistory(history) + if err != nil { + impl.logger.Errorw("error in getting config data request for history", "err", err) + return nil, nil, err + } + return secretsList, history, nil +} + +func (impl *DeploymentConfigurationServiceImpl) getResolvedSecretDataForPreviousDeployments(ctx context.Context, secretsList *bean.SecretsList, history *repository3.ConfigmapAndSecretHistory) (*bean2.CmCsScopeVariableMetadata, error) { + resolvedDataMap, variableSnapshotMap, err := impl.scopedVariableManager.GetResolvedCMCSHistoryDtos(ctx, repository3.SECRET_TYPE, bean3.ConfigList{}, history, adaptor.ReverseSecretListConvertor(*secretsList)) + if err != nil { + impl.logger.Errorw("error in GetResolvedCMCSHistoryDtos, resolving cm cs historical data", "err", err) + return nil, err + } + resolvedConfigDataList := make([]*bean.ConfigData, 0, len(resolvedDataMap)) + for _, resolvedConfigData := range resolvedDataMap { + resolvedConfigDataList = append(resolvedConfigDataList, adapter.ConvertConfigDataToPipelineConfigData(&resolvedConfigData)) + } + return &bean2.CmCsScopeVariableMetadata{ResolvedConfigData: resolvedConfigDataList, VariableSnapShot: variableSnapshotMap}, nil +} + +func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForPreviousDeployments(ctx context.Context, comparisonItemRequest *bean2.ConfigDataQueryParams) (*bean.SecretsList, *bean2.CmCsScopeVariableMetadata, error) { + secretsList, history, err := impl.getHistoryAndSecretsListForPreviousDeployments(comparisonItemRequest.WfrId, comparisonItemRequest.PipelineId) + if err != nil { + impl.logger.Errorw("error in getting history object and secret list for history", "wfrId", comparisonItemRequest.WfrId, "pipelineId", comparisonItemRequest.PipelineId, "err", err) + return nil, nil, err + } + resolvedSecretData, err := impl.getResolvedSecretDataForPreviousDeployments(ctx, secretsList, history) + if err != nil { + impl.logger.Errorw("error in getResolvedSecretDataPreviousDeployments, resolving cm cs historical data", "err", err) + return nil, nil, err + } + return secretsList, resolvedSecretData, nil +} + +func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForPublishedOnly(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, + systemMetadata *resourceQualifiers.SystemMetadata) (*bean2.SecretConfigMetadata, error) { + secretData, err := impl.getSecretConfigResponse("", 0, appEnvAndClusterMetadata.EnvId, appEnvAndClusterMetadata.AppId) + if err != nil { + impl.logger.Errorw("getCmCsPublishedConfigResponse, error in getting secret config response by appId and envId", "appId", appEnvAndClusterMetadata.AppId, "envId", appEnvAndClusterMetadata.EnvId, "err", err) + return nil, err + } + resolvedSecretData, err := impl.getResolvedSecretDataForPublishedOnly(ctx, appEnvAndClusterMetadata, systemMetadata) + if err != nil { + impl.logger.Errorw("error in getResolvedSecretDataPreviousDeployments, resolving cm cs historical data", "err", err) + return nil, err + } + secretConfigMetadata := &bean2.SecretConfigMetadata{ + SecretsList: &bean.SecretsList{ConfigData: secretData.ConfigData}, + SecretScopeVariableMetadata: resolvedSecretData, + } + return secretConfigMetadata, nil +} + +func (impl *DeploymentConfigurationServiceImpl) getResolvedSecretDataForPublishedOnly(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, + systemMetadata *resourceQualifiers.SystemMetadata) (*bean2.CmCsScopeVariableMetadata, error) { + scope := resourceQualifiers.Scope{ + AppId: appEnvAndClusterMetadata.AppId, + EnvId: appEnvAndClusterMetadata.EnvId, + ClusterId: appEnvAndClusterMetadata.ClusterId, + SystemMetadata: systemMetadata, + } + cmcsMetadataDto, err := impl.getMergedCmCs(appEnvAndClusterMetadata.EnvId, appEnvAndClusterMetadata.AppId) + if err != nil { + impl.logger.Errorw("error in getting merged cm cs", "appId", appEnvAndClusterMetadata.AppId, "envId", appEnvAndClusterMetadata.EnvId, "err", err) + return nil, err + } + _, resolvedSecretList, _, variableMapCS, err := impl.scopedVariableManager.ResolveCMCS(ctx, scope, cmcsMetadataDto.ConfigAppLevelId, cmcsMetadataDto.ConfigEnvLevelId, cmcsMetadataDto.CmMap, cmcsMetadataDto.SecretMap) + if err != nil { + impl.logger.Errorw("error in resolving CM/CS", "scope", scope, "appId", appEnvAndClusterMetadata.AppId, "envId", appEnvAndClusterMetadata.EnvId, "err", err) + return nil, err + } + + resolvedSecretDataList := make([]*bean.ConfigData, 0, len(resolvedSecretList)) + for _, resolvedSecret := range resolvedSecretList { + resolvedSecretDataList = append(resolvedSecretDataList, adapter.ConvertConfigDataToPipelineConfigData(resolvedSecret)) + } + return &bean2.CmCsScopeVariableMetadata{ResolvedConfigData: resolvedSecretDataList, VariableSnapShot: variableMapCS}, nil +} diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index da4905e29c..c1e89e2198 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -142,6 +142,7 @@ type DeploymentAndCmCsConfigDto struct { SecretsData *DeploymentAndCmCsConfig `json:"secretsData"` PipelineConfigData *DeploymentAndCmCsConfig `json:"pipelineConfigData,omitempty"` IsAppAdmin bool `json:"isAppAdmin"` + Index int `json:"index"` } func NewDeploymentAndCmCsConfigDto() *DeploymentAndCmCsConfigDto { @@ -166,22 +167,19 @@ func (r *DeploymentAndCmCsConfigDto) WithPipelineConfigData(data *DeploymentAndC } type ConfigDataQueryParams struct { - AppName string `schema:"appName"` - EnvName string `schema:"envName"` - ConfigType string `schema:"configType"` - IdentifierId int `schema:"identifierId"` - PipelineId int `schema:"pipelineId"` // req for fetching previous deployments data - ResourceName string `schema:"resourceName"` // used in case of cm and cs - ResourceType string `schema:"resourceType"` // used in case of cm and cs - ResourceId int `schema:"resourceId"` // used in case of cm and cs + AppName string `schema:"appName" json:"appName"` + EnvName string `schema:"envName" json:"envName"` + ConfigType string `schema:"configType" json:"configType"` + IdentifierId int `schema:"identifierId" json:"identifierId"` + PipelineId int `schema:"pipelineId" json:"pipelineId"` // req for fetching previous deployments data + ResourceName string `schema:"resourceName" json:"resourceName"` // used in case of cm and cs + ResourceType string `schema:"resourceType" json:"resourceType"` // used in case of cm and cs + ResourceId int `schema:"resourceId" json:"resourceId"` // used in case of cm and cs UserId int32 `schema:"-"` - WfrId int `schema:"wfrId"` - ConfigArea string `schema:"configArea"` + WfrId int `schema:"wfrId" json:"wfrId"` + ConfigArea string `schema:"configArea" json:"configArea"` } -// FilterCriteria []string `schema:"filterCriteria"` -// OffSet int `schema:"offSet"` -// Limit int `schema:"limit"` func (r *ConfigDataQueryParams) IsResourceTypeSecret() bool { return r.ResourceType == bean.CS.ToString() } @@ -232,5 +230,52 @@ type DeploymentTemplateMetadata struct { const ( NoDeploymentDoneForSelectedImage = "there were no deployments done for the selected image" ExpectedWfrIdNotPassedInQueryParamErr = "wfrId is expected in the query param which was not passed" - SecretMaskedValue = "*****" + SecretMaskedValue = "********" + SecretMaskedValueLong = "************" ) + +type ComparisonItemRequestDto struct { + Index int `json:"index"` + *ConfigDataQueryParams +} + +type ComparisonRequestDto struct { + AppName string `json:"appName"` + EnvName string `json:"envName"` + ComparisonItems []*ComparisonItemRequestDto `json:"comparisonItems"` // comparisonItems contains array of objects that a user wants to compare +} + +// revisit this maybe we can extract userId out in ComparisonRequestDto, +func (r *ComparisonRequestDto) UpdateUserIdInComparisonItems(userId int32) { + for _, item := range r.ComparisonItems { + item.UserId = userId + } +} + +type ComparisonResponseDto struct { + ComparisonItemResponse []*DeploymentAndCmCsConfigDto `json:"comparisonItemResponse"` +} + +func DefaultComparisonResponseDto() *ComparisonResponseDto { + return &ComparisonResponseDto{ComparisonItemResponse: make([]*DeploymentAndCmCsConfigDto, 0)} +} +func (r *ComparisonResponseDto) WithComparisonItemResponse(comparisonItemResponse []*DeploymentAndCmCsConfigDto) *ComparisonResponseDto { + r.ComparisonItemResponse = comparisonItemResponse + return r +} + +type AppEnvAndClusterMetadata struct { + AppId int + EnvId int + ClusterId int +} + +type CmCsScopeVariableMetadata struct { + ResolvedConfigData []*bean.ConfigData + VariableSnapShot map[string]map[string]string +} + +type SecretConfigMetadata struct { + SecretsList *bean.SecretsList + SecretScopeVariableMetadata *CmCsScopeVariableMetadata +} diff --git a/pkg/configDiff/utils/utils.go b/pkg/configDiff/utils/utils.go index 62d1272c31..0b826de390 100644 --- a/pkg/configDiff/utils/utils.go +++ b/pkg/configDiff/utils/utils.go @@ -1,6 +1,11 @@ package utils -import "encoding/json" +import ( + "encoding/json" + bean2 "github.com/devtron-labs/devtron/pkg/configDiff/bean" + "github.com/devtron-labs/devtron/pkg/pipeline/bean" + "strings" +) func ConvertToJsonRawMessage(request interface{}) (json.RawMessage, error) { var r json.RawMessage @@ -22,3 +27,83 @@ func ConvertToString(req interface{}) (string, error) { } return string(reqByte), nil } + +/* +GetKeyValMapForSecretConfigDataAndMaskData +1. unmarshall secret data +2. prepare secret's key val map +3. create new masked secret data and replace to original data +*/ +func GetKeyValMapForSecretConfigDataAndMaskData(configDataList []*bean.ConfigData) (map[string]map[string]string, error) { + keyValMapForSecretConfig := make(map[string]map[string]string) + for _, secretConfigData := range configDataList { + if secretConfigData.IsESOExternalSecretType() || secretConfigData.External { + continue + } + var secretData map[string]string + if err := json.Unmarshal(secretConfigData.Data, &secretData); err != nil { + return nil, err + } + newMaskedSecretData := make(map[string]string, len(secretData)) + for key, val := range secretData { + keyValMapForSecretConfig[secretConfigData.Name][key] = val + newMaskedSecretData[key] = bean2.SecretMaskedValue + } + maskedSecretJson, err := json.Marshal(newMaskedSecretData) + if err != nil { + return nil, err + } + secretConfigData.Data = maskedSecretJson + } + return keyValMapForSecretConfig, nil +} + +/* +CompareAndMaskSecretValuesInConfigData +1.unmarshall secrets data +2. mask secret values based on some checks +3. marshall masked secret and replace original configData +*/ +func CompareAndMaskSecretValuesInConfigData(configDataList []*bean.ConfigData, keyValMapForSecretConfig1 map[string]map[string]string) error { + for _, secretConfigData := range configDataList { + if secretConfigData.IsESOExternalSecretType() || secretConfigData.External { + continue + } + var secretDataMap map[string]string + if err := json.Unmarshal(secretConfigData.Data, &secretDataMap); err != nil { + return err + } + if _, ok := keyValMapForSecretConfig1[secretConfigData.Name]; ok { + newMaskedSecretData := make(map[string]string, len(secretDataMap)) + for key, val := range secretDataMap { + if val1, ok := keyValMapForSecretConfig1[secretConfigData.Name][key]; ok { + if strings.Compare(val, val1) == 0 { + newMaskedSecretData[key] = bean2.SecretMaskedValue + } else { + //same key name exists with diff value, mask this with SecretMaskedValueLong (i.e. "************") + newMaskedSecretData[key] = bean2.SecretMaskedValueLong + } + } else { + newMaskedSecretData[key] = bean2.SecretMaskedValue + } + } + maskedSecretJson, err := json.Marshal(newMaskedSecretData) + if err != nil { + return err + } + secretConfigData.Data = maskedSecretJson + } else { + //mask all the secret values with SecretMaskedValue(i.e. "********") + newMaskedSecretData := make(map[string]string, len(secretDataMap)) + for key, _ := range secretDataMap { + newMaskedSecretData[key] = bean2.SecretMaskedValue + } + maskedSecretJson, err := json.Marshal(newMaskedSecretData) + if err != nil { + return err + } + secretConfigData.Data = maskedSecretJson + } + } + return nil +} diff --git a/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go b/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go index 6f981eabd9..c42ac1aec4 100644 --- a/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go +++ b/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go @@ -26,7 +26,8 @@ type ConfigMapHistoryReadService interface { CheckIfTriggerHistoryExistsForPipelineIdOnTime(pipelineId int, deployedOn time.Time) (cmId int, csId int, exists bool, err error) GetDeployedHistoryDetailForCMCSByPipelineIdAndWfrId(ctx context.Context, pipelineId, wfrId int, configType repository.ConfigType, userHasAdminAccess bool) ([]*bean.ComponentLevelHistoryDetailDto, error) ConvertConfigDataToComponentLevelDto(config *bean2.ConfigData, configType repository.ConfigType, userHasAdminAccess bool) (*bean.ComponentLevelHistoryDetailDto, error) - GetConfigmapHistoryDataByDeployedOnAndPipelineId(ctx context.Context, pipelineId int, deployedOn time.Time, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, *bean3.DeploymentAndCmCsConfig, error) + GetCmCsHistoryByDeployedOnAndPipelineId(ctx context.Context, pipelineId int, deployedOn time.Time, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) + GetCmCsListObjectFromHistory(history *repository.ConfigmapAndSecretHistory) (*bean4.ConfigsList, *bean4.SecretsList, error) } type ConfigMapHistoryReadServiceImpl struct { @@ -363,19 +364,13 @@ func (impl *ConfigMapHistoryReadServiceImpl) ConvertConfigDataToComponentLevelDt return componentLevelData, nil } -func (impl *ConfigMapHistoryReadServiceImpl) GetConfigmapHistoryDataByDeployedOnAndPipelineId(ctx context.Context, pipelineId int, deployedOn time.Time, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, *bean3.DeploymentAndCmCsConfig, error) { - secretConfigData, err := impl.getResolvedConfigData(ctx, pipelineId, deployedOn, repository.SECRET_TYPE, userHasAdminAccess) +func (impl *ConfigMapHistoryReadServiceImpl) GetCmCsHistoryByDeployedOnAndPipelineId(ctx context.Context, pipelineId int, deployedOn time.Time, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) { + configData, err := impl.getResolvedConfigData(ctx, pipelineId, deployedOn, configType, userHasAdminAccess) if err != nil { - impl.logger.Errorw("error in getting resolved secret config data in case of previous deployments ", "pipelineId", pipelineId, "deployedOn", deployedOn, "err", err) - return nil, nil, err - } - cmConfigData, err := impl.getResolvedConfigData(ctx, pipelineId, deployedOn, repository.CONFIGMAP_TYPE, userHasAdminAccess) - if err != nil { - impl.logger.Errorw("error in getting resolved cm config data in case of previous deployments ", "pipelineId", pipelineId, "deployedOn", deployedOn, "err", err) - return nil, nil, err + impl.logger.Errorw("error in getting resolved secret/cm config data in case of previous deployments ", "pipelineId", pipelineId, "deployedOn", deployedOn, "err", err) + return nil, err } - - return secretConfigData, cmConfigData, nil + return configData, nil } func (impl *ConfigMapHistoryReadServiceImpl) getResolvedConfigData(ctx context.Context, pipelineId int, deployedOn time.Time, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) { @@ -388,13 +383,13 @@ func (impl *ConfigMapHistoryReadServiceImpl) getResolvedConfigData(ctx context.C return nil, err } if configType == repository.SECRET_TYPE { - _, secretsList, err = impl.getConfigDataRequestForHistory(history) + _, secretsList, err = impl.GetCmCsListObjectFromHistory(history) if err != nil { impl.logger.Errorw("error in getting config data request for history", "err", err) return nil, err } } else if configType == repository.CONFIGMAP_TYPE { - configsList, _, err = impl.getConfigDataRequestForHistory(history) + configsList, _, err = impl.GetCmCsListObjectFromHistory(history) if err != nil { impl.logger.Errorw("error in getting config data request for history", "cmCsHistory", history, "err", err) return nil, err @@ -467,7 +462,7 @@ func (impl *ConfigMapHistoryReadServiceImpl) encodeSecretDataFromNonAdminUsers(c } } -func (impl *ConfigMapHistoryReadServiceImpl) getConfigDataRequestForHistory(history *repository.ConfigmapAndSecretHistory) (*bean4.ConfigsList, *bean4.SecretsList, error) { +func (impl *ConfigMapHistoryReadServiceImpl) GetCmCsListObjectFromHistory(history *repository.ConfigmapAndSecretHistory) (*bean4.ConfigsList, *bean4.SecretsList, error) { configsList := &bean4.ConfigsList{} secretsList := &bean4.SecretsList{} diff --git a/pkg/deployment/manifest/deploymentTemplate/read/DeploymentTemplateHistoryReadService.go b/pkg/deployment/manifest/deploymentTemplate/read/DeploymentTemplateHistoryReadService.go index e823341781..bc4953e339 100644 --- a/pkg/deployment/manifest/deploymentTemplate/read/DeploymentTemplateHistoryReadService.go +++ b/pkg/deployment/manifest/deploymentTemplate/read/DeploymentTemplateHistoryReadService.go @@ -24,6 +24,7 @@ type DeploymentTemplateHistoryReadService interface { GetDeployedHistoryByPipelineIdAndWfrId(ctx context.Context, pipelineId, wfrId int) (*bean.HistoryDetailDto, error) GetTemplateHistoryModelForDeployedTemplateById(deploymentTemplateHistoryId, pipelineId int) (*repository2.DeploymentTemplateHistory, error) + GetDeployedOnByDeploymentTemplateAndPipelineId(deploymentTemplateHistoryId, pipelineId int) (time.Time, error) } type DeploymentTemplateHistoryReadServiceImpl struct { @@ -148,3 +149,12 @@ func (impl *DeploymentTemplateHistoryReadServiceImpl) GetDeployedHistoryList(pip } return historyList, nil } + +func (impl *DeploymentTemplateHistoryReadServiceImpl) GetDeployedOnByDeploymentTemplateAndPipelineId(deploymentTemplateHistoryId, pipelineId int) (time.Time, error) { + deployedOn, err := impl.deploymentTemplateHistoryRepository.GetDeployedOnByDeploymentTemplateAndPipelineId(deploymentTemplateHistoryId, pipelineId) + if err != nil { + impl.logger.Errorw("error in getting deployment template history", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) + return deployedOn, err + } + return deployedOn, nil +} diff --git a/pkg/pipeline/history/repository/DeploymentTemplateHistoryRepository.go b/pkg/pipeline/history/repository/DeploymentTemplateHistoryRepository.go index 1ce547851c..097ae24931 100644 --- a/pkg/pipeline/history/repository/DeploymentTemplateHistoryRepository.go +++ b/pkg/pipeline/history/repository/DeploymentTemplateHistoryRepository.go @@ -30,6 +30,7 @@ type DeploymentTemplateHistoryRepository interface { GetHistoryByPipelineIdAndWfrId(pipelineId, wfrId int) (*DeploymentTemplateHistory, error) GetDeployedHistoryForPipelineIdOnTime(pipelineId int, deployedOn time.Time) (*DeploymentTemplateHistory, error) GetDeployedHistoryList(pipelineId, baseConfigId int) ([]*DeploymentTemplateHistory, error) + GetDeployedOnByDeploymentTemplateAndPipelineId(id, pipelineId int) (time.Time, error) } type DeploymentTemplateHistoryRepositoryImpl struct { @@ -130,3 +131,15 @@ func (impl DeploymentTemplateHistoryRepositoryImpl) GetDeployedHistoryForPipelin Select() return &history, err } + +func (impl DeploymentTemplateHistoryRepositoryImpl) GetDeployedOnByDeploymentTemplateAndPipelineId(id, pipelineId int) (time.Time, error) { + var deployedOn time.Time + err := impl.dbConnection.Model((*DeploymentTemplateHistory)(nil)).Column("deployed_on").Where("id = ?", id). + Where("pipeline_id = ?", pipelineId). + Where("deployed = ?", true).Select(&deployedOn) + if err != nil { + impl.logger.Errorw("error in getting deployed on by deploymentTemplateHistoryId and pipelineId", "err", err) + return time.Time{}, err + } + return deployedOn, nil +} diff --git a/wire_gen.go b/wire_gen.go index c4b9161032..724b3bc7df 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run -mod=mod github.com/google/wire/cmd/wire +//go:generate go run github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject @@ -43,6 +43,7 @@ import ( "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" + configDiff2 "github.com/devtron-labs/devtron/api/restHandler/app/configDiff" pipeline3 "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" @@ -55,6 +56,7 @@ import ( 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" + configDiff3 "github.com/devtron-labs/devtron/api/router/app/configDiff" pipeline4 "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" @@ -987,8 +989,8 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - deploymentConfigurationRestHandlerImpl := restHandler.NewDeploymentConfigurationRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerUtilImpl, deploymentConfigurationServiceImpl, enforcerImpl) - deploymentConfigurationRouterImpl := router.NewDeploymentConfigurationRouter(deploymentConfigurationRestHandlerImpl) + deploymentConfigurationRestHandlerImpl := configDiff2.NewDeploymentConfigurationRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerUtilImpl, deploymentConfigurationServiceImpl, enforcerImpl) + deploymentConfigurationRouterImpl := configDiff3.NewDeploymentConfigurationRouter(deploymentConfigurationRestHandlerImpl) infraConfigRestHandlerImpl := infraConfig2.NewInfraConfigRestHandlerImpl(sugaredLogger, infraConfigServiceImpl, userServiceImpl, enforcerImpl, enforcerUtilImpl, validate) infraConfigRouterImpl := infraConfig2.NewInfraProfileRouterImpl(infraConfigRestHandlerImpl) argoApplicationRestHandlerImpl := argoApplication2.NewArgoApplicationRestHandlerImpl(argoApplicationServiceExtendedImpl, argoApplicationReadServiceImpl, sugaredLogger, enforcerImpl) From 0204f3c55935fa1f51b433f5da58ffff9a44b29e Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Fri, 22 Nov 2024 19:27:38 +0530 Subject: [PATCH 02/19] prepare final response with index in CompareCategoryWiseConfigData service func --- .../DeploymentConfigurationService.go | 39 +++++++++++++++++-- pkg/configDiff/bean/bean.go | 4 ++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 38a4479760..654fe992d2 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -932,7 +932,7 @@ func (impl *DeploymentConfigurationServiceImpl) getConfigMapResponse(resourceNam } func (impl *DeploymentConfigurationServiceImpl) CompareCategoryWiseConfigData(ctx context.Context, comparisonRequestDto bean2.ComparisonRequestDto, userHasAdminAccess bool) (*bean2.ComparisonResponseDto, error) { - allSecretConfigDto := make([]*bean2.DeploymentAndCmCsConfigDto, 0) + indexVsSecretConfigMetadata := make(map[int]*bean2.SecretConfigMetadata, len(comparisonRequestDto.ComparisonItems)) allComparisonSecretsMetadata := make([]*bean2.SecretConfigMetadata, 0, len(comparisonRequestDto.ComparisonItems)) for _, comparisonItem := range comparisonRequestDto.ComparisonItems { @@ -941,7 +941,6 @@ func (impl *DeploymentConfigurationServiceImpl) CompareCategoryWiseConfigData(ct impl.logger.Errorw("error in getting single secret config for comparison", "comparisonItem", comparisonItem, "err", err) return nil, err } - //secretConfigDto.Index = comparisonItem.Index if _, ok := indexVsSecretConfigMetadata[comparisonItem.Index]; !ok { indexVsSecretConfigMetadata[comparisonItem.Index] = secretConfigMetadata } @@ -956,11 +955,43 @@ func (impl *DeploymentConfigurationServiceImpl) CompareCategoryWiseConfigData(ct } } - //prepare response - + //prepare final response with index + allSecretConfigDto, err := impl.getAllComparableSecretResponseDto(indexVsSecretConfigMetadata) + if err != nil { + impl.logger.Errorw("error in getting all comparable secrets response dto", "err", err) + return nil, err + } return bean2.DefaultComparisonResponseDto().WithComparisonItemResponse(allSecretConfigDto), nil } +func (impl *DeploymentConfigurationServiceImpl) getAllComparableSecretResponseDto(indexVsSecretConfigMetadata map[int]*bean2.SecretConfigMetadata) ([]*bean2.DeploymentAndCmCsConfigDto, error) { + allSecretConfigDto := make([]*bean2.DeploymentAndCmCsConfigDto, 0, len(indexVsSecretConfigMetadata)) + for index, secretConfigMetadata := range indexVsSecretConfigMetadata { + // prepare secrets list data part for response + configDataReq := &bean.ConfigDataRequest{ConfigData: secretConfigMetadata.SecretsList.ConfigData} + configDataJson, err := utils.ConvertToJsonRawMessage(configDataReq) + if err != nil { + impl.logger.Errorw("error in converting secrets list config data to json raw message", "err", err) + return nil, err + } + // prepare resolved data part for response + resolvedConfigDataReq := &bean.ConfigDataRequest{ConfigData: secretConfigMetadata.SecretScopeVariableMetadata.ResolvedConfigData} + resolvedConfigDataJson, err := utils.ConvertToJsonRawMessage(resolvedConfigDataReq) + if err != nil { + impl.logger.Errorw("error in converting resolved secret config data to json raw message", "err", err) + return nil, err + } + secretConfigDto := bean2.NewDeploymentAndCmCsConfig(). + WithConfigData(configDataJson). + WithResourceType(bean.CS). + WithVariableSnapshot(secretConfigMetadata.SecretScopeVariableMetadata.VariableSnapShot). + WithResolvedValue(resolvedConfigDataJson) + + allSecretConfigDto = append(allSecretConfigDto, bean2.NewDeploymentAndCmCsConfigDto().WithSecretData(secretConfigDto).WithIndex(index)) + } + return allSecretConfigDto, nil +} + func (impl *DeploymentConfigurationServiceImpl) prepareKeyValMapForSingleSecretAndMaskValue(secretMetadata *bean2.SecretConfigMetadata) (map[string]map[string]string, map[string]map[string]string, error) { keyValMapForSecretConfig, err := utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretsList.ConfigData) diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index c1e89e2198..b62eab0516 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -165,6 +165,10 @@ func (r *DeploymentAndCmCsConfigDto) WithPipelineConfigData(data *DeploymentAndC r.PipelineConfigData = data return r } +func (r *DeploymentAndCmCsConfigDto) WithIndex(index int) *DeploymentAndCmCsConfigDto { + r.Index = index + return r +} type ConfigDataQueryParams struct { AppName string `schema:"appName" json:"appName"` From 30dc494ae1196322fb5665b20e492e20a555f542 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Tue, 26 Nov 2024 12:05:26 +0530 Subject: [PATCH 03/19] DeploymentConfigurationService_ent.go new file created for ent logic --- .../DeploymentConfigurationService.go | 13 +++++++++++++ .../DeploymentConfigurationService_ent.go | 18 ++++++++++++++++++ pkg/configDiff/bean/bean.go | 2 ++ pkg/configDiff/utils/utils.go | 3 +++ 4 files changed, 36 insertions(+) create mode 100644 pkg/configDiff/DeploymentConfigurationService_ent.go diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 0ad88fae84..0a04d7edbe 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -1111,6 +1111,19 @@ func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForAppConfigu var secretConfigMetadata *bean2.SecretConfigMetadata var err error switch comparisonItem.ConfigType { + case bean2.DraftOnly.ToString(): + secretConfigMetadata, err = impl.getSingleSecretDataForDraftOnly(ctx, appEnvAndClusterMetadata, comparisonItem.UserId) + if err != nil { + impl.logger.Errorw("error in getting single secret data for draft only", "appEnvAndClusterMetadata", appEnvAndClusterMetadata, "err", err) + return nil, err + } + case bean2.PublishedWithDraft.ToString(): + secretConfigMetadata, err = impl.getSingleSecretDataForPublishedWithDraft(ctx, appEnvAndClusterMetadata, systemMetadata, comparisonItem.UserId) + if err != nil { + impl.logger.Errorw("error in getting single secret data for published with draft ", "appEnvAndClusterMetadata", appEnvAndClusterMetadata, "err", err) + return nil, err + } + case bean2.PreviousDeployments.ToString(): secretConfigMetadata, err = impl.getHistoricalSecretData(ctx, comparisonItem) if err != nil { diff --git a/pkg/configDiff/DeploymentConfigurationService_ent.go b/pkg/configDiff/DeploymentConfigurationService_ent.go new file mode 100644 index 0000000000..b5cd92609e --- /dev/null +++ b/pkg/configDiff/DeploymentConfigurationService_ent.go @@ -0,0 +1,18 @@ +package configDiff + +import ( + "context" + "github.com/devtron-labs/devtron/internal/util" + bean2 "github.com/devtron-labs/devtron/pkg/configDiff/bean" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" + "net/http" +) + +func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForDraftOnly(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, userId int32) (*bean2.SecretConfigMetadata, error) { + return nil, util.GetApiError(http.StatusNotFound, "implementation for draft kind not found", "implementation for draft kind not found") +} + +func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForPublishedWithDraft(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, + systemMetadata *resourceQualifiers.SystemMetadata, userId int32) (*bean2.SecretConfigMetadata, error) { + return nil, util.GetApiError(http.StatusNotFound, "implementation for published with draft kind not found", "implementation for published with draft kind not found") +} diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index b62eab0516..ffc1a5b0f1 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -13,6 +13,8 @@ type ConfigState string const ( PublishedConfigState ConfigState = "PublishedOnly" + DraftOnly ConfigState = "DraftOnly" + PublishedWithDraft ConfigState = "PublishedWithDraft" PreviousDeployments ConfigState = "PreviousDeployments" DefaultVersion ConfigState = "DefaultVersion" ) diff --git a/pkg/configDiff/utils/utils.go b/pkg/configDiff/utils/utils.go index 0b826de390..f33a296b9e 100644 --- a/pkg/configDiff/utils/utils.go +++ b/pkg/configDiff/utils/utils.go @@ -46,6 +46,9 @@ func GetKeyValMapForSecretConfigDataAndMaskData(configDataList []*bean.ConfigDat } newMaskedSecretData := make(map[string]string, len(secretData)) for key, val := range secretData { + if keyValMapForSecretConfig[secretConfigData.Name] == nil { + keyValMapForSecretConfig[secretConfigData.Name] = make(map[string]string) + } keyValMapForSecretConfig[secretConfigData.Name][key] = val newMaskedSecretData[key] = bean2.SecretMaskedValue } From 1394a97373c0079ad12d633f0e2b976b708d1f68 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Tue, 26 Nov 2024 14:11:17 +0530 Subject: [PATCH 04/19] validation fixes --- .../DeploymentConfigurationRestHandler.go | 1 + api/restHandler/app/configDiff/utils.go | 8 ++++- .../DeploymentConfigurationService.go | 31 ++++++++----------- pkg/configDiff/bean/bean.go | 8 +++++ 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go index 9b1b106da8..48f91e68ef 100644 --- a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go +++ b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go @@ -169,6 +169,7 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig } comparisonRequestDto.UpdateUserIdInComparisonItems(userId) + comparisonRequestDto.UpdateAppAndEnvNameInComparisonItems(comparisonRequestDto.AppName, comparisonRequestDto.EnvName) //RBAC START token := r.Header.Get(common.TokenHeaderKey) diff --git a/api/restHandler/app/configDiff/utils.go b/api/restHandler/app/configDiff/utils.go index f4c21b47e7..e2a0630926 100644 --- a/api/restHandler/app/configDiff/utils.go +++ b/api/restHandler/app/configDiff/utils.go @@ -8,13 +8,19 @@ import ( var validConfigCategories = map[string]bool{"secret": true, "cm": true, "dt": true, "ps": true} var ErrInvalidConfigCategory = errors.New("invalid config category provided") var ErrInvalidComparisonItems = errors.New("invalid comparison items, only 2 items are supported for comparison") +var ErrInvalidIndexValInComparisonItems = errors.New("invalid index values in comparison items") func validateComparisonRequest(configCategory string, comparisonRequestDto bean.ComparisonRequestDto) error { if ok := validConfigCategories[configCategory]; !ok { return ErrInvalidConfigCategory } - if len(comparisonRequestDto.ComparisonItems) > 2 { + // comparison items expects exactly two items + if len(comparisonRequestDto.ComparisonItems) != 2 { return ErrInvalidComparisonItems } + // if index value is other than 0 or 1 then throw invalid index error + if len(comparisonRequestDto.ComparisonItems) > 1 && (comparisonRequestDto.ComparisonItems[0].Index != 0 && comparisonRequestDto.ComparisonItems[1].Index != 1) { + return ErrInvalidIndexValInComparisonItems + } return nil } diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 0a04d7edbe..e11cc8c2ee 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -934,7 +934,6 @@ func (impl *DeploymentConfigurationServiceImpl) getConfigMapResponse(resourceNam func (impl *DeploymentConfigurationServiceImpl) CompareCategoryWiseConfigData(ctx context.Context, comparisonRequestDto bean2.ComparisonRequestDto, userHasAdminAccess bool) (*bean2.ComparisonResponseDto, error) { indexVsSecretConfigMetadata := make(map[int]*bean2.SecretConfigMetadata, len(comparisonRequestDto.ComparisonItems)) - allComparisonSecretsMetadata := make([]*bean2.SecretConfigMetadata, 0, len(comparisonRequestDto.ComparisonItems)) for _, comparisonItem := range comparisonRequestDto.ComparisonItems { secretConfigMetadata, err := impl.getSingleSecretConfigForComparison(ctx, comparisonItem) if err != nil { @@ -944,11 +943,10 @@ func (impl *DeploymentConfigurationServiceImpl) CompareCategoryWiseConfigData(ct if _, ok := indexVsSecretConfigMetadata[comparisonItem.Index]; !ok { indexVsSecretConfigMetadata[comparisonItem.Index] = secretConfigMetadata } - allComparisonSecretsMetadata = append(allComparisonSecretsMetadata, secretConfigMetadata) } if !userHasAdminAccess { // compare secrets data and mask if necessary - err := impl.CompareSecretDataAndMaskIfNecessary(allComparisonSecretsMetadata) + err := impl.CompareSecretDataAndMaskIfNecessary(indexVsSecretConfigMetadata) if err != nil { impl.logger.Errorw("error in comparing secret and masking if necessary", "err", err) return nil, err @@ -1030,22 +1028,19 @@ func (impl *DeploymentConfigurationServiceImpl) compareAndMaskOtherComparableSec return nil } -func (impl *DeploymentConfigurationServiceImpl) CompareSecretDataAndMaskIfNecessary(comparisonItems []*bean2.SecretConfigMetadata) error { - if len(comparisonItems) > 1 { - secretMetadata1 := comparisonItems[0] - keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1, err := impl.prepareKeyValMapForSingleSecretAndMaskValue(secretMetadata1) - if err != nil { - impl.logger.Errorw("error in preparing key val map for secret and mask the values", "err", err) - return err - } - secretMetadata2 := comparisonItems[1] - err = impl.compareAndMaskOtherComparableSecretValues(secretMetadata2, keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1) - if err != nil { - impl.logger.Errorw("error in comparing and masking other secret's value", "err", err) - return err - } - +func (impl *DeploymentConfigurationServiceImpl) CompareSecretDataAndMaskIfNecessary(indexVsComparisonItems map[int]*bean2.SecretConfigMetadata) error { + secretComparisonItem1, secretComparisonItem2 := indexVsComparisonItems[0], indexVsComparisonItems[1] + keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1, err := impl.prepareKeyValMapForSingleSecretAndMaskValue(secretComparisonItem1) + if err != nil { + impl.logger.Errorw("error in preparing key val map for secret and mask the values", "err", err) + return err + } + err = impl.compareAndMaskOtherComparableSecretValues(secretComparisonItem2, keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1) + if err != nil { + impl.logger.Errorw("error in comparing and masking other secret's value", "err", err) + return err } + return nil } diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index ffc1a5b0f1..b2a0c02b26 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -258,6 +258,14 @@ func (r *ComparisonRequestDto) UpdateUserIdInComparisonItems(userId int32) { } } +func (r *ComparisonRequestDto) UpdateAppAndEnvNameInComparisonItems(appName, envName string) { + for _, item := range r.ComparisonItems { + item.EnvName = envName + item.AppName = appName + + } +} + type ComparisonResponseDto struct { ComparisonItemResponse []*DeploymentAndCmCsConfigDto `json:"comparisonItemResponse"` } From 75926be25e91dcf092b82226b5bbe7e91f660f82 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Tue, 26 Nov 2024 16:14:07 +0530 Subject: [PATCH 05/19] prepareKeyValMapForSingleSecretAndMaskValue-> prepareSecretNameWithKeyValMapAndMaskValue --- pkg/configDiff/DeploymentConfigurationService.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index e11cc8c2ee..90fa4db6cc 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -990,7 +990,7 @@ func (impl *DeploymentConfigurationServiceImpl) getAllComparableSecretResponseDt return allSecretConfigDto, nil } -func (impl *DeploymentConfigurationServiceImpl) prepareKeyValMapForSingleSecretAndMaskValue(secretMetadata *bean2.SecretConfigMetadata) (map[string]map[string]string, map[string]map[string]string, error) { +func (impl *DeploymentConfigurationServiceImpl) prepareSecretNameWithKeyValMapAndMaskValue(secretMetadata *bean2.SecretConfigMetadata) (map[string]map[string]string, map[string]map[string]string, error) { keyValMapForSecretConfig, err := utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretsList.ConfigData) if err != nil { @@ -1030,7 +1030,7 @@ func (impl *DeploymentConfigurationServiceImpl) compareAndMaskOtherComparableSec func (impl *DeploymentConfigurationServiceImpl) CompareSecretDataAndMaskIfNecessary(indexVsComparisonItems map[int]*bean2.SecretConfigMetadata) error { secretComparisonItem1, secretComparisonItem2 := indexVsComparisonItems[0], indexVsComparisonItems[1] - keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1, err := impl.prepareKeyValMapForSingleSecretAndMaskValue(secretComparisonItem1) + keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1, err := impl.prepareSecretNameWithKeyValMapAndMaskValue(secretComparisonItem1) if err != nil { impl.logger.Errorw("error in preparing key val map for secret and mask the values", "err", err) return err From 9ad0636f5f70ab7b34ca5b1265b1ae9d1e945e0b Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Tue, 26 Nov 2024 16:27:21 +0530 Subject: [PATCH 06/19] minor refactor --- pkg/configDiff/DeploymentConfigurationService.go | 10 ++++------ pkg/configDiff/helper/helper.go | 11 +++++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 90fa4db6cc..ce8f097aaa 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -966,24 +966,22 @@ func (impl *DeploymentConfigurationServiceImpl) getAllComparableSecretResponseDt allSecretConfigDto := make([]*bean2.DeploymentAndCmCsConfigDto, 0, len(indexVsSecretConfigMetadata)) for index, secretConfigMetadata := range indexVsSecretConfigMetadata { // prepare secrets list data part for response - configDataReq := &bean.ConfigDataRequest{ConfigData: secretConfigMetadata.SecretsList.ConfigData} - configDataJson, err := utils.ConvertToJsonRawMessage(configDataReq) + unresolvedSecretConfigData, err := helper.GetConfigDataRequestJsonRawMessage(secretConfigMetadata.SecretsList.ConfigData) if err != nil { impl.logger.Errorw("error in converting secrets list config data to json raw message", "err", err) return nil, err } // prepare resolved data part for response - resolvedConfigDataReq := &bean.ConfigDataRequest{ConfigData: secretConfigMetadata.SecretScopeVariableMetadata.ResolvedConfigData} - resolvedConfigDataJson, err := utils.ConvertToJsonRawMessage(resolvedConfigDataReq) + resolvedSecretConfigData, err := helper.GetConfigDataRequestJsonRawMessage(secretConfigMetadata.SecretScopeVariableMetadata.ResolvedConfigData) if err != nil { impl.logger.Errorw("error in converting resolved secret config data to json raw message", "err", err) return nil, err } secretConfigDto := bean2.NewDeploymentAndCmCsConfig(). - WithConfigData(configDataJson). + WithConfigData(unresolvedSecretConfigData). WithResourceType(bean.CS). WithVariableSnapshot(secretConfigMetadata.SecretScopeVariableMetadata.VariableSnapShot). - WithResolvedValue(resolvedConfigDataJson) + WithResolvedValue(resolvedSecretConfigData) allSecretConfigDto = append(allSecretConfigDto, bean2.NewDeploymentAndCmCsConfigDto().WithSecretData(secretConfigDto).WithIndex(index)) } diff --git a/pkg/configDiff/helper/helper.go b/pkg/configDiff/helper/helper.go index 3bf5e5ffaa..952914157c 100644 --- a/pkg/configDiff/helper/helper.go +++ b/pkg/configDiff/helper/helper.go @@ -1,8 +1,10 @@ package helper import ( + "encoding/json" bean3 "github.com/devtron-labs/devtron/pkg/bean" bean2 "github.com/devtron-labs/devtron/pkg/configDiff/bean" + "github.com/devtron-labs/devtron/pkg/configDiff/utils" "github.com/devtron-labs/devtron/pkg/pipeline/bean" ) @@ -56,3 +58,12 @@ func FilterOutMergedCmCsForResourceName(cmcsMerged *bean2.CmCsMetadataDto, resou } } } + +func GetConfigDataRequestJsonRawMessage(configDataList []*bean.ConfigData) (json.RawMessage, error) { + configDataReq := &bean.ConfigDataRequest{ConfigData: configDataList} + configDataJson, err := utils.ConvertToJsonRawMessage(configDataReq) + if err != nil { + return nil, err + } + return configDataJson, nil +} From a0ccf0cefb32d0a6d6ccf2096d94516c3ba0818e Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Tue, 26 Nov 2024 18:42:37 +0530 Subject: [PATCH 07/19] send secret in config-data api only if user has admin access --- .../DeploymentConfigurationService.go | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index ce8f097aaa..32a101ca1d 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -265,14 +265,16 @@ func (impl *DeploymentConfigurationServiceImpl) getConfigDataForDeploymentHistor configDataDto.WithConfigMapData(cmConfigData) // fetching for cm config ends - // fetching for cs config starts - secretConfigDto, err := impl.getCmCsConfigHistory(ctx, configDataQueryParams, repository3.SECRET_TYPE, userHasAdminAccess) - if err != nil { - impl.logger.Errorw("getConfigDataForDeploymentHistory, error in getSecretConfigHistory", "configDataQueryParams", configDataQueryParams, "err", err) - return nil, err + if userHasAdminAccess { + // fetching for cs config starts + secretConfigDto, err := impl.getCmCsConfigHistory(ctx, configDataQueryParams, repository3.SECRET_TYPE, userHasAdminAccess) + if err != nil { + impl.logger.Errorw("getConfigDataForDeploymentHistory, error in getSecretConfigHistory", "configDataQueryParams", configDataQueryParams, "err", err) + return nil, err + } + configDataDto.WithSecretData(secretConfigDto) + // fetching for cs config ends } - configDataDto.WithSecretData(secretConfigDto) - // fetching for cs config ends return configDataDto, nil } @@ -385,18 +387,21 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsDataForPreviousDeployment impl.logger.Errorw("error in getting deployment template history", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) return nil, err } - secretConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, repository3.SECRET_TYPE, userHasAdminAccess) - if err != nil { - impl.logger.Errorw("error in getting secretData and cmData", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) - return nil, err - } - cmConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, repository3.CONFIGMAP_TYPE, userHasAdminAccess) if err != nil { impl.logger.Errorw("error in getting secretData and cmData", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) return nil, err } - configDataDto.WithConfigMapData(cmConfigData).WithSecretData(secretConfigData) + configDataDto.WithConfigMapData(cmConfigData) + if userHasAdminAccess { + secretConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, repository3.SECRET_TYPE, userHasAdminAccess) + if err != nil { + impl.logger.Errorw("error in getting secretData and cmData", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) + return nil, err + } + configDataDto.WithSecretData(secretConfigData) + } + return configDataDto, nil } @@ -603,33 +608,18 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsEditDataForPublishedOnly( } func (impl *DeploymentConfigurationServiceImpl) getCmCsPublishedConfigResponse(ctx context.Context, envId, appId, clusterId int, userHasAdminAccess bool, systemMetadata *resourceQualifiers.SystemMetadata) (*bean2.DeploymentAndCmCsConfigDto, error) { - configDataDto := &bean2.DeploymentAndCmCsConfigDto{} - secretData, err := impl.getSecretConfigResponse("", 0, envId, appId) - if err != nil { - impl.logger.Errorw("getCmCsPublishedConfigResponse, error in getting secret config response by appId and envId", "appId", appId, "envId", envId, "err", err) - return nil, err - } - //iterate on secret configData and then and set draft data from draftResourcesMap if same resourceName found do the same for configMap below cmData, err := impl.getConfigMapResponse("", 0, envId, appId) if err != nil { impl.logger.Errorw("getCmCsPublishedConfigResponse, error in getting config map by appId and envId", "appId", appId, "envId", envId, "err", err) return nil, err } - - secretRespJson, err := utils.ConvertToJsonRawMessage(secretData) - if err != nil { - impl.logger.Errorw("getCmCsPublishedConfigResponse, error in converting secret data to json raw message", "appId", appId, "envId", envId, "err", err) - return nil, err - } - cmRespJson, err := utils.ConvertToJsonRawMessage(cmData) if err != nil { impl.logger.Errorw("getCmCsPublishedConfigResponse, error in converting config map data to json raw message", "appId", appId, "envId", envId, "err", err) return nil, err } - resolvedCmCsMetadataDto, err := impl.ResolveCmCs(ctx, envId, appId, clusterId, userHasAdminAccess, "", "", systemMetadata) if err != nil { impl.logger.Errorw("error in resolving cm and cs for published only config only response", "appId", appId, "envId", envId, "err", err) @@ -640,19 +630,30 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsPublishedConfigResponse(c impl.logger.Errorw("error in ConvertToJsonRawMessage for resolvedConfigMapDataStringJson", "resolvedCmData", resolvedCmCsMetadataDto.ResolvedConfigMapData, "err", err) return nil, err } - resolvedSecretDataStringJson, err := utils.ConvertToJsonRawMessage(resolvedCmCsMetadataDto.ResolvedSecretData) - if err != nil { - impl.logger.Errorw(" error in ConvertToJsonRawMessage for resolvedConfigDataString", "err", err) - return nil, err - } - cmConfigData := bean2.NewDeploymentAndCmCsConfig().WithConfigData(cmRespJson).WithResourceType(bean.CM). WithResolvedValue(resolvedConfigMapDataStringJson).WithVariableSnapshot(resolvedCmCsMetadataDto.VariableMapCM) + configDataDto.WithConfigMapData(cmConfigData) - secretConfigData := bean2.NewDeploymentAndCmCsConfig().WithConfigData(secretRespJson).WithResourceType(bean.CS). - WithResolvedValue(resolvedSecretDataStringJson).WithVariableSnapshot(resolvedCmCsMetadataDto.VariableMapCS) - - configDataDto.WithConfigMapData(cmConfigData).WithSecretData(secretConfigData) + if userHasAdminAccess { + secretData, err := impl.getSecretConfigResponse("", 0, envId, appId) + if err != nil { + impl.logger.Errorw("getCmCsPublishedConfigResponse, error in getting secret config response by appId and envId", "appId", appId, "envId", envId, "err", err) + return nil, err + } + secretRespJson, err := utils.ConvertToJsonRawMessage(secretData) + if err != nil { + impl.logger.Errorw("getCmCsPublishedConfigResponse, error in converting secret data to json raw message", "appId", appId, "envId", envId, "err", err) + return nil, err + } + resolvedSecretDataStringJson, err := utils.ConvertToJsonRawMessage(resolvedCmCsMetadataDto.ResolvedSecretData) + if err != nil { + impl.logger.Errorw(" error in ConvertToJsonRawMessage for resolvedConfigDataString", "err", err) + return nil, err + } + secretConfigData := bean2.NewDeploymentAndCmCsConfig().WithConfigData(secretRespJson).WithResourceType(bean.CS). + WithResolvedValue(resolvedSecretDataStringJson).WithVariableSnapshot(resolvedCmCsMetadataDto.VariableMapCS) + configDataDto.WithSecretData(secretConfigData) + } return configDataDto, nil } From 7f2ae8a5095bffc63279dfe24ce9c6ebdca57e8e Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Wed, 27 Nov 2024 01:19:33 +0530 Subject: [PATCH 08/19] rename var names for better clarity --- .../DeploymentConfigurationService.go | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 32a101ca1d..7a16dc1bbb 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -991,36 +991,36 @@ func (impl *DeploymentConfigurationServiceImpl) getAllComparableSecretResponseDt func (impl *DeploymentConfigurationServiceImpl) prepareSecretNameWithKeyValMapAndMaskValue(secretMetadata *bean2.SecretConfigMetadata) (map[string]map[string]string, map[string]map[string]string, error) { - keyValMapForSecretConfig, err := utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretsList.ConfigData) + unresolvedSecretMapping, err := utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretsList.ConfigData) if err != nil { impl.logger.Errorw("error in getting key val map for SecretsList's config data with masking", "err", err) return nil, nil, err } - keyValMapForResolvedSecretConfig := make(map[string]map[string]string) + resolvedSecretMapping := make(map[string]map[string]string) if len(secretMetadata.SecretScopeVariableMetadata.VariableSnapShot) > 0 { //scope variable is used so mask scope variable secret data also - keyValMapForResolvedSecretConfig, err = utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretScopeVariableMetadata.ResolvedConfigData) + resolvedSecretMapping, err = utils.GetKeyValMapForSecretConfigDataAndMaskData(secretMetadata.SecretScopeVariableMetadata.ResolvedConfigData) if err != nil { impl.logger.Errorw("error in getting key val map for resolved config data with masking", "err", err) return nil, nil, err } } - return keyValMapForSecretConfig, keyValMapForResolvedSecretConfig, nil + return unresolvedSecretMapping, resolvedSecretMapping, nil } -func (impl *DeploymentConfigurationServiceImpl) compareAndMaskOtherComparableSecretValues(secretMetadata2 *bean2.SecretConfigMetadata, keyValMapForSecretConfig1 map[string]map[string]string, - keyValMapForResolvedSecretConfig1 map[string]map[string]string) error { +func (impl *DeploymentConfigurationServiceImpl) compareAndMaskOtherComparableSecretValues(secretMetadata2 *bean2.SecretConfigMetadata, unresolvedSecretMapping1 map[string]map[string]string, + resolvedSecretMapping1 map[string]map[string]string) error { - err := utils.CompareAndMaskSecretValuesInConfigData(secretMetadata2.SecretsList.ConfigData, keyValMapForSecretConfig1) + err := utils.CompareAndMaskSecretValuesInConfigData(secretMetadata2.SecretsList.ConfigData, unresolvedSecretMapping1) if err != nil { - impl.logger.Errorw("error in comparing and masking secretsList's secret values ", "err", err) + impl.logger.Errorw("error in comparing and masking secretsList's secret values", "err", err) return err } if len(secretMetadata2.SecretScopeVariableMetadata.VariableSnapShot) > 0 { - err = utils.CompareAndMaskSecretValuesInConfigData(secretMetadata2.SecretScopeVariableMetadata.ResolvedConfigData, keyValMapForResolvedSecretConfig1) + err = utils.CompareAndMaskSecretValuesInConfigData(secretMetadata2.SecretScopeVariableMetadata.ResolvedConfigData, resolvedSecretMapping1) if err != nil { - impl.logger.Errorw("error in comparing and masking resolvedConfigData's secret values ", "err", err) + impl.logger.Errorw("error in comparing and masking resolvedConfigData's secret values", "err", err) return err } } @@ -1029,17 +1029,16 @@ func (impl *DeploymentConfigurationServiceImpl) compareAndMaskOtherComparableSec func (impl *DeploymentConfigurationServiceImpl) CompareSecretDataAndMaskIfNecessary(indexVsComparisonItems map[int]*bean2.SecretConfigMetadata) error { secretComparisonItem1, secretComparisonItem2 := indexVsComparisonItems[0], indexVsComparisonItems[1] - keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1, err := impl.prepareSecretNameWithKeyValMapAndMaskValue(secretComparisonItem1) + unresolvedSecretMapping1, resolvedSecretMapping1, err := impl.prepareSecretNameWithKeyValMapAndMaskValue(secretComparisonItem1) if err != nil { impl.logger.Errorw("error in preparing key val map for secret and mask the values", "err", err) return err } - err = impl.compareAndMaskOtherComparableSecretValues(secretComparisonItem2, keyValMapForSecretConfig1, keyValMapForResolvedSecretConfig1) + err = impl.compareAndMaskOtherComparableSecretValues(secretComparisonItem2, unresolvedSecretMapping1, resolvedSecretMapping1) if err != nil { impl.logger.Errorw("error in comparing and masking other secret's value", "err", err) return err } - return nil } From b391b00eacd26695b2e2c20fd3a502547d634bcc Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Thu, 28 Nov 2024 15:37:09 +0530 Subject: [PATCH 09/19] add omitempty with json key Index in DeploymentAndCmCsConfigDto --- pkg/configDiff/bean/bean.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index b2a0c02b26..c42fcbe655 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -144,7 +144,7 @@ type DeploymentAndCmCsConfigDto struct { SecretsData *DeploymentAndCmCsConfig `json:"secretsData"` PipelineConfigData *DeploymentAndCmCsConfig `json:"pipelineConfigData,omitempty"` IsAppAdmin bool `json:"isAppAdmin"` - Index int `json:"index"` + Index int `json:"index,omitempty"` } func NewDeploymentAndCmCsConfigDto() *DeploymentAndCmCsConfigDto { From bcfd4e7806d37e0ed859fa56934ca2f3c79aa340 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Thu, 28 Nov 2024 15:58:04 +0530 Subject: [PATCH 10/19] some refact after code review -1 --- .../DeploymentConfigurationRestHandler.go | 2 +- api/restHandler/app/configDiff/utils.go | 2 +- api/router/app/configDiff/DeploymentConfigRouter.go | 2 +- cmd/external-app/wire_gen.go | 2 +- pkg/configDiff/DeploymentConfigurationService.go | 8 ++++---- .../DeploymentConfigurationService_ent.go | 4 ++-- pkg/configDiff/bean/bean.go | 13 +++++++++++++ 7 files changed, 23 insertions(+), 10 deletions(-) diff --git a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go index 48f91e68ef..5cdd55459b 100644 --- a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go +++ b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go @@ -154,7 +154,7 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig return } vars := mux.Vars(r) - configCategory := vars["category"] + configCategory := vars["resource"] var comparisonRequestDto bean.ComparisonRequestDto err = json.NewDecoder(r.Body).Decode(&comparisonRequestDto) if err != nil { diff --git a/api/restHandler/app/configDiff/utils.go b/api/restHandler/app/configDiff/utils.go index e2a0630926..49e0c59157 100644 --- a/api/restHandler/app/configDiff/utils.go +++ b/api/restHandler/app/configDiff/utils.go @@ -5,7 +5,7 @@ import ( "github.com/devtron-labs/devtron/pkg/configDiff/bean" ) -var validConfigCategories = map[string]bool{"secret": true, "cm": true, "dt": true, "ps": true} +var validConfigCategories = map[string]bool{bean.Secret.ToString(): true, bean.ConfigMap.ToString(): true, bean.DeploymentTemplate.ToString(): true, bean.PipelineStrategy.ToString(): true} var ErrInvalidConfigCategory = errors.New("invalid config category provided") var ErrInvalidComparisonItems = errors.New("invalid comparison items, only 2 items are supported for comparison") var ErrInvalidIndexValInComparisonItems = errors.New("invalid index values in comparison items") diff --git a/api/router/app/configDiff/DeploymentConfigRouter.go b/api/router/app/configDiff/DeploymentConfigRouter.go index 56d1816bc4..4a97d8f975 100644 --- a/api/router/app/configDiff/DeploymentConfigRouter.go +++ b/api/router/app/configDiff/DeploymentConfigRouter.go @@ -27,7 +27,7 @@ func (router DeploymentConfigurationRouterImpl) InitDeploymentConfigurationRoute configRouter.Path("/data"). HandlerFunc(router.deploymentGroupRestHandler.GetConfigData). Methods("GET") - configRouter.Path("/compare/{category}"). + configRouter.Path("/compare/{resource}"). HandlerFunc(router.deploymentGroupRestHandler.CompareCategoryWiseConfigData). Methods("GET") diff --git a/cmd/external-app/wire_gen.go b/cmd/external-app/wire_gen.go index 9b4b74f225..710a514f37 100644 --- a/cmd/external-app/wire_gen.go +++ b/cmd/external-app/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run -mod=mod github.com/google/wire/cmd/wire +//go:generate go run github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 7a16dc1bbb..904ac93c17 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -1105,13 +1105,13 @@ func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForAppConfigu var err error switch comparisonItem.ConfigType { case bean2.DraftOnly.ToString(): - secretConfigMetadata, err = impl.getSingleSecretDataForDraftOnly(ctx, appEnvAndClusterMetadata, comparisonItem.UserId) + secretConfigMetadata, err = impl.getSecretDataForDraftOnly(ctx, appEnvAndClusterMetadata, comparisonItem.UserId) if err != nil { impl.logger.Errorw("error in getting single secret data for draft only", "appEnvAndClusterMetadata", appEnvAndClusterMetadata, "err", err) return nil, err } case bean2.PublishedWithDraft.ToString(): - secretConfigMetadata, err = impl.getSingleSecretDataForPublishedWithDraft(ctx, appEnvAndClusterMetadata, systemMetadata, comparisonItem.UserId) + secretConfigMetadata, err = impl.getSecretDataForPublishedWithDraft(ctx, appEnvAndClusterMetadata, systemMetadata, comparisonItem.UserId) if err != nil { impl.logger.Errorw("error in getting single secret data for published with draft ", "appEnvAndClusterMetadata", appEnvAndClusterMetadata, "err", err) return nil, err @@ -1124,7 +1124,7 @@ func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForAppConfigu return nil, err } default: // keeping default as PublishedOnly - secretConfigMetadata, err = impl.getSingleSecretDataForPublishedOnly(ctx, appEnvAndClusterMetadata, systemMetadata) + secretConfigMetadata, err = impl.getSecretDataForPublishedOnly(ctx, appEnvAndClusterMetadata, systemMetadata) if err != nil { impl.logger.Errorw("error in config data for PublishedOnly", "comparisonDataPayload", comparisonItem.ConfigDataQueryParams, "err", err) return nil, err @@ -1174,7 +1174,7 @@ func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForPreviousDe return secretsList, resolvedSecretData, nil } -func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForPublishedOnly(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, +func (impl *DeploymentConfigurationServiceImpl) getSecretDataForPublishedOnly(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, systemMetadata *resourceQualifiers.SystemMetadata) (*bean2.SecretConfigMetadata, error) { secretData, err := impl.getSecretConfigResponse("", 0, appEnvAndClusterMetadata.EnvId, appEnvAndClusterMetadata.AppId) if err != nil { diff --git a/pkg/configDiff/DeploymentConfigurationService_ent.go b/pkg/configDiff/DeploymentConfigurationService_ent.go index b5cd92609e..e09e278194 100644 --- a/pkg/configDiff/DeploymentConfigurationService_ent.go +++ b/pkg/configDiff/DeploymentConfigurationService_ent.go @@ -8,11 +8,11 @@ import ( "net/http" ) -func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForDraftOnly(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, userId int32) (*bean2.SecretConfigMetadata, error) { +func (impl *DeploymentConfigurationServiceImpl) getSecretDataForDraftOnly(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, userId int32) (*bean2.SecretConfigMetadata, error) { return nil, util.GetApiError(http.StatusNotFound, "implementation for draft kind not found", "implementation for draft kind not found") } -func (impl *DeploymentConfigurationServiceImpl) getSingleSecretDataForPublishedWithDraft(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, +func (impl *DeploymentConfigurationServiceImpl) getSecretDataForPublishedWithDraft(ctx context.Context, appEnvAndClusterMetadata *bean2.AppEnvAndClusterMetadata, systemMetadata *resourceQualifiers.SystemMetadata, userId int32) (*bean2.SecretConfigMetadata, error) { return nil, util.GetApiError(http.StatusNotFound, "implementation for published with draft kind not found", "implementation for published with draft kind not found") } diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index c42fcbe655..d31f08364b 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -293,3 +293,16 @@ type SecretConfigMetadata struct { SecretsList *bean.SecretsList SecretScopeVariableMetadata *CmCsScopeVariableMetadata } + +type Resource string + +const ( + ConfigMap Resource = "cm" + Secret Resource = "secret" + DeploymentTemplate Resource = "dt" + PipelineStrategy Resource = "ps" +) + +func (r Resource) ToString() string { + return string(r) +} From be86fd0aad8e252684d9140d88326b11ddec0cd6 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Fri, 29 Nov 2024 13:54:51 +0530 Subject: [PATCH 11/19] take in query param ComparisonRequestDto instead of payload in get req --- .../app/configDiff/DeploymentConfigurationRestHandler.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go index 5cdd55459b..924994c8a6 100644 --- a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go +++ b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go @@ -155,10 +155,13 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig } vars := mux.Vars(r) configCategory := vars["resource"] + + v := r.URL.Query() + comparisonReqString := v.Get("compareConfig") var comparisonRequestDto bean.ComparisonRequestDto - err = json.NewDecoder(r.Body).Decode(&comparisonRequestDto) + err = json.Unmarshal([]byte(comparisonReqString), &comparisonRequestDto) if err != nil { - handler.logger.Errorw("error in decoding request body", "err", err) + handler.logger.Errorw("error in unmarshalling stringified json query param", "err", err) common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return } From 740c3ae7a86142f696b95f839fc76d3847f5848a Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Fri, 29 Nov 2024 17:30:11 +0530 Subject: [PATCH 12/19] envName and appName in comparisonItems --- .../DeploymentConfigurationRestHandler.go | 18 +++++++++++++++--- pkg/configDiff/bean/bean.go | 9 +++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go index 924994c8a6..1df240c9db 100644 --- a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go +++ b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go @@ -172,11 +172,11 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig } comparisonRequestDto.UpdateUserIdInComparisonItems(userId) - comparisonRequestDto.UpdateAppAndEnvNameInComparisonItems(comparisonRequestDto.AppName, comparisonRequestDto.EnvName) + appName := comparisonRequestDto.GetAppName() //RBAC START token := r.Header.Get(common.TokenHeaderKey) - object := handler.enforcerUtil.GetAppRBACName(comparisonRequestDto.AppName) + object := handler.enforcerUtil.GetAppRBACName(appName) ok := handler.enforcerUtil.CheckAppRbacForAppOrJob(token, object, casbin.ActionGet) if !ok { @@ -188,7 +188,7 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig //or not while resolving scope variable. isSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*") //userHasAdminAccess is required to mask secrets in the response after scope resolution. - userHasAdminAccess := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionUpdate, object) + userHasAdminAccess := handler.checkIfUserHasAdminAccessForLeastPrivilegeEnv(token, comparisonRequestDto) ctx := util2.SetSuperAdminInContext(r.Context(), isSuperAdmin) res, err := handler.deploymentConfigurationService.CompareCategoryWiseConfigData(ctx, comparisonRequestDto, userHasAdminAccess) @@ -201,3 +201,15 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig common.WriteJsonResp(w, nil, res, http.StatusOK) } + +// checkIfUserHasAdminAccessForLeastPrivilegeEnv computes if a user has admin access or not for all env, +// if a user is non admin for at least one env then return false. +func (handler *DeploymentConfigurationRestHandlerImpl) checkIfUserHasAdminAccessForLeastPrivilegeEnv(token string, comparisonRequestDto bean.ComparisonRequestDto) bool { + for _, item := range comparisonRequestDto.ComparisonItems { + userHadAdminAccess := handler.enforcer.Enforce(token, casbin.ResourceEnvironment, casbin.ActionGet, item.EnvName) + if !userHadAdminAccess { + return false + } + } + return true +} diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index d31f08364b..9c4bbb6e2d 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -246,8 +246,6 @@ type ComparisonItemRequestDto struct { } type ComparisonRequestDto struct { - AppName string `json:"appName"` - EnvName string `json:"envName"` ComparisonItems []*ComparisonItemRequestDto `json:"comparisonItems"` // comparisonItems contains array of objects that a user wants to compare } @@ -258,12 +256,11 @@ func (r *ComparisonRequestDto) UpdateUserIdInComparisonItems(userId int32) { } } -func (r *ComparisonRequestDto) UpdateAppAndEnvNameInComparisonItems(appName, envName string) { +func (r *ComparisonRequestDto) GetAppName() string { for _, item := range r.ComparisonItems { - item.EnvName = envName - item.AppName = appName - + return item.AppName } + return "" } type ComparisonResponseDto struct { From b5008f32b49d219b9ee7594291590a8eff98f560 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Fri, 29 Nov 2024 19:38:57 +0530 Subject: [PATCH 13/19] support wfrid in case of previous deployments as config type --- .../DeploymentConfigurationService.go | 78 +++++++++---------- .../read/ConfigMapHistoryReadService.go | 18 ++--- .../repository/ConfigMapHistoryRepository.go | 25 ------ .../PipelineStrategyHistoryRepository.go | 9 --- 4 files changed, 44 insertions(+), 86 deletions(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 904ac93c17..bff8902827 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -378,25 +378,20 @@ func (impl *DeploymentConfigurationServiceImpl) encodeSecretDataFromNonAdminUser } } -func (impl *DeploymentConfigurationServiceImpl) getCmCsDataForPreviousDeployments(ctx context.Context, deploymentTemplateHistoryId, pipelineId int, userHasAdminAccess bool) (*bean2.DeploymentAndCmCsConfigDto, error) { +func (impl *DeploymentConfigurationServiceImpl) getCmCsDataForPreviousDeployments(ctx context.Context, wfrId, pipelineId int, userHasAdminAccess bool) (*bean2.DeploymentAndCmCsConfigDto, error) { configDataDto := &bean2.DeploymentAndCmCsConfigDto{} - deplTemplateHistory, err := impl.deploymentTemplateHistoryReadService.GetTemplateHistoryModelForDeployedTemplateById(deploymentTemplateHistoryId, pipelineId) + cmConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByWfrIdAndPipelineId(ctx, pipelineId, wfrId, repository3.CONFIGMAP_TYPE, userHasAdminAccess) if err != nil { - impl.logger.Errorw("error in getting deployment template history", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) - return nil, err - } - cmConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, repository3.CONFIGMAP_TYPE, userHasAdminAccess) - if err != nil { - impl.logger.Errorw("error in getting secretData and cmData", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) + impl.logger.Errorw("error in getting secretData and cmData", "err", err, "wfrId", wfrId, "pipelineId", pipelineId) return nil, err } configDataDto.WithConfigMapData(cmConfigData) if userHasAdminAccess { - secretConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByDeployedOnAndPipelineId(ctx, pipelineId, deplTemplateHistory.DeployedOn, repository3.SECRET_TYPE, userHasAdminAccess) + secretConfigData, err := impl.configMapHistoryReadService.GetCmCsHistoryByWfrIdAndPipelineId(ctx, pipelineId, wfrId, repository3.SECRET_TYPE, userHasAdminAccess) if err != nil { - impl.logger.Errorw("error in getting secretData and cmData", "err", err, "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId) + impl.logger.Errorw("error in getting secretData and cmData", "err", err, "wfrId", wfrId, "pipelineId", pipelineId) return nil, err } configDataDto.WithSecretData(secretConfigData) @@ -405,47 +400,44 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsDataForPreviousDeployment return configDataDto, nil } -func (impl *DeploymentConfigurationServiceImpl) getPipelineStrategyForPreviousDeployments(ctx context.Context, deploymentTemplateHistoryId, pipelineId int) (*bean2.DeploymentAndCmCsConfig, error) { +func (impl *DeploymentConfigurationServiceImpl) getPipelineStrategyForPreviousDeployments(ctx context.Context, wfrId, pipelineId int) (*bean2.DeploymentAndCmCsConfig, error) { pipelineStrategyJson := json.RawMessage{} pipelineConfig := bean2.NewDeploymentAndCmCsConfig() - deplTemplateHistory, err := impl.deploymentTemplateHistoryReadService.GetTemplateHistoryModelForDeployedTemplateById(deploymentTemplateHistoryId, pipelineId) - if err != nil { - impl.logger.Errorw("error in getting deployment template history", "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "pipelineId", pipelineId, "err", err) - return nil, err - } - pipelineStrategyHistory, err := impl.pipelineStrategyHistoryRepository.FindPipelineStrategyForDeployedOnAndPipelineId(pipelineId, deplTemplateHistory.DeployedOn) + pipelineStrategyHistory, err := impl.pipelineStrategyHistoryRepository.GetHistoryByPipelineIdAndWfrId(ctx, pipelineId, wfrId) if err != nil && !util.IsErrNoRows(err) { - impl.logger.Errorw("error in FindPipelineStrategyForDeployedOnAndPipelineId", "deploymentTemplateHistoryId", deploymentTemplateHistoryId, "deployedOn", deplTemplateHistory.DeployedOn, "pipelineId", pipelineId, "err", err) + impl.logger.Errorw("error in FindPipelineStrategyForDeployedOnAndPipelineId", "wfrId", wfrId, "pipelineId", pipelineId, "err", err) return nil, err } else if util.IsErrNoRows(err) { return pipelineConfig, nil } - err = pipelineStrategyJson.UnmarshalJSON([]byte(pipelineStrategyHistory.Config)) - if err != nil { - impl.logger.Errorw("getDeploymentTemplateForEnvLevel, error in unmarshalling string pipelineStrategyHistory data into json Raw message", "err", err) - return nil, err + if pipelineStrategyHistory != nil { + err = pipelineStrategyJson.UnmarshalJSON([]byte(pipelineStrategyHistory.Config)) + if err != nil { + impl.logger.Errorw("getDeploymentTemplateForEnvLevel, error in unmarshalling string pipelineStrategyHistory data into json Raw message", "err", err) + return nil, err + } + pipelineConfig.WithConfigData(pipelineStrategyJson). + WithResourceType(bean.PipelineStrategy). + WithPipelineStrategyMetadata(pipelineStrategyHistory.PipelineTriggerType, string(pipelineStrategyHistory.Strategy)) } - pipelineConfig.WithConfigData(pipelineStrategyJson). - WithResourceType(bean.PipelineStrategy). - WithPipelineStrategyMetadata(pipelineStrategyHistory.PipelineTriggerType, string(pipelineStrategyHistory.Strategy)) return pipelineConfig, nil } -func (impl *DeploymentConfigurationServiceImpl) getDeploymentsConfigForPreviousDeployments(ctx context.Context, configDataQueryParams *bean2.ConfigDataQueryParams, - appId, envId int) (generateManifest.DeploymentTemplateResponse, error) { - deploymentTemplateRequest := generateManifest.DeploymentTemplateRequest{ - PipelineId: configDataQueryParams.PipelineId, - DeploymentTemplateHistoryId: configDataQueryParams.IdentifierId, - RequestDataMode: generateManifest.Values, - Type: repository2.DeployedOnSelfEnvironment, - } +func (impl *DeploymentConfigurationServiceImpl) getDeploymentsConfigForPreviousDeployments(ctx context.Context, configDataQueryParams *bean2.ConfigDataQueryParams) (generateManifest.DeploymentTemplateResponse, error) { + var deploymentTemplateResponse generateManifest.DeploymentTemplateResponse - deploymentTemplateResponse, err := impl.deploymentTemplateService.GetDeploymentTemplate(ctx, deploymentTemplateRequest) + deplTemplate, err := impl.deploymentTemplateHistoryReadService.GetDeployedHistoryByPipelineIdAndWfrId(ctx, configDataQueryParams.PipelineId, configDataQueryParams.WfrId) if err != nil { - impl.logger.Errorw("getDeploymentTemplateForEnvLevel, error in getting deployment template for ", "deploymentTemplateRequest", deploymentTemplateRequest, "err", err) + impl.logger.Errorw("getDeploymentsConfigForPreviousDeployments, error in getting deployment template by pipelineId and wfrId ", "pipelineId", configDataQueryParams.PipelineId, "wfrId", configDataQueryParams.WfrId, "err", err) return deploymentTemplateResponse, err } - + deploymentTemplateResponse = generateManifest.DeploymentTemplateResponse{ + Data: deplTemplate.CodeEditorValue.Value, + ResolvedData: deplTemplate.CodeEditorValue.ResolvedValue, + VariableSnapshot: deplTemplate.CodeEditorValue.VariableSnapshot, + TemplateVersion: deplTemplate.TemplateVersion, + IsAppMetricsEnabled: *deplTemplate.IsAppMetricsEnabled, + } return deploymentTemplateResponse, nil } @@ -453,29 +445,29 @@ func (impl *DeploymentConfigurationServiceImpl) getDeploymentAndCmCsConfigDataFo appId, envId int, userHasAdminAccess bool) (*bean2.DeploymentAndCmCsConfigDto, error) { // getting DeploymentAndCmCsConfigDto obj with cm and cs data populated - configDataDto, err := impl.getCmCsDataForPreviousDeployments(ctx, configDataQueryParams.IdentifierId, configDataQueryParams.PipelineId, userHasAdminAccess) + configDataDto, err := impl.getCmCsDataForPreviousDeployments(ctx, configDataQueryParams.WfrId, configDataQueryParams.PipelineId, userHasAdminAccess) if err != nil { - impl.logger.Errorw("error in getting cm cs for PreviousDeployments state", "deploymentTemplateHistoryId", configDataQueryParams.IdentifierId, "pipelineId", configDataQueryParams.PipelineId, "err", err) + impl.logger.Errorw("error in getting cm cs for PreviousDeployments state", "configDataQueryParams", configDataQueryParams, "err", err) return nil, err } - pipelineStrategy, err := impl.getPipelineStrategyForPreviousDeployments(ctx, configDataQueryParams.IdentifierId, configDataQueryParams.PipelineId) + pipelineStrategy, err := impl.getPipelineStrategyForPreviousDeployments(ctx, configDataQueryParams.WfrId, configDataQueryParams.PipelineId) if err != nil { - impl.logger.Errorw(" error in getting cm cs for PreviousDeployments state", "deploymentTemplateHistoryId", configDataQueryParams.IdentifierId, "pipelineId", configDataQueryParams.PipelineId, "err", err) + impl.logger.Errorw(" error in getting cm cs for PreviousDeployments state", "configDataQueryParams", configDataQueryParams, "err", err) return nil, err } if len(pipelineStrategy.Data) > 0 { configDataDto.WithPipelineConfigData(pipelineStrategy) } - deploymentTemplateData, err := impl.getDeploymentsConfigForPreviousDeployments(ctx, configDataQueryParams, appId, envId) + deploymentTemplateData, err := impl.getDeploymentsConfigForPreviousDeployments(ctx, configDataQueryParams) if err != nil { - impl.logger.Errorw("error in getting deployment config", "appName", configDataQueryParams.AppName, "envName", configDataQueryParams.EnvName, "err", err) + impl.logger.Errorw("error in getting deployment config", "configDataQueryParams", configDataQueryParams, "err", err) return nil, err } deploymentJson := json.RawMessage{} err = deploymentJson.UnmarshalJSON([]byte(deploymentTemplateData.Data)) if err != nil { - impl.logger.Errorw("error in unmarshalling string deploymentTemplateResponse data into json Raw message", "appName", configDataQueryParams.AppName, "envName", configDataQueryParams.EnvName, "err", err) + impl.logger.Errorw("error in unmarshalling string deploymentTemplateResponse data into json Raw message", "configDataQueryParams", configDataQueryParams, "err", err) return nil, err } variableSnapShotMap := map[string]map[string]string{bean.DeploymentTemplate.ToString(): deploymentTemplateData.VariableSnapshot} diff --git a/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go b/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go index c42ac1aec4..15e9287f04 100644 --- a/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go +++ b/pkg/deployment/manifest/configMapAndSecret/read/ConfigMapHistoryReadService.go @@ -26,7 +26,7 @@ type ConfigMapHistoryReadService interface { CheckIfTriggerHistoryExistsForPipelineIdOnTime(pipelineId int, deployedOn time.Time) (cmId int, csId int, exists bool, err error) GetDeployedHistoryDetailForCMCSByPipelineIdAndWfrId(ctx context.Context, pipelineId, wfrId int, configType repository.ConfigType, userHasAdminAccess bool) ([]*bean.ComponentLevelHistoryDetailDto, error) ConvertConfigDataToComponentLevelDto(config *bean2.ConfigData, configType repository.ConfigType, userHasAdminAccess bool) (*bean.ComponentLevelHistoryDetailDto, error) - GetCmCsHistoryByDeployedOnAndPipelineId(ctx context.Context, pipelineId int, deployedOn time.Time, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) + GetCmCsHistoryByWfrIdAndPipelineId(ctx context.Context, pipelineId int, wfrId int, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) GetCmCsListObjectFromHistory(history *repository.ConfigmapAndSecretHistory) (*bean4.ConfigsList, *bean4.SecretsList, error) } @@ -364,22 +364,22 @@ func (impl *ConfigMapHistoryReadServiceImpl) ConvertConfigDataToComponentLevelDt return componentLevelData, nil } -func (impl *ConfigMapHistoryReadServiceImpl) GetCmCsHistoryByDeployedOnAndPipelineId(ctx context.Context, pipelineId int, deployedOn time.Time, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) { - configData, err := impl.getResolvedConfigData(ctx, pipelineId, deployedOn, configType, userHasAdminAccess) +func (impl *ConfigMapHistoryReadServiceImpl) GetCmCsHistoryByWfrIdAndPipelineId(ctx context.Context, pipelineId int, wfrId int, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) { + configData, err := impl.getResolvedConfigData(ctx, pipelineId, wfrId, configType, userHasAdminAccess) if err != nil { - impl.logger.Errorw("error in getting resolved secret/cm config data in case of previous deployments ", "pipelineId", pipelineId, "deployedOn", deployedOn, "err", err) + impl.logger.Errorw("error in getting resolved secret/cm config data in case of previous deployments ", "pipelineId", pipelineId, "wfrId", wfrId, "err", err) return nil, err } return configData, nil } -func (impl *ConfigMapHistoryReadServiceImpl) getResolvedConfigData(ctx context.Context, pipelineId int, deployedOn time.Time, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) { +func (impl *ConfigMapHistoryReadServiceImpl) getResolvedConfigData(ctx context.Context, pipelineId int, wfrId int, configType repository.ConfigType, userHasAdminAccess bool) (*bean3.DeploymentAndCmCsConfig, error) { configsList := &bean4.ConfigsList{} secretsList := &bean4.SecretsList{} var err error - history, err := impl.configMapHistoryRepository.GetDeployedHistoryByPipelineIdAndDeployedOn(pipelineId, deployedOn, configType) + history, err := impl.configMapHistoryRepository.GetHistoryByPipelineIdAndWfrId(pipelineId, wfrId, configType) if err != nil { - impl.logger.Errorw("error in getting deployed history by pipeline id and deployed on", "pipelineId", pipelineId, "deployedOn", deployedOn, "err", err) + impl.logger.Errorw("error in getting deployed history by pipeline id and deployed on", "pipelineId", pipelineId, "wfrId", wfrId, "err", err) return nil, err } if configType == repository.SECRET_TYPE { @@ -418,13 +418,13 @@ func (impl *ConfigMapHistoryReadServiceImpl) getResolvedConfigData(ctx context.C configDataJson, err := utils.ConvertToJsonRawMessage(configDataReq) if err != nil { - impl.logger.Errorw("getCmCsPublishedConfigResponse, error in converting config data to json raw message", "pipelineId", pipelineId, "deployedOn", deployedOn, "err", err) + impl.logger.Errorw("getCmCsPublishedConfigResponse, error in converting config data to json raw message", "pipelineId", pipelineId, "wfrId", wfrId, "err", err) return nil, err } resolvedConfigDataReq := &bean4.ConfigDataRequest{ConfigData: resolvedConfigDataList} resolvedConfigDataString, err := utils.ConvertToString(resolvedConfigDataReq) if err != nil { - impl.logger.Errorw("getCmCsPublishedConfigResponse, error in converting config data to json raw message", "pipelineId", pipelineId, "deployedOn", deployedOn, "err", err) + impl.logger.Errorw("getCmCsPublishedConfigResponse, error in converting config data to json raw message", "pipelineId", pipelineId, "wfrId", wfrId, "err", err) return nil, err } resolvedConfigDataStringJson, err := utils.ConvertToJsonRawMessage(resolvedConfigDataString) diff --git a/pkg/pipeline/history/repository/ConfigMapHistoryRepository.go b/pkg/pipeline/history/repository/ConfigMapHistoryRepository.go index ebf45afe84..50628891f9 100644 --- a/pkg/pipeline/history/repository/ConfigMapHistoryRepository.go +++ b/pkg/pipeline/history/repository/ConfigMapHistoryRepository.go @@ -35,11 +35,9 @@ type ConfigMapHistoryRepository interface { sql.TransactionWrapper CreateHistory(tx *pg.Tx, model *ConfigmapAndSecretHistory) (*ConfigmapAndSecretHistory, error) GetHistoryForDeployedCMCSById(id, pipelineId int, configType ConfigType) (*ConfigmapAndSecretHistory, error) - GetDeploymentDetailsForDeployedCMCSHistory(pipelineId int, configType ConfigType) ([]*ConfigmapAndSecretHistory, error) GetHistoryByPipelineIdAndWfrId(pipelineId, wfrId int, configType ConfigType) (*ConfigmapAndSecretHistory, error) GetDeployedHistoryForPipelineIdOnTime(pipelineId int, deployedOn time.Time, configType ConfigType) (*ConfigmapAndSecretHistory, error) GetDeployedHistoryList(pipelineId, baseConfigId int, configType ConfigType, componentName string) ([]*ConfigmapAndSecretHistory, error) - GetDeployedHistoryByPipelineIdAndDeployedOn(pipelineId int, deployedOn time.Time, configType ConfigType) (*ConfigmapAndSecretHistory, error) } type ConfigMapHistoryRepositoryImpl struct { @@ -106,18 +104,6 @@ func (impl ConfigMapHistoryRepositoryImpl) GetHistoryForDeployedCMCSById(id, pip return &history, nil } -func (impl ConfigMapHistoryRepositoryImpl) GetDeploymentDetailsForDeployedCMCSHistory(pipelineId int, configType ConfigType) ([]*ConfigmapAndSecretHistory, error) { - var histories []*ConfigmapAndSecretHistory - err := impl.dbConnection.Model(&histories).Where("pipeline_id = ?", pipelineId). - Where("data_type = ?", configType). - Where("deployed = ?", true).Select() - if err != nil { - impl.logger.Errorw("error in getting deployed CM/CS history", "err", err) - return histories, err - } - return histories, nil -} - func (impl ConfigMapHistoryRepositoryImpl) GetHistoryByPipelineIdAndWfrId(pipelineId, wfrId int, configType ConfigType) (*ConfigmapAndSecretHistory, error) { var history ConfigmapAndSecretHistory query := "SELECT cmh.* FROM config_map_history cmh" + @@ -157,14 +143,3 @@ func (impl ConfigMapHistoryRepositoryImpl) GetDeployedHistoryForPipelineIdOnTime Select() return &history, err } - -func (impl ConfigMapHistoryRepositoryImpl) GetDeployedHistoryByPipelineIdAndDeployedOn(pipelineId int, deployedOn time.Time, configType ConfigType) (*ConfigmapAndSecretHistory, error) { - var history ConfigmapAndSecretHistory - err := impl.dbConnection.Model(&history). - Where("pipeline_id = ?", pipelineId). - Where("data_type = ?", configType). - Where("deployed_on = ?", deployedOn). - Where("deployed = ?", true). - Select() - return &history, err -} diff --git a/pkg/pipeline/history/repository/PipelineStrategyHistoryRepository.go b/pkg/pipeline/history/repository/PipelineStrategyHistoryRepository.go index 755d38686c..092a81239e 100644 --- a/pkg/pipeline/history/repository/PipelineStrategyHistoryRepository.go +++ b/pkg/pipeline/history/repository/PipelineStrategyHistoryRepository.go @@ -35,7 +35,6 @@ type PipelineStrategyHistoryRepository interface { GetHistoryByPipelineIdAndWfrId(ctx context.Context, pipelineId, wfrId int) (*PipelineStrategyHistory, error) CheckIfTriggerHistoryExistsForPipelineIdOnTime(pipelineId int, deployedOn time.Time) (bool, error) GetDeployedHistoryList(pipelineId, baseConfigId int) ([]*PipelineStrategyHistory, error) - FindPipelineStrategyForDeployedOnAndPipelineId(pipelineId int, deployedOn time.Time) (PipelineStrategyHistory, error) } type PipelineStrategyHistoryRepositoryImpl struct { @@ -146,11 +145,3 @@ func (impl PipelineStrategyHistoryRepositoryImpl) CheckIfTriggerHistoryExistsFor Exists() return exists, err } - -func (impl PipelineStrategyHistoryRepositoryImpl) FindPipelineStrategyForDeployedOnAndPipelineId(pipelineId int, deployedOn time.Time) (PipelineStrategyHistory, error) { - var history PipelineStrategyHistory - err := impl.dbConnection.Model(&history). - Where("pipeline_strategy_history.deployed_on = ?", deployedOn). - Where("pipeline_strategy_history.pipeline_id = ?", pipelineId).Select() - return history, err -} From e5a6a00236a0ae6541fd17c7b6ccd73c6bb34aa8 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Sun, 1 Dec 2024 18:15:01 +0530 Subject: [PATCH 14/19] bug fix --- pkg/configDiff/utils/utils.go | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/pkg/configDiff/utils/utils.go b/pkg/configDiff/utils/utils.go index f33a296b9e..37a433ff45 100644 --- a/pkg/configDiff/utils/utils.go +++ b/pkg/configDiff/utils/utils.go @@ -40,8 +40,12 @@ func GetKeyValMapForSecretConfigDataAndMaskData(configDataList []*bean.ConfigDat if secretConfigData.IsESOExternalSecretType() || secretConfigData.External { continue } + secretRawData := secretConfigData.Data + if secretConfigData.Global { + secretRawData = secretConfigData.DefaultData + } var secretData map[string]string - if err := json.Unmarshal(secretConfigData.Data, &secretData); err != nil { + if err := json.Unmarshal(secretRawData, &secretData); err != nil { return nil, err } newMaskedSecretData := make(map[string]string, len(secretData)) @@ -56,7 +60,11 @@ func GetKeyValMapForSecretConfigDataAndMaskData(configDataList []*bean.ConfigDat if err != nil { return nil, err } - secretConfigData.Data = maskedSecretJson + if secretConfigData.Global { + secretConfigData.DefaultData = maskedSecretJson + } else { + secretConfigData.Data = maskedSecretJson + } } return keyValMapForSecretConfig, nil } @@ -72,8 +80,12 @@ func CompareAndMaskSecretValuesInConfigData(configDataList []*bean.ConfigData, k if secretConfigData.IsESOExternalSecretType() || secretConfigData.External { continue } + secretConfig := secretConfigData.Data + if secretConfigData.Global { + secretConfig = secretConfigData.DefaultData + } var secretDataMap map[string]string - if err := json.Unmarshal(secretConfigData.Data, &secretDataMap); err != nil { + if err := json.Unmarshal(secretConfig, &secretDataMap); err != nil { return err } if _, ok := keyValMapForSecretConfig1[secretConfigData.Name]; ok { @@ -94,7 +106,12 @@ func CompareAndMaskSecretValuesInConfigData(configDataList []*bean.ConfigData, k if err != nil { return err } - secretConfigData.Data = maskedSecretJson + if secretConfigData.Global { + secretConfigData.DefaultData = maskedSecretJson + } else { + secretConfigData.Data = maskedSecretJson + } + } else { //mask all the secret values with SecretMaskedValue(i.e. "********") newMaskedSecretData := make(map[string]string, len(secretDataMap)) @@ -105,7 +122,12 @@ func CompareAndMaskSecretValuesInConfigData(configDataList []*bean.ConfigData, k if err != nil { return err } - secretConfigData.Data = maskedSecretJson + if secretConfigData.Global { + secretConfigData.DefaultData = maskedSecretJson + } else { + secretConfigData.Data = maskedSecretJson + } + } } return nil From 22cd18ab05d6c326c5cb9a059fac4d42aaed47e6 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Tue, 3 Dec 2024 00:44:11 +0530 Subject: [PATCH 15/19] dev test fix:- instead of checking on global field in secret config data while unmarshalling leverage data and defaultData fields --- .../DeploymentConfigurationRestHandler.go | 1 - pkg/configDiff/bean/bean.go | 2 +- pkg/configDiff/utils/utils.go | 30 +++++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go index 1df240c9db..116b743507 100644 --- a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go +++ b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go @@ -197,7 +197,6 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) return } - //res.IsAppAdmin = handler.enforceForAppAndEnv(configDataQueryParams.AppName, configDataQueryParams.EnvName, token, casbin.ActionUpdate) common.WriteJsonResp(w, nil, res, http.StatusOK) } diff --git a/pkg/configDiff/bean/bean.go b/pkg/configDiff/bean/bean.go index 9c4bbb6e2d..8693341005 100644 --- a/pkg/configDiff/bean/bean.go +++ b/pkg/configDiff/bean/bean.go @@ -144,7 +144,7 @@ type DeploymentAndCmCsConfigDto struct { SecretsData *DeploymentAndCmCsConfig `json:"secretsData"` PipelineConfigData *DeploymentAndCmCsConfig `json:"pipelineConfigData,omitempty"` IsAppAdmin bool `json:"isAppAdmin"` - Index int `json:"index,omitempty"` + Index int `json:"index"` } func NewDeploymentAndCmCsConfigDto() *DeploymentAndCmCsConfigDto { diff --git a/pkg/configDiff/utils/utils.go b/pkg/configDiff/utils/utils.go index 37a433ff45..de69021f4f 100644 --- a/pkg/configDiff/utils/utils.go +++ b/pkg/configDiff/utils/utils.go @@ -40,9 +40,9 @@ func GetKeyValMapForSecretConfigDataAndMaskData(configDataList []*bean.ConfigDat if secretConfigData.IsESOExternalSecretType() || secretConfigData.External { continue } - secretRawData := secretConfigData.Data - if secretConfigData.Global { - secretRawData = secretConfigData.DefaultData + secretRawData := secretConfigData.DefaultData + if len(secretConfigData.Data) > 0 { + secretRawData = secretConfigData.Data } var secretData map[string]string if err := json.Unmarshal(secretRawData, &secretData); err != nil { @@ -60,10 +60,10 @@ func GetKeyValMapForSecretConfigDataAndMaskData(configDataList []*bean.ConfigDat if err != nil { return nil, err } - if secretConfigData.Global { - secretConfigData.DefaultData = maskedSecretJson - } else { + if len(secretConfigData.Data) > 0 { secretConfigData.Data = maskedSecretJson + } else { + secretConfigData.DefaultData = maskedSecretJson } } return keyValMapForSecretConfig, nil @@ -80,9 +80,9 @@ func CompareAndMaskSecretValuesInConfigData(configDataList []*bean.ConfigData, k if secretConfigData.IsESOExternalSecretType() || secretConfigData.External { continue } - secretConfig := secretConfigData.Data - if secretConfigData.Global { - secretConfig = secretConfigData.DefaultData + secretConfig := secretConfigData.DefaultData + if len(secretConfigData.Data) > 0 { + secretConfig = secretConfigData.Data } var secretDataMap map[string]string if err := json.Unmarshal(secretConfig, &secretDataMap); err != nil { @@ -106,10 +106,10 @@ func CompareAndMaskSecretValuesInConfigData(configDataList []*bean.ConfigData, k if err != nil { return err } - if secretConfigData.Global { - secretConfigData.DefaultData = maskedSecretJson - } else { + if len(secretConfigData.Data) > 0 { secretConfigData.Data = maskedSecretJson + } else { + secretConfigData.DefaultData = maskedSecretJson } } else { @@ -122,10 +122,10 @@ func CompareAndMaskSecretValuesInConfigData(configDataList []*bean.ConfigData, k if err != nil { return err } - if secretConfigData.Global { - secretConfigData.DefaultData = maskedSecretJson - } else { + if len(secretConfigData.Data) > 0 { secretConfigData.Data = maskedSecretJson + } else { + secretConfigData.DefaultData = maskedSecretJson } } From e3ae3a03123c1cf5ab8d136e6b83406fb40d6668 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Tue, 3 Dec 2024 14:02:59 +0530 Subject: [PATCH 16/19] first depl fix --- .../pipelineConfig/CdWorfkflowRepository.go | 17 ++++++++++++++ .../DeploymentConfigurationService.go | 23 +++++++++++++++++-- wire_gen.go | 2 +- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go b/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go index abd4444103..5acce38e04 100644 --- a/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go +++ b/internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go @@ -79,6 +79,7 @@ type CdWorkflowRepository interface { MigrateIsArtifactUploaded(wfrId int, isArtifactUploaded bool) MigrateCdArtifactLocation(wfrId int, cdArtifactLocation string) + FindDeployedCdWorkflowRunnersByPipelineId(pipelineId int) ([]*CdWorkflowRunner, error) } type CdWorkflowRepositoryImpl struct { @@ -761,3 +762,19 @@ func (impl *CdWorkflowRepositoryImpl) MigrateCdArtifactLocation(wfrId int, cdArt impl.logger.Errorw("error in updating cd artifact location", "wfrId", wfrId, "err", err) } } + +func (impl *CdWorkflowRepositoryImpl) FindDeployedCdWorkflowRunnersByPipelineId(pipelineId int) ([]*CdWorkflowRunner, error) { + var runners []*CdWorkflowRunner + err := impl.dbConnection. + Model(&runners). + Column("cd_workflow_runner.*", "CdWorkflow"). + Where("cd_workflow.pipeline_id = ?", pipelineId). + Where("workflow_type = ? ", apiBean.CD_WORKFLOW_TYPE_DEPLOY). + Order("cd_workflow_runner.id"). + Select() + if err != nil { + impl.logger.Errorw("error in finding previous co workflow runners by pipeline id ", "pipelineId", pipelineId, "err", err) + return nil, err + } + return runners, nil +} diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index bff8902827..3a266be354 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -60,6 +60,7 @@ type DeploymentConfigurationServiceImpl struct { configMapHistoryService configMapAndSecret.ConfigMapHistoryService deploymentTemplateHistoryReadService read.DeploymentTemplateHistoryReadService configMapHistoryReadService read2.ConfigMapHistoryReadService + cdWorkflowRepository pipelineConfig.CdWorkflowRepository } func NewDeploymentConfigurationServiceImpl(logger *zap.SugaredLogger, @@ -79,6 +80,7 @@ func NewDeploymentConfigurationServiceImpl(logger *zap.SugaredLogger, configMapHistoryService configMapAndSecret.ConfigMapHistoryService, deploymentTemplateHistoryReadService read.DeploymentTemplateHistoryReadService, configMapHistoryReadService read2.ConfigMapHistoryReadService, + cdWorkflowRepository pipelineConfig.CdWorkflowRepository, ) (*DeploymentConfigurationServiceImpl, error) { deploymentConfigurationService := &DeploymentConfigurationServiceImpl{ logger: logger, @@ -98,6 +100,7 @@ func NewDeploymentConfigurationServiceImpl(logger *zap.SugaredLogger, configMapHistoryService: configMapHistoryService, deploymentTemplateHistoryReadService: deploymentTemplateHistoryReadService, configMapHistoryReadService: configMapHistoryReadService, + cdWorkflowRepository: cdWorkflowRepository, } return deploymentConfigurationService, nil @@ -264,8 +267,12 @@ func (impl *DeploymentConfigurationServiceImpl) getConfigDataForDeploymentHistor } configDataDto.WithConfigMapData(cmConfigData) // fetching for cm config ends - - if userHasAdminAccess { + isWfrFirstDeployment, err := impl.IsFirstDeployment(configDataQueryParams.PipelineId, configDataQueryParams.WfrId) + if err != nil { + impl.logger.Errorw("error in checking if a single deployment history is present for pipelineId or not", "pipelineId", configDataQueryParams.PipelineId, "err", err) + return nil, err + } + if userHasAdminAccess || isWfrFirstDeployment { // fetching for cs config starts secretConfigDto, err := impl.getCmCsConfigHistory(ctx, configDataQueryParams, repository3.SECRET_TYPE, userHasAdminAccess) if err != nil { @@ -279,6 +286,18 @@ func (impl *DeploymentConfigurationServiceImpl) getConfigDataForDeploymentHistor return configDataDto, nil } +func (impl *DeploymentConfigurationServiceImpl) IsFirstDeployment(pipelineId, wfrId int) (bool, error) { + wfrs, err := impl.cdWorkflowRepository.FindDeployedCdWorkflowRunnersByPipelineId(pipelineId) + if err != nil { + impl.logger.Errorw("error in getting all cd workflow runners for a pipeline id", "pipelineId", pipelineId, "err", err) + return false, err + } + if len(wfrs) > 0 && wfrs[0].Id == wfrId { + return true, nil + } + return false, nil +} + func (impl *DeploymentConfigurationServiceImpl) getCmCsConfigHistory(ctx context.Context, configDataQueryParams *bean2.ConfigDataQueryParams, configType repository3.ConfigType, userHasAdminAccess bool) (*bean2.DeploymentAndCmCsConfig, error) { var resourceType bean.ResourceType history, err := impl.configMapHistoryRepository.GetHistoryByPipelineIdAndWfrId(configDataQueryParams.PipelineId, configDataQueryParams.WfrId, configType) diff --git a/wire_gen.go b/wire_gen.go index 6537a009a4..0468bb9c72 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -992,7 +992,7 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - deploymentConfigurationServiceImpl, err := configDiff.NewDeploymentConfigurationServiceImpl(sugaredLogger, configMapServiceImpl, appRepositoryImpl, environmentRepositoryImpl, chartServiceImpl, generateManifestDeploymentTemplateServiceImpl, deploymentTemplateHistoryRepositoryImpl, pipelineStrategyHistoryRepositoryImpl, configMapHistoryRepositoryImpl, scopedVariableCMCSManagerImpl, configMapRepositoryImpl, pipelineDeploymentConfigServiceImpl, chartRefServiceImpl, pipelineRepositoryImpl, configMapHistoryServiceImpl, deploymentTemplateHistoryReadServiceImpl, configMapHistoryReadServiceImpl) + deploymentConfigurationServiceImpl, err := configDiff.NewDeploymentConfigurationServiceImpl(sugaredLogger, configMapServiceImpl, appRepositoryImpl, environmentRepositoryImpl, chartServiceImpl, generateManifestDeploymentTemplateServiceImpl, deploymentTemplateHistoryRepositoryImpl, pipelineStrategyHistoryRepositoryImpl, configMapHistoryRepositoryImpl, scopedVariableCMCSManagerImpl, configMapRepositoryImpl, pipelineDeploymentConfigServiceImpl, chartRefServiceImpl, pipelineRepositoryImpl, configMapHistoryServiceImpl, deploymentTemplateHistoryReadServiceImpl, configMapHistoryReadServiceImpl, cdWorkflowRepositoryImpl) if err != nil { return nil, err } From 457febeece2c8427c1528bbaff5c0e259f010664 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Wed, 4 Dec 2024 17:22:15 +0530 Subject: [PATCH 17/19] mask secret in case of view only when request is for only one secret --- pkg/configDiff/DeploymentConfigurationService.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 3a266be354..0c72ca50a5 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -581,9 +581,16 @@ func (impl *DeploymentConfigurationServiceImpl) getCmCsEditDataForPublishedOnly( } cmcsConfigData, err := fetchConfigFunc(configDataQueryParams.ResourceName, configDataQueryParams.ResourceId, envId, appId) if err != nil { - impl.logger.Errorw("getCmCsEditDataForPublishedOnly, error in getting config response", "resourceName", configDataQueryParams.ResourceName, "envName", configDataQueryParams.EnvName, "err", err) + impl.logger.Errorw("error in getting config response", "resourceName", configDataQueryParams.ResourceName, "envName", configDataQueryParams.EnvName, "err", err) return nil, err } + if configDataQueryParams.IsResourceTypeSecret() && !userHasAdminAccess { + _, err := utils.GetKeyValMapForSecretConfigDataAndMaskData(cmcsConfigData.ConfigData) + if err != nil { + impl.logger.Errorw("error in getting config response", "resourceName", configDataQueryParams.ResourceName, "envName", configDataQueryParams.EnvName, "err", err) + return nil, err + } + } respJson, err := utils.ConvertToJsonRawMessage(cmcsConfigData) if err != nil { From d3ad04a2df3c8e63eb579a1ca3fc5e9e383d3166 Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Thu, 5 Dec 2024 13:31:25 +0530 Subject: [PATCH 18/19] code review --- .../DeploymentConfigurationService.go | 4 +-- pkg/pipeline/ConfigMapService.go | 28 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pkg/configDiff/DeploymentConfigurationService.go b/pkg/configDiff/DeploymentConfigurationService.go index 0c72ca50a5..d6b6270841 100644 --- a/pkg/configDiff/DeploymentConfigurationService.go +++ b/pkg/configDiff/DeploymentConfigurationService.go @@ -927,7 +927,7 @@ func (impl *DeploymentConfigurationServiceImpl) getSecretConfigResponse(resource if envId > 0 { return impl.configMapService.CSEnvironmentFetchForEdit(resourceName, resourceId, appId, envId) } - return impl.configMapService.ConfigGlobalFetchEditUsingAppId(resourceName, appId, bean.CS) + return impl.configMapService.CmCsConfigGlobalFetchUsingAppId(resourceName, appId, bean.CS) } if envId > 0 { @@ -941,7 +941,7 @@ func (impl *DeploymentConfigurationServiceImpl) getConfigMapResponse(resourceNam if envId > 0 { return impl.configMapService.CMEnvironmentFetchForEdit(resourceName, resourceId, appId, envId) } - return impl.configMapService.ConfigGlobalFetchEditUsingAppId(resourceName, appId, bean.CM) + return impl.configMapService.CmCsConfigGlobalFetchUsingAppId(resourceName, appId, bean.CM) } if envId > 0 { diff --git a/pkg/pipeline/ConfigMapService.go b/pkg/pipeline/ConfigMapService.go index 5eef93c671..eebd77202f 100644 --- a/pkg/pipeline/ConfigMapService.go +++ b/pkg/pipeline/ConfigMapService.go @@ -54,7 +54,9 @@ type ConfigMapService interface { CMEnvironmentFetch(appId int, envId int) (*bean.ConfigDataRequest, error) CMGlobalFetchForEdit(name string, id int) (*bean.ConfigDataRequest, error) CMEnvironmentFetchForEdit(name string, id int, appId int, envId int) (*bean.ConfigDataRequest, error) - ConfigGlobalFetchEditUsingAppId(name string, appId int, resourceType bean.ResourceType) (*bean.ConfigDataRequest, error) + + CmCsConfigGlobalFetchUsingAppId(name string, appId int, resourceType bean.ResourceType) (*bean.ConfigDataRequest, error) + CmCsConfigOverrideFetchUsingAppAndEnvId(name string, appId, envId int, resourceType bean.ResourceType) (*bean.ConfigDataRequest, error) CSGlobalAddUpdate(configMapRequest *bean.ConfigDataRequest) (*bean.ConfigDataRequest, error) CSGlobalFetch(appId int) (*bean.ConfigDataRequest, error) @@ -1938,7 +1940,7 @@ func (impl ConfigMapServiceImpl) FetchCmCsNamesAppAndEnvLevel(appId int, envId i return cMCSNamesAppLevel, cMCSNamesEnvLevel, nil } -func (impl ConfigMapServiceImpl) ConfigGlobalFetchEditUsingAppId(name string, appId int, resourceType bean.ResourceType) (*bean.ConfigDataRequest, error) { +func (impl ConfigMapServiceImpl) CmCsConfigGlobalFetchUsingAppId(name string, appId int, resourceType bean.ResourceType) (*bean.ConfigDataRequest, error) { var fetchGlobalConfigFunc func(int) (*bean.ConfigDataRequest, error) if resourceType == bean.CS { fetchGlobalConfigFunc = impl.CSGlobalFetch @@ -1959,3 +1961,25 @@ func (impl ConfigMapServiceImpl) ConfigGlobalFetchEditUsingAppId(name string, ap configDataRequest.ConfigData = configs return configDataRequest, nil } + +func (impl ConfigMapServiceImpl) CmCsConfigOverrideFetchUsingAppAndEnvId(name string, appId, envId int, resourceType bean.ResourceType) (*bean.ConfigDataRequest, error) { + var fetchGlobalConfigFunc func(int, int) (*bean.ConfigDataRequest, error) + if resourceType == bean.CS { + fetchGlobalConfigFunc = impl.CSEnvironmentFetch + } else if resourceType == bean.CM { + fetchGlobalConfigFunc = impl.CMEnvironmentFetch + } + configDataRequest, err := fetchGlobalConfigFunc(appId, envId) + if err != nil { + impl.logger.Errorw("error in fetching global cm using app id ", "cmName", name, "appId", appId, "err", err) + return nil, err + } + configs := make([]*bean.ConfigData, 0, len(configDataRequest.ConfigData)) + for _, configData := range configDataRequest.ConfigData { + if configData.Name == name { + configs = append(configs, configData) + } + } + configDataRequest.ConfigData = configs + return configDataRequest, nil +} From 8ef9681e1af81a2f3c6b3b1ea0832645dd47f93d Mon Sep 17 00:00:00 2001 From: Prakash Kumar Date: Mon, 9 Dec 2024 12:37:46 +0530 Subject: [PATCH 19/19] comment --- .../app/configDiff/DeploymentConfigurationRestHandler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go index 116b743507..5d1417b87c 100644 --- a/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go +++ b/api/restHandler/app/configDiff/DeploymentConfigurationRestHandler.go @@ -193,7 +193,7 @@ func (handler *DeploymentConfigurationRestHandlerImpl) CompareCategoryWiseConfig ctx := util2.SetSuperAdminInContext(r.Context(), isSuperAdmin) res, err := handler.deploymentConfigurationService.CompareCategoryWiseConfigData(ctx, comparisonRequestDto, userHasAdminAccess) if err != nil { - handler.logger.Errorw("service err, GetAllConfigData ", "err", err) + handler.logger.Errorw("service err, CompareCategoryWiseConfigData ", "err", err) common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) return }