@@ -53,6 +53,9 @@ type AppCloneServiceImpl struct {
5353 pipelineStageService pipeline.PipelineStageService
5454 ciTemplateService pipeline.CiTemplateService
5555 appRepository app2.AppRepository
56+ ciPipelineRepository pipelineConfig.CiPipelineRepository
57+ pipelineRepository pipelineConfig.PipelineRepository
58+ appWorkflowRepository appWorkflow2.AppWorkflowRepository
5659}
5760
5861func NewAppCloneServiceImpl (logger * zap.SugaredLogger ,
@@ -65,7 +68,8 @@ func NewAppCloneServiceImpl(logger *zap.SugaredLogger,
6568 propertiesConfigService pipeline.PropertiesConfigService ,
6669 ciTemplateOverrideRepository pipelineConfig.CiTemplateOverrideRepository ,
6770 pipelineStageService pipeline.PipelineStageService , ciTemplateService pipeline.CiTemplateService ,
68- appRepository app2.AppRepository ) * AppCloneServiceImpl {
71+ appRepository app2.AppRepository , ciPipelineRepository pipelineConfig.CiPipelineRepository ,
72+ pipelineRepository pipelineConfig.PipelineRepository , appWorkflowRepository appWorkflow2.AppWorkflowRepository ) * AppCloneServiceImpl {
6973 return & AppCloneServiceImpl {
7074 logger : logger ,
7175 pipelineBuilder : pipelineBuilder ,
@@ -78,6 +82,9 @@ func NewAppCloneServiceImpl(logger *zap.SugaredLogger,
7882 pipelineStageService : pipelineStageService ,
7983 ciTemplateService : ciTemplateService ,
8084 appRepository : appRepository ,
85+ ciPipelineRepository : ciPipelineRepository ,
86+ pipelineRepository : pipelineRepository ,
87+ appWorkflowRepository : appWorkflowRepository ,
8188 }
8289}
8390
@@ -90,6 +97,16 @@ type CloneRequest struct {
9097 AppType helper.AppType `json:"appType"`
9198}
9299
100+ type CreateWorkflowMappingDto struct {
101+ oldAppId int
102+ newAppId int
103+ userId int32
104+ newWfId int
105+ gitMaterialMapping map [int ]int
106+ isSameProject bool
107+ externalCiPipelineId int
108+ }
109+
93110func (impl * AppCloneServiceImpl ) CloneApp (createReq * bean.CreateAppDTO , context context.Context ) (* bean.CreateAppDTO , error ) {
94111 //validate template app
95112 templateApp , err := impl .appRepository .FindById (createReq .TemplateId )
@@ -587,6 +604,7 @@ func (impl *AppCloneServiceImpl) CreateWf(oldAppId, newAppId int, userId int32,
587604 return nil , err
588605 }
589606 impl .logger .Debugw ("workflow found" , "wf" , refAppWFs )
607+
590608 for _ , refAppWF := range refAppWFs {
591609 thisWf := appWorkflow.AppWorkflowDto {
592610 Id : 0 ,
@@ -595,24 +613,38 @@ func (impl *AppCloneServiceImpl) CreateWf(oldAppId, newAppId int, userId int32,
595613 AppWorkflowMappingDto : nil , //first create new mapping then add it
596614 UserId : userId ,
597615 }
616+ thisWf , err = impl .appWorkflowService .CreateAppWorkflow (thisWf )
617+ if err != nil {
618+ impl .logger .Errorw ("error in creating workflow without external-ci" , "err" , err )
619+ return nil , err
620+ }
598621
599622 isExternalCiPresent := false
600623 for _ , awm := range refAppWF .AppWorkflowMappingDto {
601624 if awm .Type == appWorkflow2 .WEBHOOK {
602625 isExternalCiPresent = true
626+ break
603627 }
604628 }
605-
606- if ! isExternalCiPresent {
607- thisWf , err = impl .appWorkflowService .CreateAppWorkflow (thisWf )
608- impl .logger .Debugw ("workflow found" , thisWf )
629+ createWorkflowMappingDto := CreateWorkflowMappingDto {
630+ newAppId : newAppId ,
631+ oldAppId : oldAppId ,
632+ newWfId : thisWf .Id ,
633+ userId : userId ,
634+ }
635+ var externalCiPipelineId int
636+ if isExternalCiPresent {
637+ externalCiPipelineId , err = impl .createExternalCiAndAppWorkflowMapping (createWorkflowMappingDto )
609638 if err != nil {
610- impl .logger .Errorw ("errir in creating workflow without extenal-ci " , "err" , err )
639+ impl .logger .Errorw ("error in createExternalCiAndAppWorkflowMapping " , "err" , err )
611640 return nil , err
612641 }
613642 }
643+ createWorkflowMappingDto .gitMaterialMapping = gitMaterialMapping
644+ createWorkflowMappingDto .isSameProject = isSameProject
645+ createWorkflowMappingDto .externalCiPipelineId = externalCiPipelineId
614646
615- err = impl .createWfMappings (refAppWF .AppWorkflowMappingDto , oldAppId , newAppId , userId , thisWf . Id , gitMaterialMapping , ctx , isSameProject )
647+ err = impl .createWfInstances (refAppWF .AppWorkflowMappingDto , createWorkflowMappingDto , ctx )
616648 if err != nil {
617649 impl .logger .Errorw ("error in creating workflow mapping" , "err" , err )
618650 return nil , err
@@ -621,7 +653,28 @@ func (impl *AppCloneServiceImpl) CreateWf(oldAppId, newAppId int, userId int32,
621653 return nil , nil
622654}
623655
624- func (impl * AppCloneServiceImpl ) createWfMappings (refWfMappings []appWorkflow.AppWorkflowMappingDto , oldAppId , newAppId int , userId int32 , thisWfId int , gitMaterialMapping map [int ]int , ctx context.Context , isSameProject bool ) error {
656+ func (impl * AppCloneServiceImpl ) createExternalCiAndAppWorkflowMapping (createWorkflowMappingDto CreateWorkflowMappingDto ) (int , error ) {
657+ dbConnection := impl .pipelineRepository .GetConnection ()
658+ tx , err := dbConnection .Begin ()
659+ if err != nil {
660+ impl .logger .Errorw ("error in beginning transaction" , "err" , err )
661+ return 0 , err
662+ }
663+ // Rollback tx on error.
664+ defer tx .Rollback ()
665+ externalCiPipelineId , err := impl .pipelineBuilder .CreateExternalCiAndAppWorkflowMapping (createWorkflowMappingDto .newAppId , createWorkflowMappingDto .newWfId , createWorkflowMappingDto .userId , tx )
666+ if err != nil {
667+ impl .logger .Errorw ("error in creating new external ci pipeline and new app workflow mapping" , "refAppId" , createWorkflowMappingDto .oldAppId , "newAppId" , createWorkflowMappingDto .newAppId , "err" , err )
668+ return 0 , err
669+ }
670+ err = tx .Commit ()
671+ if err != nil {
672+ return 0 , err
673+ }
674+ return externalCiPipelineId , nil
675+ }
676+
677+ func (impl * AppCloneServiceImpl ) createWfInstances (refWfMappings []appWorkflow.AppWorkflowMappingDto , createWorkflowMappingDto CreateWorkflowMappingDto , ctx context.Context ) error {
625678 impl .logger .Debugw ("wf mapping cloning" , "refWfMappings" , refWfMappings )
626679 var ciMapping []appWorkflow.AppWorkflowMappingDto
627680 var cdMappings []appWorkflow.AppWorkflowMappingDto
@@ -637,23 +690,30 @@ func (impl *AppCloneServiceImpl) createWfMappings(refWfMappings []appWorkflow.Ap
637690 return fmt .Errorf ("unsupported wf type: %s" , appWf .Type )
638691 }
639692 }
640- refApp , err := impl .pipelineBuilder .GetApp (oldAppId )
693+ sourceToNewPipelineIdMapping := make (map [int ]int )
694+ refApp , err := impl .pipelineBuilder .GetApp (createWorkflowMappingDto .oldAppId )
695+ if err != nil {
696+ impl .logger .Errorw ("error in getting app from refAppId" , "refAppId" , createWorkflowMappingDto .oldAppId )
697+ return err
698+ }
641699 if len (webhookMappings ) > 0 {
642- if isSameProject {
700+ if createWorkflowMappingDto . isSameProject {
643701 for _ , refwebhookMappings := range cdMappings {
644702 cdCloneReq := & cloneCdPipelineRequest {
645- refCdPipelineId : refwebhookMappings .ComponentId ,
646- refAppId : oldAppId ,
647- appId : newAppId ,
648- userId : userId ,
649- ciPipelineId : 0 ,
650- appWfId : thisWfId ,
651- refAppName : refApp .AppName ,
703+ refCdPipelineId : refwebhookMappings .ComponentId ,
704+ refAppId : createWorkflowMappingDto .oldAppId ,
705+ appId : createWorkflowMappingDto .newAppId ,
706+ userId : createWorkflowMappingDto .userId ,
707+ ciPipelineId : 0 ,
708+ appWfId : createWorkflowMappingDto .newWfId ,
709+ refAppName : refApp .AppName ,
710+ sourceToNewPipelineId : sourceToNewPipelineIdMapping ,
711+ externalCiPipelineId : createWorkflowMappingDto .externalCiPipelineId ,
652712 }
653713 pipeline , err := impl .CreateCdPipeline (cdCloneReq , ctx )
654714 impl .logger .Debugw ("cd pipeline created" , "pipeline" , pipeline )
655715 if err != nil {
656- impl .logger .Errorw ("error in getting cd-pipeling" , "err" , err )
716+ impl .logger .Errorw ("error in getting cd-pipeline" , "refAppId" , createWorkflowMappingDto . oldAppId , "newAppId" , createWorkflowMappingDto . newAppId , "err" , err )
657717 return err
658718 }
659719 }
@@ -667,7 +727,7 @@ func (impl *AppCloneServiceImpl) createWfMappings(refWfMappings []appWorkflow.Ap
667727 impl .logger .Warn ("no ci pipeline found" )
668728 return nil
669729 } else if len (ciMapping ) != 1 {
670- impl .logger .Warn ("more than one cd pipeline not supported" )
730+ impl .logger .Warn ("more than one ci pipeline not supported" )
671731 return nil
672732 }
673733
@@ -679,12 +739,12 @@ func (impl *AppCloneServiceImpl) createWfMappings(refWfMappings []appWorkflow.Ap
679739 impl .logger .Debugw ("creating ci" , "ref" , refCiMapping )
680740
681741 cloneCiPipelineRequest := & cloneCiPipelineRequest {
682- refAppId : oldAppId ,
742+ refAppId : createWorkflowMappingDto . oldAppId ,
683743 refCiPipelineId : refCiMapping .ComponentId ,
684- userId : userId ,
685- appId : newAppId ,
686- wfId : thisWfId ,
687- gitMaterialMapping : gitMaterialMapping ,
744+ userId : createWorkflowMappingDto . userId ,
745+ appId : createWorkflowMappingDto . newAppId ,
746+ wfId : createWorkflowMappingDto . newWfId ,
747+ gitMaterialMapping : createWorkflowMappingDto . gitMaterialMapping ,
688748 refAppName : refApp .AppName ,
689749 }
690750 ci , err = impl .CreateCiPipeline (cloneCiPipelineRequest )
@@ -694,16 +754,18 @@ func (impl *AppCloneServiceImpl) createWfMappings(refWfMappings []appWorkflow.Ap
694754 }
695755 impl .logger .Debugw ("ci created" , "ci" , ci )
696756 }
697- if isSameProject {
757+
758+ if createWorkflowMappingDto .isSameProject {
698759 for _ , refCdMapping := range cdMappings {
699760 cdCloneReq := & cloneCdPipelineRequest {
700- refCdPipelineId : refCdMapping .ComponentId ,
701- refAppId : oldAppId ,
702- appId : newAppId ,
703- userId : userId ,
704- ciPipelineId : ci .CiPipelines [0 ].Id ,
705- appWfId : thisWfId ,
706- refAppName : refApp .AppName ,
761+ refCdPipelineId : refCdMapping .ComponentId ,
762+ refAppId : createWorkflowMappingDto .oldAppId ,
763+ appId : createWorkflowMappingDto .newAppId ,
764+ userId : createWorkflowMappingDto .userId ,
765+ ciPipelineId : ci .CiPipelines [0 ].Id ,
766+ appWfId : createWorkflowMappingDto .newWfId ,
767+ refAppName : refApp .AppName ,
768+ sourceToNewPipelineId : sourceToNewPipelineIdMapping ,
707769 }
708770 pipeline , err := impl .CreateCdPipeline (cdCloneReq , ctx )
709771 if err != nil {
@@ -868,13 +930,15 @@ func (impl *AppCloneServiceImpl) CreateCiPipeline(req *cloneCiPipelineRequest) (
868930}
869931
870932type cloneCdPipelineRequest struct {
871- refCdPipelineId int
872- refAppId int
873- appId int
874- userId int32
875- ciPipelineId int
876- appWfId int
877- refAppName string
933+ refCdPipelineId int
934+ refAppId int
935+ appId int
936+ userId int32
937+ ciPipelineId int
938+ appWfId int
939+ refAppName string
940+ sourceToNewPipelineId map [int ]int
941+ externalCiPipelineId int
878942}
879943
880944func (impl * AppCloneServiceImpl ) CreateCdPipeline (req * cloneCdPipelineRequest , ctx context.Context ) (* bean.CdPipelines , error ) {
@@ -892,6 +956,7 @@ func (impl *AppCloneServiceImpl) CreateCdPipeline(req *cloneCdPipelineRequest, c
892956 if refCdPipeline == nil {
893957 return nil , fmt .Errorf ("no cd pipeline found" )
894958 }
959+ refCdPipeline .SourceToNewPipelineId = req .sourceToNewPipelineId
895960 pipelineName := refCdPipeline .Name
896961 if strings .HasPrefix (pipelineName , req .refAppName ) {
897962 pipelineName = strings .Replace (pipelineName , req .refAppName + "-" , "" , 1 )
@@ -922,35 +987,6 @@ func (impl *AppCloneServiceImpl) CreateCdPipeline(req *cloneCdPipelineRequest, c
922987 deploymentAppType = util .PIPELINE_DEPLOYMENT_TYPE_HELM
923988 }
924989
925- if refCdPipeline .ParentPipelineType == "WEBHOOK" {
926- cdPipeline := & bean.CDPipelineConfigObject {
927- Id : 0 ,
928- EnvironmentId : refCdPipeline .EnvironmentId ,
929- CiPipelineId : 0 ,
930- TriggerType : refCdPipeline .TriggerType ,
931- Name : pipelineName ,
932- Strategies : refCdPipeline .Strategies ,
933- Namespace : refCdPipeline .Namespace ,
934- AppWorkflowId : 0 ,
935- DeploymentTemplate : refCdPipeline .DeploymentTemplate ,
936- PreStage : refCdPipeline .PreStage , //FIXME
937- PostStage : refCdPipeline .PostStage ,
938- PreStageConfigMapSecretNames : refCdPipeline .PreStageConfigMapSecretNames ,
939- PostStageConfigMapSecretNames : refCdPipeline .PostStageConfigMapSecretNames ,
940- RunPostStageInEnv : refCdPipeline .RunPostStageInEnv ,
941- RunPreStageInEnv : refCdPipeline .RunPreStageInEnv ,
942- DeploymentAppType : refCdPipeline .DeploymentAppType ,
943- ParentPipelineId : 0 ,
944- ParentPipelineType : refCdPipeline .ParentPipelineType ,
945- }
946- cdPipelineReq := & bean.CdPipelines {
947- Pipelines : []* bean.CDPipelineConfigObject {cdPipeline },
948- AppId : req .appId ,
949- UserId : req .userId ,
950- }
951- cdPipelineRes , err := impl .pipelineBuilder .CreateCdPipelines (cdPipelineReq , ctx )
952- return cdPipelineRes , err
953- }
954990 cdPipeline := & bean.CDPipelineConfigObject {
955991 Id : 0 ,
956992 EnvironmentId : refCdPipeline .EnvironmentId ,
@@ -970,6 +1006,15 @@ func (impl *AppCloneServiceImpl) CreateCdPipeline(req *cloneCdPipelineRequest, c
9701006 DeploymentAppType : deploymentAppType ,
9711007 PreDeployStage : refCdPipeline .PreDeployStage ,
9721008 PostDeployStage : refCdPipeline .PostDeployStage ,
1009+ SourceToNewPipelineId : refCdPipeline .SourceToNewPipelineId ,
1010+ RefPipelineId : refCdPipeline .Id ,
1011+ ParentPipelineType : refCdPipeline .ParentPipelineType ,
1012+ }
1013+ if refCdPipeline .ParentPipelineType == "WEBHOOK" {
1014+ cdPipeline .CiPipelineId = 0
1015+ cdPipeline .ParentPipelineId = req .externalCiPipelineId
1016+ } else if refCdPipeline .ParentPipelineType != appWorkflow .CI_PIPELINE_TYPE {
1017+ cdPipeline .ParentPipelineId = refCdPipeline .ParentPipelineId
9731018 }
9741019 cdPipelineReq := & bean.CdPipelines {
9751020 Pipelines : []* bean.CDPipelineConfigObject {cdPipeline },
0 commit comments