Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
5 changes: 3 additions & 2 deletions Wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import (
appStoreDeploymentGitopsTool "github.com/devtron-labs/devtron/pkg/appStore/deployment/tool/gitops"
"github.com/devtron-labs/devtron/pkg/appWorkflow"
"github.com/devtron-labs/devtron/pkg/attributes"
"github.com/devtron-labs/devtron/pkg/bulkAction"
"github.com/devtron-labs/devtron/pkg/chart"
chartRepoRepository "github.com/devtron-labs/devtron/pkg/chartRepo/repository"
"github.com/devtron-labs/devtron/pkg/commonService"
Expand Down Expand Up @@ -219,8 +220,8 @@ func InitializeApp() (*App, error) {
wire.Bind(new(util.ChartTemplateService), new(*util.ChartTemplateServiceImpl)),
chart.NewChartServiceImpl,
wire.Bind(new(chart.ChartService), new(*chart.ChartServiceImpl)),
pipeline.NewBulkUpdateServiceImpl,
wire.Bind(new(pipeline.BulkUpdateService), new(*pipeline.BulkUpdateServiceImpl)),
bulkAction.NewBulkUpdateServiceImpl,
wire.Bind(new(bulkAction.BulkUpdateService), new(*bulkAction.BulkUpdateServiceImpl)),

repository.NewGitProviderRepositoryImpl,
wire.Bind(new(repository.GitProviderRepository), new(*repository.GitProviderRepositoryImpl)),
Expand Down
7 changes: 7 additions & 0 deletions api/appbean/AppDetail.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ type AppDetail struct {
EnvironmentOverrides map[string]*EnvironmentOverride `json:"environmentOverride"`
}

type AppWorkflowCloneDto struct {
AppId int `json:"appId"`
AppName string `json:"appName"`
AppWorkflows []*AppWorkflow `json:"workflows"`
EnvironmentOverrides map[string]*EnvironmentOverride `json:"environmentOverride"`
}

type AppMetadata struct {
AppName string `json:"appName" validate:"required"`
ProjectName string `json:"projectName" validate:"required"`
Expand Down
2 changes: 1 addition & 1 deletion api/restHandler/AppWorkflowRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (handler AppWorkflowRestHandlerImpl) DeleteAppWorkflow(w http.ResponseWrite
}
//rback block ends here

err = handler.appWorkflowService.DeleteAppWorkflow(appId, appWorkflowId, userId)
err = handler.appWorkflowService.DeleteAppWorkflow(appWorkflowId, userId)
if err != nil {
if _, ok := err.(*util.ApiError); ok {
handler.Logger.Warnw("error on deleting", "err", err)
Expand Down
104 changes: 95 additions & 9 deletions api/restHandler/BulkUpdateRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/devtron-labs/devtron/internal/sql/repository/security"
"github.com/devtron-labs/devtron/pkg/appClone"
"github.com/devtron-labs/devtron/pkg/appWorkflow"
"github.com/devtron-labs/devtron/pkg/bulkAction"
"github.com/devtron-labs/devtron/pkg/chart"
request "github.com/devtron-labs/devtron/pkg/cluster"
"github.com/devtron-labs/devtron/pkg/pipeline"
Expand All @@ -24,6 +25,7 @@ import (
"go.uber.org/zap"
"gopkg.in/go-playground/validator.v9"
"net/http"
"strconv"
"strings"
)

Expand All @@ -36,13 +38,15 @@ type BulkUpdateRestHandler interface {
BulkUnHibernate(w http.ResponseWriter, r *http.Request)
BulkDeploy(w http.ResponseWriter, r *http.Request)
BulkBuildTrigger(w http.ResponseWriter, r *http.Request)

HandleCdPipelineBulkAction(w http.ResponseWriter, r *http.Request)
}
type BulkUpdateRestHandlerImpl struct {
pipelineBuilder pipeline.PipelineBuilder
ciPipelineRepository pipelineConfig.CiPipelineRepository
ciHandler pipeline.CiHandler
logger *zap.SugaredLogger
bulkUpdateService pipeline.BulkUpdateService
bulkUpdateService bulkAction.BulkUpdateService
chartService chart.ChartService
propertiesConfigService pipeline.PropertiesConfigService
dbMigrationService pipeline.DbMigrationService
Expand All @@ -67,7 +71,7 @@ type BulkUpdateRestHandlerImpl struct {
}

func NewBulkUpdateRestHandlerImpl(pipelineBuilder pipeline.PipelineBuilder, logger *zap.SugaredLogger,
bulkUpdateService pipeline.BulkUpdateService,
bulkUpdateService bulkAction.BulkUpdateService,
chartService chart.ChartService,
propertiesConfigService pipeline.PropertiesConfigService,
dbMigrationService pipeline.DbMigrationService,
Expand Down Expand Up @@ -129,7 +133,7 @@ func (handler BulkUpdateRestHandlerImpl) FindBulkUpdateReadme(w http.ResponseWri
return
}
//auth free, only login required
var responseArr []*pipeline.BulkUpdateSeeExampleResponse
var responseArr []*bulkAction.BulkUpdateSeeExampleResponse
responseArr = append(responseArr, response)
common.WriteJsonResp(w, nil, responseArr, http.StatusOK)
}
Expand All @@ -151,7 +155,7 @@ func (handler BulkUpdateRestHandlerImpl) CheckAuthForImpactedObjects(AppId int,
}
func (handler BulkUpdateRestHandlerImpl) GetImpactedAppsName(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var script pipeline.BulkUpdateScript
var script bulkAction.BulkUpdateScript
err := decoder.Decode(&script)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
Expand Down Expand Up @@ -206,7 +210,7 @@ func (handler BulkUpdateRestHandlerImpl) CheckAuthForBulkUpdate(AppId int, EnvId
}
func (handler BulkUpdateRestHandlerImpl) BulkUpdate(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var script pipeline.BulkUpdateScript
var script bulkAction.BulkUpdateScript
err := decoder.Decode(&script)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
Expand Down Expand Up @@ -255,7 +259,7 @@ func (handler BulkUpdateRestHandlerImpl) BulkHibernate(w http.ResponseWriter, r
return
}
decoder := json.NewDecoder(r.Body)
var request pipeline.BulkApplicationForEnvironmentPayload
var request bulkAction.BulkApplicationForEnvironmentPayload
err = decoder.Decode(&request)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
Expand Down Expand Up @@ -292,7 +296,7 @@ func (handler BulkUpdateRestHandlerImpl) BulkUnHibernate(w http.ResponseWriter,
return
}
decoder := json.NewDecoder(r.Body)
var request pipeline.BulkApplicationForEnvironmentPayload
var request bulkAction.BulkApplicationForEnvironmentPayload
err = decoder.Decode(&request)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
Expand Down Expand Up @@ -329,7 +333,7 @@ func (handler BulkUpdateRestHandlerImpl) BulkDeploy(w http.ResponseWriter, r *ht
return
}
decoder := json.NewDecoder(r.Body)
var request pipeline.BulkApplicationForEnvironmentPayload
var request bulkAction.BulkApplicationForEnvironmentPayload
err = decoder.Decode(&request)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
Expand Down Expand Up @@ -365,7 +369,7 @@ func (handler BulkUpdateRestHandlerImpl) BulkBuildTrigger(w http.ResponseWriter,
return
}
decoder := json.NewDecoder(r.Body)
var request pipeline.BulkApplicationForEnvironmentPayload
var request bulkAction.BulkApplicationForEnvironmentPayload
err = decoder.Decode(&request)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
Expand Down Expand Up @@ -403,3 +407,85 @@ func (handler BulkUpdateRestHandlerImpl) checkAuthForBulkActions(token string, a
}
return true
}

func (handler BulkUpdateRestHandlerImpl) HandleCdPipelineBulkAction(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
userId, err := handler.userAuthService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
var cdPipelineBulkActionReq bulkAction.CdBulkActionRequestDto
err = decoder.Decode(&cdPipelineBulkActionReq)
cdPipelineBulkActionReq.UserId = userId
if err != nil {
handler.logger.Errorw("request err, HandleCdPipelineBulkAction", "err", err, "payload", cdPipelineBulkActionReq)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

v := r.URL.Query()
forceDelete := false
forceDeleteParam := v.Get("forceDelete")
if len(forceDeleteParam) > 0 {
forceDelete, err = strconv.ParseBool(forceDeleteParam)
if err != nil {
handler.logger.Errorw("request err, HandleCdPipelineBulkAction", "err", err, "payload", cdPipelineBulkActionReq)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
}
cdPipelineBulkActionReq.ForceDelete = forceDelete

dryRun := false
dryRunParam := v.Get("dryRun")
if len(dryRunParam) > 0 {
dryRun, err = strconv.ParseBool(dryRunParam)
if err != nil {
handler.logger.Errorw("request err, HandleCdPipelineBulkAction", "err", err, "payload", cdPipelineBulkActionReq)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
}
handler.logger.Infow("request payload, HandleCdPipelineBulkAction", "payload", cdPipelineBulkActionReq)
impactedPipelines, impactedAppWfIds, impactedCiPipelineIds, err := handler.bulkUpdateService.GetBulkActionImpactedPipelinesAndWfs(&cdPipelineBulkActionReq)
if err != nil {
handler.logger.Errorw("service err, GetBulkActionImpactedPipelinesAndWfs", "err", err, "payload", cdPipelineBulkActionReq)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
token := r.Header.Get("token")

appsHavingRbacChecked := make(map[string]bool)
for _, impactedPipeline := range impactedPipelines {
//check to avoid same rbac matching multiple times
if _, ok := appsHavingRbacChecked[impactedPipeline.App.AppName]; !ok {
resourceName := handler.enforcerUtil.GetAppRBACName(impactedPipeline.App.AppName)
if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionUpdate, resourceName); !ok {
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
return
} else {
appsHavingRbacChecked[impactedPipeline.App.AppName] = true
}
}
object := handler.enforcerUtil.GetAppRBACByAppNameAndEnvId(impactedPipeline.App.AppName, impactedPipeline.EnvironmentId)
if ok := handler.enforcer.Enforce(token, casbin.ResourceEnvironment, casbin.ActionUpdate, object); !ok {
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
return
}
}
acdToken, err := handler.argoUserService.GetLatestDevtronArgoCdUserToken()
if err != nil {
handler.logger.Errorw("error in getting acd token", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
ctx := context.WithValue(r.Context(), "token", acdToken)
resp, err := handler.bulkUpdateService.PerformBulkActionOnCdPipelines(&cdPipelineBulkActionReq, impactedPipelines, ctx, dryRun, impactedAppWfIds, impactedCiPipelineIds)
if err != nil {
handler.logger.Errorw("service err, HandleCdPipelineBulkAction", "err", err, "payload", cdPipelineBulkActionReq)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, resp, http.StatusOK)
}
Loading