Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 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
2 changes: 1 addition & 1 deletion api/restHandler/AppListingRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ func (handler AppListingRestHandlerImpl) FetchResourceTree(w http.ResponseWriter
if cdPipeline.DeploymentAppType == util.PIPELINE_DEPLOYMENT_TYPE_ACD {
apiError, ok := err.(*util.ApiError)
if ok && apiError != nil {
if apiError.Code == constants.AppDetailResourceTreeNotFound && cdPipeline.DeploymentAppDeleteRequest == true {
if apiError.Code == constants.AppDetailResourceTreeNotFound && cdPipeline.DeploymentAppDeleteRequest == true && cdPipeline.DeploymentAppCreated == true {
acdAppFound, _ := handler.pipeline.MarkGitOpsDevtronAppsDeletedWhereArgoAppIsDeleted(appId, envId, acdToken, cdPipeline)
if acdAppFound {
common.WriteJsonResp(w, fmt.Errorf("unable to fetch resource tree"), nil, http.StatusInternalServerError)
Expand Down
131 changes: 131 additions & 0 deletions api/restHandler/app/DeploymentPipelineRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type DevtronAppDeploymentRestHandler interface {
GetCdPipelineById(w http.ResponseWriter, r *http.Request)
PatchCdPipeline(w http.ResponseWriter, r *http.Request)
HandleChangeDeploymentRequest(w http.ResponseWriter, r *http.Request)
HandleChangeDeploymentTypeRequest(w http.ResponseWriter, r *http.Request)
HandleTriggerDeploymentAfterTypeChange(w http.ResponseWriter, r *http.Request)
GetCdPipelines(w http.ResponseWriter, r *http.Request)
GetCdPipelinesForAppAndEnv(w http.ResponseWriter, r *http.Request)

Expand Down Expand Up @@ -357,6 +359,135 @@ func (handler PipelineConfigRestHandlerImpl) HandleChangeDeploymentRequest(w htt
return
}

func (handler PipelineConfigRestHandlerImpl) HandleChangeDeploymentTypeRequest(w http.ResponseWriter, r *http.Request) {

// Auth check
userId, err := handler.userAuthService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}

// Retrieving and parsing request body
decoder := json.NewDecoder(r.Body)
var deploymentTypeChangeRequest *bean.DeploymentAppTypeChangeRequest
err = decoder.Decode(&deploymentTypeChangeRequest)
if err != nil {
handler.Logger.Errorw("request err, HandleChangeDeploymentTypeRequest", "err", err, "payload",
deploymentTypeChangeRequest)

common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
deploymentTypeChangeRequest.UserId = userId

// Validate incoming request
err = handler.validator.Struct(deploymentTypeChangeRequest)
if err != nil {
handler.Logger.Errorw("validation err, HandleChangeDeploymentTypeRequest", "err", err, "payload",
deploymentTypeChangeRequest)

common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

// Only super-admin access
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionDelete, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}

// Retrieve argocd token
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.pipelineBuilder.ChangePipelineDeploymentType(ctx, deploymentTypeChangeRequest)

if err != nil {
nErr := errors.New("failed to change deployment type with error msg: " + err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

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

we can use format printer

handler.Logger.Errorw(err.Error(),
"payload", deploymentTypeChangeRequest,
"err", err)

common.WriteJsonResp(w, nErr, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, resp, http.StatusOK)
return
}

func (handler PipelineConfigRestHandlerImpl) HandleTriggerDeploymentAfterTypeChange(w http.ResponseWriter, r *http.Request) {

// Auth check
Copy link
Contributor

Choose a reason for hiding this comment

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

remove this comment

userId, err := handler.userAuthService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}

// Retrieving and parsing request body
decoder := json.NewDecoder(r.Body)
var deploymentAppTriggerRequest *bean.DeploymentAppTypeChangeRequest
err = decoder.Decode(&deploymentAppTriggerRequest)
if err != nil {
handler.Logger.Errorw("request err, HandleChangeDeploymentTypeRequest", "err", err, "payload",
deploymentAppTriggerRequest)

common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
deploymentAppTriggerRequest.UserId = userId

// Validate incoming request
err = handler.validator.Struct(deploymentAppTriggerRequest)
if err != nil {
handler.Logger.Errorw("validation err, HandleChangeDeploymentTypeRequest", "err", err, "payload",
deploymentAppTriggerRequest)

common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

// Only super-admin access
token := r.Header.Get("token")

if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionDelete, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}

// Retrieve argocd token
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.pipelineBuilder.TriggerDeploymentAfterTypeChange(ctx, deploymentAppTriggerRequest)

if err != nil {
nErr := errors.New("failed to change deployment type with error msg: " + err.Error())
handler.Logger.Errorw(err.Error(),
"payload", deploymentAppTriggerRequest,
"err", err)

common.WriteJsonResp(w, nErr, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, resp, http.StatusOK)
return
}

func (handler PipelineConfigRestHandlerImpl) EnvConfigOverrideCreate(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userAuthService.GetLoggedInUser(r)
if userId == 0 || err != nil {
Expand Down
2 changes: 2 additions & 0 deletions api/router/PipelineConfigRouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func (router PipelineConfigRouterImpl) initPipelineConfigRouter(configRouter *mu
configRouter.Path("/cd-pipeline").HandlerFunc(router.restHandler.CreateCdPipeline).Methods("POST")
configRouter.Path("/cd-pipeline/patch").HandlerFunc(router.restHandler.PatchCdPipeline).Methods("POST")
configRouter.Path("/cd-pipeline/patch/deployment").HandlerFunc(router.restHandler.HandleChangeDeploymentRequest).Methods("POST")
configRouter.Path("/cd-pipeline/patch/deployment/type").HandlerFunc(router.restHandler.HandleChangeDeploymentTypeRequest).Methods("POST")
configRouter.Path("/cd-pipeline/patch/deployment/trigger").HandlerFunc(router.restHandler.HandleTriggerDeploymentAfterTypeChange).Methods("POST")
configRouter.Path("/cd-pipeline/{appId}").HandlerFunc(router.restHandler.GetCdPipelines).Methods("GET")
configRouter.Path("/cd-pipeline/{appId}/env/{envId}").HandlerFunc(router.restHandler.GetCdPipelinesForAppAndEnv).Methods("GET")
//save environment specific override
Expand Down
31 changes: 19 additions & 12 deletions internal/sql/repository/pipelineConfig/PipelineRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ type PipelineRepository interface {
FindActiveByNotFilter(envId int, appIdExcludes []int) (pipelines []*Pipeline, err error)
FindAllPipelinesByChartsOverrideAndAppIdAndChartId(chartOverridden bool, appId int, chartId int) (pipelines []*Pipeline, err error)
FindActiveByAppIdAndPipelineId(appId int, pipelineId int) ([]*Pipeline, error)
UpdateCdPipeline(pipeline *Pipeline) error
UpdateCdPipelineDeploymentAppInFilter(deploymentAppType string, cdPipelineIdIncludes []int, userId int32) error
SetDeploymentAppCreatedInPipeline(deploymentAppCreated bool, pipelineId int, userId int32) error
UpdateCdPipelineDeploymentAppInFilter(deploymentAppType string, cdPipelineIdIncludes []int, userId int32, deploymentAppCreated bool, delete bool) error
UpdateCdPipelineAfterDeployment(deploymentAppType string, cdPipelineIdIncludes []int, userId int32, delete bool) error
FindNumberOfAppsWithCdPipeline(appIds []int) (count int, err error)
GetAppAndEnvDetailsForDeploymentAppTypePipeline(deploymentAppType string, clusterIds []int) ([]*Pipeline, error)
GetArgoPipelinesHavingTriggersStuckInLastPossibleNonTerminalTimelines(pendingSinceSeconds int, timeForDegradation int) ([]*Pipeline, error)
Expand Down Expand Up @@ -490,25 +491,31 @@ func (impl PipelineRepositoryImpl) FindActiveByAppIdAndPipelineId(appId int, pip
return pipelines, err
}

func (impl PipelineRepositoryImpl) UpdateCdPipeline(pipeline *Pipeline) error {
err := impl.dbConnection.Update(pipeline)
func (impl PipelineRepositoryImpl) SetDeploymentAppCreatedInPipeline(deploymentAppCreated bool, pipelineId int, userId int32) error {
query := "update pipeline set deployment_app_created=?, updated_on=?, updated_by=? where id=?;"
Copy link
Contributor

Choose a reason for hiding this comment

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

avoid writing native queries

var pipeline *Pipeline
_, err := impl.dbConnection.Query(pipeline, query, deploymentAppCreated, time.Now(), userId, pipelineId)
return err
}

// UpdateCdPipelineDeploymentAppInFilter takes in deployment app type and list of cd pipeline ids and
// updates the deployment_app_type and sets deployment_app_created to false in the table for given ids.
func (impl PipelineRepositoryImpl) UpdateCdPipelineDeploymentAppInFilter(deploymentAppType string,
cdPipelineIdIncludes []int, userId int32) error {
cdPipelineIdIncludes []int, userId int32, deploymentAppCreated bool, delete bool) error {
query := "update pipeline set deployment_app_created = ?, deployment_app_type = ?, " +
"updated_by = ?, updated_on = ?, deployment_app_delete_request = ? where id in (?);"
var pipeline *Pipeline
_, err := impl.dbConnection.Query(pipeline, query, deploymentAppCreated, deploymentAppType, userId, time.Now(), delete, pg.In(cdPipelineIdIncludes))
Copy link
Contributor

Choose a reason for hiding this comment

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

check empty array for pg.In


query := "update pipeline set " +
"deployment_app_created = false, " +
"deployment_app_type = ?, " +
"updated_by = ?, " +
"updated_on = ? " +
"where id in (?)"
return err
}

func (impl PipelineRepositoryImpl) UpdateCdPipelineAfterDeployment(deploymentAppType string,
cdPipelineIdIncludes []int, userId int32, delete bool) error {
query := "update pipeline set deployment_app_type = ?, " +
"updated_by = ?, updated_on = ?, deployment_app_delete_request = ? where id in (?);"
var pipeline *Pipeline
_, err := impl.dbConnection.Query(pipeline, query, deploymentAppType, userId, time.Now(), pg.In(cdPipelineIdIncludes))
_, err := impl.dbConnection.Query(pipeline, query, deploymentAppType, userId, time.Now(), delete, pg.In(cdPipelineIdIncludes))
Copy link
Contributor

Choose a reason for hiding this comment

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

use isDeleted


return err
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions pkg/app/AppService.go
Original file line number Diff line number Diff line change
Expand Up @@ -2122,10 +2122,7 @@ func (impl *AppServiceImpl) CreateHistoriesForDeploymentTrigger(pipeline *pipeli
}

func (impl *AppServiceImpl) updatePipeline(pipeline *pipelineConfig.Pipeline, userId int32) (bool, error) {
pipeline.DeploymentAppCreated = true
pipeline.UpdatedOn = time.Now()
pipeline.UpdatedBy = userId
err := impl.pipelineRepository.UpdateCdPipeline(pipeline)
err := impl.pipelineRepository.SetDeploymentAppCreatedInPipeline(true, pipeline.Id, userId)
if err != nil {
impl.logger.Errorw("error on updating cd pipeline for setting deployment app created", "err", err)
return false, err
Expand Down
6 changes: 4 additions & 2 deletions pkg/bean/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,10 @@ const (
type Status string

const (
Success Status = "Success"
Failed Status = "Failed"
Success Status = "Success"
Failed Status = "Failed"
INITIATED Status = "Migration initiated"
NOT_YET_DELETED Status = "Not yet deleted"
)

func (a CdPatchAction) String() string {
Expand Down
Loading