diff --git a/Wire.go b/Wire.go index fbf6941638..ed33cc998c 100644 --- a/Wire.go +++ b/Wire.go @@ -97,6 +97,8 @@ import ( "github.com/devtron-labs/devtron/pkg/commonService" delete2 "github.com/devtron-labs/devtron/pkg/delete" "github.com/devtron-labs/devtron/pkg/deploymentGroup" + "github.com/devtron-labs/devtron/pkg/devtronResource" + repository9 "github.com/devtron-labs/devtron/pkg/devtronResource/repository" "github.com/devtron-labs/devtron/pkg/dockerRegistry" "github.com/devtron-labs/devtron/pkg/git" "github.com/devtron-labs/devtron/pkg/gitops" @@ -111,6 +113,7 @@ import ( "github.com/devtron-labs/devtron/pkg/plugin" repository6 "github.com/devtron-labs/devtron/pkg/plugin/repository" "github.com/devtron-labs/devtron/pkg/projectManagementService/jira" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/security" "github.com/devtron-labs/devtron/pkg/sql" util3 "github.com/devtron-labs/devtron/pkg/util" @@ -902,6 +905,18 @@ func InitializeApp() (*App, error) { dockerRegistryRepository.NewOCIRegistryConfigRepositoryImpl, wire.Bind(new(dockerRegistryRepository.OCIRegistryConfigRepository), new(*dockerRegistryRepository.OCIRegistryConfigRepositoryImpl)), // end: docker registry wire set injection + + resourceQualifiers.NewQualifiersMappingRepositoryImpl, + wire.Bind(new(resourceQualifiers.QualifiersMappingRepository), new(*resourceQualifiers.QualifiersMappingRepositoryImpl)), + + resourceQualifiers.NewQualifierMappingServiceImpl, + wire.Bind(new(resourceQualifiers.QualifierMappingService), new(*resourceQualifiers.QualifierMappingServiceImpl)), + + repository9.NewDevtronResourceSearchableKeyRepositoryImpl, + wire.Bind(new(repository9.DevtronResourceSearchableKeyRepository), new(*repository9.DevtronResourceSearchableKeyRepositoryImpl)), + + devtronResource.NewDevtronResourceSearchableKeyServiceImpl, + wire.Bind(new(devtronResource.DevtronResourceService), new(*devtronResource.DevtronResourceSearchableKeyServiceImpl)), ) return &App{}, nil } diff --git a/api/restHandler/app/DeploymentPipelineRestHandler.go b/api/restHandler/app/DeploymentPipelineRestHandler.go index 4655864336..4fafec18ba 100644 --- a/api/restHandler/app/DeploymentPipelineRestHandler.go +++ b/api/restHandler/app/DeploymentPipelineRestHandler.go @@ -16,8 +16,8 @@ import ( "github.com/devtron-labs/devtron/pkg/chart" "github.com/devtron-labs/devtron/pkg/pipeline" bean3 "github.com/devtron-labs/devtron/pkg/pipeline/bean" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/user/casbin" - "github.com/devtron-labs/devtron/pkg/variables/models" "github.com/go-pg/pg" "github.com/gorilla/mux" "go.opentelemetry.io/otel" @@ -110,7 +110,7 @@ func (handler PipelineConfigRestHandlerImpl) ConfigureDeploymentTemplateForApp(w } chartRefId := templateRequest.ChartRefId //VARIABLE_RESOLVE - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: templateRequest.AppId, } validate, err2 := handler.chartService.DeploymentTemplateValidate(r.Context(), templateRequest.ValuesOverride, chartRefId, scope) @@ -575,7 +575,7 @@ func (handler PipelineConfigRestHandlerImpl) ChangeChartRef(w http.ResponseWrite } //VARIABLE_RESOLVE - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: request.AppId, EnvId: request.EnvId, ClusterId: envConfigProperties.ClusterId, @@ -696,7 +696,7 @@ func (handler PipelineConfigRestHandlerImpl) EnvConfigOverrideCreate(w http.Resp } chartRefId := envConfigProperties.ChartRefId //VARIABLE_RESOLVE - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: appId, EnvId: environmentId, ClusterId: envConfigProperties.ClusterId, @@ -805,7 +805,7 @@ func (handler PipelineConfigRestHandlerImpl) EnvConfigOverrideUpdate(w http.Resp } chartRefId := envConfigProperties.ChartRefId //VARIABLE_RESOLVE - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: appId, EnvId: envId, ClusterId: envConfigProperties.ClusterId, @@ -1291,7 +1291,7 @@ func (handler PipelineConfigRestHandlerImpl) UpdateAppOverride(w http.ResponseWr } chartRefId := templateRequest.ChartRefId //VARIABLE_RESOLVE - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: templateRequest.AppId, } _, span = otel.Tracer("orchestrator").Start(ctx, "chartService.DeploymentTemplateValidate") diff --git a/api/restHandler/scopedVariable/ScopedVariableRestHandler.go b/api/restHandler/scopedVariable/ScopedVariableRestHandler.go index e3b8b11f54..00e3a47547 100644 --- a/api/restHandler/scopedVariable/ScopedVariableRestHandler.go +++ b/api/restHandler/scopedVariable/ScopedVariableRestHandler.go @@ -7,6 +7,7 @@ import ( "github.com/devtron-labs/devtron/api/restHandler/common" "github.com/devtron-labs/devtron/pkg/bean" "github.com/devtron-labs/devtron/pkg/pipeline" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/user" "github.com/devtron-labs/devtron/pkg/user/casbin" "github.com/devtron-labs/devtron/pkg/variables" @@ -123,7 +124,7 @@ func (handler *ScopedVariableRestHandlerImpl) GetScopedVariables(w http.Response return } - var scope models.Scope + var scope resourceQualifiers.Scope scopeQueryParam := r.URL.Query().Get("scope") if scopeQueryParam != "" { if err := json.Unmarshal([]byte(scopeQueryParam), &scope); err != nil { diff --git a/pkg/app/AppService.go b/pkg/app/AppService.go index 232aa69b49..229ed758f2 100644 --- a/pkg/app/AppService.go +++ b/pkg/app/AppService.go @@ -37,8 +37,8 @@ import ( "github.com/devtron-labs/devtron/pkg/k8s" repository3 "github.com/devtron-labs/devtron/pkg/pipeline/history/repository" repository5 "github.com/devtron-labs/devtron/pkg/pipeline/repository" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/variables" - models2 "github.com/devtron-labs/devtron/pkg/variables/models" "github.com/devtron-labs/devtron/pkg/variables/parsers" _ "github.com/devtron-labs/devtron/pkg/variables/repository" repository6 "github.com/devtron-labs/devtron/pkg/variables/repository" @@ -1251,7 +1251,7 @@ func (impl *AppServiceImpl) GetDeploymentStrategyByTriggerType(overrideRequest * func (impl *AppServiceImpl) GetEnvOverrideByTriggerType(overrideRequest *bean.ValuesOverrideRequest, triggeredAt time.Time, ctx context.Context) (*chartConfig.EnvConfigOverride, error) { //VARIABLE different cases for variable resolution - scope := models2.Scope{ + scope := resourceQualifiers.Scope{ AppId: overrideRequest.AppId, EnvId: overrideRequest.EnvId, ClusterId: overrideRequest.ClusterId, @@ -1438,7 +1438,7 @@ func (impl *AppServiceImpl) getResolvedTemplateWithSnapshot(deploymentTemplateHi return resolvedTemplate, variableSnapshotMap, nil } -func (impl *AppServiceImpl) extractVariablesAndResolveTemplate(scope models2.Scope, template string, entity repository6.Entity) (string, map[string]string, error) { +func (impl *AppServiceImpl) extractVariablesAndResolveTemplate(scope resourceQualifiers.Scope, template string, entity repository6.Entity) (string, map[string]string, error) { entityToVariables, err := impl.variableEntityMappingService.GetAllMappingsForEntities([]repository6.Entity{entity}) if err != nil { diff --git a/pkg/chart/ChartService.go b/pkg/chart/ChartService.go index fd2c206672..a6e5405026 100644 --- a/pkg/chart/ChartService.go +++ b/pkg/chart/ChartService.go @@ -22,8 +22,8 @@ import ( "context" "encoding/json" "fmt" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/variables" - models2 "github.com/devtron-labs/devtron/pkg/variables/models" "github.com/devtron-labs/devtron/pkg/variables/parsers" repository5 "github.com/devtron-labs/devtron/pkg/variables/repository" @@ -81,7 +81,7 @@ type ChartService interface { FindPreviousChartByAppId(appId int) (chartTemplate *TemplateRequest, err error) UpgradeForApp(appId int, chartRefId int, newAppOverride map[string]interface{}, userId int32, ctx context.Context) (bool, error) AppMetricsEnableDisable(appMetricRequest AppMetricEnableDisableRequest) (*AppMetricEnableDisableRequest, error) - DeploymentTemplateValidate(ctx context.Context, templatejson interface{}, chartRefId int, scope models2.Scope) (bool, error) + DeploymentTemplateValidate(ctx context.Context, templatejson interface{}, chartRefId int, scope resourceQualifiers.Scope) (bool, error) JsonSchemaExtractFromFile(chartRefId int) (map[string]interface{}, string, error) GetSchemaAndReadmeForTemplateByChartRefId(chartRefId int) (schema []byte, readme []byte, err error) ExtractChartIfMissing(chartData []byte, refChartDir string, location string) (*ChartDataInfo, error) @@ -1330,7 +1330,7 @@ const cpuPattern = `"50m" or "0.05"` const cpu = "cpu" const memory = "memory" -func (impl ChartServiceImpl) extractVariablesAndResolveTemplate(scope models2.Scope, template string) (string, error) { +func (impl ChartServiceImpl) extractVariablesAndResolveTemplate(scope resourceQualifiers.Scope, template string) (string, error) { usedVariables, err := impl.variableTemplateParser.ExtractVariables(template) if err != nil { @@ -1356,7 +1356,7 @@ func (impl ChartServiceImpl) extractVariablesAndResolveTemplate(scope models2.Sc return resolvedTemplate, nil } -func (impl ChartServiceImpl) DeploymentTemplateValidate(ctx context.Context, template interface{}, chartRefId int, scope models2.Scope) (bool, error) { +func (impl ChartServiceImpl) DeploymentTemplateValidate(ctx context.Context, template interface{}, chartRefId int, scope resourceQualifiers.Scope) (bool, error) { _, span := otel.Tracer("orchestrator").Start(ctx, "JsonSchemaExtractFromFile") schemajson, version, err := impl.JsonSchemaExtractFromFile(chartRefId) span.End() diff --git a/pkg/devtronResource/DevtronResourceService.go b/pkg/devtronResource/DevtronResourceService.go new file mode 100644 index 0000000000..d77c9c85f3 --- /dev/null +++ b/pkg/devtronResource/DevtronResourceService.go @@ -0,0 +1,60 @@ +package devtronResource + +import ( + "github.com/devtron-labs/devtron/pkg/devtronResource/bean" + "github.com/devtron-labs/devtron/pkg/devtronResource/repository" + "go.uber.org/zap" +) + +type DevtronResourceService interface { + GetAllSearchableKeyNameIdMap() map[bean.DevtronResourceSearchableKeyName]int + GetAllSearchableKeyIdNameMap() map[int]bean.DevtronResourceSearchableKeyName +} + +type DevtronResourceSearchableKeyServiceImpl struct { + logger *zap.SugaredLogger + devtronResourceSearchableKeyRepository repository.DevtronResourceSearchableKeyRepository + searchableKeyNameIdMap map[bean.DevtronResourceSearchableKeyName]int + searchableKeyIdNameMap map[int]bean.DevtronResourceSearchableKeyName +} + +func NewDevtronResourceSearchableKeyServiceImpl(logger *zap.SugaredLogger, + devtronResourceSearchableKeyRepository repository.DevtronResourceSearchableKeyRepository) (*DevtronResourceSearchableKeyServiceImpl, error) { + impl := &DevtronResourceSearchableKeyServiceImpl{ + logger: logger, + devtronResourceSearchableKeyRepository: devtronResourceSearchableKeyRepository, + } + searchableKeyNameIdMap, searchableKeyIdNameMap, err := impl.getAllSearchableKeyNameIdAndIdNameMaps() + if err != nil { + impl.logger.Errorw("error, GetAllSearchableKeyNameIdAndIdNameMaps", "err", err) + return nil, err + } + impl.searchableKeyNameIdMap = searchableKeyNameIdMap + impl.searchableKeyIdNameMap = searchableKeyIdNameMap + return impl, nil +} + +func (impl *DevtronResourceSearchableKeyServiceImpl) getAllSearchableKeyNameIdAndIdNameMaps() (map[bean.DevtronResourceSearchableKeyName]int, + map[int]bean.DevtronResourceSearchableKeyName, error) { + //getting searchable keys from db + searchableKeys, err := impl.devtronResourceSearchableKeyRepository.GetAll() + if err != nil { + impl.logger.Errorw("error in getting all attributes from db", "err", err) + return nil, nil, err + } + searchableKeyNameIdMap := make(map[bean.DevtronResourceSearchableKeyName]int) + searchableKeyIdNameMap := make(map[int]bean.DevtronResourceSearchableKeyName) + for _, searchableKey := range searchableKeys { + searchableKeyNameIdMap[searchableKey.Name] = searchableKey.Id + searchableKeyIdNameMap[searchableKey.Id] = searchableKey.Name + } + return searchableKeyNameIdMap, searchableKeyIdNameMap, nil +} + +func (impl *DevtronResourceSearchableKeyServiceImpl) GetAllSearchableKeyNameIdMap() map[bean.DevtronResourceSearchableKeyName]int { + return impl.searchableKeyNameIdMap +} + +func (impl *DevtronResourceSearchableKeyServiceImpl) GetAllSearchableKeyIdNameMap() map[int]bean.DevtronResourceSearchableKeyName { + return impl.searchableKeyIdNameMap +} diff --git a/pkg/devtronResource/bean/bean.go b/pkg/devtronResource/bean/bean.go new file mode 100644 index 0000000000..7e74fc1046 --- /dev/null +++ b/pkg/devtronResource/bean/bean.go @@ -0,0 +1,70 @@ +package bean + +type DevtronResourceSearchableKeyName string + +const ( + DEVTRON_RESOURCE_SEARCHABLE_KEY_PROJECT_APP_NAME DevtronResourceSearchableKeyName = "PROJECT_APP_NAME" + DEVTRON_RESOURCE_SEARCHABLE_KEY_CLUSTER_ENV_NAME DevtronResourceSearchableKeyName = "CLUSTER_ENV_NAME" + DEVTRON_RESOURCE_SEARCHABLE_KEY_IS_ALL_PRODUCTION_ENV DevtronResourceSearchableKeyName = "IS_ALL_PRODUCTION_ENV" + DEVTRON_RESOURCE_SEARCHABLE_KEY_CI_PIPELINE_BRANCH DevtronResourceSearchableKeyName = "CI_PIPELINE_BRANCH" + DEVTRON_RESOURCE_SEARCHABLE_KEY_CI_PIPELINE_TRIGGER_ACTION DevtronResourceSearchableKeyName = "CI_PIPELINE_TRIGGER_ACTION" + DEVTRON_RESOURCE_SEARCHABLE_KEY_APP_ID DevtronResourceSearchableKeyName = "APP_ID" + DEVTRON_RESOURCE_SEARCHABLE_KEY_ENV_ID DevtronResourceSearchableKeyName = "ENV_ID" + DEVTRON_RESOURCE_SEARCHABLE_KEY_CLUSTER_ID DevtronResourceSearchableKeyName = "CLUSTER_ID" +) + +func (n DevtronResourceSearchableKeyName) ToString() string { + return string(n) +} + +type DevtronResourceName string + +const ( + DEVTRON_RESOURCE_PROJECT DevtronResourceName = "PROJECT" + DEVTRON_RESOURCE_APP DevtronResourceName = "APP" + DEVTRON_RESOURCE_CLUSTER DevtronResourceName = "CLUSTER" + DEVTRON_RESOURCE_ENVIRONMENT DevtronResourceName = "ENVIRONMENT" + DEVTRON_RESOURCE_CI_PIPELINE DevtronResourceName = "CI_PIPELINE" + DEVTRON_RESOURCE_CD_PIPELINE DevtronResourceName = "CD_PIPELINE" +) + +func (n DevtronResourceName) ToString() string { + return string(n) +} + +type DevtronResourceAttributeName string + +const ( + DEVTRON_RESOURCE_ATTRIBUTE_APP_NAME DevtronResourceAttributeName = "APP_NAME" + DEVTRON_RESOURCE_ATTRIBUTE_PROJECT_NAME DevtronResourceAttributeName = "PROJECT_NAME" + DEVTRON_RESOURCE_ATTRIBUTE_CLUSTER_NAME DevtronResourceAttributeName = "CLUSTER_NAME" + DEVTRON_RESOURCE_ATTRIBUTE_ENVIRONMENT_NAME DevtronResourceAttributeName = "ENVIRONMENT_NAME" + DEVTRON_RESOURCE_ATTRIBUTE_ENVIRONMENT_IS_PRODUCTION DevtronResourceAttributeName = "IS_PRODUCTION_ENVIRONMENT" + DEVTRON_RESOURCE_ATTRIBUTE_CI_PIPELINE_BRANCH_VALUE DevtronResourceAttributeName = "CI_PIPELINE_BRANCH_VALUE" + DEVTRON_RESOURCE_ATTRIBUTE_CI_PIPELINE_STAGE DevtronResourceAttributeName = "CI_PIPELINE_STAGE" +) + +func (n DevtronResourceAttributeName) ToString() string { + return string(n) +} + +type DevtronResourceAttributeType string + +const ( + DEVTRON_RESOURCE_ATTRIBUTE_TYPE_PLUGIN DevtronResourceAttributeType = "PLUGIN" +) + +func (n DevtronResourceAttributeType) ToString() string { + return string(n) +} + +type ValueType string + +const ( + VALUE_TYPE_REGEX ValueType = "REGEX" + VALUE_TYPE_FIXED ValueType = "FIXED" +) + +func (v ValueType) ToString() string { + return string(v) +} diff --git a/pkg/devtronResource/mocks/DevtronResourceService.go b/pkg/devtronResource/mocks/DevtronResourceService.go new file mode 100644 index 0000000000..05e539a1a6 --- /dev/null +++ b/pkg/devtronResource/mocks/DevtronResourceService.go @@ -0,0 +1,61 @@ +// Code generated by mockery v2.20.0. DO NOT EDIT. + +package mocks + +import ( + bean "github.com/devtron-labs/devtron/pkg/devtronResource/bean" + + mock "github.com/stretchr/testify/mock" +) + +// DevtronResourceService is an autogenerated mock type for the DevtronResourceService type +type DevtronResourceService struct { + mock.Mock +} + +// GetAllSearchableKeyIdNameMap provides a mock function with given fields: +func (_m *DevtronResourceService) GetAllSearchableKeyIdNameMap() map[int]bean.DevtronResourceSearchableKeyName { + ret := _m.Called() + + var r0 map[int]bean.DevtronResourceSearchableKeyName + if rf, ok := ret.Get(0).(func() map[int]bean.DevtronResourceSearchableKeyName); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[int]bean.DevtronResourceSearchableKeyName) + } + } + + return r0 +} + +// GetAllSearchableKeyNameIdMap provides a mock function with given fields: +func (_m *DevtronResourceService) GetAllSearchableKeyNameIdMap() map[bean.DevtronResourceSearchableKeyName]int { + ret := _m.Called() + + var r0 map[bean.DevtronResourceSearchableKeyName]int + if rf, ok := ret.Get(0).(func() map[bean.DevtronResourceSearchableKeyName]int); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[bean.DevtronResourceSearchableKeyName]int) + } + } + + return r0 +} + +type mockConstructorTestingTNewDevtronResourceService interface { + mock.TestingT + Cleanup(func()) +} + +// NewDevtronResourceService creates a new instance of DevtronResourceService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewDevtronResourceService(t mockConstructorTestingTNewDevtronResourceService) *DevtronResourceService { + mock := &DevtronResourceService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/devtronResource/repository/DevtronResourceSearchableKeyRepository.go b/pkg/devtronResource/repository/DevtronResourceSearchableKeyRepository.go new file mode 100644 index 0000000000..abb5fd5ae0 --- /dev/null +++ b/pkg/devtronResource/repository/DevtronResourceSearchableKeyRepository.go @@ -0,0 +1,43 @@ +package repository + +import ( + "github.com/devtron-labs/devtron/pkg/devtronResource/bean" + "github.com/devtron-labs/devtron/pkg/sql" + "github.com/go-pg/pg" + "go.uber.org/zap" +) + +type DevtronResourceSearchableKeyRepository interface { + GetAll() ([]*DevtronResourceSearchableKey, error) +} + +type DevtronResourceSearchableKeyRepositoryImpl struct { + logger *zap.SugaredLogger + dbConnection *pg.DB +} + +func NewDevtronResourceSearchableKeyRepositoryImpl(logger *zap.SugaredLogger, + dbConnection *pg.DB) *DevtronResourceSearchableKeyRepositoryImpl { + return &DevtronResourceSearchableKeyRepositoryImpl{ + logger: logger, + dbConnection: dbConnection, + } +} + +type DevtronResourceSearchableKey struct { + tableName struct{} `sql:"devtron_resource_searchable_key" pg:",discard_unknown_columns"` + Id int `sql:"id,pk"` + Name bean.DevtronResourceSearchableKeyName `sql:"name"` + IsRemoved bool `sql:"is_removed,notnull"` + sql.AuditLog +} + +func (repo *DevtronResourceSearchableKeyRepositoryImpl) GetAll() ([]*DevtronResourceSearchableKey, error) { + var models []*DevtronResourceSearchableKey + err := repo.dbConnection.Model(&models).Where("is_removed = ?", false).Select() + if err != nil { + repo.logger.Errorw("error in getting all devtron resources searchable key", "err", err) + return nil, err + } + return models, nil +} diff --git a/pkg/devtronResource/repository/mocks/DevtronResourceSearchableKeyRepository.go b/pkg/devtronResource/repository/mocks/DevtronResourceSearchableKeyRepository.go new file mode 100644 index 0000000000..1ee67ebfbd --- /dev/null +++ b/pkg/devtronResource/repository/mocks/DevtronResourceSearchableKeyRepository.go @@ -0,0 +1,51 @@ +// Code generated by mockery v2.14.0. DO NOT EDIT. + +package mocks + +import ( + repository "github.com/devtron-labs/devtron/pkg/devtronResource/repository" + mock "github.com/stretchr/testify/mock" +) + +// DevtronResourceSearchableKeyRepository is an autogenerated mock type for the DevtronResourceSearchableKeyRepository type +type DevtronResourceSearchableKeyRepository struct { + mock.Mock +} + +// GetAll provides a mock function with given fields: +func (_m *DevtronResourceSearchableKeyRepository) GetAll() ([]*repository.DevtronResourceSearchableKey, error) { + ret := _m.Called() + + var r0 []*repository.DevtronResourceSearchableKey + if rf, ok := ret.Get(0).(func() []*repository.DevtronResourceSearchableKey); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*repository.DevtronResourceSearchableKey) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewDevtronResourceSearchableKeyRepository interface { + mock.TestingT + Cleanup(func()) +} + +// NewDevtronResourceSearchableKeyRepository creates a new instance of DevtronResourceSearchableKeyRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewDevtronResourceSearchableKeyRepository(t mockConstructorTestingTNewDevtronResourceSearchableKeyRepository) *DevtronResourceSearchableKeyRepository { + mock := &DevtronResourceSearchableKeyRepository{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/pipeline/CiService.go b/pkg/pipeline/CiService.go index 5b1004079a..383a65d6b8 100644 --- a/pkg/pipeline/CiService.go +++ b/pkg/pipeline/CiService.go @@ -30,9 +30,9 @@ import ( "github.com/devtron-labs/devtron/pkg/pipeline/history" "github.com/devtron-labs/devtron/pkg/pipeline/repository" repository2 "github.com/devtron-labs/devtron/pkg/plugin/repository" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/user" "github.com/devtron-labs/devtron/pkg/variables" - "github.com/devtron-labs/devtron/pkg/variables/models" repository4 "github.com/devtron-labs/devtron/pkg/variables/repository" "github.com/go-pg/pg" "path/filepath" @@ -56,23 +56,23 @@ type CiService interface { } type CiServiceImpl struct { - Logger *zap.SugaredLogger - workflowService WorkflowService - ciPipelineMaterialRepository pipelineConfig.CiPipelineMaterialRepository - ciWorkflowRepository pipelineConfig.CiWorkflowRepository - eventClient client.EventClient - eventFactory client.EventFactory - mergeUtil *util.MergeUtil - ciPipelineRepository pipelineConfig.CiPipelineRepository - prePostCiScriptHistoryService history.PrePostCiScriptHistoryService - pipelineStageService PipelineStageService - userService user.UserService - ciTemplateService CiTemplateService - appCrudOperationService app.AppCrudOperationService - envRepository repository1.EnvironmentRepository - appRepository appRepository.AppRepository + Logger *zap.SugaredLogger + workflowService WorkflowService + ciPipelineMaterialRepository pipelineConfig.CiPipelineMaterialRepository + ciWorkflowRepository pipelineConfig.CiWorkflowRepository + eventClient client.EventClient + eventFactory client.EventFactory + mergeUtil *util.MergeUtil + ciPipelineRepository pipelineConfig.CiPipelineRepository + prePostCiScriptHistoryService history.PrePostCiScriptHistoryService + pipelineStageService PipelineStageService + userService user.UserService + ciTemplateService CiTemplateService + appCrudOperationService app.AppCrudOperationService + envRepository repository1.EnvironmentRepository + appRepository appRepository.AppRepository variableSnapshotHistoryService variables.VariableSnapshotHistoryService - config *CiConfig + config *CiConfig } func NewCiServiceImpl(Logger *zap.SugaredLogger, workflowService WorkflowService, @@ -86,21 +86,21 @@ func NewCiServiceImpl(Logger *zap.SugaredLogger, workflowService WorkflowService variableSnapshotHistoryService variables.VariableSnapshotHistoryService, ) *CiServiceImpl { cis := &CiServiceImpl{ - Logger: Logger, - workflowService: workflowService, - ciPipelineMaterialRepository: ciPipelineMaterialRepository, - ciWorkflowRepository: ciWorkflowRepository, - eventClient: eventClient, - eventFactory: eventFactory, - mergeUtil: mergeUtil, - ciPipelineRepository: ciPipelineRepository, - prePostCiScriptHistoryService: prePostCiScriptHistoryService, - pipelineStageService: pipelineStageService, - userService: userService, - ciTemplateService: ciTemplateService, - appCrudOperationService: appCrudOperationService, - envRepository: envRepository, - appRepository: appRepository, + Logger: Logger, + workflowService: workflowService, + ciPipelineMaterialRepository: ciPipelineMaterialRepository, + ciWorkflowRepository: ciWorkflowRepository, + eventClient: eventClient, + eventFactory: eventFactory, + mergeUtil: mergeUtil, + ciPipelineRepository: ciPipelineRepository, + prePostCiScriptHistoryService: prePostCiScriptHistoryService, + pipelineStageService: pipelineStageService, + userService: userService, + ciTemplateService: ciTemplateService, + appCrudOperationService: appCrudOperationService, + envRepository: envRepository, + appRepository: appRepository, variableSnapshotHistoryService: variableSnapshotHistoryService, } config, err := GetCiConfig() @@ -153,7 +153,7 @@ func (impl *CiServiceImpl) TriggerCiPipeline(trigger Trigger) (int, error) { return 0, err } - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: pipeline.App.Id, } env, isJob, err := impl.getEnvironmentForJob(pipeline, trigger) diff --git a/pkg/pipeline/DeploymentConfigService.go b/pkg/pipeline/DeploymentConfigService.go index 1beec10580..7f5ec89832 100644 --- a/pkg/pipeline/DeploymentConfigService.go +++ b/pkg/pipeline/DeploymentConfigService.go @@ -8,6 +8,7 @@ import ( chartRepoRepository "github.com/devtron-labs/devtron/pkg/chartRepo/repository" "github.com/devtron-labs/devtron/pkg/pipeline/history" repository2 "github.com/devtron-labs/devtron/pkg/pipeline/history/repository" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/variables" "github.com/devtron-labs/devtron/pkg/variables/models" repository6 "github.com/devtron-labs/devtron/pkg/variables/repository" @@ -95,7 +96,7 @@ func (impl *DeploymentConfigServiceImpl) GetLatestDeploymentConfigurationByPipel return configResp, nil } -func (impl *DeploymentConfigServiceImpl) extractVariablesAndGetScopedVariables(scope models.Scope, entity repository6.Entity) (map[string]string, error) { +func (impl *DeploymentConfigServiceImpl) extractVariablesAndGetScopedVariables(scope resourceQualifiers.Scope, entity repository6.Entity) (map[string]string, error) { variableMap := make(map[string]string) entityToVariables, err := impl.variableEntityMappingService.GetAllMappingsForEntities([]repository6.Entity{entity}) @@ -145,7 +146,7 @@ func (impl *DeploymentConfigServiceImpl) GetLatestDeploymentTemplateConfig(pipel impl.logger.Errorw("error in getting chartRef by id", "err", err, "chartRefId", envOverride.Chart.ChartRefId) return nil, err } - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: pipeline.AppId, EnvId: pipeline.EnvironmentId, ClusterId: pipeline.Environment.ClusterId, @@ -182,7 +183,7 @@ func (impl *DeploymentConfigServiceImpl) GetLatestDeploymentTemplateConfig(pipel return nil, err } //Scope contains env and cluster ID because a pipeline will always have those even if inheriting base template - scope := models.Scope{ + scope := resourceQualifiers.Scope{ AppId: pipeline.AppId, EnvId: pipeline.EnvironmentId, ClusterId: pipeline.Environment.ClusterId, diff --git a/pkg/pipeline/PipelineStageService.go b/pkg/pipeline/PipelineStageService.go index 00266b1f0d..aaa8db1502 100644 --- a/pkg/pipeline/PipelineStageService.go +++ b/pkg/pipeline/PipelineStageService.go @@ -8,9 +8,9 @@ import ( "github.com/devtron-labs/devtron/pkg/pipeline/bean" "github.com/devtron-labs/devtron/pkg/pipeline/repository" repository2 "github.com/devtron-labs/devtron/pkg/plugin/repository" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/sql" "github.com/devtron-labs/devtron/pkg/variables" - "github.com/devtron-labs/devtron/pkg/variables/models" "github.com/devtron-labs/devtron/pkg/variables/parsers" repository3 "github.com/devtron-labs/devtron/pkg/variables/repository" "github.com/devtron-labs/devtron/pkg/variables/utils" @@ -24,7 +24,7 @@ type PipelineStageService interface { CreatePipelineStage(stageReq *bean.PipelineStageDto, stageType repository.PipelineStageType, pipelineId int, userId int32) error UpdatePipelineStage(stageReq *bean.PipelineStageDto, stageType repository.PipelineStageType, pipelineId int, userId int32) error DeletePipelineStage(stageReq *bean.PipelineStageDto, userId int32, tx *pg.Tx) error - BuildPrePostAndRefPluginStepsDataForWfRequest(pipelineId int, stageType string, scope models.Scope) (*bean.PrePostAndRefPluginStepsResponse, error) + BuildPrePostAndRefPluginStepsDataForWfRequest(pipelineId int, stageType string, scope resourceQualifiers.Scope) (*bean.PrePostAndRefPluginStepsResponse, error) GetCiPipelineStageDataDeepCopy(ciPipelineId int) (preCiStage *bean.PipelineStageDto, postCiStage *bean.PipelineStageDto, err error) GetCdPipelineStageDataDeepCopy(cdPipelineId int) (*bean.PipelineStageDto, *bean.PipelineStageDto, error) GetCdPipelineStageDataDeepCopyForPipelineIds(cdPipelineIds []int) (map[int][]*bean.PipelineStageDto, error) @@ -1622,7 +1622,7 @@ func (impl *PipelineStageServiceImpl) DeletePipelineStage(stageReq *bean.Pipelin //DeleteCiStage and related methods starts // BuildPrePostAndRefPluginStepsDataForWfRequest and related methods starts -func (impl *PipelineStageServiceImpl) BuildPrePostAndRefPluginStepsDataForWfRequest(pipelineId int, stageType string, scope models.Scope) (*bean.PrePostAndRefPluginStepsResponse, error) { +func (impl *PipelineStageServiceImpl) BuildPrePostAndRefPluginStepsDataForWfRequest(pipelineId int, stageType string, scope resourceQualifiers.Scope) (*bean.PrePostAndRefPluginStepsResponse, error) { //get all stages By pipelineId (it can be ciPipelineId or cdPipelineId) var pipelineStages []*repository.PipelineStage var err error @@ -2094,7 +2094,7 @@ func (impl *PipelineStageServiceImpl) BuildPluginVariableAndConditionDataForWfRe //BuildPrePostAndRefPluginStepsDataForWfRequest and related methods ends -func (impl *PipelineStageServiceImpl) fetchScopedVariablesAndResolveTemplate(unresolvedResponse *bean.PrePostAndRefPluginStepsResponse, pipelineStageIds []int, scope models.Scope) (*bean.PrePostAndRefPluginStepsResponse, error) { +func (impl *PipelineStageServiceImpl) fetchScopedVariablesAndResolveTemplate(unresolvedResponse *bean.PrePostAndRefPluginStepsResponse, pipelineStageIds []int, scope resourceQualifiers.Scope) (*bean.PrePostAndRefPluginStepsResponse, error) { entities := make([]repository3.Entity, 0) for _, stageId := range pipelineStageIds { diff --git a/pkg/pipeline/WorkflowDagExecutor.go b/pkg/pipeline/WorkflowDagExecutor.go index 8602375f7d..17d43f8ef6 100644 --- a/pkg/pipeline/WorkflowDagExecutor.go +++ b/pkg/pipeline/WorkflowDagExecutor.go @@ -28,8 +28,8 @@ import ( "github.com/devtron-labs/devtron/pkg/k8s" bean3 "github.com/devtron-labs/devtron/pkg/pipeline/bean" repository4 "github.com/devtron-labs/devtron/pkg/pipeline/repository" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/variables" - models2 "github.com/devtron-labs/devtron/pkg/variables/models" repository5 "github.com/devtron-labs/devtron/pkg/variables/repository" util4 "github.com/devtron-labs/devtron/util" "github.com/devtron-labs/devtron/util/argo" @@ -898,7 +898,7 @@ func (impl *WorkflowDagExecutorImpl) buildWFRequest(runner *pipelineConfig.CdWor if pipelineStage != nil { //Scope will pick the environment of CD pipeline irrespective of in-cluster mode, //since user sees the environment of the CD pipeline - scope := models2.Scope{ + scope := resourceQualifiers.Scope{ AppId: cdPipeline.App.Id, EnvId: env.Id, ClusterId: env.ClusterId, diff --git a/pkg/resourceQualifiers/QualifierMappingService.go b/pkg/resourceQualifiers/QualifierMappingService.go new file mode 100644 index 0000000000..6c1c27d081 --- /dev/null +++ b/pkg/resourceQualifiers/QualifierMappingService.go @@ -0,0 +1,41 @@ +package resourceQualifiers + +import ( + "github.com/devtron-labs/devtron/pkg/devtronResource" + "github.com/devtron-labs/devtron/pkg/sql" + "github.com/go-pg/pg" + "go.uber.org/zap" +) + +type QualifierMappingService interface { + CreateQualifierMappings(qualifierMappings []*QualifierMapping, tx *pg.Tx) ([]*QualifierMapping, error) + GetQualifierMappings(resourceType ResourceType, scope *Scope, resourceIds []int) ([]*QualifierMapping, error) + DeleteAllQualifierMappings(resourceType ResourceType, auditLog sql.AuditLog, tx *pg.Tx) error +} + +type QualifierMappingServiceImpl struct { + logger *zap.SugaredLogger + qualifierMappingRepository QualifiersMappingRepository + devtronResourceService devtronResource.DevtronResourceService +} + +func NewQualifierMappingServiceImpl(logger *zap.SugaredLogger, qualifierMappingRepository QualifiersMappingRepository, devtronResourceService devtronResource.DevtronResourceService) (*QualifierMappingServiceImpl, error) { + return &QualifierMappingServiceImpl{ + logger: logger, + qualifierMappingRepository: qualifierMappingRepository, + devtronResourceService: devtronResourceService, + }, nil +} + +func (impl QualifierMappingServiceImpl) CreateQualifierMappings(qualifierMappings []*QualifierMapping, tx *pg.Tx) ([]*QualifierMapping, error) { + return impl.qualifierMappingRepository.CreateQualifierMappings(qualifierMappings, tx) +} + +func (impl QualifierMappingServiceImpl) GetQualifierMappings(resourceType ResourceType, scope *Scope, resourceIds []int) ([]*QualifierMapping, error) { + searchableKeyNameIdMap := impl.devtronResourceService.GetAllSearchableKeyNameIdMap() + return impl.qualifierMappingRepository.GetQualifierMappings(resourceType, scope, searchableKeyNameIdMap, resourceIds) +} + +func (impl QualifierMappingServiceImpl) DeleteAllQualifierMappings(resourceType ResourceType, auditLog sql.AuditLog, tx *pg.Tx) error { + return impl.qualifierMappingRepository.DeleteAllQualifierMappings(resourceType, auditLog, tx) +} diff --git a/pkg/resourceQualifiers/ResourceQualifiersMappingDto.go b/pkg/resourceQualifiers/ResourceQualifiersMappingDto.go new file mode 100644 index 0000000000..fd70e0507a --- /dev/null +++ b/pkg/resourceQualifiers/ResourceQualifiersMappingDto.go @@ -0,0 +1,27 @@ +package resourceQualifiers + +import "github.com/devtron-labs/devtron/pkg/sql" + +type ResourceType int + +const ( + Variable ResourceType = 0 + Filter = 1 +) + +type QualifierMapping struct { + tableName struct{} `sql:"resource_qualifier_mapping" pg:",discard_unknown_columns"` + Id int `sql:"id,pk"` + ResourceId int `sql:"resource_id"` + ResourceType ResourceType `sql:"resource_type"` + QualifierId int `sql:"qualifier_id"` + IdentifierKey int `sql:"identifier_key"` + IdentifierValueInt int `sql:"identifier_value_int"` + Active bool `sql:"active"` + IdentifierValueString string `sql:"identifier_value_string"` + ParentIdentifier int `sql:"parent_identifier"` + CompositeKey string `sql:"-"` + //Data string `sql:"-"` + //VariableData *VariableData + sql.AuditLog +} diff --git a/pkg/resourceQualifiers/ResourceQualifiersMappingRepository.go b/pkg/resourceQualifiers/ResourceQualifiersMappingRepository.go new file mode 100644 index 0000000000..8de89eb735 --- /dev/null +++ b/pkg/resourceQualifiers/ResourceQualifiersMappingRepository.go @@ -0,0 +1,67 @@ +package resourceQualifiers + +import ( + "github.com/devtron-labs/devtron/pkg/devtronResource/bean" + "github.com/devtron-labs/devtron/pkg/sql" + "github.com/go-pg/pg" + "go.uber.org/zap" +) + +type QualifiersMappingRepository interface { + //transaction util funcs + sql.TransactionWrapper + CreateQualifierMappings(qualifierMappings []*QualifierMapping, tx *pg.Tx) ([]*QualifierMapping, error) + GetQualifierMappings(resourceType ResourceType, scope *Scope, searchableIdMap map[bean.DevtronResourceSearchableKeyName]int, resourceIds []int) ([]*QualifierMapping, error) + DeleteAllQualifierMappings(ResourceType, sql.AuditLog, *pg.Tx) error +} + +type QualifiersMappingRepositoryImpl struct { + dbConnection *pg.DB + *sql.TransactionUtilImpl + logger *zap.SugaredLogger +} + +func NewQualifiersMappingRepositoryImpl(dbConnection *pg.DB, logger *zap.SugaredLogger) (*QualifiersMappingRepositoryImpl, error) { + return &QualifiersMappingRepositoryImpl{ + dbConnection: dbConnection, + logger: logger, + TransactionUtilImpl: sql.NewTransactionUtilImpl(dbConnection), + }, nil +} + +func (repo *QualifiersMappingRepositoryImpl) CreateQualifierMappings(qualifierMappings []*QualifierMapping, tx *pg.Tx) ([]*QualifierMapping, error) { + err := tx.Insert(&qualifierMappings) + if err != nil { + return nil, err + } + return qualifierMappings, nil +} + +func (repo *QualifiersMappingRepositoryImpl) GetQualifierMappings(resourceType ResourceType, scope *Scope, searchableIdMap map[bean.DevtronResourceSearchableKeyName]int, resourceIds []int) ([]*QualifierMapping, error) { + var qualifierMappings []*QualifierMapping + query := repo.dbConnection.Model(&qualifierMappings). + Where("active = ?", true). + Where("resource_type = ?", resourceType). + Where("(qualifier_id = ?)", GLOBAL_QUALIFIER) + + if len(resourceIds) > 0 { + query = query.Where("resource_id IN (?)", pg.In(resourceIds)) + } + + err := query.Select() + if err != nil { + return nil, err + } + return qualifierMappings, nil +} + +func (repo *QualifiersMappingRepositoryImpl) DeleteAllQualifierMappings(resourceType ResourceType, auditLog sql.AuditLog, tx *pg.Tx) error { + _, err := tx.Model(&QualifierMapping{}). + Set("updated_by = ?", auditLog.UpdatedBy). + Set("updated_on = ?", auditLog.UpdatedOn). + Set("active = ?", false). + Where("active = ?", true). + Where("resource_type = ?", resourceType). + Update() + return err +} diff --git a/pkg/resourceQualifiers/bean.go b/pkg/resourceQualifiers/bean.go new file mode 100644 index 0000000000..39dc408cb9 --- /dev/null +++ b/pkg/resourceQualifiers/bean.go @@ -0,0 +1,19 @@ +package resourceQualifiers + +type Scope struct { + AppId int `json:"appId"` + EnvId int `json:"envId"` + ClusterId int `json:"clusterId"` +} + +type Qualifier int + +const ( + GLOBAL_QUALIFIER Qualifier = 5 +) + +var CompoundQualifiers []Qualifier + +func GetNumOfChildQualifiers(qualifier Qualifier) int { + return 0 +} diff --git a/pkg/resourceQualifiers/mocks/QualifierMappingService.go b/pkg/resourceQualifiers/mocks/QualifierMappingService.go new file mode 100644 index 0000000000..9dffa5a996 --- /dev/null +++ b/pkg/resourceQualifiers/mocks/QualifierMappingService.go @@ -0,0 +1,99 @@ +// Code generated by mockery v2.34.0. DO NOT EDIT. + +package mocks + +import ( + bean "github.com/devtron-labs/devtron/pkg/devtronResource/bean" + mock "github.com/stretchr/testify/mock" + + pg "github.com/go-pg/pg" + + resourceQualifiers "github.com/devtron-labs/devtron/pkg/resourceQualifiers" + + sql "github.com/devtron-labs/devtron/pkg/sql" +) + +// QualifierMappingService is an autogenerated mock type for the QualifierMappingService type +type QualifierMappingService struct { + mock.Mock +} + +// CreateQualifierMappings provides a mock function with given fields: qualifierMappings, tx +func (_m *QualifierMappingService) CreateQualifierMappings(qualifierMappings []*resourceQualifiers.QualifierMapping, tx *pg.Tx) ([]*resourceQualifiers.QualifierMapping, error) { + ret := _m.Called(qualifierMappings, tx) + + var r0 []*resourceQualifiers.QualifierMapping + var r1 error + if rf, ok := ret.Get(0).(func([]*resourceQualifiers.QualifierMapping, *pg.Tx) ([]*resourceQualifiers.QualifierMapping, error)); ok { + return rf(qualifierMappings, tx) + } + if rf, ok := ret.Get(0).(func([]*resourceQualifiers.QualifierMapping, *pg.Tx) []*resourceQualifiers.QualifierMapping); ok { + r0 = rf(qualifierMappings, tx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*resourceQualifiers.QualifierMapping) + } + } + + if rf, ok := ret.Get(1).(func([]*resourceQualifiers.QualifierMapping, *pg.Tx) error); ok { + r1 = rf(qualifierMappings, tx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteAllQualifierMappings provides a mock function with given fields: resourceType, auditLog, tx +func (_m *QualifierMappingService) DeleteAllQualifierMappings(resourceType resourceQualifiers.ResourceType, auditLog sql.AuditLog, tx *pg.Tx) error { + ret := _m.Called(resourceType, auditLog, tx) + + var r0 error + if rf, ok := ret.Get(0).(func(resourceQualifiers.ResourceType, sql.AuditLog, *pg.Tx) error); ok { + r0 = rf(resourceType, auditLog, tx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetQualifierMappings provides a mock function with given fields: resourceType, scope, searchableIdMap, resourceIds +func (_m *QualifierMappingService) GetQualifierMappings(resourceType resourceQualifiers.ResourceType, scope resourceQualifiers.Scope, searchableIdMap map[bean.DevtronResourceSearchableKeyName]int, resourceIds []int) ([]*resourceQualifiers.QualifierMapping, error) { + ret := _m.Called(resourceType, scope, searchableIdMap, resourceIds) + + var r0 []*resourceQualifiers.QualifierMapping + var r1 error + if rf, ok := ret.Get(0).(func(resourceQualifiers.ResourceType, resourceQualifiers.Scope, map[bean.DevtronResourceSearchableKeyName]int, []int) ([]*resourceQualifiers.QualifierMapping, error)); ok { + return rf(resourceType, scope, searchableIdMap, resourceIds) + } + if rf, ok := ret.Get(0).(func(resourceQualifiers.ResourceType, resourceQualifiers.Scope, map[bean.DevtronResourceSearchableKeyName]int, []int) []*resourceQualifiers.QualifierMapping); ok { + r0 = rf(resourceType, scope, searchableIdMap, resourceIds) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*resourceQualifiers.QualifierMapping) + } + } + + if rf, ok := ret.Get(1).(func(resourceQualifiers.ResourceType, resourceQualifiers.Scope, map[bean.DevtronResourceSearchableKeyName]int, []int) error); ok { + r1 = rf(resourceType, scope, searchableIdMap, resourceIds) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewQualifierMappingService creates a new instance of QualifierMappingService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewQualifierMappingService(t interface { + mock.TestingT + Cleanup(func()) +}) *QualifierMappingService { + mock := &QualifierMappingService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/variables/ScopedVariableService.go b/pkg/variables/ScopedVariableService.go index 393987b4ea..a69b948fb0 100644 --- a/pkg/variables/ScopedVariableService.go +++ b/pkg/variables/ScopedVariableService.go @@ -2,6 +2,8 @@ package variables import ( "github.com/caarlos0/env" + "github.com/devtron-labs/devtron/pkg/devtronResource" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/sql" "github.com/devtron-labs/devtron/pkg/variables/cache" @@ -18,21 +20,25 @@ import ( type ScopedVariableService interface { CreateVariables(payload models.Payload) error - GetScopedVariables(scope models.Scope, varNames []string, maskSensitiveData bool) (scopedVariableDataObj []*models.ScopedVariableData, err error) + GetScopedVariables(scope resourceQualifiers.Scope, varNames []string, maskSensitiveData bool) (scopedVariableDataObj []*models.ScopedVariableData, err error) GetJsonForVariables() (*models.Payload, error) } type ScopedVariableServiceImpl struct { logger *zap.SugaredLogger scopedVariableRepository repository2.ScopedVariableRepository + qualifierMappingService resourceQualifiers.QualifierMappingService + devtronResourceService devtronResource.DevtronResourceService VariableNameConfig *VariableConfig VariableCache *cache.VariableCacheObj } -func NewScopedVariableServiceImpl(logger *zap.SugaredLogger, scopedVariableRepository repository2.ScopedVariableRepository) (*ScopedVariableServiceImpl, error) { +func NewScopedVariableServiceImpl(logger *zap.SugaredLogger, scopedVariableRepository repository2.ScopedVariableRepository, + qualifierMappingService resourceQualifiers.QualifierMappingService) (*ScopedVariableServiceImpl, error) { scopedVariableService := &ScopedVariableServiceImpl{ logger: logger, scopedVariableRepository: scopedVariableRepository, + qualifierMappingService: qualifierMappingService, VariableCache: &cache.VariableCacheObj{CacheLock: &sync.Mutex{}}, } cfg, err := GetVariableNameConfig() @@ -100,6 +106,11 @@ func (impl *ScopedVariableServiceImpl) CreateVariables(payload models.Payload) e } }(impl.scopedVariableRepository, tx) + err = impl.qualifierMappingService.DeleteAllQualifierMappings(resourceQualifiers.Variable, auditLog, tx) + if err != nil { + impl.logger.Errorw("error in deleting qualifier mappings", "err", err) + return err + } err = impl.scopedVariableRepository.DeleteVariables(auditLog, tx) if err != nil { impl.logger.Errorw("error in deleting variables", "err", err) @@ -170,9 +181,8 @@ func (impl *ScopedVariableServiceImpl) storeVariableDefinitions(payload models.P func (impl *ScopedVariableServiceImpl) createVariableScopes(payload models.Payload, variableNameToId map[string]int, auditLog sql.AuditLog, tx *pg.Tx) (map[int]string, error) { - variableScopes := make([]*repository2.VariableScope, 0) + variableScopes := make([]*models.VariableScope, 0) for _, variable := range payload.Variables { - variableId := variableNameToId[variable.Definition.VarName] for _, value := range variable.AttributeValues { var varValue string @@ -181,36 +191,39 @@ func (impl *ScopedVariableServiceImpl) createVariableScopes(payload models.Paylo return nil, err } if value.AttributeType == models.Global { - scope := &repository2.VariableScope{ - VariableDefinitionId: variableId, - QualifierId: int(helper.GetQualifierId(value.AttributeType)), - Active: true, - Data: varValue, - AuditLog: auditLog, + scope := &models.VariableScope{ + QualifierMapping: &resourceQualifiers.QualifierMapping{ + ResourceId: variableId, + ResourceType: resourceQualifiers.Variable, + QualifierId: int(helper.GetQualifierId(value.AttributeType)), + Active: true, + AuditLog: auditLog, + }, + Data: varValue, } variableScopes = append(variableScopes, scope) } } } - parentVariableScope := make([]*repository2.VariableScope, 0) - childrenVariableScope := make([]*repository2.VariableScope, 0) - parentScopesMap := make(map[string]*repository2.VariableScope) + parentVariableScope := make([]*resourceQualifiers.QualifierMapping, 0) + childrenVariableScope := make([]*resourceQualifiers.QualifierMapping, 0) + parentScopesMap := make(map[string]*resourceQualifiers.QualifierMapping) - var parentVarScope []*repository2.VariableScope + var parentVarScope []*resourceQualifiers.QualifierMapping for _, scope := range variableScopes { - parentVariableScope = append(parentVariableScope, scope) + parentVariableScope = append(parentVariableScope, scope.QualifierMapping) } var err error if len(parentVariableScope) > 0 { - parentVarScope, err = impl.scopedVariableRepository.CreateVariableScope(parentVariableScope, tx) + parentVarScope, err = impl.qualifierMappingService.CreateQualifierMappings(parentVariableScope, tx) if err != nil { - impl.logger.Errorw("error in getting parentVarScope", parentVarScope) + impl.logger.Errorw("error in getting parentVarScope", "parentVarScope", parentVarScope, "err", err) return nil, err } } scopeIdToVarData := make(map[int]string) - for _, parentVar := range parentVarScope { + for _, parentVar := range variableScopes { scopeIdToVarData[parentVar.Id] = parentVar.Data } for _, childScope := range childrenVariableScope { @@ -220,39 +233,39 @@ func (impl *ScopedVariableServiceImpl) createVariableScopes(payload models.Paylo } } if len(childrenVariableScope) > 0 { - childVarScope, err := impl.scopedVariableRepository.CreateVariableScope(childrenVariableScope, tx) + childVarScope, err := impl.qualifierMappingService.CreateQualifierMappings(childrenVariableScope, tx) if err != nil { - impl.logger.Errorw("error in getting childVarScope", err, childVarScope) + impl.logger.Errorw("error in getting childVarScope", "childVarScope", childVarScope, "err", err) return nil, err } } return scopeIdToVarData, nil } -func (impl *ScopedVariableServiceImpl) getMatchedScopedVariables(varScope []*repository2.VariableScope) map[int]int { - variableIdToVariableScopes := make(map[int][]*repository2.VariableScope) +func (impl *ScopedVariableServiceImpl) getMatchedScopedVariables(varScope []*resourceQualifiers.QualifierMapping) map[int]int { + variableIdToVariableScopes := make(map[int][]*resourceQualifiers.QualifierMapping) variableIdToSelectedScopeId := make(map[int]int) for _, vScope := range varScope { - variableId := vScope.VariableDefinitionId + variableId := vScope.ResourceId variableIdToVariableScopes[variableId] = append(variableIdToVariableScopes[variableId], vScope) } // Filter out the unneeded scoped which were fetched from DB for the same variable and qualifier for variableId, scopes := range variableIdToVariableScopes { - selectedScopes := make([]*repository2.VariableScope, 0) - compoundQualifierToScopes := make(map[repository2.Qualifier][]*repository2.VariableScope) + selectedScopes := make([]*resourceQualifiers.QualifierMapping, 0) + compoundQualifierToScopes := make(map[resourceQualifiers.Qualifier][]*resourceQualifiers.QualifierMapping) for _, variableScope := range scopes { - qualifier := repository2.Qualifier(variableScope.QualifierId) - if slices.Contains(repository2.CompoundQualifiers, qualifier) { + qualifier := resourceQualifiers.Qualifier(variableScope.QualifierId) + if slices.Contains(resourceQualifiers.CompoundQualifiers, qualifier) { compoundQualifierToScopes[qualifier] = append(compoundQualifierToScopes[qualifier], variableScope) } else { selectedScopes = append(selectedScopes, variableScope) } } - for _, qualifier := range repository2.CompoundQualifiers { - selectedScope := impl.selectScopeForCompoundQualifier(compoundQualifierToScopes[qualifier], repository2.GetNumOfChildQualifiers(qualifier)) + for _, qualifier := range resourceQualifiers.CompoundQualifiers { + selectedScope := impl.selectScopeForCompoundQualifier(compoundQualifierToScopes[qualifier], resourceQualifiers.GetNumOfChildQualifiers(qualifier)) if selectedScope != nil { selectedScopes = append(selectedScopes, selectedScope) } @@ -260,7 +273,7 @@ func (impl *ScopedVariableServiceImpl) getMatchedScopedVariables(varScope []*rep variableIdToVariableScopes[variableId] = selectedScopes } - var minScope *repository2.VariableScope + var minScope *resourceQualifiers.QualifierMapping for variableId, scopes := range variableIdToVariableScopes { minScope = helper.FindMinWithComparator(scopes, helper.QualifierComparator) if minScope != nil { @@ -270,9 +283,9 @@ func (impl *ScopedVariableServiceImpl) getMatchedScopedVariables(varScope []*rep return variableIdToSelectedScopeId } -func (impl *ScopedVariableServiceImpl) selectScopeForCompoundQualifier(scopes []*repository2.VariableScope, numQualifiers int) *repository2.VariableScope { - parentIdToChildScopes := make(map[int][]*repository2.VariableScope) - parentScopeIdToScope := make(map[int]*repository2.VariableScope, 0) +func (impl *ScopedVariableServiceImpl) selectScopeForCompoundQualifier(scopes []*resourceQualifiers.QualifierMapping, numQualifiers int) *resourceQualifiers.QualifierMapping { + parentIdToChildScopes := make(map[int][]*resourceQualifiers.QualifierMapping) + parentScopeIdToScope := make(map[int]*resourceQualifiers.QualifierMapping, 0) parentScopeIds := make([]int, 0) for _, scope := range scopes { // is not parent so append it to the list in the map with key as its parent scopeID @@ -294,7 +307,7 @@ func (impl *ScopedVariableServiceImpl) selectScopeForCompoundQualifier(scopes [] // Now in the map only those will exist with all child matched or partial matches. // Because only one will entry exist with all matched we'll return that scope. - var selectedParentScope *repository2.VariableScope + var selectedParentScope *resourceQualifiers.QualifierMapping for parentScopeId, childScopes := range parentIdToChildScopes { if len(childScopes) == numQualifiers { selectedParentScope = parentScopeIdToScope[parentScopeId] @@ -303,7 +316,7 @@ func (impl *ScopedVariableServiceImpl) selectScopeForCompoundQualifier(scopes [] return selectedParentScope } -func (impl *ScopedVariableServiceImpl) GetScopedVariables(scope models.Scope, varNames []string, maskSensitiveData bool) (scopedVariableDataObj []*models.ScopedVariableData, err error) { +func (impl *ScopedVariableServiceImpl) GetScopedVariables(scope resourceQualifiers.Scope, varNames []string, maskSensitiveData bool) (scopedVariableDataObj []*models.ScopedVariableData, err error) { // getting all variables from cache allVariableDefinitions := impl.VariableCache.GetData() @@ -344,7 +357,7 @@ func (impl *ScopedVariableServiceImpl) GetScopedVariables(scope models.Scope, va return make([]*models.ScopedVariableData, 0), nil } - varScope, err := impl.scopedVariableRepository.GetScopedVariableData(scope, variableIds) + varScope, err := impl.qualifierMappingService.GetQualifierMappings(resourceQualifiers.Variable, &scope, variableIds) if err != nil { impl.logger.Errorw("error in getting varScope", "err", err) return nil, err @@ -420,7 +433,7 @@ func (impl *ScopedVariableServiceImpl) GetJsonForVariables() (*models.Payload, e if allVariableDefinitions != nil && len(allVariableDefinitions) == 0 { return nil, nil } - dataForJson, err := impl.scopedVariableRepository.GetAllVariableScopeAndDefinition() + dataForJson, err := impl.scopedVariableRepository.GetAllVariableDefinition() if err != nil { impl.logger.Errorw("error in getting data for json", "err", err) return nil, err @@ -431,6 +444,15 @@ func (impl *ScopedVariableServiceImpl) GetJsonForVariables() (*models.Payload, e } variables := make([]*models.Variables, 0) + varIdVsScopeMappings, varScopeIds, err := impl.getVariableScopes(dataForJson) + if err != nil { + return nil, err + } + scopeIdVsDataMap, err := impl.getVariableScopeData(varScopeIds) + if err != nil { + return nil, err + } + for _, data := range dataForJson { definition := models.Definition{ VarName: data.Name, @@ -441,12 +463,13 @@ func (impl *ScopedVariableServiceImpl) GetJsonForVariables() (*models.Payload, e } attributes := make([]models.AttributeValue, 0) - scopeIdToVarScopes := make(map[int][]*repository2.VariableScope) - for _, scope := range data.VariableScope { + scopedVariables := varIdVsScopeMappings[data.Id] + scopeIdToVarScopes := make(map[int][]*resourceQualifiers.QualifierMapping) + for _, scope := range scopedVariables { if scope.ParentIdentifier != 0 { scopeIdToVarScopes[scope.ParentIdentifier] = append(scopeIdToVarScopes[scope.ParentIdentifier], scope) } else { - scopeIdToVarScopes[scope.Id] = []*repository2.VariableScope{scope} + scopeIdToVarScopes[scope.Id] = []*resourceQualifiers.QualifierMapping{scope} } } for parentScopeId, scopes := range scopeIdToVarScopes { @@ -454,16 +477,18 @@ func (impl *ScopedVariableServiceImpl) GetJsonForVariables() (*models.Payload, e AttributeParams: make(map[models.IdentifierType]string), } for _, scope := range scopes { - if parentScopeId == scope.Id { + scopeId := scope.Id + if parentScopeId == scopeId { + variableData := scopeIdVsDataMap[scopeId] var value interface{} - value, err = utils.DestringifyValue(scope.VariableData.Data) + value, err = utils.DestringifyValue(variableData.Data) if err != nil { return nil, err } attribute.VariableValue = models.VariableValue{ Value: value, } - attribute.AttributeType = helper.GetAttributeType(repository2.Qualifier(scope.QualifierId)) + attribute.AttributeType = helper.GetAttributeType(resourceQualifiers.Qualifier(scope.QualifierId)) } } if len(attribute.AttributeParams) == 0 { @@ -486,6 +511,47 @@ func (impl *ScopedVariableServiceImpl) GetJsonForVariables() (*models.Payload, e return payload, nil } +func (impl *ScopedVariableServiceImpl) getVariableScopes(dataForJson []*repository2.VariableDefinition) (map[int][]*resourceQualifiers.QualifierMapping, []int, error) { + varIdVsScopeMappings := make(map[int][]*resourceQualifiers.QualifierMapping) + var varScopeIds []int + varDefnIds := make([]int, 0, len(dataForJson)) + for _, variableDefinition := range dataForJson { + varDefnIds = append(varDefnIds, variableDefinition.Id) + } + if len(varDefnIds) == 0 { + return varIdVsScopeMappings, varScopeIds, nil + } + scopedVariableMappings, err := impl.qualifierMappingService.GetQualifierMappings(resourceQualifiers.Variable, nil, varDefnIds) + if err != nil { + //TODO KB: handle this + return varIdVsScopeMappings, varScopeIds, err + } + + for _, scopedVariableMapping := range scopedVariableMappings { + varId := scopedVariableMapping.ResourceId + varScopeIds = append(varScopeIds, scopedVariableMapping.Id) + varIdVsScopeMappings[varId] = append(varIdVsScopeMappings[varId], scopedVariableMapping) + } + return varIdVsScopeMappings, varScopeIds, nil +} + +func (impl *ScopedVariableServiceImpl) getVariableScopeData(scopeIds []int) (map[int]*repository2.VariableData, error) { + scopeIdVsVarDataMap := make(map[int]*repository2.VariableData, len(scopeIds)) + if len(scopeIds) == 0 { + return scopeIdVsVarDataMap, nil + } + variableDataArray, err := impl.scopedVariableRepository.GetDataForScopeIds(scopeIds) + if err != nil { + impl.logger.Errorw("error occurred while fetching data for scope ids", "err", err) + return scopeIdVsVarDataMap, err + } + for _, variableData := range variableDataArray { + variableScopeId := variableData.VariableScopeId + scopeIdVsVarDataMap[variableScopeId] = variableData + } + return scopeIdVsVarDataMap, nil +} + func getAuditLog(payload models.Payload) sql.AuditLog { auditLog := sql.AuditLog{ CreatedOn: time.Now(), diff --git a/pkg/variables/helper/mappers.go b/pkg/variables/helper/mappers.go index 0d63ad5de2..949ea6a0b5 100644 --- a/pkg/variables/helper/mappers.go +++ b/pkg/variables/helper/mappers.go @@ -1,22 +1,22 @@ package helper import ( + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" "github.com/devtron-labs/devtron/pkg/variables/models" - "github.com/devtron-labs/devtron/pkg/variables/repository" ) -func GetQualifierId(attributeType models.AttributeType) repository.Qualifier { +func GetQualifierId(attributeType models.AttributeType) resourceQualifiers.Qualifier { switch attributeType { case models.Global: - return repository.GLOBAL_QUALIFIER + return resourceQualifiers.GLOBAL_QUALIFIER default: return 0 } } -func GetAttributeType(qualifier repository.Qualifier) models.AttributeType { +func GetAttributeType(qualifier resourceQualifiers.Qualifier) models.AttributeType { switch qualifier { - case repository.GLOBAL_QUALIFIER: + case resourceQualifiers.GLOBAL_QUALIFIER: return models.Global default: return "" diff --git a/pkg/variables/helper/priority-manager.go b/pkg/variables/helper/priority-manager.go index af26a65f4f..cd6c3b65d8 100644 --- a/pkg/variables/helper/priority-manager.go +++ b/pkg/variables/helper/priority-manager.go @@ -1,28 +1,28 @@ package helper import ( - repository2 "github.com/devtron-labs/devtron/pkg/variables/repository" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" ) -func QualifierComparator(a, b repository2.Qualifier) bool { +func QualifierComparator(a, b resourceQualifiers.Qualifier) bool { return GetPriority(a) < GetPriority(b) } -func FindMinWithComparator(variableScope []*repository2.VariableScope, comparator func(a, b repository2.Qualifier) bool) *repository2.VariableScope { +func FindMinWithComparator(variableScope []*resourceQualifiers.QualifierMapping, comparator func(a, b resourceQualifiers.Qualifier) bool) *resourceQualifiers.QualifierMapping { if len(variableScope) == 0 { return nil } min := variableScope[0] for _, val := range variableScope { - if comparator(repository2.Qualifier(val.QualifierId), repository2.Qualifier(min.QualifierId)) { + if comparator(resourceQualifiers.Qualifier(val.QualifierId), resourceQualifiers.Qualifier(min.QualifierId)) { min = val } } return min } -func GetPriority(qualifier repository2.Qualifier) int { +func GetPriority(qualifier resourceQualifiers.Qualifier) int { switch qualifier { - case repository2.GLOBAL_QUALIFIER: + case resourceQualifiers.GLOBAL_QUALIFIER: return 5 default: return 0 diff --git a/pkg/variables/models/service-models.go b/pkg/variables/models/service-models.go index 85b544ccf7..8f299db3ca 100644 --- a/pkg/variables/models/service-models.go +++ b/pkg/variables/models/service-models.go @@ -1,5 +1,7 @@ package models +import "github.com/devtron-labs/devtron/pkg/resourceQualifiers" + type ScopedVariableData struct { VariableName string `json:"variableName"` ShortDescription string `json:"shortDescription"` @@ -10,3 +12,8 @@ type ScopedVariableData struct { type VariableScopeMapping struct { ScopeId int } + +type VariableScope struct { + *resourceQualifiers.QualifierMapping + Data string +} diff --git a/pkg/variables/models/variable-payload.go b/pkg/variables/models/variable-payload.go index 5049b98b82..3ee5e522b6 100644 --- a/pkg/variables/models/variable-payload.go +++ b/pkg/variables/models/variable-payload.go @@ -74,9 +74,3 @@ func (value VariableValue) StringValue() string { } return value.Value.(string) } - -type Scope struct { - AppId int `json:"appId"` - EnvId int `json:"envId"` - ClusterId int `json:"clusterId"` -} diff --git a/pkg/variables/repository/ScopedVariableDto.go b/pkg/variables/repository/ScopedVariableDto.go index ef4441f348..521dd037d1 100644 --- a/pkg/variables/repository/ScopedVariableDto.go +++ b/pkg/variables/repository/ScopedVariableDto.go @@ -14,23 +14,6 @@ type VariableDefinition struct { Active bool `sql:"active"` Description string `sql:"description"` ShortDescription string `json:"short_description"` - VariableScope []*VariableScope - sql.AuditLog -} - -type VariableScope struct { - tableName struct{} `sql:"variable_scope" pg:",discard_unknown_columns"` - Id int `sql:"id,pk"` - VariableDefinitionId int `sql:"variable_definition_id"` - QualifierId int `sql:"qualifier_id"` - IdentifierKey int `sql:"identifier_key"` - IdentifierValueInt int `sql:"identifier_value_int"` - Active bool `sql:"active"` - IdentifierValueString string `sql:"identifier_value_string"` - ParentIdentifier int `sql:"parent_identifier"` - CompositeKey string `sql:"-"` - Data string `sql:"-"` - VariableData *VariableData sql.AuditLog } @@ -42,18 +25,6 @@ type VariableData struct { sql.AuditLog } -type Qualifier int - -const ( - GLOBAL_QUALIFIER Qualifier = 5 -) - -var CompoundQualifiers []Qualifier - -func GetNumOfChildQualifiers(qualifier Qualifier) int { - return 0 -} - func CreateFromDefinition(definition models.Definition, auditLog sql.AuditLog) *VariableDefinition { varDefinition := &VariableDefinition{} varDefinition.Name = definition.VarName diff --git a/pkg/variables/repository/ScopedVariableRepository.go b/pkg/variables/repository/ScopedVariableRepository.go index a8d553093a..4615c878bf 100644 --- a/pkg/variables/repository/ScopedVariableRepository.go +++ b/pkg/variables/repository/ScopedVariableRepository.go @@ -2,9 +2,7 @@ package repository import ( "github.com/devtron-labs/devtron/pkg/sql" - "github.com/devtron-labs/devtron/pkg/variables/models" "github.com/go-pg/pg" - "github.com/go-pg/pg/orm" "go.uber.org/zap" ) @@ -13,7 +11,6 @@ type ScopedVariableRepository interface { sql.TransactionWrapper // Create CreateVariableDefinition(variableDefinition []*VariableDefinition, tx *pg.Tx) ([]*VariableDefinition, error) - CreateVariableScope(variableDefinition []*VariableScope, tx *pg.Tx) ([]*VariableScope, error) CreateVariableData(variableDefinition []*VariableData, tx *pg.Tx) error // Get @@ -21,8 +18,7 @@ type ScopedVariableRepository interface { GetAllVariableMetadata() ([]*VariableDefinition, error) GetVariablesForVarIds(ids []int) ([]*VariableDefinition, error) GetVariablesByNames(vars []string) ([]*VariableDefinition, error) - GetAllVariableScopeAndDefinition() ([]*VariableDefinition, error) - GetScopedVariableData(scope models.Scope, varIds []int) ([]*VariableScope, error) + GetAllVariableDefinition() ([]*VariableDefinition, error) GetDataForScopeIds(scopeIds []int) ([]*VariableData, error) // Delete @@ -51,15 +47,6 @@ func (impl *ScopedVariableRepositoryImpl) CreateVariableDefinition(variableDefin return variableDefinition, nil } -func (impl *ScopedVariableRepositoryImpl) CreateVariableScope(variableScope []*VariableScope, tx *pg.Tx) ([]*VariableScope, error) { - err := tx.Insert(&variableScope) - if err != nil { - return nil, err - } - return variableScope, nil - -} - func (impl *ScopedVariableRepositoryImpl) CreateVariableData(variableDefinition []*VariableData, tx *pg.Tx) error { return tx.Insert(&variableDefinition) } @@ -100,18 +87,15 @@ func (impl *ScopedVariableRepositoryImpl) GetVariablesByNames(vars []string) ([] var variableDefinition []*VariableDefinition err := impl.dbConnection.Model(&variableDefinition).Where("active = ?", true). Where("name in (?)", pg.In(vars)).Select() - impl.logger.Info("variableDefinition: ", variableDefinition) + impl.logger.Debug("variableDefinition: ", variableDefinition) return variableDefinition, err } -func (impl *ScopedVariableRepositoryImpl) GetAllVariableScopeAndDefinition() ([]*VariableDefinition, error) { +func (impl *ScopedVariableRepositoryImpl) GetAllVariableDefinition() ([]*VariableDefinition, error) { var variableDefinition []*VariableDefinition err := impl.dbConnection. Model(&variableDefinition). - Column("variable_definition.*", "VariableScope", "VariableScope.VariableData"). - Relation("VariableScope", func(q *orm.Query) (query *orm.Query, err error) { - return q.Where("variable_scope.active = ?", true), nil - }). + Column("variable_definition.*"). Where("variable_definition.active = ?", true). Select() if err != nil { @@ -120,25 +104,12 @@ func (impl *ScopedVariableRepositoryImpl) GetAllVariableScopeAndDefinition() ([] return variableDefinition, err } -func (impl *ScopedVariableRepositoryImpl) GetScopedVariableData(scope models.Scope, varIds []int) ([]*VariableScope, error) { - var variableScopes []*VariableScope - query := impl.dbConnection.Model(&variableScopes). - Where("active = ?", true). - Where("(qualifier_id = ?)", GLOBAL_QUALIFIER) - - if len(varIds) > 0 { - query = query.Where("variable_definition_id IN (?)", pg.In(varIds)) - } - - err := query.Select() - if err != nil { - return nil, err - } - return variableScopes, nil -} func (impl *ScopedVariableRepositoryImpl) GetDataForScopeIds(scopeIds []int) ([]*VariableData, error) { var variableData []*VariableData + if len(scopeIds) == 0 { + return variableData, nil + } err := impl.dbConnection. Model(&variableData). Where("variable_scope_id in(?)", pg.In(scopeIds)). @@ -148,16 +119,7 @@ func (impl *ScopedVariableRepositoryImpl) GetDataForScopeIds(scopeIds []int) ([] } func (impl *ScopedVariableRepositoryImpl) DeleteVariables(auditLog sql.AuditLog, tx *pg.Tx) error { - _, err := tx.Model(&VariableScope{}). - Set("updated_by = ?", auditLog.UpdatedBy). - Set("updated_on = ?", auditLog.UpdatedOn). - Set("active = ?", false). - Where("active = ?", true). - Update() - if err != nil { - return err - } - _, err = tx.Model(&VariableDefinition{}). + _, err := tx.Model(&VariableDefinition{}). Set("updated_by = ?", auditLog.UpdatedBy). Set("updated_on = ?", auditLog.UpdatedOn). Set("active = ?", false). diff --git a/scripts/sql/175_resource_filter.down.sql b/scripts/sql/175_resource_filter.down.sql new file mode 100644 index 0000000000..42b8634b23 --- /dev/null +++ b/scripts/sql/175_resource_filter.down.sql @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS "public"."resource_filter"; + +DROP SEQUENCE IF EXISTS public.resource_filter_seq; + +ALTER TABLE resource_qualifier_mapping DROP COLUMN IF EXISTS resource_type; + +ALTER TABLE resource_qualifier_mapping RENAME TO variable_scope; + +ALTER TABLE variable_scope RENAME COLUMN resource_id TO variable_definition_id; + +DELETE from devtron_resource_searchable_key where name = 'PROJECT_ID'; + +ALTER TABLE variable_scope ADD CONSTRAINT variable_scope_variable_id_fkey FOREIGN KEY ("variable_definition_id") REFERENCES "public"."variable_definition" ("id"); + +ALTER TABLE variable_data ADD CONSTRAINT variable_data_variable_id_fkey FOREIGN KEY ("variable_scope_id") REFERENCES "public"."variable_scope" ("id"); + + + diff --git a/scripts/sql/175_resource_filter.up.sql b/scripts/sql/175_resource_filter.up.sql new file mode 100644 index 0000000000..77014f7c62 --- /dev/null +++ b/scripts/sql/175_resource_filter.up.sql @@ -0,0 +1,28 @@ +CREATE SEQUENCE IF NOT EXISTS resource_filter_seq; +CREATE TABLE IF NOT EXISTS "public"."resource_filter" +( + "id" integer not null default nextval('resource_filter_seq' :: regclass), + "name" varchar(300) NOT NULL, + "target_object" integer NOT NULL, + "condition_expression" text NOT NULL, + "deleted" bool NOT NULL, + "description" text, + "created_on" timestamptz, + "created_by" integer, + "updated_on" timestamptz, + "updated_by" integer, + PRIMARY KEY ("id") +); + +ALTER TABLE variable_scope DROP CONSTRAINT variable_scope_variable_id_fkey; + +ALTER TABLE variable_data DROP CONSTRAINT variable_data_variable_id_fkey; + +ALTER TABLE variable_scope RENAME TO resource_qualifier_mapping; + +ALTER TABLE resource_qualifier_mapping RENAME COLUMN variable_definition_id TO resource_id; + +ALTER TABLE resource_qualifier_mapping ADD COLUMN resource_type integer DEFAULT 0; + +INSERT INTO devtron_resource_searchable_key(name, is_removed, created_on, created_by, updated_on, updated_by) +VALUES ('PROJECT_ID', false, now(), 1, now(), 1); \ No newline at end of file diff --git a/wire_gen.go b/wire_gen.go index 847956300d..522c44d3e0 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -61,7 +61,7 @@ import ( "github.com/devtron-labs/devtron/internal/sql/repository/chartConfig" repository5 "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry" "github.com/devtron-labs/devtron/internal/sql/repository/helper" - repository12 "github.com/devtron-labs/devtron/internal/sql/repository/imageTagging" + repository13 "github.com/devtron-labs/devtron/internal/sql/repository/imageTagging" "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig" "github.com/devtron-labs/devtron/internal/sql/repository/security" "github.com/devtron-labs/devtron/internal/util" @@ -98,10 +98,12 @@ import ( "github.com/devtron-labs/devtron/pkg/commonService" delete2 "github.com/devtron-labs/devtron/pkg/delete" "github.com/devtron-labs/devtron/pkg/deploymentGroup" + "github.com/devtron-labs/devtron/pkg/devtronResource" + repository9 "github.com/devtron-labs/devtron/pkg/devtronResource/repository" "github.com/devtron-labs/devtron/pkg/dockerRegistry" "github.com/devtron-labs/devtron/pkg/externalLink" "github.com/devtron-labs/devtron/pkg/genericNotes" - repository9 "github.com/devtron-labs/devtron/pkg/genericNotes/repository" + repository10 "github.com/devtron-labs/devtron/pkg/genericNotes/repository" "github.com/devtron-labs/devtron/pkg/git" "github.com/devtron-labs/devtron/pkg/gitops" jira2 "github.com/devtron-labs/devtron/pkg/jira" @@ -110,7 +112,7 @@ import ( "github.com/devtron-labs/devtron/pkg/k8s/capacity" "github.com/devtron-labs/devtron/pkg/k8s/informer" "github.com/devtron-labs/devtron/pkg/kubernetesResourceAuditLogs" - repository13 "github.com/devtron-labs/devtron/pkg/kubernetesResourceAuditLogs/repository" + repository14 "github.com/devtron-labs/devtron/pkg/kubernetesResourceAuditLogs/repository" "github.com/devtron-labs/devtron/pkg/module" "github.com/devtron-labs/devtron/pkg/module/repo" "github.com/devtron-labs/devtron/pkg/module/store" @@ -118,10 +120,11 @@ import ( "github.com/devtron-labs/devtron/pkg/pipeline" "github.com/devtron-labs/devtron/pkg/pipeline/history" repository6 "github.com/devtron-labs/devtron/pkg/pipeline/history/repository" - repository10 "github.com/devtron-labs/devtron/pkg/pipeline/repository" + repository11 "github.com/devtron-labs/devtron/pkg/pipeline/repository" "github.com/devtron-labs/devtron/pkg/plugin" - repository11 "github.com/devtron-labs/devtron/pkg/plugin/repository" + repository12 "github.com/devtron-labs/devtron/pkg/plugin/repository" "github.com/devtron-labs/devtron/pkg/projectManagementService/jira" + "github.com/devtron-labs/devtron/pkg/resourceQualifiers" security2 "github.com/devtron-labs/devtron/pkg/security" "github.com/devtron-labs/devtron/pkg/server" "github.com/devtron-labs/devtron/pkg/server/config" @@ -338,7 +341,20 @@ func InitializeApp() (*App, error) { variableEntityMappingServiceImpl := variables.NewVariableEntityMappingServiceImpl(variableEntityMappingRepositoryImpl, sugaredLogger) variableTemplateParserImpl := parsers.NewVariableTemplateParserImpl(sugaredLogger) scopedVariableRepositoryImpl := repository7.NewScopedVariableRepository(db, sugaredLogger) - scopedVariableServiceImpl, err := variables.NewScopedVariableServiceImpl(sugaredLogger, scopedVariableRepositoryImpl) + qualifiersMappingRepositoryImpl, err := resourceQualifiers.NewQualifiersMappingRepositoryImpl(db, sugaredLogger) + if err != nil { + return nil, err + } + devtronResourceSearchableKeyRepositoryImpl := repository9.NewDevtronResourceSearchableKeyRepositoryImpl(sugaredLogger, db) + devtronResourceSearchableKeyServiceImpl, err := devtronResource.NewDevtronResourceSearchableKeyServiceImpl(sugaredLogger, devtronResourceSearchableKeyRepositoryImpl) + if err != nil { + return nil, err + } + qualifierMappingServiceImpl, err := resourceQualifiers.NewQualifierMappingServiceImpl(sugaredLogger, qualifiersMappingRepositoryImpl, devtronResourceSearchableKeyServiceImpl) + if err != nil { + return nil, err + } + scopedVariableServiceImpl, err := variables.NewScopedVariableServiceImpl(sugaredLogger, scopedVariableRepositoryImpl, qualifierMappingServiceImpl) if err != nil { return nil, err } @@ -354,8 +370,8 @@ func InitializeApp() (*App, error) { } pipelineStatusTimelineRepositoryImpl := pipelineConfig.NewPipelineStatusTimelineRepositoryImpl(db, sugaredLogger) appLabelRepositoryImpl := pipelineConfig.NewAppLabelRepositoryImpl(db) - genericNoteRepositoryImpl := repository9.NewGenericNoteRepositoryImpl(db) - genericNoteHistoryRepositoryImpl := repository9.NewGenericNoteHistoryRepositoryImpl(db) + genericNoteRepositoryImpl := repository10.NewGenericNoteRepositoryImpl(db) + genericNoteHistoryRepositoryImpl := repository10.NewGenericNoteHistoryRepositoryImpl(db) genericNoteHistoryServiceImpl := genericNotes.NewGenericNoteHistoryServiceImpl(genericNoteHistoryRepositoryImpl, sugaredLogger) genericNoteServiceImpl := genericNotes.NewGenericNoteServiceImpl(genericNoteRepositoryImpl, genericNoteHistoryServiceImpl, userRepositoryImpl, sugaredLogger) appCrudOperationServiceImpl := app2.NewAppCrudOperationServiceImpl(appLabelRepositoryImpl, sugaredLogger, appRepositoryImpl, userRepositoryImpl, installedAppRepositoryImpl, genericNoteServiceImpl) @@ -386,7 +402,7 @@ func InitializeApp() (*App, error) { } appStoreDeploymentServiceImpl := service.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, clusterInstalledAppsRepositoryImpl, appRepositoryImpl, appStoreDeploymentHelmServiceImpl, appStoreDeploymentArgoCdServiceImpl, environmentServiceImpl, clusterServiceImplExtended, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, globalEnvVariables, installedAppVersionHistoryRepositoryImpl, gitOpsConfigRepositoryImpl, attributesServiceImpl, deploymentServiceTypeConfig, chartTemplateServiceImpl, pubSubClientServiceImpl) k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sUtil, clusterServiceImplExtended) - manifestPushConfigRepositoryImpl := repository10.NewManifestPushConfigRepository(sugaredLogger, db) + manifestPushConfigRepositoryImpl := repository11.NewManifestPushConfigRepository(sugaredLogger, db) gitOpsManifestPushServiceImpl := app2.NewGitOpsManifestPushServiceImpl(sugaredLogger, chartTemplateServiceImpl, chartServiceImpl, gitOpsConfigRepositoryImpl, gitFactory, pipelineStatusTimelineServiceImpl) appServiceImpl := app2.NewAppService(envConfigOverrideRepositoryImpl, pipelineOverrideRepositoryImpl, mergeUtil, sugaredLogger, ciArtifactRepositoryImpl, pipelineRepositoryImpl, dbMigrationConfigRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, applicationServiceClientImpl, tokenCache, acdAuthConfig, enforcerImpl, enforcerUtilImpl, userServiceImpl, appListingRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineConfigRepositoryImpl, configMapRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, chartRepositoryImpl, ciPipelineMaterialRepositoryImpl, cdWorkflowRepositoryImpl, commonServiceImpl, imageScanDeployInfoRepositoryImpl, imageScanHistoryRepositoryImpl, argoK8sClientImpl, gitFactory, pipelineStrategyHistoryServiceImpl, configMapHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, chartTemplateServiceImpl, refChartDir, chartRefRepositoryImpl, chartServiceImpl, helmAppClientImpl, argoUserServiceImpl, pipelineStatusTimelineRepositoryImpl, appCrudOperationServiceImpl, configMapHistoryRepositoryImpl, pipelineStrategyHistoryRepositoryImpl, deploymentTemplateHistoryRepositoryImpl, dockerRegistryIpsConfigServiceImpl, pipelineStatusTimelineResourcesServiceImpl, pipelineStatusSyncDetailServiceImpl, pipelineStatusTimelineServiceImpl, appServiceConfig, gitOpsConfigRepositoryImpl, appStatusServiceImpl, installedAppRepositoryImpl, appStoreDeploymentServiceImpl, k8sCommonServiceImpl, installedAppVersionHistoryRepositoryImpl, globalEnvVariables, helmAppServiceImpl, manifestPushConfigRepositoryImpl, gitOpsManifestPushServiceImpl, variableSnapshotHistoryServiceImpl, scopedVariableServiceImpl, variableEntityMappingServiceImpl, variableTemplateParserImpl) validate, err := util.IntValidator() @@ -421,8 +437,8 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - pipelineStageRepositoryImpl := repository10.NewPipelineStageRepository(sugaredLogger, db) - globalPluginRepositoryImpl := repository11.NewGlobalPluginRepository(sugaredLogger, db) + pipelineStageRepositoryImpl := repository11.NewPipelineStageRepository(sugaredLogger, db) + globalPluginRepositoryImpl := repository12.NewGlobalPluginRepository(sugaredLogger, db) pipelineStageServiceImpl := pipeline.NewPipelineStageService(sugaredLogger, pipelineStageRepositoryImpl, globalPluginRepositoryImpl, pipelineRepositoryImpl, scopedVariableServiceImpl, variableEntityMappingServiceImpl, variableTemplateParserImpl) workflowDagExecutorImpl := pipeline.NewWorkflowDagExecutorImpl(sugaredLogger, pipelineRepositoryImpl, cdWorkflowRepositoryImpl, pubSubClientServiceImpl, appServiceImpl, workflowServiceImpl, ciArtifactRepositoryImpl, ciPipelineRepositoryImpl, materialRepositoryImpl, pipelineOverrideRepositoryImpl, userServiceImpl, deploymentGroupRepositoryImpl, environmentRepositoryImpl, enforcerImpl, enforcerUtilImpl, tokenCache, acdAuthConfig, eventSimpleFactoryImpl, eventRESTClientImpl, cvePolicyRepositoryImpl, imageScanResultRepositoryImpl, appWorkflowRepositoryImpl, prePostCdScriptHistoryServiceImpl, argoUserServiceImpl, pipelineStatusTimelineRepositoryImpl, pipelineStatusTimelineServiceImpl, ciTemplateRepositoryImpl, ciWorkflowRepositoryImpl, appLabelRepositoryImpl, clientImpl, pipelineStageServiceImpl, k8sCommonServiceImpl, variableSnapshotHistoryServiceImpl) deploymentGroupAppRepositoryImpl := repository.NewDeploymentGroupAppRepositoryImpl(sugaredLogger, db) @@ -460,7 +476,7 @@ func InitializeApp() (*App, error) { appGroupMappingRepositoryImpl := appGroup.NewAppGroupMappingRepositoryImpl(db) appGroupServiceImpl := appGroup2.NewAppGroupServiceImpl(sugaredLogger, appGroupRepositoryImpl, appGroupMappingRepositoryImpl, enforcerUtilImpl) chartDeploymentServiceImpl := util.NewChartDeploymentServiceImpl(sugaredLogger, repositoryServiceClientImpl) - imageTaggingRepositoryImpl := repository12.NewImageTaggingRepositoryImpl(db) + imageTaggingRepositoryImpl := repository13.NewImageTaggingRepositoryImpl(db) imageTaggingServiceImpl := pipeline.NewImageTaggingServiceImpl(imageTaggingRepositoryImpl, ciPipelineRepositoryImpl, pipelineRepositoryImpl, environmentRepositoryImpl, sugaredLogger) pipelineBuilderImpl := pipeline.NewPipelineBuilderImpl(sugaredLogger, ciCdPipelineOrchestratorImpl, dockerArtifactStoreRepositoryImpl, materialRepositoryImpl, appRepositoryImpl, pipelineRepositoryImpl, propertiesConfigServiceImpl, ciTemplateRepositoryImpl, ciPipelineRepositoryImpl, applicationServiceClientImpl, chartRepositoryImpl, ciArtifactRepositoryImpl, ecrConfig, envConfigOverrideRepositoryImpl, environmentRepositoryImpl, clusterRepositoryImpl, pipelineConfigRepositoryImpl, utilMergeUtil, appWorkflowRepositoryImpl, ciCdConfig, cdWorkflowRepositoryImpl, appServiceImpl, imageScanResultRepositoryImpl, argoK8sClientImpl, gitFactory, attributesServiceImpl, acdAuthConfig, gitOpsConfigRepositoryImpl, pipelineStrategyHistoryServiceImpl, prePostCiScriptHistoryServiceImpl, prePostCdScriptHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, appLevelMetricsRepositoryImpl, pipelineStageServiceImpl, chartRefRepositoryImpl, chartTemplateServiceImpl, chartServiceImpl, helmAppServiceImpl, deploymentGroupRepositoryImpl, ciPipelineMaterialRepositoryImpl, userServiceImpl, ciTemplateServiceImpl, ciTemplateOverrideRepositoryImpl, gitMaterialHistoryServiceImpl, ciTemplateHistoryServiceImpl, ciPipelineHistoryServiceImpl, globalStrategyMetadataRepositoryImpl, globalStrategyMetadataChartRefMappingRepositoryImpl, pipelineDeploymentServiceTypeConfig, appStatusRepositoryImpl, workflowDagExecutorImpl, enforcerUtilImpl, argoUserServiceImpl, ciWorkflowRepositoryImpl, appGroupServiceImpl, chartDeploymentServiceImpl, k8sUtil, attributesRepositoryImpl, imageTaggingServiceImpl, variableEntityMappingServiceImpl, variableTemplateParserImpl) dbMigrationServiceImpl := pipeline.NewDbMogrationService(sugaredLogger, dbMigrationConfigRepositoryImpl) @@ -497,7 +513,7 @@ func InitializeApp() (*App, error) { migrateDbRouterImpl := router.NewMigrateDbRouterImpl(migrateDbRestHandlerImpl) appStoreVersionValuesRepositoryImpl := appStoreValuesRepository.NewAppStoreVersionValuesRepositoryImpl(sugaredLogger, db) appStoreValuesServiceImpl := service2.NewAppStoreValuesServiceImpl(sugaredLogger, appStoreApplicationVersionRepositoryImpl, installedAppRepositoryImpl, appStoreVersionValuesRepositoryImpl, userServiceImpl) - k8sResourceHistoryRepositoryImpl := repository13.NewK8sResourceHistoryRepositoryImpl(db, sugaredLogger) + k8sResourceHistoryRepositoryImpl := repository14.NewK8sResourceHistoryRepositoryImpl(db, sugaredLogger) k8sResourceHistoryServiceImpl := kubernetesResourceAuditLogs.Newk8sResourceHistoryServiceImpl(k8sResourceHistoryRepositoryImpl, sugaredLogger, appRepositoryImpl, environmentRepositoryImpl) ephemeralContainersRepositoryImpl := repository2.NewEphemeralContainersRepositoryImpl(db) ephemeralContainerServiceImpl := cluster2.NewEphemeralContainerServiceImpl(ephemeralContainersRepositoryImpl, sugaredLogger)