diff --git a/core/cautils/scaninfo.go b/core/cautils/scaninfo.go index 2c5631e2..dc398da9 100644 --- a/core/cautils/scaninfo.go +++ b/core/cautils/scaninfo.go @@ -140,7 +140,6 @@ type Getters struct { func (scanInfo *ScanInfo) Init() { scanInfo.setUseFrom() - scanInfo.setOutputFile() scanInfo.setUseArtifactsFrom() if scanInfo.ScanID == "" { scanInfo.ScanID = uuid.NewString() @@ -188,25 +187,39 @@ func (scanInfo *ScanInfo) setUseFrom() { } } -func (scanInfo *ScanInfo) setOutputFile() { - if scanInfo.Output == "" { - return - } - if scanInfo.Format == "json" { - if filepath.Ext(scanInfo.Output) != ".json" { - scanInfo.Output += ".json" +func (scanInfo *ScanInfo) GetFormats() []string { + return strings.Split(scanInfo.Format, ",") +} + +func (scanInfo *ScanInfo) GetOutputFiles() []string { + formats := scanInfo.GetFormats() + outputs := make([]string, 0) + + for _, format := range formats { + if scanInfo.Output == "" { + outputs = append(outputs, "") } - } - if scanInfo.Format == "junit" { - if filepath.Ext(scanInfo.Output) != ".xml" { - scanInfo.Output += ".xml" + + output := scanInfo.Output + + if format == "json" { + if filepath.Ext(output) != ".json" { + output += ".json" + } } - } - if scanInfo.Format == "pdf" { - if filepath.Ext(scanInfo.Output) != ".pdf" { - scanInfo.Output += ".pdf" + if format == "junit" { + if filepath.Ext(output) != ".xml" { + output += ".xml" + } } + if format == "pdf" { + if filepath.Ext(output) != ".pdf" { + output += ".pdf" + } + } + outputs = append(outputs, output) } + return outputs } func (scanInfo *ScanInfo) SetPolicyIdentifiers(policies []string, kind apisv1.NotificationPolicyKind) { diff --git a/core/core/scan.go b/core/core/scan.go index f17405c0..7b91cd79 100644 --- a/core/core/scan.go +++ b/core/core/scan.go @@ -27,7 +27,7 @@ type componentInterfaces struct { tenantConfig cautils.ITenantConfig resourceHandler resourcehandler.IResourceHandler report reporter.IReport - printerHandler printer.IPrinter + printerHandlers []printer.IPrinter hostSensorHandler hostsensorutils.IHostSensor } @@ -93,9 +93,16 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces { // reporting behavior - setup reporter reportHandler := getReporter(tenantConfig, scanInfo.ScanID, scanInfo.Submit, scanInfo.FrameworkScan, scanInfo.GetScanningContext()) - // setup printer - printerHandler := resultshandling.NewPrinter(scanInfo.Format, scanInfo.FormatVersion, scanInfo.VerboseMode, cautils.ViewTypes(scanInfo.View)) - printerHandler.SetWriter(scanInfo.Output) + // setup printers + formats := scanInfo.GetFormats() + outputs := scanInfo.GetOutputFiles() + + printerHandlers := make([]printer.IPrinter, 0) + for formatIdx, format := range formats { + printerHandler := resultshandling.NewPrinter(format, scanInfo.FormatVersion, scanInfo.VerboseMode, cautils.ViewTypes(scanInfo.View)) + printerHandler.SetWriter(outputs[formatIdx]) + printerHandlers = append(printerHandlers, printerHandler) + } // ================== return interface ====================================== @@ -103,7 +110,7 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces { tenantConfig: tenantConfig, resourceHandler: resourceHandler, report: reportHandler, - printerHandler: printerHandler, + printerHandlers: printerHandlers, hostSensorHandler: hostSensorHandler, } } @@ -141,7 +148,7 @@ func (ks *Kubescape) Scan(scanInfo *cautils.ScanInfo) (*resultshandling.ResultsH } }() - resultsHandling := resultshandling.NewResultsHandler(interfaces.report, interfaces.printerHandler) + resultsHandling := resultshandling.NewResultsHandler(interfaces.report, interfaces.printerHandlers) // ===================== policies & resources ===================== policyHandler := policyhandler.NewPolicyHandler(interfaces.resourceHandler) diff --git a/core/pkg/resultshandling/results.go b/core/pkg/resultshandling/results.go index 94e3b913..b222a2f7 100644 --- a/core/pkg/resultshandling/results.go +++ b/core/pkg/resultshandling/results.go @@ -16,14 +16,14 @@ import ( type ResultsHandler struct { reporterObj reporter.IReport - printerObj printer.IPrinter + printerObjs []printer.IPrinter scanData *cautils.OPASessionObj } -func NewResultsHandler(reporterObj reporter.IReport, printerObj printer.IPrinter) *ResultsHandler { +func NewResultsHandler(reporterObj reporter.IReport, printerObjs []printer.IPrinter) *ResultsHandler { return &ResultsHandler{ reporterObj: reporterObj, - printerObj: printerObj, + printerObjs: printerObjs, } } @@ -43,8 +43,8 @@ func (resultsHandler *ResultsHandler) SetData(data *cautils.OPASessionObj) { } // GetPrinter get printer object -func (resultsHandler *ResultsHandler) GetPrinter() printer.IPrinter { - return resultsHandler.printerObj +func (resultsHandler *ResultsHandler) GetPrinters() []printer.IPrinter { + return resultsHandler.printerObjs } // GetReporter get reporter object @@ -65,13 +65,19 @@ func (resultsHandler *ResultsHandler) GetResults() *reporthandlingv2.PostureRepo // HandleResults handle the scan results according to the pre defined interfaces func (resultsHandler *ResultsHandler) HandleResults() error { - resultsHandler.printerObj.ActionPrint(resultsHandler.scanData) + printerObjs := resultsHandler.printerObjs + + for _, printerObj := range printerObjs { + printerObj.ActionPrint(resultsHandler.scanData) + } if err := resultsHandler.reporterObj.Submit(resultsHandler.scanData); err != nil { return err } - resultsHandler.printerObj.Score(resultsHandler.GetRiskScore()) + for _, printerObj := range printerObjs { + printerObj.Score(resultsHandler.GetRiskScore()) + } resultsHandler.reporterObj.DisplayReportURL()