Skip to content

chore: App template oss ent #6369

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

Merged
merged 11 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -565,15 +565,12 @@ func (handler *PipelineConfigRestHandlerImpl) GetCiPipeline(w http.ResponseWrite
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
return
}
ciConf, err := handler.pipelineBuilder.GetCiPipeline(appId)
ciConf, err := handler.pipelineBuilder.GetCiPipelineRespResolved(appId)
if err != nil {
handler.Logger.Errorw("service err, GetCiPipeline", "err", err, "appId", appId)
handler.Logger.Errorw("service err, GetCiPipelineRespResolved", "appId", appId, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
if ciConf == nil || ciConf.Id == 0 {
err = &util.ApiError{Code: "404", HttpStatusCode: 200, UserMessage: "no data found"}
}
common.WriteJsonResp(w, err, ciConf, http.StatusOK)
}

Expand Down Expand Up @@ -1286,13 +1283,12 @@ func (handler *PipelineConfigRestHandlerImpl) GetCIPipelineById(w http.ResponseW
}
}

ciPipeline, err := handler.pipelineBuilder.GetCiPipelineById(pipelineId)
ciPipeline, err := handler.pipelineBuilder.GetCiPipelineByIdWithDefaultTag(pipelineId)
if err != nil {
handler.Logger.Infow("service error, GetCIPipelineById", "err", err, "appId", appId, "pipelineId", pipelineId)
handler.Logger.Infow("service error, GetCiPipelineByIdWithDefaultTag", "err", err, "appId", appId, "pipelineId", pipelineId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
ciPipeline.DefaultTag = []string{"{git_hash}", "{ci_pipeline_id}", "{global_counter}"}
common.WriteJsonResp(w, err, ciPipeline, http.StatusOK)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import (
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
"github.com/devtron-labs/devtron/pkg/bean"
"github.com/devtron-labs/devtron/pkg/generateManifest"
"github.com/devtron-labs/devtron/pkg/pipeline"
pipelineBean "github.com/devtron-labs/devtron/pkg/pipeline/bean"
resourceGroup2 "github.com/devtron-labs/devtron/pkg/resourceGroup"
"github.com/devtron-labs/devtron/pkg/resourceQualifiers"
Expand Down Expand Up @@ -718,48 +717,22 @@ func (handler *PipelineConfigRestHandlerImpl) EnvConfigOverrideCreate(w http.Res
return
}

createResp, err := handler.propertiesConfigService.CreateEnvironmentProperties(appId, &envConfigProperties)
if err != nil {
if err.Error() == bean4.NOCHARTEXIST {
ctx, cancel := context.WithCancel(r.Context())
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
appMetrics := false
if envConfigProperties.AppMetrics != nil {
appMetrics = *envConfigProperties.AppMetrics
}
templateRequest := bean3.TemplateRequest{
AppId: appId,
ChartRefId: envConfigProperties.ChartRefId,
ValuesOverride: []byte("{}"),
UserId: userId,
IsAppMetricsEnabled: appMetrics,
ctx, cancel := context.WithCancel(r.Context())
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}

_, err = handler.chartService.CreateChartFromEnvOverride(templateRequest, ctx)
if err != nil {
handler.Logger.Errorw("service err, EnvConfigOverrideCreate", "err", err, "payload", envConfigProperties)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
createResp, err = handler.propertiesConfigService.CreateEnvironmentProperties(appId, &envConfigProperties)
if err != nil {
handler.Logger.Errorw("service err, EnvConfigOverrideCreate", "err", err, "payload", envConfigProperties)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
} else {
handler.Logger.Errorw("service err, EnvConfigOverrideCreate", "err", err, "payload", envConfigProperties)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
createResp, err := handler.propertiesConfigService.CreateEnvironmentPropertiesAndBaseIfNeeded(ctx, appId, &envConfigProperties)
if err != nil {
handler.Logger.Errorw("service err, CreateEnvironmentPropertiesAndBaseIfNeeded", "payload", envConfigProperties, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, err, createResp, http.StatusOK)
}
Expand Down Expand Up @@ -1037,77 +1010,12 @@ func (handler *PipelineConfigRestHandlerImpl) GetDeploymentTemplate(w http.Respo
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
return
}

appConfigResponse := make(map[string]interface{})
appConfigResponse["globalConfig"] = nil

err = handler.chartRefService.CheckChartExists(chartRefId)
appConfigResponse, err := handler.chartService.GetDeploymentTemplateDataByAppIdAndCharRefId(appId, chartRefId)
if err != nil {
handler.Logger.Errorw("refChartDir Not Found err, JsonSchemaExtractFromFile", err)
common.WriteJsonResp(w, err, nil, http.StatusForbidden)
return
}

schema, readme, err := handler.chartRefService.GetSchemaAndReadmeForTemplateByChartRefId(chartRefId)
if err != nil {
handler.Logger.Errorw("err in getting schema and readme, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
}

template, err := handler.chartReadService.FindLatestChartForAppByAppId(appId)
if err != nil && pg.ErrNoRows != err {
handler.Logger.Errorw("service err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}

if pg.ErrNoRows == err {
appOverride, _, err := handler.chartRefService.GetAppOverrideForDefaultTemplate(chartRefId)
if err != nil {
handler.Logger.Errorw("service err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
appOverride["schema"] = json.RawMessage(schema)
appOverride["readme"] = string(readme)
mapB, err := json.Marshal(appOverride)
if err != nil {
handler.Logger.Errorw("marshal err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
return
}
appConfigResponse["globalConfig"] = json.RawMessage(mapB)
} else {
if template.ChartRefId != chartRefId {
templateRequested, err := handler.chartService.GetByAppIdAndChartRefId(appId, chartRefId)
if err != nil && err != pg.ErrNoRows {
handler.Logger.Errorw("service err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}

if pg.ErrNoRows == err {
template.ChartRefId = chartRefId
template.Id = 0
template.Latest = false
} else {
template.ChartRefId = templateRequested.ChartRefId
template.Id = templateRequested.Id
template.ChartRepositoryId = templateRequested.ChartRepositoryId
template.RefChartTemplate = templateRequested.RefChartTemplate
template.RefChartTemplateVersion = templateRequested.RefChartTemplateVersion
template.Latest = templateRequested.Latest
}
}
template.Schema = schema
template.Readme = string(readme)
bytes, err := json.Marshal(template)
if err != nil {
handler.Logger.Errorw("marshal err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
return
}
appOverride := json.RawMessage(bytes)
appConfigResponse["globalConfig"] = appOverride
}

common.WriteJsonResp(w, nil, appConfigResponse, http.StatusOK)
}

Expand Down Expand Up @@ -1992,15 +1900,9 @@ func (handler *PipelineConfigRestHandlerImpl) GetCdPipelineById(w http.ResponseW
return
}

cdPipeline, err := handler.pipelineBuilder.GetCdPipelineById(pipelineId)
if err != nil {
handler.Logger.Errorw("service err, GetCdPipelineById", "err", err, "appId", appId, "pipelineId", pipelineId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
cdResp, err := pipeline.CreatePreAndPostStageResponse(cdPipeline, version)
cdResp, err := handler.pipelineBuilder.GetCdPipelineByIdResolved(pipelineId, version)
if err != nil {
handler.Logger.Errorw("service err, CheckForVersionAndCreatePreAndPostStagePayload", "err", err, "appId", appId, "pipelineId", pipelineId)
handler.Logger.Errorw("service err, GetCdPipelineByIdResolved", "appId", appId, "pipelineId", pipelineId, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
security2 "github.com/devtron-labs/devtron/pkg/policyGovernance/security/imageScanning"
"github.com/devtron-labs/devtron/pkg/policyGovernance/security/imageScanning/read"
read3 "github.com/devtron-labs/devtron/pkg/team/read"
"github.com/devtron-labs/devtron/util/beHelper"
"io"
"net/http"
"strconv"
Expand All @@ -60,7 +61,6 @@ import (
"github.com/devtron-labs/devtron/pkg/bean"
"github.com/devtron-labs/devtron/pkg/pipeline"
"github.com/devtron-labs/devtron/pkg/team"
util2 "github.com/devtron-labs/devtron/util"
"github.com/devtron-labs/devtron/util/rbac"
"github.com/gorilla/mux"
"go.uber.org/zap"
Expand Down Expand Up @@ -663,7 +663,7 @@ func (handler *PipelineConfigRestHandlerImpl) PipelineNameSuggestion(w http.Resp
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
suggestedName := fmt.Sprintf("%s-%d-%s", pType, appId, util2.Generate(4))
suggestedName := beHelper.GetPipelineNameByPipelineType(pType, appId)
resourceName := handler.enforcerUtil.GetAppRBACName(app.AppName)
ok := handler.enforcerUtil.CheckAppRbacForAppOrJob(token, resourceName, casbin.ActionGet)
if !ok {
Expand Down
40 changes: 9 additions & 31 deletions api/restHandler/app/workflow/AppWorkflowRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,6 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
return
}
token := r.Header.Get("token")
app, err := impl.pipelineBuilder.GetApp(appId)
if err != nil {
impl.Logger.Errorw("bad request", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

v := r.URL.Query()
envIdsString := v.Get("envIds")
envIds := make([]int, 0)
Expand All @@ -207,16 +200,15 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
}

// RBAC enforcer applying
object := impl.enforcerUtil.GetAppRBACName(app.AppName)
object := impl.enforcerUtil.GetAppRBACNameByAppId(appId)
impl.Logger.Debugw("rbac object for other environment list", "object", object)
ok := impl.enforcerUtil.CheckAppRbacForAppOrJob(token, object, casbin.ActionGet)
if !ok {
common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden)
return
}
// RBAC enforcer Ends
workflows := make(map[string]interface{})
workflowsList, err := impl.appWorkflowService.FindAppWorkflows(appId)
//RBAC enforcer Ends
workflowsListResp, appType, err := impl.appWorkflowService.FindAppWorkflowsListResolvedResp(appId)
if err != nil {
impl.Logger.Errorw("error in fetching workflows for app", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
Expand All @@ -231,7 +223,7 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
return
}
triggerViewPayload := &bean2.TriggerViewWorkflowConfig{
Workflows: workflowsList,
Workflows: workflowsListResp.Workflows,
CdPipelines: cdPipelineWfData,
}
queryParam := bean2.NewWorkflowsFilterQuery().WithEnvIds(envIds)
Expand All @@ -242,12 +234,10 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
workflowsList = response.Workflows
workflowsListResp.Workflows = response.Workflows
}

workflows["appId"] = app.Id
workflows["appName"] = app.AppName
if len(workflowsList) > 0 && app.AppType == helper.Job {
if len(workflowsListResp.Workflows) > 0 && appType == helper.Job {
// RBAC

var workflowNames []string
Expand All @@ -256,15 +246,15 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
var rbacObjects []string
workNameObjectMap := make(map[string]bean2.AppWorkflowDto)

for _, workflow := range workflowsList {
for _, workflow := range workflowsListResp.Workflows {
workflowNames = append(workflowNames, workflow.Name)
workflowIds = append(workflowIds, workflow.Id)
}
workflowIdToObjectMap := impl.enforcerUtil.GetAllWorkflowRBACObjectsByAppId(appId, workflowNames, workflowIds)
itr := 0
for _, val := range workflowIdToObjectMap {
rbacObjects = append(rbacObjects, val)
workNameObjectMap[val] = workflowsList[itr]
workNameObjectMap[val] = workflowsListResp.Workflows[itr]
itr++
}

Expand All @@ -277,20 +267,8 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
if len(updatedWorkflowList) == 0 {
updatedWorkflowList = []bean2.AppWorkflowDto{}
}
workflows[bean3.Workflows] = updatedWorkflowList
} else if len(workflowsList) > 0 {
workflows[bean3.Workflows] = workflowsList
} else {
workflows[bean3.Workflows] = []bean2.AppWorkflowDto{}
}
isAppLevelGitOpsConfigured, err := impl.chartService.IsGitOpsRepoConfiguredForDevtronApp(appId)
if err != nil && !util.IsErrNoRows(err) {
impl.Logger.Errorw("service err, IsGitOpsRepoConfiguredForDevtronApp", "appId", appId, "envIds", envIds, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
workflows["isGitOpsRepoNotConfigured"] = !isAppLevelGitOpsConfigured
common.WriteJsonResp(w, nil, workflows, http.StatusOK)
common.WriteJsonResp(w, nil, workflowsListResp, http.StatusOK)
}

func (impl AppWorkflowRestHandlerImpl) FindAllWorkflows(w http.ResponseWriter, r *http.Request) {
Expand Down
33 changes: 33 additions & 0 deletions pkg/appWorkflow/AppWorkflowService.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package appWorkflow
import (
"errors"
"fmt"
"github.com/devtron-labs/devtron/internal/sql/repository/helper"
bean4 "github.com/devtron-labs/devtron/pkg/appWorkflow/bean"
"github.com/devtron-labs/devtron/pkg/deployment/common"
util2 "github.com/devtron-labs/devtron/util"
Expand Down Expand Up @@ -46,6 +47,7 @@ import (

type AppWorkflowService interface {
CreateAppWorkflow(req bean4.AppWorkflowDto) (bean4.AppWorkflowDto, error)
FindAppWorkflowsListResolvedResp(appId int) (resp bean4.AppWorkflowListRespDto, appType helper.AppType, err error)
FindAppWorkflows(appId int) ([]bean4.AppWorkflowDto, error)
FindAppWorkflowById(Id int, appId int) (bean4.AppWorkflowDto, error)
DeleteAppWorkflow(appWorkflowId int, userId int32) error
Expand Down Expand Up @@ -79,13 +81,15 @@ type AppWorkflowServiceImpl struct {
userAuthService user.UserAuthService
chartService chart.ChartService
deploymentConfigService common.DeploymentConfigService
pipelineBuilder pipeline.PipelineBuilder
}

func NewAppWorkflowServiceImpl(logger *zap.SugaredLogger, appWorkflowRepository appWorkflow.AppWorkflowRepository,
ciCdPipelineOrchestrator pipeline.CiCdPipelineOrchestrator, ciPipelineRepository pipelineConfig.CiPipelineRepository,
pipelineRepository pipelineConfig.PipelineRepository, enforcerUtil rbac.EnforcerUtil, resourceGroupService resourceGroup2.ResourceGroupService,
appRepository appRepository.AppRepository, userAuthService user.UserAuthService, chartService chart.ChartService,
deploymentConfigService common.DeploymentConfigService,
pipelineBuilder pipeline.PipelineBuilder,
) *AppWorkflowServiceImpl {
return &AppWorkflowServiceImpl{
Logger: logger,
Expand All @@ -99,6 +103,7 @@ func NewAppWorkflowServiceImpl(logger *zap.SugaredLogger, appWorkflowRepository
userAuthService: userAuthService,
chartService: chartService,
deploymentConfigService: deploymentConfigService,
pipelineBuilder: pipelineBuilder,
}
}

Expand Down Expand Up @@ -153,6 +158,34 @@ func (impl AppWorkflowServiceImpl) CreateAppWorkflow(req bean4.AppWorkflowDto) (
return req, nil
}

func (impl AppWorkflowServiceImpl) FindAppWorkflowsListResolvedResp(appId int) (resp bean4.AppWorkflowListRespDto, appType helper.AppType, err error) {
app, err := impl.pipelineBuilder.GetApp(appId)
if err != nil {
impl.Logger.Errorw("error, GetApp", "appId", appId, "err", err)
return resp, appType, err
}
workflowsList, err := impl.FindAppWorkflows(appId)
if err != nil {
impl.Logger.Errorw("error in fetching workflows for app", "appId", appId, "err", err)
return resp, appType, err
}
isAppLevelGitOpsConfigured, err := impl.chartService.IsGitOpsRepoConfiguredForDevtronApp(appId)
if err != nil && !util.IsErrNoRows(err) {
impl.Logger.Errorw("service err, IsGitOpsRepoConfiguredForDevtronApp", "appId", appId, "err", err)
return resp, appType, err
}
resp.AppId = app.Id
resp.AppName = app.AppName
resp.Workflows = workflowsList
resp.IsGitOpsRepoNotConfigured = !isAppLevelGitOpsConfigured
if len(workflowsList) > 0 {
resp.Workflows = workflowsList
} else {
resp.Workflows = []bean4.AppWorkflowDto{}
}
return resp, app.AppType, nil
}

func (impl AppWorkflowServiceImpl) FindAppWorkflows(appId int) ([]bean4.AppWorkflowDto, error) {
appWorkflows, err := impl.appWorkflowRepository.FindByAppId(appId)
if err != nil && err != pg.ErrNoRows {
Expand Down
Loading
Loading