Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config diff #4619

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1fc038b
story(configDiffView) : open api spec
adi6859 Feb 1, 2024
8eda368
story(configDiffView) : open api spec updated
adi6859 Feb 1, 2024
2d00c6a
story(configDiffView) : open api spec updated for error state
adi6859 Feb 1, 2024
00d1e6c
story(configDiffView) : WIP
adi6859 Feb 1, 2024
4e3582b
story(configDiffView) : WIP "some code changed"
adi6859 Feb 1, 2024
8c9a4cc
story(configDiffView) : support for names added
adi6859 Feb 2, 2024
55a2c0c
story(configDiffView) : iota removed
adi6859 Feb 2, 2024
bcdfa26
story(configDiffView) : pg no rows handled
adi6859 Feb 2, 2024
197db9b
story(configDiffView) : spelling check
adi6859 Feb 2, 2024
7469461
story(configDiffView) : code review comment resolved
adi6859 Feb 5, 2024
c7a145a
story(configDiffView) : env id added
adi6859 Feb 5, 2024
4eaa138
story(configDiffView) : intersection added
adi6859 Feb 5, 2024
256e505
story(configDiffView) : comments removed
adi6859 Feb 5, 2024
47f798f
story(configDiffView) : code review comment resolved
adi6859 Feb 6, 2024
de50f02
story(configDiffView) : comment removed
adi6859 Feb 6, 2024
f2947e3
story(configDiffView) : CMCSNames DTO moved
adi6859 Feb 6, 2024
a3b3271
story(configDiffView) : main merge
adi6859 Feb 7, 2024
44862e9
story(configDiffView) : null case handled
adi6859 Feb 7, 2024
7733ea0
story(configDiffView) : logger added
adi6859 Feb 7, 2024
06e39fc
story(configDiffView) : main merge
adi6859 Feb 8, 2024
e4e39c6
story(configDiffView) : code refactored
adi6859 Feb 8, 2024
dce967a
story(configDiffView) : code refactored v2
adi6859 Feb 8, 2024
4174161
story(configDiffView) : spec updated
adi6859 Feb 8, 2024
186efa7
story(configDiffView) : main merge
adi6859 Feb 13, 2024
736047a
story(configDiffView) : code refactored
adi6859 Feb 14, 2024
16d07d3
story(configDiffView) : config names
adi6859 Feb 14, 2024
3a55c5b
Merge branch 'main' into config-diff
prakash100198 Feb 19, 2024
a4e9c4f
Merge branch 'main' into config-diff
prakash100198 Feb 20, 2024
706afc6
merged with main
vikramdevtron Jun 25, 2024
014e59d
Merge branch 'main' into config-diff
prakash100198 Jul 3, 2024
6196f31
main sync
prakash100198 Jul 3, 2024
e076783
overridden and global flag introduced in config diff autocomplete api
prakash100198 Jul 3, 2024
a1eba0f
Merge branch 'main' into config-diff
prakash100198 Jul 9, 2024
ffa3ba1
ent sync
prakash100198 Jul 9, 2024
4749c45
Merge branch 'main' into config-diff
prakash100198 Jul 16, 2024
0e319d2
Merge branch 'main' into config-diff
prakash100198 Jul 17, 2024
2c5c7c6
using a single key instead of global and overridden key in config/aut…
prakash100198 Jul 17, 2024
8696b08
ConfigState made string instead of int
prakash100198 Jul 17, 2024
a11549f
Merge branch 'main' into config-diff
prakash100198 Jul 23, 2024
f9d9c65
not sending inheriting in case base config
prakash100198 Jul 23, 2024
359022a
Merge branch 'main' into config-diff
prakash100198 Jul 30, 2024
5628d6c
code review comment incorporation
prakash100198 Jul 30, 2024
41784ca
Merge branch 'main' into config-diff
prakash100198 Jul 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ import (
"github.com/devtron-labs/devtron/pkg/chart/gitOpsConfig"
chartRepoRepository "github.com/devtron-labs/devtron/pkg/chartRepo/repository"
"github.com/devtron-labs/devtron/pkg/commonService"
"github.com/devtron-labs/devtron/pkg/configDiff"
delete2 "github.com/devtron-labs/devtron/pkg/delete"
deployment2 "github.com/devtron-labs/devtron/pkg/deployment"
git2 "github.com/devtron-labs/devtron/pkg/deployment/gitOps/git"
Expand Down Expand Up @@ -699,6 +700,13 @@ 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)),
configDiff.NewDeploymentConfigurationServiceImpl,
wire.Bind(new(configDiff.DeploymentConfigurationService), new(*configDiff.DeploymentConfigurationServiceImpl)),

