Skip to content

Commit 9626bfc

Browse files
hubadrmichaelkubiaczykthtrisumeetpatil
authored
checkmarxOneExecuteScan - Fix report generation in CxOne 3.20 (#5170)
* Initial in progress * compiling but not yet functional * Missed file * updated checkmarxone step * Working up to fetching a project then breaks * Missed file * Breaks when retrieving projects+proxy set * Create project & run scan working, now polling * Fixed polling * added back the zipfile remove command * Fixed polling again * Generates and downloads PDF report * Updated and working, prep for refactor * Added compliance steps * Cleanup, reporting, added groovy connector * fixed groovy file * checkmarxone to checkmarxOne * checkmarxone to checkmarxOne * split credentials (id+secret, apikey), renamed pullrequestname to branch, groovy fix * Fixed filenames & yaml * missed the metadata_generated.go * added json to sarif conversion * fix:type in new checkmarxone package * fix:type in new checkmarxone package * removed test logs, added temp error log for creds * extra debugging to fix crash * improved auth logging, fixed query parse issue * fixed bug with group fetch when using oauth user * CWE can be -1 if not defined, can't be uint * Query also had CweID * Disabled predicates-fetch in sarif generation * Removing leftover info log message * Better error handling * fixed default preset configuration * removing .bat files - sorry * Cleanup per initial review * refactoring per Gist, fixed project find, add apps * small fix - sorry for commit noise while testing * Fixing issues with incremental scans. * removing maxretries * Updated per PR feedback, further changes todo toda * JSON Report changes and reporting cleanup * removing .bat (again?) * adding docs, groovy unit test, linter fixes * Started adding tests maybe 15% covered * fix(checkmarxOne): test cases for pkg and reporting * fix(checkmarxOne):fix formatting * feat(checkmarxone): update interface with missing method * feat(checkmarxone):change runStep signature to be able to inject dependency * feat(checkmarxone): add tests for step (wip) * Adding a bit more coverage * feat(checkmarxOne): fix code review * feat(checkmarxOne): fix code review * feat(checkmarxOne): fix code review * feat(checkmarxOne): fix integration test PR * adding scan-summary bug workaround, reportgen fail * enforceThresholds fix when no results passed in * fixed gap when preset empty in yaml & project conf * fixed another gap in preset selection * fix 0-result panic * fail when no preset is set anywhere * removed comment * initial project-under-app support * fixing sarif reportgen * some cleanup of error messages * post-merge test fixes * revert previous upstream merge * adding "incremental" to "full" triggers * wrong boolean * project-in-application api change prep * Fixing SARIF report without preset access * fix sarif deeplink * removing comments * fix(cxone):formatting * fix(cxone):formatting * small sarif fixes * fixed merge * attempt at pulling git source repo branch * fix(cxone):new endpoint for project creation * fix(cxOne): taxa is an array * fix(cxOne): get Git branch from commonPipelineEnvironment * fix(cxOne): add params to tag a scan and a project * fix(cxOne): unit test - update project * fix(cxOne): unit test - update project tags * fix(cxOne): improve logs * fix(cxOne): improve logs * adding RequestNewPDFReport function using v2 api * added version check * fix(cxone): JSON report using v2 API * update to set reportType in v2 reportgen --------- Co-authored-by: michael kubiaczyk <[email protected]> Co-authored-by: thtri <[email protected]> Co-authored-by: Thanh-Hai Trinh <[email protected]> Co-authored-by: michaelkubiaczyk <[email protected]> Co-authored-by: sumeet patil <[email protected]>
1 parent c1e800a commit 9626bfc

File tree

1 file changed

+91
-4
lines changed

1 file changed

+91
-4
lines changed

pkg/checkmarxone/checkmarxone.go

+91-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@ import (
88
"net/http"
99
"net/url"
1010
"os"
11-
12-
//"strconv"
11+
"strconv"
1312
"strings"
1413
"time"
1514

16-
//"encoding/xml"
1715
piperHttp "github.com/SAP/jenkins-library/pkg/http"
1816
"github.com/SAP/jenkins-library/pkg/log"
1917
"github.com/SAP/jenkins-library/pkg/piperutils"
@@ -1314,6 +1312,19 @@ func (sys *SystemInstance) GetResultsPredicates(SimilarityID int64, ProjectID st
13141312

13151313
// RequestNewReport triggers the generation of a report for a specific scan addressed by scanID
13161314
func (sys *SystemInstance) RequestNewReport(scanID, projectID, branch, reportType string) (string, error) {
1315+
if strings.EqualFold("pdf", reportType) || strings.EqualFold("json", reportType) {
1316+
version, err := sys.GetVersion()
1317+
if err == nil {
1318+
if version.CheckCxOne("3.20.0") >= 0 && version.CheckCxOne("3.21.0") == -1 {
1319+
sys.logger.Debugf("Current version is %v - between 3.20.0 and 3.21.0 - using v2 %v report", reportType, version.CxOne)
1320+
return sys.RequestNewReportV2(scanID, reportType)
1321+
}
1322+
sys.logger.Debugf("Current version is %v - using v1 %v report", reportType, version.CxOne)
1323+
} else {
1324+
sys.logger.Errorf("Failed to get the CxOne version during report-gen request, will use v1 %v report. Error: %s", reportType, err)
1325+
}
1326+
}
1327+
13171328
jsonData := map[string]interface{}{
13181329
"fileFormat": reportType,
13191330
"reportType": "ui",
@@ -1352,13 +1363,52 @@ func (sys *SystemInstance) RequestNewReport(scanID, projectID, branch, reportTyp
13521363
return reportResponse.ReportId, err
13531364
}
13541365

1366+
// Use the new V2 Report API to generate a PDF report
1367+
func (sys *SystemInstance) RequestNewReportV2(scanID, reportType string) (string, error) {
1368+
jsonData := map[string]interface{}{
1369+
"reportName": "improved-scan-report",
1370+
"entities": []map[string]interface{}{
1371+
{
1372+
"entity": "scan",
1373+
"ids": []string{scanID},
1374+
"tags": []string{},
1375+
},
1376+
},
1377+
"filters": map[string][]string{
1378+
"scanners": {"sast"},
1379+
},
1380+
"reportType": "ui",
1381+
"fileFormat": reportType,
1382+
}
1383+
1384+
jsonValue, _ := json.Marshal(jsonData)
1385+
1386+
header := http.Header{}
1387+
header.Set("cxOrigin", cxOrigin)
1388+
header.Set("Content-Type", "application/json")
1389+
data, err := sendRequest(sys, http.MethodPost, "/reports/v2", bytes.NewBuffer(jsonValue), header, []int{})
1390+
if err != nil {
1391+
return "", errors.Wrapf(err, "Failed to trigger report generation for scan %v", scanID)
1392+
} else {
1393+
sys.logger.Infof("Generating report %v", string(data))
1394+
}
1395+
1396+
var reportResponse struct {
1397+
ReportId string
1398+
}
1399+
err = json.Unmarshal(data, &reportResponse)
1400+
1401+
return reportResponse.ReportId, err
1402+
1403+
}
1404+
13551405
// GetReportStatus returns the status of the report generation process
13561406
func (sys *SystemInstance) GetReportStatus(reportID string) (ReportStatus, error) {
13571407
var response ReportStatus
13581408

13591409
header := http.Header{}
13601410
header.Set("Accept", "application/json")
1361-
data, err := sendRequest(sys, http.MethodGet, fmt.Sprintf("/reports/%v", reportID), nil, header, []int{})
1411+
data, err := sendRequest(sys, http.MethodGet, fmt.Sprintf("/reports/%v?returnUrl=true", reportID), nil, header, []int{})
13621412
if err != nil {
13631413
sys.logger.Errorf("Failed to fetch report status for reportID %v: %s", reportID, err)
13641414
return response, errors.Wrapf(err, "failed to fetch report status for reportID %v", reportID)
@@ -1412,3 +1462,40 @@ func (sys *SystemInstance) GetVersion() (VersionInfo, error) {
14121462
err = json.Unmarshal(data, &version)
14131463
return version, err
14141464
}
1465+
1466+
func (v VersionInfo) CheckCxOne(version string) int {
1467+
check := versionStringToInts(version)
1468+
cx1 := versionStringToInts(v.CxOne)
1469+
1470+
if check[0] < cx1[0] {
1471+
return 1
1472+
} else if check[0] > cx1[0] {
1473+
return -1
1474+
} else {
1475+
if check[1] < cx1[1] {
1476+
return 1
1477+
} else if check[1] > cx1[1] {
1478+
return -1
1479+
} else {
1480+
if check[2] < cx1[2] {
1481+
return 1
1482+
} else if check[2] > cx1[2] {
1483+
return -1
1484+
} else {
1485+
return 0
1486+
}
1487+
}
1488+
}
1489+
}
1490+
1491+
func versionStringToInts(version string) []int64 {
1492+
if version == "" {
1493+
return []int64{0, 0, 0}
1494+
}
1495+
str := strings.Split(version, ".")
1496+
ints := make([]int64, len(str))
1497+
for id, val := range str {
1498+
ints[id], _ = strconv.ParseInt(val, 10, 64)
1499+
}
1500+
return ints
1501+
}

0 commit comments

Comments
 (0)