mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
Fix issue with not generating sarif file when projectName was specified (#4199)
* Fixed bug in generating sarif file in whitesource step --------- Co-authored-by: sumeet patil <sumeet.patil@sap.com>
This commit is contained in:
parent
501f7d214d
commit
27a3e687a5
@ -587,100 +587,177 @@ func checkPolicyViolations(ctx context.Context, config *ScanOptions, scan *ws.Sc
|
||||
}
|
||||
|
||||
func checkSecurityViolations(ctx context.Context, config *ScanOptions, scan *ws.Scan, sys whitesource, utils whitesourceUtils, influx *whitesourceExecuteScanInflux) ([]piperutils.Path, error) {
|
||||
var reportPaths []piperutils.Path
|
||||
// Check for security vulnerabilities and fail the build if cvssSeverityLimit threshold is crossed
|
||||
// convert config.CvssSeverityLimit to float64
|
||||
cvssSeverityLimit, err := strconv.ParseFloat(config.CvssSeverityLimit, 64)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return reportPaths, fmt.Errorf("failed to parse parameter cvssSeverityLimit (%s) "+
|
||||
return []piperutils.Path{}, fmt.Errorf("failed to parse parameter cvssSeverityLimit (%s) "+
|
||||
"as floating point number: %w", config.CvssSeverityLimit, err)
|
||||
}
|
||||
|
||||
// inhale assessments from file system
|
||||
assessments := readAssessmentsFromFile(config.AssessmentFile, utils)
|
||||
|
||||
vulnerabilitiesCount := 0
|
||||
var allOccurredErrors []string
|
||||
allAlerts := []ws.Alert{}
|
||||
allAssessedAlerts := []ws.Alert{}
|
||||
allLibraries := []ws.Library{}
|
||||
|
||||
if config.ProjectToken != "" {
|
||||
project := ws.Project{Name: config.ProjectName, Token: config.ProjectToken}
|
||||
// ToDo: see if HTML report generation is really required here
|
||||
// we anyway need to do some refactoring here since config.ProjectToken != "" essentially indicates an aggregated project
|
||||
if _, _, _, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx); err != nil {
|
||||
return reportPaths, err
|
||||
}
|
||||
|
||||
vulnerabilitiesCount, allAlerts, allAssessedAlerts, allLibraries, allOccurredErrors = collectVulnsAndLibsForProject(
|
||||
config,
|
||||
cvssSeverityLimit,
|
||||
project,
|
||||
sys,
|
||||
assessments,
|
||||
influx,
|
||||
)
|
||||
|
||||
log.Entry().Debugf("Collected %v libraries for project %v", len(allLibraries), project.Name)
|
||||
|
||||
} else {
|
||||
vulnerabilitiesCount := 0
|
||||
var errorsOccured []string
|
||||
allAlerts := []ws.Alert{}
|
||||
allAssessedAlerts := []ws.Alert{}
|
||||
allLibraries := []ws.Library{}
|
||||
for _, project := range scan.ScannedProjects() {
|
||||
// collect errors and aggregate vulnerabilities from all projects
|
||||
vulCount, alerts, assessedAlerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
vulCount, alerts, assessedAlerts, libraries, occurredErrors := collectVulnsAndLibsForProject(
|
||||
config,
|
||||
cvssSeverityLimit,
|
||||
project,
|
||||
sys,
|
||||
assessments,
|
||||
influx,
|
||||
)
|
||||
if len(occurredErrors) != 0 {
|
||||
allOccurredErrors = append(allOccurredErrors, occurredErrors...)
|
||||
}
|
||||
|
||||
allAlerts = append(allAlerts, alerts...)
|
||||
allAssessedAlerts = append(allAssessedAlerts, assessedAlerts...)
|
||||
vulnerabilitiesCount += vulCount
|
||||
|
||||
// collect all libraries detected in all related projects and errors
|
||||
libraries, err := sys.GetProjectHierarchy(project.Token, true)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
log.Entry().Debugf("Collected %v libraries for project %v", len(libraries), project.Name)
|
||||
allLibraries = append(allLibraries, libraries...)
|
||||
}
|
||||
log.Entry().Debugf("Aggregated %v alerts for scanned projects", len(allAlerts))
|
||||
}
|
||||
|
||||
if config.CreateResultIssue && vulnerabilitiesCount > 0 && len(config.GithubToken) > 0 && len(config.GithubAPIURL) > 0 && len(config.Owner) > 0 && len(config.Repository) > 0 {
|
||||
log.Entry().Debugf("Creating result issues for %v alert(s)", vulnerabilitiesCount)
|
||||
issueDetails := make([]reporting.IssueDetail, len(allAlerts))
|
||||
piperutils.CopyAtoB(allAlerts, issueDetails)
|
||||
gh := reporting.GitHub{
|
||||
Owner: &config.Owner,
|
||||
Repository: &config.Repository,
|
||||
Assignees: &config.Assignees,
|
||||
IssueService: utils.GetIssueService(),
|
||||
SearchService: utils.GetSearchService(),
|
||||
}
|
||||
if err := gh.UploadMultipleReports(ctx, &issueDetails); err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
reportPaths, errors := reportGitHubIssuesAndCreateReports(
|
||||
ctx,
|
||||
config,
|
||||
utils,
|
||||
scan,
|
||||
allAlerts,
|
||||
allLibraries,
|
||||
allAssessedAlerts,
|
||||
cvssSeverityLimit,
|
||||
vulnerabilitiesCount,
|
||||
)
|
||||
|
||||
allOccurredErrors = append(allOccurredErrors, errors...)
|
||||
|
||||
if len(allOccurredErrors) > 0 {
|
||||
if vulnerabilitiesCount > 0 {
|
||||
log.SetErrorCategory(log.ErrorCompliance)
|
||||
}
|
||||
return reportPaths, fmt.Errorf(strings.Join(allOccurredErrors, ": "))
|
||||
}
|
||||
|
||||
return reportPaths, nil
|
||||
}
|
||||
|
||||
func collectVulnsAndLibsForProject(
|
||||
config *ScanOptions,
|
||||
cvssSeverityLimit float64,
|
||||
project ws.Project,
|
||||
sys whitesource,
|
||||
assessments *[]format.Assessment,
|
||||
influx *whitesourceExecuteScanInflux,
|
||||
) (
|
||||
int,
|
||||
[]ws.Alert,
|
||||
[]ws.Alert,
|
||||
[]ws.Library,
|
||||
[]string,
|
||||
) {
|
||||
var errorsOccurred []string
|
||||
vulCount, alerts, assessedAlerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx)
|
||||
if err != nil {
|
||||
errorsOccurred = append(errorsOccurred, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
// collect all libraries detected in all related projects and errors
|
||||
libraries, err := sys.GetProjectHierarchy(project.Token, true)
|
||||
if err != nil {
|
||||
errorsOccurred = append(errorsOccurred, fmt.Sprint(err))
|
||||
}
|
||||
log.Entry().Debugf("Collected %v libraries for project %v", len(libraries), project.Name)
|
||||
|
||||
return vulCount, alerts, assessedAlerts, libraries, errorsOccurred
|
||||
}
|
||||
|
||||
func reportGitHubIssuesAndCreateReports(
|
||||
ctx context.Context,
|
||||
config *ScanOptions,
|
||||
utils whitesourceUtils,
|
||||
scan *ws.Scan,
|
||||
allAlerts []ws.Alert,
|
||||
allLibraries []ws.Library,
|
||||
allAssessedAlerts []ws.Alert,
|
||||
cvssSeverityLimit float64,
|
||||
vulnerabilitiesCount int,
|
||||
) ([]piperutils.Path, []string) {
|
||||
errorsOccured := make([]string, 0)
|
||||
reportPaths := make([]piperutils.Path, 0)
|
||||
|
||||
if config.CreateResultIssue && vulnerabilitiesCount > 0 && len(config.GithubToken) > 0 && len(config.GithubAPIURL) > 0 && len(config.Owner) > 0 && len(config.Repository) > 0 {
|
||||
log.Entry().Debugf("Creating result issues for %v alert(s)", vulnerabilitiesCount)
|
||||
issueDetails := make([]reporting.IssueDetail, len(allAlerts))
|
||||
piperutils.CopyAtoB(allAlerts, issueDetails)
|
||||
gh := reporting.GitHub{
|
||||
Owner: &config.Owner,
|
||||
Repository: &config.Repository,
|
||||
Assignees: &config.Assignees,
|
||||
IssueService: utils.GetIssueService(),
|
||||
SearchService: utils.GetSearchService(),
|
||||
}
|
||||
|
||||
scanReport := ws.CreateCustomVulnerabilityReport(config.ProductName, scan, &allAlerts, cvssSeverityLimit)
|
||||
paths, err := ws.WriteCustomVulnerabilityReports(config.ProductName, scan, scanReport, utils)
|
||||
if err != nil {
|
||||
if err := gh.UploadMultipleReports(ctx, &issueDetails); err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
reportPaths = append(reportPaths, paths...)
|
||||
|
||||
sarif := ws.CreateSarifResultFile(scan, &allAlerts)
|
||||
paths, err = ws.WriteSarifFile(sarif, utils)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
reportPaths = append(reportPaths, paths...)
|
||||
|
||||
sbom, err := ws.CreateCycloneSBOM(scan, &allLibraries, &allAlerts, &allAssessedAlerts)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
paths, err = ws.WriteCycloneSBOM(sbom, utils)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
reportPaths = append(reportPaths, paths...)
|
||||
|
||||
if len(errorsOccured) > 0 {
|
||||
if vulnerabilitiesCount > 0 {
|
||||
log.SetErrorCategory(log.ErrorCompliance)
|
||||
}
|
||||
return reportPaths, fmt.Errorf(strings.Join(errorsOccured, ": "))
|
||||
}
|
||||
}
|
||||
return reportPaths, nil
|
||||
|
||||
scanReport := ws.CreateCustomVulnerabilityReport(config.ProductName, scan, &allAlerts, cvssSeverityLimit)
|
||||
paths, err := ws.WriteCustomVulnerabilityReports(config.ProductName, scan, scanReport, utils)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
reportPaths = append(reportPaths, paths...)
|
||||
|
||||
sarif := ws.CreateSarifResultFile(scan, &allAlerts)
|
||||
paths, err = ws.WriteSarifFile(sarif, utils)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
reportPaths = append(reportPaths, paths...)
|
||||
|
||||
sbom, err := ws.CreateCycloneSBOM(scan, &allLibraries, &allAlerts, &allAssessedAlerts)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
paths, err = ws.WriteCycloneSBOM(sbom, utils)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
|
||||
reportPaths = append(reportPaths, paths...)
|
||||
|
||||
return reportPaths, errorsOccured
|
||||
}
|
||||
|
||||
// read assessments from file and expose them to match alerts and filter them before processing
|
||||
|
@ -595,7 +595,7 @@ func TestCheckSecurityViolations(t *testing.T) {
|
||||
|
||||
reportPaths, err := checkSecurityViolations(ctx, &config, scan, systemMock, utilsMock, &influx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(reportPaths))
|
||||
assert.Equal(t, 3, len(reportPaths))
|
||||
})
|
||||
|
||||
t.Run("error - wrong limit", func(t *testing.T) {
|
||||
@ -651,7 +651,7 @@ func TestCheckSecurityViolations(t *testing.T) {
|
||||
|
||||
reportPaths, err := checkSecurityViolations(ctx, &config, scan, systemMock, utilsMock, &influx)
|
||||
assert.Contains(t, fmt.Sprint(err), "1 Open Source Software Security vulnerabilities")
|
||||
assert.Equal(t, 0, len(reportPaths))
|
||||
assert.Equal(t, 3, len(reportPaths))
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user