router.NewTelemetryRouterImpl,
wire.Bind(new(router.TelemetryRouter), new(*router.TelemetryRouterImpl)),
restHandler.NewTelemetryRestHandlerImpl,
Expand Down
71 changes: 71 additions & 0 deletions api/restHandler/DeploymentConfigurationRestHandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package restHandler

import (
"fmt"
"github.com/devtron-labs/devtron/api/restHandler/common"
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
"github.com/devtron-labs/devtron/pkg/auth/user"
"github.com/devtron-labs/devtron/pkg/configDiff"
"github.com/devtron-labs/devtron/util/rbac"
"go.uber.org/zap"
"gopkg.in/go-playground/validator.v9"
"net/http"
)

type DeploymentConfigurationRestHandler interface {
ConfigAutoComplete(w http.ResponseWriter, r *http.Request)
}
type DeploymentConfigurationRestHandlerImpl struct {
logger *zap.SugaredLogger
userAuthService user.UserService
adi6859 marked this conversation as resolved.
Show resolved Hide resolved
validator *validator.Validate
enforcerUtil rbac.EnforcerUtil
deploymentConfigurationService configDiff.DeploymentConfigurationService
}

func NewDeploymentConfigurationRestHandlerImpl(logger *zap.SugaredLogger,
userAuthService user.UserService,
enforcerUtil rbac.EnforcerUtil,
deploymentConfigurationService configDiff.DeploymentConfigurationService,
) *DeploymentConfigurationRestHandlerImpl {
return &DeploymentConfigurationRestHandlerImpl{
logger: logger,
userAuthService: userAuthService,
enforcerUtil: enforcerUtil,
deploymentConfigurationService: deploymentConfigurationService,
}
}

func (handler *DeploymentConfigurationRestHandlerImpl) ConfigAutoComplete(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
}
adi6859 marked this conversation as resolved.
Show resolved Hide resolved
appId, err := common.ExtractIntQueryParam(w, r, "appId", 0)
if err != nil {
return
}
envId, err := common.ExtractIntQueryParam(w, r, "envId", 0)
if err != nil {
return
}

//RBAC START
token := r.Header.Get(common.TokenHeaderKey)
object := handler.enforcerUtil.GetAppRBACNameByAppId(appId)
ok := handler.enforcerUtil.CheckAppRbacForAppOrJob(token, object, casbin.ActionGet)
if !ok {
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), nil, http.StatusForbidden)
return
}
//RBAC END

res, err := handler.deploymentConfigurationService.ConfigAutoComplete(appId, envId)
if err != nil {
handler.logger.Errorw("service err, ConfigAutoComplete ", "err", err)
prakash100198 marked this conversation as resolved.
Show resolved Hide resolved
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, err, res, http.StatusOK)
}
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ func (handler *PipelineConfigRestHandlerImpl) GetRestartWorkloadData(w http.Resp
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
envId, err := common.ExtractIntQueryParam(w, r, "envId", nil)
envId, err := common.ExtractIntQueryParam(w, r, "envId", 0)
if err != nil {
return
}
Expand Down
6 changes: 3 additions & 3 deletions api/restHandler/common/ParamParserUtils.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ func convertToIntArray(w http.ResponseWriter, paramValue string) ([]int, error)
return paramValues, nil
}

