@@ -33,6 +33,7 @@ import (
33
33
"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig/adapter/cdWorkflow"
34
34
"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig/bean/workflow"
35
35
cdWorkflow2 "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig/bean/workflow/cdWorkflow"
36
+ "github.com/devtron-labs/devtron/internal/sql/repository/security"
36
37
"github.com/devtron-labs/devtron/pkg/app/status"
37
38
"github.com/devtron-labs/devtron/pkg/build/artifacts"
38
39
bean5 "github.com/devtron-labs/devtron/pkg/build/pipeline/bean"
@@ -44,6 +45,7 @@ import (
44
45
"github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/userDeploymentRequest/service"
45
46
eventProcessorBean "github.com/devtron-labs/devtron/pkg/eventProcessor/bean"
46
47
"github.com/devtron-labs/devtron/pkg/pipeline"
48
+ constants2 "github.com/devtron-labs/devtron/pkg/pipeline/constants"
47
49
"github.com/devtron-labs/devtron/pkg/pipeline/executors"
48
50
repository2 "github.com/devtron-labs/devtron/pkg/plugin/repository"
49
51
"github.com/devtron-labs/devtron/pkg/sql"
@@ -125,6 +127,7 @@ type WorkflowDagExecutorImpl struct {
125
127
commonArtifactService artifacts.CommonArtifactService
126
128
deploymentConfigService common2.DeploymentConfigService
127
129
asyncRunnable * async.Runnable
130
+ scanHistoryRepository security.ImageScanHistoryRepository
128
131
}
129
132
130
133
func NewWorkflowDagExecutorImpl (Logger * zap.SugaredLogger , pipelineRepository pipelineConfig.PipelineRepository ,
@@ -148,7 +151,8 @@ func NewWorkflowDagExecutorImpl(Logger *zap.SugaredLogger, pipelineRepository pi
148
151
manifestCreationService manifest.ManifestCreationService ,
149
152
commonArtifactService artifacts.CommonArtifactService ,
150
153
deploymentConfigService common2.DeploymentConfigService ,
151
- asyncRunnable * async.Runnable ) * WorkflowDagExecutorImpl {
154
+ asyncRunnable * async.Runnable ,
155
+ scanHistoryRepository security.ImageScanHistoryRepository ) * WorkflowDagExecutorImpl {
152
156
wde := & WorkflowDagExecutorImpl {logger : Logger ,
153
157
pipelineRepository : pipelineRepository ,
154
158
cdWorkflowRepository : cdWorkflowRepository ,
@@ -172,6 +176,7 @@ func NewWorkflowDagExecutorImpl(Logger *zap.SugaredLogger, pipelineRepository pi
172
176
commonArtifactService : commonArtifactService ,
173
177
deploymentConfigService : deploymentConfigService ,
174
178
asyncRunnable : asyncRunnable ,
179
+ scanHistoryRepository : scanHistoryRepository ,
175
180
}
176
181
config , err := types .GetCdConfig ()
177
182
if err != nil {
@@ -559,6 +564,20 @@ func (impl *WorkflowDagExecutorImpl) HandlePreStageSuccessEvent(triggerContext t
559
564
if err != nil {
560
565
return err
561
566
}
567
+ scanEnabled , scanned := ciArtifact .ScanEnabled , ciArtifact .Scanned
568
+ err = impl .handleScanningEventForArtifact (ciArtifact , cdStageCompleteEvent .CdPipelineId , repository4 .PIPELINE_STAGE_TYPE_PRE_CD )
569
+ if err != nil {
570
+ impl .logger .Errorw ("error in handling scanning event for ci artifact" , "ciArtifact" , ciArtifact , "err" , err )
571
+ return err
572
+ }
573
+ // if ciArtifact scanEnabled and scanned state changed from above func then update ciArtifact
574
+ if scanEnabled != ciArtifact .ScanEnabled || scanned != ciArtifact .Scanned {
575
+ ciArtifact , err = impl .ciArtifactRepository .Update (ciArtifact )
576
+ if err != nil {
577
+ impl .logger .Errorw ("error in updating ci artifact after handling scan event for this artifact" , "ciArtifact" , ciArtifact , "err" , err )
578
+ return err
579
+ }
580
+ }
562
581
// Migration of deprecated DataSource Type
563
582
if ciArtifact .IsMigrationRequired () {
564
583
migrationErr := impl .ciArtifactRepository .MigrateToWebHookDataSourceType (ciArtifact .Id )
@@ -652,6 +671,20 @@ func (impl *WorkflowDagExecutorImpl) HandlePostStageSuccessEvent(triggerContext
652
671
impl .logger .Errorw ("error in finding artifact by cd workflow id" , "err" , err , "cdWorkflowId" , cdWorkflowId )
653
672
return err
654
673
}
674
+ scanEnabled , scanned := ciArtifact .ScanEnabled , ciArtifact .Scanned
675
+ err = impl .handleScanningEventForArtifact (ciArtifact , cdPipelineId , repository4 .PIPELINE_STAGE_TYPE_POST_CD )
676
+ if err != nil {
677
+ impl .logger .Errorw ("error in handling scanning event for ci artifact" , "ciArtifact" , ciArtifact , "err" , err )
678
+ return err
679
+ }
680
+ // if ciArtifact scanEnabled and scanned state changed from above func then update ciArtifact
681
+ if scanEnabled != ciArtifact .ScanEnabled || scanned != ciArtifact .Scanned {
682
+ ciArtifact , err = impl .ciArtifactRepository .Update (ciArtifact )
683
+ if err != nil {
684
+ impl .logger .Errorw ("error in updating ci artifact after handling scan event for this artifact" , "ciArtifact" , ciArtifact , "err" , err )
685
+ return err
686
+ }
687
+ }
655
688
if len (pluginRegistryImageDetails ) > 0 {
656
689
PostCDArtifacts , err := impl .commonArtifactService .SavePluginArtifacts (ciArtifact , pluginRegistryImageDetails , cdPipelineId , repository .POST_CD , triggeredBy )
657
690
if err != nil {
@@ -711,22 +744,49 @@ func (impl *WorkflowDagExecutorImpl) UpdateCiWorkflowForCiSuccess(request *bean2
711
744
return nil
712
745
}
713
746
714
- func (impl * WorkflowDagExecutorImpl ) isImageScanningPluginConfiguredInCiPipeline (ciPipelineId int ) (bool , error ) {
715
- var isScanPluginConfigured bool
716
- var err error
717
- plugin , err := impl .globalPluginRepository .GetPluginByName (bean3 .VULNERABILITY_SCANNING_PLUGIN )
718
- if err != nil || len (plugin ) == 0 {
719
- impl .logger .Errorw ("error in getting image scanning plugin" , "err" , err )
720
- return isScanPluginConfigured , err
747
+ func (impl * WorkflowDagExecutorImpl ) isScanPluginConfiguredAtPipelineStage (pipelineId int , pipelineStage repository4.PipelineStageType ) (bool , error ) {
748
+ plugin , err := impl .globalPluginRepository .GetPluginByName (bean2 .ImageScanningPluginToCheckInPipelineStageStep )
749
+ if err != nil {
750
+ impl .logger .Errorw ("error in getting image scanning plugin, Vulnerability Scanning" , "pipelineId" , pipelineId , "pipelineStage" , pipelineStage , "err" , err )
751
+ return false , err
721
752
}
722
- isScanPluginConfigured , err = impl .pipelineStageRepository .CheckPluginExistsInCiPipeline (ciPipelineId , string (repository4 .PIPELINE_STAGE_TYPE_POST_CI ), plugin [0 ].Id )
753
+ if len (plugin ) == 0 {
754
+ return false , nil
755
+ }
756
+ isScanPluginConfigured , err := impl .pipelineStageRepository .CheckIfPluginExistsInPipelineStage (pipelineId , pipelineStage , plugin [0 ].Id )
723
757
if err != nil {
724
- impl .logger .Errorw ("error in getting ci pipelineModal plugin" , "err" , err , "ciPipelineId " , ciPipelineId , "pluginId" , plugin [0 ].Id )
725
- return isScanPluginConfigured , err
758
+ impl .logger .Errorw ("error in getting ci pipeline plugin" , "err" , err , "pipelineId " , pipelineId , "pluginId" , plugin [0 ].Id )
759
+ return false , err
726
760
}
727
761
return isScanPluginConfigured , nil
728
762
}
729
763
764
+ func (impl * WorkflowDagExecutorImpl ) handleScanningEventForArtifact (ciArtifact * repository.CiArtifact , pipelineId int ,
765
+ pipelineStage repository4.PipelineStageType ) error {
766
+
767
+ isScanPluginConfigured , err := impl .isScanPluginConfiguredAtPipelineStage (pipelineId , pipelineStage )
768
+ if err != nil {
769
+ impl .logger .Errorw ("error in fetching if a scan plugin is configured or not in a pipeline" , "pipelineStage" , pipelineStage , "ciArtifact" , ciArtifact )
770
+ return err
771
+ }
772
+ if isScanPluginConfigured {
773
+ ciArtifact .ScanEnabled = true
774
+ // if scan history is present for this artifact, then this image has been scanned
775
+ // else there was some issue with the scanning plugin completing its job.
776
+ _ , err := impl .scanHistoryRepository .FindByImageAndDigest (ciArtifact .ImageDigest , ciArtifact .Image )
777
+ if err != nil && ! util .IsErrNoRows (err ) {
778
+ impl .logger .Errorw ("error while fetching latest image scan execution history for image and image digest" , "image" , ciArtifact .Image , "imageDigest" , ciArtifact .ImageDigest , "err" , err )
779
+ return err
780
+ } else if util .IsErrNoRows (err ) {
781
+ //scan history not found for image and digest hence marking scanned as false
782
+ ciArtifact .Scanned = false
783
+ } else {
784
+ ciArtifact .Scanned = true
785
+ }
786
+ }
787
+ return nil
788
+ }
789
+
730
790
func (impl * WorkflowDagExecutorImpl ) HandleCiSuccessEvent (triggerContext triggerBean.TriggerContext , ciPipelineId int , request * bean2.CiArtifactWebhookRequest , imagePushedAt time.Time ) (id int , err error ) {
731
791
impl .logger .Infow ("webhook for artifact save" , "req" , request )
732
792
pipelineModal , err := impl .ciPipelineRepository .FindByCiAndAppDetailsById (ciPipelineId )
@@ -749,13 +809,16 @@ func (impl *WorkflowDagExecutorImpl) HandleCiSuccessEvent(triggerContext trigger
749
809
}
750
810
buildArtifact := helper .GetBuildArtifact (request , pipelineModal .Id , materialJson , createdOn , updatedOn )
751
811
752
- isScanPluginConfigured , err := impl .isImageScanningPluginConfiguredInCiPipeline (pipelineModal .Id )
812
+ pipelineStage := repository4 .PIPELINE_STAGE_TYPE_POST_CI
813
+ if pipelineModal .PipelineType == constants2 .CI_JOB .ToString () {
814
+ pipelineStage = repository4 .PIPELINE_STAGE_TYPE_PRE_CI
815
+ }
816
+ err = impl .handleScanningEventForArtifact (buildArtifact , pipelineModal .Id , pipelineStage )
753
817
if err != nil {
754
- impl .logger .Errorw ("error in checking isImageScanningPluginConfiguredInCiPipeline " , "ciPipelineId " , ciPipelineId , "err" , err )
818
+ impl .logger .Errorw ("error in handling scanning event for this ci artifact " , "ciArtifact " , buildArtifact , "err" , err )
755
819
return 0 , err
756
820
}
757
-
758
- if request .IsScanEnabled || isScanPluginConfigured {
821
+ if request .IsScanEnabled {
759
822
buildArtifact .Scanned = true
760
823
buildArtifact .ScanEnabled = true
761
824
}
0 commit comments