Skip to content

Commit 5fd313c

Browse files
cx-sumit-morchhaleSumit Morchhale
andauthored
Json report from cx cli is same as in cx UI (AST-94779) (#1142)
* clone of pdf report # Conflicts: # internal/params/flags.go * Added code changes for testing json report * added test for json report * Added unit and integration test * Added json Report changes for scan create * intermittent issue * clone of pdf report * Added code changes for testing json report * added test for json report * Added unit and integration test * Added json Report changes for scan create * intermittent issue * Chnage jsonReport to jsonCxOne * Fix lint issues * fix lint issue * Lint issue * Lint issue * Lint * Lint issue * Lint Issue * fix duplicate * Trying to fix lint error * Lint issue * Resolve conflict * clone of pdf report # Conflicts: # internal/params/flags.go # Conflicts: # cmd/main.go # internal/commands/result.go # internal/commands/root.go # internal/commands/scan.go # internal/params/binds.go # internal/params/envs.go # internal/params/keys.go * Added code changes for testing json report * added test for json report * Added unit and integration test * Added json Report changes for scan create * intermittent issue * clone of pdf report * Added code changes for testing json report * added test for json report * Added unit and integration test * Added json Report changes for scan create * intermittent issue * Chnage jsonReport to jsonCxOne * Fix lint issues * fix lint issue * Lint issue * Lint issue * Lint * Lint issue * Lint Issue * fix duplicate * Trying to fix lint error * Lint issue * Remove code for optional flag * resolve lint issue --------- Co-authored-by: Sumit Morchhale <[email protected]>
1 parent 2910e3d commit 5fd313c

File tree

16 files changed

+384
-8
lines changed

16 files changed

+384
-8
lines changed

cmd/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func main() {
5050
descriptionsPath := viper.GetString(params.DescriptionsPathKey)
5151
tenantConfigurationPath := viper.GetString(params.TenantConfigurationPathKey)
5252
resultsPdfPath := viper.GetString(params.ResultsPdfReportPathKey)
53+
resultsJSONPath := viper.GetString(params.ResultsJSONReportPathKey)
5354
exportPath := viper.GetString(params.ExportPathKey)
5455
featureFlagsPath := viper.GetString(params.FeatureFlagsKey)
5556
policyEvaluationPath := viper.GetString(params.PolicyEvaluationPathKey)
@@ -61,6 +62,7 @@ func main() {
6162
customStatesWrapper := wrappers.NewCustomStatesHTTPWrapper()
6263
scansWrapper := wrappers.NewHTTPScansWrapper(scans)
6364
resultsPdfReportsWrapper := wrappers.NewResultsPdfReportsHTTPWrapper(resultsPdfPath)
65+
resultsJSONReportsWrapper := wrappers.NewResultsJSONReportsHTTPWrapper(resultsJSONPath)
6466
exportWrapper := wrappers.NewExportHTTPWrapper(exportPath)
6567
groupsWrapper := wrappers.NewHTTPGroupsWrapper(groups)
6668
logsWrapper := wrappers.NewLogsWrapper(logs)
@@ -99,6 +101,7 @@ func main() {
99101
scansWrapper,
100102
exportWrapper,
101103
resultsPdfReportsWrapper,
104+
resultsJSONReportsWrapper,
102105
resultsPredicatesWrapper,
103106
customStatesWrapper,
104107
codeBashingWrapper,

internal/commands/result.go

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ const (
112112
ScaDevAndTestExclusionParam = "DEV_AND_TEST"
113113
ScaExcludeResultTypesParam = "exclude-result-types"
114114
noFileForScorecardResultString = "Issue Found in your GitHub repository"
115+
CliType = "cli"
115116
)
116117

117118
var (
@@ -179,6 +180,7 @@ func NewResultsCommand(
179180
scanWrapper wrappers.ScansWrapper,
180181
exportWrapper wrappers.ExportWrapper,
181182
resultsPdfReportsWrapper wrappers.ResultsPdfWrapper,
183+
resultsJSONReportsWrapper wrappers.ResultsJSONWrapper,
182184
codeBashingWrapper wrappers.CodeBashingWrapper,
183185
bflWrapper wrappers.BflWrapper,
184186
risksOverviewWrapper wrappers.RisksOverviewWrapper,
@@ -198,7 +200,7 @@ func NewResultsCommand(
198200
),
199201
},
200202
}
201-
showResultCmd := resultShowSubCommand(resultsWrapper, scanWrapper, exportWrapper, resultsPdfReportsWrapper,
203+
showResultCmd := resultShowSubCommand(resultsWrapper, scanWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper,
202204
risksOverviewWrapper, scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper)
203205
codeBashingCmd := resultCodeBashing(codeBashingWrapper)
204206
bflResultCmd := resultBflSubCommand(bflWrapper)
@@ -256,6 +258,7 @@ func resultShowSubCommand(
256258
scanWrapper wrappers.ScansWrapper,
257259
exportWrapper wrappers.ExportWrapper,
258260
resultsPdfReportsWrapper wrappers.ResultsPdfWrapper,
261+
resultsJSONReportsWrapper wrappers.ResultsJSONWrapper,
259262
risksOverviewWrapper wrappers.RisksOverviewWrapper,
260263
scsScanOverviewWrapper wrappers.ScanOverviewWrapper,
261264
policyWrapper wrappers.PolicyWrapper,
@@ -270,12 +273,13 @@ func resultShowSubCommand(
270273
$ cx results show --scan-id <scan Id>
271274
`,
272275
),
273-
RunE: runGetResultCommand(resultsWrapper, scanWrapper, exportWrapper, resultsPdfReportsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper),
276+
RunE: runGetResultCommand(resultsWrapper, scanWrapper, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, policyWrapper, featureFlagsWrapper),
274277
}
275278
addScanIDFlag(resultShowCmd, "ID to report on")
276279
addResultFormatFlag(
277280
resultShowCmd,
278281
printer.FormatJSON,
282+
printer.FormatJSONv2,
279283
printer.FormatSummary,
280284
printer.FormatSummaryConsole,
281285
printer.FormatSarif,
@@ -1008,6 +1012,7 @@ func runGetResultCommand(
10081012
scanWrapper wrappers.ScansWrapper,
10091013
exportWrapper wrappers.ExportWrapper,
10101014
resultsPdfReportsWrapper wrappers.ResultsPdfWrapper,
1015+
resultsJSONReportsWrapper wrappers.ResultsJSONWrapper,
10111016
risksOverviewWrapper wrappers.RisksOverviewWrapper,
10121017
scsScanOverviewWrapper wrappers.ScanOverviewWrapper,
10131018
policyWrapper wrappers.PolicyWrapper,
@@ -1063,7 +1068,7 @@ func runGetResultCommand(
10631068
}
10641069

10651070
_, err = CreateScanReport(resultsWrapper, risksOverviewWrapper, scsScanOverviewWrapper, exportWrapper,
1066-
policyResponseModel, resultsPdfReportsWrapper, scan, format, formatPdfToEmail, formatPdfOptions,
1071+
policyResponseModel, resultsPdfReportsWrapper, resultsJSONReportsWrapper, scan, format, formatPdfToEmail, formatPdfOptions,
10671072
formatSbomOptions, targetFile, targetPath, agent, resultsParams, featureFlagsWrapper)
10681073
return err
10691074
}
@@ -1162,6 +1167,7 @@ func CreateScanReport(
11621167
exportWrapper wrappers.ExportWrapper,
11631168
policyResponseModel *wrappers.PolicyResponseModel,
11641169
resultsPdfReportsWrapper wrappers.ResultsPdfWrapper,
1170+
resultsJSONReportsWrapper wrappers.ResultsJSONWrapper,
11651171
scan *wrappers.ScanResponseModel,
11661172
reportTypes,
11671173
formatPdfToEmail,
@@ -1202,7 +1208,7 @@ func CreateScanReport(
12021208
}
12031209
for _, reportType := range reportList {
12041210
err = createReport(reportType, formatPdfToEmail, formatPdfOptions, formatSbomOptions, targetFile,
1205-
targetPath, results, summary, exportWrapper, resultsPdfReportsWrapper, featureFlagsWrapper, agent)
1211+
targetPath, results, summary, exportWrapper, resultsPdfReportsWrapper, resultsJSONReportsWrapper, featureFlagsWrapper, agent)
12061212
if err != nil {
12071213
return nil, err
12081214
}
@@ -1380,6 +1386,7 @@ func createReport(format,
13801386
summary *wrappers.ResultSummary,
13811387
exportWrapper wrappers.ExportWrapper,
13821388
resultsPdfReportsWrapper wrappers.ResultsPdfWrapper,
1389+
resultsJSONReportsWrapper wrappers.ResultsJSONWrapper,
13831390
featureFlagsWrapper wrappers.FeatureFlagsWrapper,
13841391
agent string) error {
13851392
if printer.IsFormat(format, printer.FormatIndentedJSON) {
@@ -1397,6 +1404,10 @@ func createReport(format,
13971404
jsonRpt := createTargetName(targetFile, targetPath, printer.FormatJSON)
13981405
return exportJSONResults(jsonRpt, results)
13991406
}
1407+
if printer.IsFormat(format, printer.FormatJSONv2) && isValidScanStatus(summary.Status, printer.FormatJSONv2) {
1408+
summaryRpt := createTargetName(targetFile, targetPath, printer.FormatJSON)
1409+
return exportJSONReportResults(resultsJSONReportsWrapper, summary, summaryRpt, featureFlagsWrapper)
1410+
}
14001411
if printer.IsFormat(format, printer.FormatGLSast) {
14011412
jsonRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, glSastTypeLabel), targetPath, printer.FormatJSON)
14021413
return exportGlSastResults(jsonRpt, results, summary)
@@ -1773,6 +1784,92 @@ func exportJSONResults(targetFile string, results *wrappers.ScanResultsCollectio
17731784
return nil
17741785
}
17751786

1787+
func exportJSONReportResults(jsonWrapper wrappers.ResultsJSONWrapper, summary *wrappers.ResultSummary, summaryRpt string, featureFlagsWrapper wrappers.FeatureFlagsWrapper) error {
1788+
jsonReportsPayload := &wrappers.JSONReportsPayload{}
1789+
pollingResp := &wrappers.JSONPollingResponse{}
1790+
flagResponse, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.NewScanReportEnabled)
1791+
newScanReportEnabled := flagResponse.Status
1792+
if newScanReportEnabled {
1793+
jsonReportsPayload.ReportName = reportNameImprovedScanReport
1794+
} else {
1795+
jsonReportsPayload.ReportName = reportNameScanReport
1796+
}
1797+
1798+
jsonOptionsSections, jsonOptionsEngines := parseJSONOptions(summary.EnginesEnabled, jsonReportsPayload.ReportName)
1799+
1800+
jsonReportsPayload.ReportType = CliType
1801+
jsonReportsPayload.FileFormat = printer.FormatJSON
1802+
jsonReportsPayload.Data.ScanID = summary.ScanID
1803+
jsonReportsPayload.Data.ProjectID = summary.ProjectID
1804+
jsonReportsPayload.Data.BranchName = summary.BranchName
1805+
jsonReportsPayload.Data.Scanners = jsonOptionsEngines
1806+
jsonReportsPayload.Data.Sections = jsonOptionsSections
1807+
1808+
jsonReportID, webErr, err := jsonWrapper.GenerateJSONReport(jsonReportsPayload)
1809+
if webErr != nil {
1810+
return errors.Errorf("Error generating JSON report - %s", webErr.Message)
1811+
}
1812+
if err != nil {
1813+
return errors.Errorf("Error generating JSON report - %s", err.Error())
1814+
}
1815+
log.Println("Generating JSON report")
1816+
pollingResp.Status = startedStatus
1817+
for pollingResp.Status == startedStatus || pollingResp.Status == requestedStatus {
1818+
pollingResp, webErr, err = jsonWrapper.CheckJSONReportStatus(jsonReportID.ReportID)
1819+
if err != nil || webErr != nil {
1820+
return errors.Wrapf(err, "%v", webErr)
1821+
}
1822+
logger.PrintfIfVerbose("JSON report status: %s", pollingResp.Status)
1823+
time.Sleep(delayValueForReport * time.Millisecond)
1824+
}
1825+
if pollingResp.Status != completedStatus {
1826+
return errors.Errorf("JSON generating failed - Current status: %s", pollingResp.Status)
1827+
}
1828+
1829+
minioEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.MinioEnabled)
1830+
infoPathType := ""
1831+
if minioEnabled.Status {
1832+
infoPathType = jsonReportID.ReportID
1833+
} else {
1834+
infoPathType = pollingResp.URL
1835+
}
1836+
err = jsonWrapper.DownloadJSONReport(infoPathType, summaryRpt, minioEnabled.Status)
1837+
if err != nil {
1838+
return errors.Wrapf(err, "%s", "Failed downloading JSON report")
1839+
}
1840+
return nil
1841+
}
1842+
1843+
func parseJSONOptions(enabledEngines []string, reportName string) (jsonOptionsSections, jsonOptionsEngines []string) {
1844+
jsonOptionsSections = []string{
1845+
"ScanSummary",
1846+
"ExecutiveSummary",
1847+
"ScanResults",
1848+
}
1849+
1850+
var jsonOptionsEnginesMap = map[string]string{
1851+
commonParams.ScaType: "SCA",
1852+
commonParams.SastType: "SAST",
1853+
commonParams.KicsType: "KICS",
1854+
commonParams.IacType: "KICS",
1855+
commonParams.ContainersType: "Containers",
1856+
commonParams.ScsType: "Microengines",
1857+
}
1858+
if jsonOptionsEngines == nil {
1859+
for _, engine := range enabledEngines {
1860+
if jsonOptionsEnginesMap[engine] != "" {
1861+
jsonOptionsEngines = append(jsonOptionsEngines, jsonOptionsEnginesMap[engine])
1862+
}
1863+
}
1864+
}
1865+
1866+
if reportName == reportNameImprovedScanReport {
1867+
jsonOptionsSections = translateReportSectionsForImproved(jsonOptionsSections)
1868+
}
1869+
1870+
return jsonOptionsSections, jsonOptionsEngines
1871+
}
1872+
17761873
func exportJSONSummaryResults(targetFile string, results *wrappers.ResultSummary) error {
17771874
var err error
17781875
var resultsJSON []byte
@@ -1807,7 +1904,7 @@ func exportPdfResults(pdfWrapper wrappers.ResultsPdfWrapper, summary *wrappers.R
18071904
return err
18081905
}
18091906

1810-
pdfReportsPayload.ReportType = "cli"
1907+
pdfReportsPayload.ReportType = CliType
18111908
pdfReportsPayload.FileFormat = printer.FormatPDF
18121909
pdfReportsPayload.Data.ScanID = summary.ScanID
18131910
pdfReportsPayload.Data.ProjectID = summary.ProjectID

internal/commands/result_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,24 @@ func TestRunGetResultsGeneratingPdfReportWithOptions(t *testing.T) {
732732
assert.NilError(t, err, "report file should exist: "+fileName+printer.FormatPDF)
733733
}
734734

735+
func TestRunGetResultsGeneratingJsonV2Report(t *testing.T) {
736+
clearFlags()
737+
mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.NewScanReportEnabled, Status: false}
738+
cmd := createASTTestCommand()
739+
err := executeTestCommand(cmd,
740+
"results", "show",
741+
"--report-format", "json-v2",
742+
"--scan-id", "MOCK",
743+
"--output-name", fileName)
744+
defer func() {
745+
removeFileBySuffix(t, printer.FormatJSON)
746+
fmt.Println("test file removed!")
747+
}()
748+
assert.NilError(t, err)
749+
_, err = os.Stat(fmt.Sprintf("%s.%s", fileName, printer.FormatJSON))
750+
assert.NilError(t, err, "report file should exist: "+fileName+printer.FormatJSON)
751+
}
752+
735753
func TestSBOMReportInvalidSBOMOption(t *testing.T) {
736754
err := execCmdNotNilAssertion(t,
737755
"results", "show",

internal/commands/root.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func NewAstCLI(
2626
scansWrapper wrappers.ScansWrapper,
2727
exportWrapper wrappers.ExportWrapper,
2828
resultsPdfReportsWrapper wrappers.ResultsPdfWrapper,
29+
resultsJSONReportsWrapper wrappers.ResultsJSONWrapper,
2930
resultsPredicatesWrapper wrappers.ResultsPredicatesWrapper,
3031
customStatesWrapper wrappers.CustomStatesWrapper,
3132
codeBashingWrapper wrappers.CodeBashingWrapper,
@@ -149,6 +150,7 @@ func NewAstCLI(
149150
scansWrapper,
150151
exportWrapper,
151152
resultsPdfReportsWrapper,
153+
resultsJSONReportsWrapper,
152154
uploadsWrapper,
153155
resultsWrapper,
154156
projectsWrapper,
@@ -172,6 +174,7 @@ func NewAstCLI(
172174
scansWrapper,
173175
exportWrapper,
174176
resultsPdfReportsWrapper,
177+
resultsJSONReportsWrapper,
175178
codeBashingWrapper,
176179
bflWrapper,
177180
risksOverviewWrapper,

internal/commands/root_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func createASTTestCommand() *cobra.Command {
3838
scansMockWrapper := &mock.ScansMockWrapper{}
3939
exportWrapper := &mock.ExportMockWrapper{}
4040
resultsPdfWrapper := &mock.ResultsPdfWrapper{}
41+
resultsJSONWrapper := &mock.ResultsJSONWrapper{}
4142
scansMockWrapper.Running = true
4243
resultsPredicatesMockWrapper := &mock.ResultsPredicatesMockWrapper{}
4344
groupsMockWrapper := &mock.GroupsMockWrapper{}
@@ -74,6 +75,7 @@ func createASTTestCommand() *cobra.Command {
7475
scansMockWrapper,
7576
exportWrapper,
7677
resultsPdfWrapper,
78+
resultsJSONWrapper,
7779
resultsPredicatesMockWrapper,
7880
customStatesMockWrapper,
7981
codeBashingWrapper,

0 commit comments

Comments
 (0)