func ExtractIntQueryParam(w http.ResponseWriter, r *http.Request, paramName string, defaultVal *int) (int, error) {
func ExtractIntQueryParam(w http.ResponseWriter, r *http.Request, paramName string, defaultVal int) (int, error) {
queryParams := r.URL.Query()
paramValue := queryParams.Get(paramName)
if len(paramValue) == 0 {
return *defaultVal, nil
return defaultVal, nil
}
paramIntValue, err := convertToInt(w, paramValue)
if err != nil {
return 0, err
return defaultVal, err
}
return paramIntValue, nil
}
Expand Down
27 changes: 27 additions & 0 deletions api/router/DeploymentConfigRouter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package router

import (
"github.com/devtron-labs/devtron/api/restHandler"
"github.com/gorilla/mux"
)

type DeploymentConfigurationRouter interface {
initDeploymentConfigurationRouter(configRouter *mux.Router)
}

type DeploymentConfigurationRouterImpl struct {
deploymentGroupRestHandler restHandler.DeploymentConfigurationRestHandler
}

func NewDeploymentConfigurationRouter(deploymentGroupRestHandler restHandler.DeploymentConfigurationRestHandler) *DeploymentConfigurationRouterImpl {
router := &DeploymentConfigurationRouterImpl{
deploymentGroupRestHandler: deploymentGroupRestHandler,
}
return router
}

func (router DeploymentConfigurationRouterImpl) initDeploymentConfigurationRouter(configRouter *mux.Router) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

subrouter for orchestrator/config, should add deployment in route. also service does not aligns with the name and route, have to discuss this

configRouter.Path("/autocomplete").
HandlerFunc(router.deploymentGroupRestHandler.ConfigAutoComplete).
Methods("GET")
}
8 changes: 6 additions & 2 deletions api/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ type MuxRouter struct {
rbacRoleRouter user.RbacRoleRouter
scopedVariableRouter ScopedVariableRouter
ciTriggerCron cron.CiTriggerCron
deploymentConfigurationRouter DeploymentConfigurationRouter
infraConfigRouter infraConfig.InfraConfigRouter
argoApplicationRouter argoApplication.ArgoApplicationRouter
devtronResourceRouter devtronResource.DevtronResourceRouter
Expand Down Expand Up @@ -144,6 +145,7 @@ func NewMuxRouter(logger *zap.SugaredLogger,
scopedVariableRouter ScopedVariableRouter,
ciTriggerCron cron.CiTriggerCron,
proxyRouter proxy.ProxyRouter,
deploymentConfigurationRouter DeploymentConfigurationRouter,
infraConfigRouter infraConfig.InfraConfigRouter,
argoApplicationRouter argoApplication.ArgoApplicationRouter,
devtronResourceRouter devtronResource.DevtronResourceRouter) *MuxRouter {
Expand Down Expand Up @@ -206,6 +208,7 @@ func NewMuxRouter(logger *zap.SugaredLogger,
rbacRoleRouter: rbacRoleRouter,
scopedVariableRouter: scopedVariableRouter,
ciTriggerCron: ciTriggerCron,
deploymentConfigurationRouter: deploymentConfigurationRouter,
infraConfigRouter: infraConfigRouter,
argoApplicationRouter: argoApplicationRouter,
devtronResourceRouter: devtronResourceRouter,
Expand Down Expand Up @@ -288,8 +291,9 @@ func (r MuxRouter) Init() {
chartRefRouter := r.Router.PathPrefix("/orchestrator/chartref").Subrouter()
r.ChartRefRouter.initChartRefRouter(chartRefRouter)

configMapRouter := r.Router.PathPrefix("/orchestrator/config").Subrouter()
r.ConfigMapRouter.initConfigMapRouter(configMapRouter)
configRouter := r.Router.PathPrefix("/orchestrator/config").Subrouter()
r.ConfigMapRouter.initConfigMapRouter(configRouter)
r.deploymentConfigurationRouter.initDeploymentConfigurationRouter(configRouter)

appStoreRouter := r.Router.PathPrefix("/orchestrator/app-store").Subrouter()
r.AppStoreRouter.Init(appStoreRouter)
Expand Down
55 changes: 55 additions & 0 deletions internal/sql/repository/chartConfig/ConfigMapRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package chartConfig

import (
"github.com/devtron-labs/devtron/pkg/pipeline/bean"
"github.com/devtron-labs/devtron/pkg/sql"
"github.com/go-pg/pg"
"github.com/go-pg/pg/orm"
Expand All @@ -38,6 +39,7 @@ type ConfigMapRepository interface {
GetByAppIdAppLevel(appId int) (*ConfigMapAppModel, error)
GetByAppIdAndEnvIdEnvLevel(appId int, envId int) (*ConfigMapEnvModel, error)
GetEnvLevelByAppId(appId int) ([]*ConfigMapEnvModel, error)
GetConfigNamesForAppAndEnvLevel(appId int, envId int) ([]bean.ConfigNameAndType, error)
}

type ConfigMapRepositoryImpl struct {
Expand All @@ -49,6 +51,11 @@ func NewConfigMapRepositoryImpl(Logger *zap.SugaredLogger, dbConnection *pg.DB)
return &ConfigMapRepositoryImpl{dbConnection: dbConnection, Logger: Logger}
}

const (
ConfigMapAppLevel string = "config_map_app_level"
ConfigMapEnvLevel string = "config_map_env_level"
)

type ConfigMapAppModel struct {
TableName struct{} `sql:"config_map_app_level" pg:",discard_unknown_columns"`
Id int `sql:"id,pk"`
Expand All @@ -57,6 +64,54 @@ type ConfigMapAppModel struct {
SecretData string `sql:"secret_data"`
sql.AuditLog
}
type cMCSNames struct {
Id int `json:"id"`
CMName string `json:"cm_name"`
CSName string `json:"cs_name"`
}

func (impl ConfigMapRepositoryImpl) GetConfigNamesForAppAndEnvLevel(appId int, envId int) ([]bean.ConfigNameAndType, error) {
var cMCSNames []cMCSNames
tableName := ConfigMapEnvLevel
if envId == -1 {
tableName = ConfigMapAppLevel
}
query := impl.dbConnection.
Model().
Table(tableName).
prakash100198 marked this conversation as resolved.
Show resolved Hide resolved
Column("id").
ColumnExpr("json_array_elements(CASE WHEN (config_map_data::json->'maps')::TEXT != 'null' THEN (config_map_data::json->'maps') ELSE '[]' END )->>'name' AS cm_name").
ColumnExpr("json_array_elements(CASE WHEN (secret_data::json->'secrets')::TEXT != 'null' THEN (secret_data::json->'secrets') ELSE '[]' END )->>'name' AS cs_name").
Comment on lines +84 to +85
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have to add comments here on what we are trying to achieve

Where("app_id = ?", appId)

if envId > 0 {
query = query.Where("environment_id=?", envId)
}
if err := query.Select(&cMCSNames); err != nil {
if err != pg.ErrNoRows {
impl.Logger.Errorw("error occurred while fetching CM/CS names", "appId", appId, "err", err)
return nil, err
}
}
var configNames []bean.ConfigNameAndType
for _, name := range cMCSNames {
if name.CMName != "" {
configNames = append(configNames, bean.ConfigNameAndType{
Id: name.Id,
Name: name.CMName,
Type: bean.CM,
})
}
if name.CSName != "" {
configNames = append(configNames, bean.ConfigNameAndType{
Id: name.Id,
Name: name.CSName,
Type: bean.CS,
})
}
}
return configNames, nil
}

func (impl ConfigMapRepositoryImpl) CreateAppLevel(model *ConfigMapAppModel) (*ConfigMapAppModel, error) {
err := impl.dbConnection.Insert(model)
Expand Down
53 changes: 53 additions & 0 deletions pkg/configDiff/DeploymentConfigurationService.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package configDiff

import (
bean2 "github.com/devtron-labs/devtron/pkg/configDiff/bean"
"github.com/devtron-labs/devtron/pkg/configDiff/helper"
"github.com/devtron-labs/devtron/pkg/pipeline"
"github.com/devtron-labs/devtron/pkg/pipeline/bean"
"go.uber.org/zap"
)

type DeploymentConfigurationService interface {
ConfigAutoComplete(appId int, envId int) (*bean2.ConfigDataResponse, error)
}

type DeploymentConfigurationServiceImpl struct {
logger *zap.SugaredLogger
configMapService pipeline.ConfigMapService
}

func NewDeploymentConfigurationServiceImpl(logger *zap.SugaredLogger,
configMapService pipeline.ConfigMapService,
) (*DeploymentConfigurationServiceImpl, error) {
deploymentConfigurationService := &DeploymentConfigurationServiceImpl{
logger: logger,
configMapService: configMapService,
}

return deploymentConfigurationService, nil
}
func (impl *DeploymentConfigurationServiceImpl) ConfigAutoComplete(appId int, envId int) (*bean2.ConfigDataResponse, error) {
cMCSNamesAppLevel, cMCSNamesEnvLevel, err := impl.configMapService.FetchCmCsNamesAppAndEnvLevel(appId, envId)
if err != nil {
impl.logger.Errorw("error in fetching CM and CS names at app or env level", "appId", appId, "envId", envId, "err", err)
return nil, err
}
cmcsKeyPropertyAppLevelMap, cmcsKeyPropertyEnvLevelMap := helper.GetCmCsAppAndEnvLevelMap(cMCSNamesAppLevel, cMCSNamesEnvLevel)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks more like adapter

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

for key, configProperty := range cmcsKeyPropertyAppLevelMap {
if _, ok := cmcsKeyPropertyEnvLevelMap[key]; !ok {
configProperty.Global = true
}
}
for key, configProperty := range cmcsKeyPropertyEnvLevelMap {
if _, ok := cmcsKeyPropertyAppLevelMap[key]; ok {
configProperty.Global = true
configProperty.Overridden = true
}
}
combinedProperties := helper.GetCombinedPropertiesMap(cmcsKeyPropertyAppLevelMap, cmcsKeyPropertyEnvLevelMap)
combinedProperties = append(combinedProperties, helper.GetConfigProperty(0, "", bean.DeploymentTemplate, bean2.PublishedConfigState))

configDataResp := bean2.NewConfigDataResponse().WithResourceConfig(combinedProperties)
return configDataResp, nil
}
67 changes: 67 additions & 0 deletions pkg/configDiff/bean/bean.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package bean

import (
"fmt"
"github.com/devtron-labs/devtron/pkg/pipeline/bean"
)

type ConfigState int

const (
PublishedConfigState ConfigState = 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why starting from 3?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has been removed, now we don't use enum, just simple string

)

type ConfigProperty struct {
Id int `json:"id"`
Name string `json:"name"`
ConfigState ConfigState `json:"configState"`
Type bean.ResourceType `json:"type"`
Overridden bool `json:"overridden"`
Global bool `json:"global"`
}

func NewConfigProperty() *ConfigProperty {
return &ConfigProperty{}
}

func (r *ConfigProperty) IsConfigPropertyGlobal() bool {
return r.Global
}

func (r *ConfigProperty) SetConfigProperty(Name string, ConfigState ConfigState, Type bean.ResourceType, Overridden bool, Global bool) *ConfigProperty {
r.Name = Name
r.ConfigState = ConfigState
r.Type = Type
r.Overridden = Overridden
r.Global = Global
return r
}

type ConfigDataResponse struct {
ResourceConfig []*ConfigProperty `json:"resourceConfig"`
}

func NewConfigDataResponse() *ConfigDataResponse {
return &ConfigDataResponse{}
}

func (r *ConfigDataResponse) WithResourceConfig(resourceConfig []*ConfigProperty) *ConfigDataResponse {
r.ResourceConfig = resourceConfig
return r
}

func (r *ConfigProperty) GetKey() string {
return fmt.Sprintf("%s-%s", string(r.Type), r.Name)
}

type ConfigPropertyIdentifier struct {
Name string `json:"name"`
Type bean.ResourceType `json:"type"`
}

func (r *ConfigProperty) GetIdentifier() ConfigPropertyIdentifier {
return ConfigPropertyIdentifier{
Name: r.Name,
Type: r.Type,
}
}
Loading
Loading