mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
feat(protecodeExecuteScan): Add protecode report (#2981)
* Fix exclude and enhance docs * Fix test * Fix test * Add reporting to checkmarx step * Improve text * Add protecode report * Fix fmt * Add error handling
This commit is contained in:
parent
8a432078cf
commit
3e7595920f
@ -222,6 +222,16 @@ func executeProtecodeScan(influx *protecodeExecuteScanInflux, client protecode.P
|
||||
{Name: "Protecode Report", Target: path.Join("artifact", config.ReportFileName), Scope: "job"},
|
||||
}
|
||||
|
||||
// write custom report
|
||||
scanReport := protecode.CreateCustomReport(fileName, productID, parsedResult, vulns)
|
||||
paths, err := protecode.WriteCustomReports(scanReport, fileName, fmt.Sprint(productID))
|
||||
if err != nil {
|
||||
// do not fail - consider failing later on
|
||||
log.Entry().Warning("failed to create custom HTML/MarkDown file ...", err)
|
||||
} else {
|
||||
reports = append(reports, paths...)
|
||||
}
|
||||
|
||||
// create toolrecord file
|
||||
toolRecordFileName, err := createToolRecordProtecode("./", config, productID, webuiURL)
|
||||
if err != nil {
|
||||
|
@ -96,7 +96,7 @@ func WriteCustomReports(scanReport reporting.ScanReport, projectName, projectID
|
||||
return reportPaths, errors.Wrap(err, "failed to create reporting directory")
|
||||
}
|
||||
}
|
||||
if err := utils.FileWrite(filepath.Join(reporting.StepReportDirectory, fmt.Sprintf("checkmarxExecuteScan_sast_%v.json", reportShaFortify([]string{projectName, projectID}))), jsonReport, 0666); err != nil {
|
||||
if err := utils.FileWrite(filepath.Join(reporting.StepReportDirectory, fmt.Sprintf("checkmarxExecuteScan_sast_%v.json", reportShaCheckmarx([]string{projectName, projectID}))), jsonReport, 0666); err != nil {
|
||||
return reportPaths, errors.Wrapf(err, "failed to write json report")
|
||||
}
|
||||
// we do not add the json report to the overall list of reports for now,
|
||||
@ -106,7 +106,7 @@ func WriteCustomReports(scanReport reporting.ScanReport, projectName, projectID
|
||||
return reportPaths, nil
|
||||
}
|
||||
|
||||
func reportShaFortify(parts []string) string {
|
||||
func reportShaCheckmarx(parts []string) string {
|
||||
reportShaData := []byte(strings.Join(parts, ","))
|
||||
return fmt.Sprintf("%x", sha1.Sum(reportShaData))
|
||||
}
|
||||
|
@ -16,6 +16,9 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ReportsDirectory defines the subfolder for the Protecode reports which are generated
|
||||
const ReportsDirectory = "protecode"
|
||||
|
||||
// ProductData holds the product information of the protecode product
|
||||
type ProductData struct {
|
||||
Products []Product `json:"products,omitempty"`
|
||||
|
@ -1,12 +1,18 @@
|
||||
package protecode
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||
"github.com/SAP/jenkins-library/pkg/reporting"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//ReportData is representing the data of the step report JSON
|
||||
@ -50,3 +56,85 @@ func writeJSON(path, name string, data interface{}, writeToFile func(f string, d
|
||||
}
|
||||
return writeToFile(filepath.Join(path, name), jsonData, 0644)
|
||||
}
|
||||
|
||||
func CreateCustomReport(productName string, productID int, data map[string]int, vulns []Vuln) reporting.ScanReport {
|
||||
scanReport := reporting.ScanReport{
|
||||
Title: "Procode Vulnerability Report",
|
||||
Subheaders: []reporting.Subheader{
|
||||
{Description: "Product name", Details: productName},
|
||||
{Description: "Product ID", Details: fmt.Sprint(productID)},
|
||||
},
|
||||
Overview: []reporting.OverviewRow{
|
||||
{Description: "Vulnerabilities", Details: fmt.Sprint(data["vulnerabilities"])},
|
||||
{Description: "Major Vulnerabilities", Details: fmt.Sprint(data["major_vulnerabilities"])},
|
||||
{Description: "Minor Vulnerabilities", Details: fmt.Sprint(data["minor_vulnerabilities"])},
|
||||
{Description: "Triaged Vulnerabilities", Details: fmt.Sprint(data["triaged_vulnerabilities"])},
|
||||
{Description: "Excluded Vulnerabilities", Details: fmt.Sprint(data["excluded_vulnerabilities"])},
|
||||
},
|
||||
ReportTime: time.Now(),
|
||||
}
|
||||
|
||||
detailTable := reporting.ScanDetailTable{
|
||||
NoRowsMessage: "No findings detected",
|
||||
Headers: []string{
|
||||
"Issue CVE",
|
||||
"CVSS Score",
|
||||
"CVSS v3 Score",
|
||||
},
|
||||
WithCounter: true,
|
||||
CounterHeader: "Entry #",
|
||||
}
|
||||
|
||||
for _, vuln := range vulns {
|
||||
row := reporting.ScanRow{}
|
||||
row.AddColumn(fmt.Sprint(*&vuln.Cve), 0)
|
||||
row.AddColumn(fmt.Sprint(*&vuln.Cvss), 0)
|
||||
row.AddColumn(fmt.Sprint(*&vuln.Cvss3Score), 0)
|
||||
|
||||
detailTable.Rows = append(detailTable.Rows, row)
|
||||
}
|
||||
scanReport.DetailTable = detailTable
|
||||
|
||||
return scanReport
|
||||
}
|
||||
|
||||
func WriteCustomReports(scanReport reporting.ScanReport, projectName, projectID string) ([]piperutils.Path, error) {
|
||||
utils := piperutils.Files{}
|
||||
reportPaths := []piperutils.Path{}
|
||||
|
||||
// ignore templating errors since template is in our hands and issues will be detected with the automated tests
|
||||
htmlReport, _ := scanReport.ToHTML()
|
||||
htmlReportPath := filepath.Join(ReportsDirectory, "piper_protecode_report.html")
|
||||
// Ensure reporting directory exists
|
||||
if err := utils.MkdirAll(ReportsDirectory, 0777); err != nil {
|
||||
return reportPaths, errors.Wrapf(err, "failed to create report directory")
|
||||
}
|
||||
if err := utils.FileWrite(htmlReportPath, htmlReport, 0666); err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return reportPaths, errors.Wrapf(err, "failed to write html report")
|
||||
}
|
||||
reportPaths = append(reportPaths, piperutils.Path{Name: "Protecode Vulnerability Report", Target: htmlReportPath})
|
||||
|
||||
// JSON reports are used by step pipelineCreateSummary in order to e.g. prepare an issue creation in GitHub
|
||||
// ignore JSON errors since structure is in our hands
|
||||
jsonReport, _ := scanReport.ToJSON()
|
||||
if exists, _ := utils.DirExists(reporting.StepReportDirectory); !exists {
|
||||
err := utils.MkdirAll(reporting.StepReportDirectory, 0777)
|
||||
if err != nil {
|
||||
return reportPaths, errors.Wrap(err, "failed to create reporting directory")
|
||||
}
|
||||
}
|
||||
if err := utils.FileWrite(filepath.Join(reporting.StepReportDirectory, fmt.Sprintf("protecodeExecuteScan_osvm_%v.json", reportShaProtecode([]string{projectName, projectID}))), jsonReport, 0666); err != nil {
|
||||
return reportPaths, errors.Wrapf(err, "failed to write json report")
|
||||
}
|
||||
// we do not add the json report to the overall list of reports for now,
|
||||
// since it is just an intermediary report used as input for later
|
||||
// and there does not seem to be real benefit in archiving it.
|
||||
|
||||
return reportPaths, nil
|
||||
}
|
||||
|
||||
func reportShaProtecode(parts []string) string {
|
||||
reportShaData := []byte(strings.Join(parts, ","))
|
||||
return fmt.Sprintf("%x", sha1.Sum(reportShaData))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user