From af48757ba1ad299002a6907f6436f6ed7c77782e Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Sun, 7 Apr 2024 17:34:17 +0300 Subject: [PATCH 01/60] results exit-code --- internal/commands/result.go | 115 +++++++++++++++++++++- internal/commands/util/printer/printer.go | 9 +- internal/wrappers/mock/scans-mock.go | 5 +- test/integration/scan_test.go | 2 - 4 files changed, 126 insertions(+), 5 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 224b02b79..494851722 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -162,12 +162,32 @@ func NewResultsCommand( showResultCmd := resultShowSubCommand(resultsWrapper, scanWrapper, resultsSbomWrapper, resultsPdfReportsWrapper, risksOverviewWrapper, policyWrapper) codeBashingCmd := resultCodeBashing(codeBashingWrapper) bflResultCmd := resultBflSubCommand(bflWrapper) + exitCodeSubcommand := exitCodeSubCommand(scanWrapper) resultCmd.AddCommand( - showResultCmd, bflResultCmd, codeBashingCmd, + showResultCmd, bflResultCmd, codeBashingCmd, exitCodeSubcommand, ) return resultCmd } +func exitCodeSubCommand(scanWrapper wrappers.ScansWrapper) *cobra.Command { + exitCodeCmd := &cobra.Command{ + Use: "exit-code", + Short: "Get exit code and details of a scan", + Long: "The exit-code command enables to get the exit code and failure details of a requested scan in Checkmarx One.", + Example: heredoc.Doc( + ` + $ cx results exit-code --scan-id --scan-types + `, + ), + RunE: runGetExitCodeCommand(scanWrapper), + } + + exitCodeCmd.PersistentFlags().String(commonParams.ScanIDFlag, "", "Scan ID") + exitCodeCmd.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types") + + return exitCodeCmd +} + func resultShowSubCommand( resultsWrapper wrappers.ResultsWrapper, scanWrapper wrappers.ScansWrapper, @@ -251,6 +271,87 @@ func resultBflSubCommand(bflWrapper wrappers.BflWrapper) *cobra.Command { return resultBflCmd } +func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { + scanID, _ := cmd.Flags().GetString(commonParams.ScanIDFlag) + if scanID == "" { + return errors.New("Scan ID is required") + } + scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) + if errorModel != nil || err != nil { + _ = printer.Print(cmd.OutOrStdout(), fmt.Sprintf("Scan %s not found", scanID), printer.FormatJSON) + } + scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) + var results []interface{} + + if scanTypesFlagValue == "" { + results = createFailedScannersResponse(scanResponseModel) + return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) + } + scanTypes := sanitizeScannerNames(scanTypesFlagValue) + results = createRequestedScannersResponse(scanTypes, scanResponseModel) + + return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) + } +} + +func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrappers.ScanResponseModel) []interface{} { + var results []interface{} + for i := range scanTypes { + for j := range scanResponseModel.StatusDetails { + if scanResponseModel.StatusDetails[j].Name == scanTypes[i] { + results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[j])) + } + } + } + return results +} + +func createFailedScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []interface{} { + var results []interface{} + for i := range scanResponseModel.StatusDetails { + if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed { + results = append(results, createFailedScannerResponse(&scanResponseModel.StatusDetails[i])) + } + } + + return results +} + +func createScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { + if statusDetails.Status == wrappers.ScanFailed { + return createFailedScannerResponse(statusDetails) + } else { + return createNonFailedScannerResponse(statusDetails) + } +} + +func sanitizeScannerNames(scanTypes string) []string { + scanTypeSlice := strings.Split(scanTypes, ",") + for i := range scanTypeSlice { + scanTypeSlice[i] = strings.ToLower(scanTypeSlice[i]) + } + + return scanTypeSlice +} + +func createFailedScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { + return FailedScannerResponse{ + Name: statusDetails.Name, + Status: statusDetails.Status, + Details: statusDetails.Details, + ErrorCode: strconv.Itoa(statusDetails.ErrorCode), + } +} + +func createNonFailedScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { + return SuccessfulScannerResponse{ + Name: statusDetails.Name, + Status: statusDetails.Status, + Details: "", + } +} + func runGetBestFixLocationCommand(bflWrapper wrappers.BflWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { var bflResponseModel *wrappers.BFLResponseModel @@ -1828,3 +1929,15 @@ func filterViolatedRules(policyModel wrappers.PolicyResponseModel) *wrappers.Pol policyModel.Policies = policyModel.Policies[:i] return &policyModel } + +type SuccessfulScannerResponse struct { + Name string + Status string + Details string +} +type FailedScannerResponse struct { + Name string + Status string + Details string + ErrorCode string +} diff --git a/internal/commands/util/printer/printer.go b/internal/commands/util/printer/printer.go index f6c83a5f7..13013e21c 100644 --- a/internal/commands/util/printer/printer.go +++ b/internal/commands/util/printer/printer.go @@ -14,6 +14,7 @@ import ( const ( FormatJSON = "json" + FormatIndentedJSON = "indented-json" FormatSarif = "sarif" FormatSonar = "sonar" FormatSummary = "summaryHTML" @@ -31,7 +32,13 @@ const ( ) func Print(w io.Writer, view interface{}, format string) error { - if IsFormat(format, FormatJSON) { + if IsFormat(format, FormatIndentedJSON) { + viewJSON, err := json.MarshalIndent(view, "", " ") + if err != nil { + return err + } + _, _ = fmt.Fprintln(w, string(viewJSON)) + } else if IsFormat(format, FormatJSON) { viewJSON, err := json.Marshal(view) if err != nil { return err diff --git a/internal/wrappers/mock/scans-mock.go b/internal/wrappers/mock/scans-mock.go index ba79bd425..39c0a061b 100644 --- a/internal/wrappers/mock/scans-mock.go +++ b/internal/wrappers/mock/scans-mock.go @@ -109,7 +109,10 @@ func (m *ScansMockWrapper) GetByID(scanID string) (*wrappers.ScanResponseModel, Status: wrappers.ScanFailed, StatusDetails: []wrappers.StatusInfo{ { - Status: wrappers.ScanFailed, Name: "kics", + Status: wrappers.ScanFailed, + Name: "kics", + Details: "error message from kics scanner", + ErrorCode: 1234, }, }, }, nil, nil diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 758de3279..f9f80234e 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -691,8 +691,6 @@ func TestFailedScanWithWrongPreset(t *testing.T) { flag(params.PolicyTimeoutFlag), "999999", } - res := strings.Join(args, " ") - fmt.Println(res) err, _ := executeCommand(t, args...) assertAstError(t, err, "scan did not complete successfully", exitCodes.SastExitCode) } From c5335fb114230f7eb95f0371a93fbc6aa34f461c Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 8 Apr 2024 14:23:43 +0300 Subject: [PATCH 02/60] Added handling for ScanCanceled, ScanRunning and ScanQueued --- internal/commands/result.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 494851722..010094bf8 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -281,9 +281,19 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co if errorModel != nil || err != nil { _ = printer.Print(cmd.OutOrStdout(), fmt.Sprintf("Scan %s not found", scanID), printer.FormatJSON) } - scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) - var results []interface{} + if scanResponseModel.Status == wrappers.ScanCanceled || + scanResponseModel.Status == wrappers.ScanRunning || + scanResponseModel.Status == wrappers.ScanQueued { + result := ScanCanceledOrInProgressResponse{ + ScanID: scanResponseModel.ID, + Status: scanResponseModel.Status, + } + return printer.Print(cmd.OutOrStdout(), result, printer.FormatIndentedJSON) + } + + var results []interface{} + scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { results = createFailedScannersResponse(scanResponseModel) return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) @@ -299,7 +309,7 @@ func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrap var results []interface{} for i := range scanTypes { for j := range scanResponseModel.StatusDetails { - if scanResponseModel.StatusDetails[j].Name == scanTypes[i] { + if scanTypes[i] == scanResponseModel.StatusDetails[j].Name { results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[j])) } } @@ -1941,3 +1951,7 @@ type FailedScannerResponse struct { Details string ErrorCode string } +type ScanCanceledOrInProgressResponse struct { + ScanID string + Status wrappers.ScanStatus +} From e8e9f15aef573e6601caae115c9e9075b073cfa6 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 8 Apr 2024 17:09:10 +0300 Subject: [PATCH 03/60] using one model for response --- internal/commands/result.go | 59 +++++++++++++------------------------ 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 010094bf8..61135572b 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -285,9 +285,9 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co if scanResponseModel.Status == wrappers.ScanCanceled || scanResponseModel.Status == wrappers.ScanRunning || scanResponseModel.Status == wrappers.ScanQueued { - result := ScanCanceledOrInProgressResponse{ + result := ScannerResponse{ ScanID: scanResponseModel.ID, - Status: scanResponseModel.Status, + Status: string(scanResponseModel.Status), } return printer.Print(cmd.OutOrStdout(), result, printer.FormatIndentedJSON) } @@ -295,7 +295,9 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co var results []interface{} scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { - results = createFailedScannersResponse(scanResponseModel) + results = createAllScannersResponse(scanResponseModel) + viewjson, _ := json.MarshalIndent(results, " ", " ") + fmt.Println(string(viewjson)) return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) } scanTypes := sanitizeScannerNames(scanTypesFlagValue) @@ -317,25 +319,14 @@ func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrap return results } -func createFailedScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []interface{} { +func createAllScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []interface{} { var results []interface{} for i := range scanResponseModel.StatusDetails { - if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed { - results = append(results, createFailedScannerResponse(&scanResponseModel.StatusDetails[i])) - } + results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) } - return results } -func createScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { - if statusDetails.Status == wrappers.ScanFailed { - return createFailedScannerResponse(statusDetails) - } else { - return createNonFailedScannerResponse(statusDetails) - } -} - func sanitizeScannerNames(scanTypes string) []string { scanTypeSlice := strings.Split(scanTypes, ",") for i := range scanTypeSlice { @@ -345,20 +336,20 @@ func sanitizeScannerNames(scanTypes string) []string { return scanTypeSlice } -func createFailedScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { - return FailedScannerResponse{ +func createScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { + return ScannerResponse{ Name: statusDetails.Name, Status: statusDetails.Status, Details: statusDetails.Details, - ErrorCode: strconv.Itoa(statusDetails.ErrorCode), + ErrorCode: stringifyErrorCode(statusDetails.ErrorCode), } } -func createNonFailedScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { - return SuccessfulScannerResponse{ - Name: statusDetails.Name, - Status: statusDetails.Status, - Details: "", +func stringifyErrorCode(errorCode int) string { + if errorCode == 0 { + return "" + } else { + return strconv.Itoa(errorCode) } } @@ -1940,18 +1931,10 @@ func filterViolatedRules(policyModel wrappers.PolicyResponseModel) *wrappers.Pol return &policyModel } -type SuccessfulScannerResponse struct { - Name string - Status string - Details string -} -type FailedScannerResponse struct { - Name string - Status string - Details string - ErrorCode string -} -type ScanCanceledOrInProgressResponse struct { - ScanID string - Status wrappers.ScanStatus +type ScannerResponse struct { + ScanID string `json:"ScanID,omitempty"` + Name string `json:"Name,omitempty"` + Status string `json:"Status,omitempty"` + Details string `json:"Details,omitempty"` + ErrorCode string `json:"ErrorCode,omitempty"` } From f327cc85775769f212c0203bbf33a65359c3b3b8 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 8 Apr 2024 17:21:29 +0300 Subject: [PATCH 04/60] removed fmt prints --- internal/commands/result.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 61135572b..8fbf2ecc9 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -296,13 +296,10 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { results = createAllScannersResponse(scanResponseModel) - viewjson, _ := json.MarshalIndent(results, " ", " ") - fmt.Println(string(viewjson)) return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) } scanTypes := sanitizeScannerNames(scanTypesFlagValue) results = createRequestedScannersResponse(scanTypes, scanResponseModel) - return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) } } From 8889358a0529bafd72c1fc7c6d8e1c2d8414ece1 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 8 Apr 2024 17:55:47 +0300 Subject: [PATCH 05/60] Added additional unit tests and integration test --- internal/commands/result.go | 8 +++++--- internal/commands/result_test.go | 28 ++++++++++++++++++++++++++++ internal/wrappers/mock/scans-mock.go | 13 +++++++------ test/integration/result_test.go | 14 +++++++++++++- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 8fbf2ecc9..242ae195a 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -295,7 +295,7 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co var results []interface{} scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { - results = createAllScannersResponse(scanResponseModel) + results = createAllFailedScannersResponse(scanResponseModel) return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) } scanTypes := sanitizeScannerNames(scanTypesFlagValue) @@ -316,10 +316,12 @@ func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrap return results } -func createAllScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []interface{} { +func createAllFailedScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []interface{} { var results []interface{} for i := range scanResponseModel.StatusDetails { - results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) + if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed { + results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) + } } return results } diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 534d3cd47..cf4eebc7e 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -34,6 +34,34 @@ func TestResultHelp(t *testing.T) { execCmdNilAssertion(t, "help", "results") } +func TestResultsExitCode_OnFailedKicsScanner_PrintCorrectFailedScannerInfoToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-scanner-fail") +} + +func TestResultsExitCode_OnFailedKicsAndScaScanners_PrintCorrectFailedScannersInfoToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-multiple-scanner-fails") +} + +func TestResultsExitCode_OnFailedKicsAndScaScannersAndRequestedScannerIsSca_PrintCorrectFailedScannersInfoToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-multiple-scanner-fails", "--scan-types", "sca") +} + +func TestResultsExitCode_OnPartialScan_PrintOnlyFailedScannersInfoToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-sca-fail-partial-id") +} + +func TestResultsExitCode_OnCanceledScan_PrintOnlyScanIDAndStatusCanceledToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-fail-sast-canceled-id") +} + +func TestResultsExitCode_OnCanceledScanWithRequestedSuccessfulScanner_PrintOnlyScanIDAndStatusCanceledToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-fail-sast-canceled-id", "--scan-types", "sast") +} + +func TestResultsExitCode_OnCanceledScanWithRequestedFailedScanner_PrintOnlyScanIDAndStatusCanceledToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-fail-sast-canceled-id", "--scan-types", "kics") +} + func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sarif") // Remove generated sarif file diff --git a/internal/wrappers/mock/scans-mock.go b/internal/wrappers/mock/scans-mock.go index 39c0a061b..94c7933a9 100644 --- a/internal/wrappers/mock/scans-mock.go +++ b/internal/wrappers/mock/scans-mock.go @@ -122,8 +122,8 @@ func (m *ScansMockWrapper) GetByID(scanID string) (*wrappers.ScanResponseModel, ID: "fake-scan-id-multiple-scanner-fails", Status: wrappers.ScanFailed, StatusDetails: []wrappers.StatusInfo{ - {Status: wrappers.ScanFailed, Name: "kics"}, - {Status: wrappers.ScanFailed, Name: "sca"}, + {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 2344}, + {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, }, }, nil, nil } @@ -132,18 +132,19 @@ func (m *ScansMockWrapper) GetByID(scanID string) (*wrappers.ScanResponseModel, ID: "fake-scan-id-sca-fail-partial-id", Status: wrappers.ScanPartial, StatusDetails: []wrappers.StatusInfo{ - {Status: wrappers.ScanFailed, Name: "sca"}, + {Status: wrappers.ScanCompleted, Name: "sast"}, + {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, }, }, nil, nil } if scanID == "fake-scan-id-kics-fail-sast-canceled-id" { return &wrappers.ScanResponseModel{ ID: "fake-scan-id-kics-fail-sast-canceled-id", - Status: wrappers.ScanFailed, + Status: wrappers.ScanCanceled, StatusDetails: []wrappers.StatusInfo{ {Status: wrappers.ScanCompleted, Name: "general"}, - {Status: wrappers.ScanCanceled, Name: "sast"}, - {Status: wrappers.ScanFailed, Name: "kics"}, + {Status: wrappers.ScanCompleted, Name: "sast"}, + {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 6455}, }, }, nil, nil } diff --git a/test/integration/result_test.go b/test/integration/result_test.go index b3711da84..89ce8303f 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -21,7 +21,19 @@ const ( resultsDirectory = "output-results-folder/" ) -// Create a scan and test getting its results +func TestResultsExitCode_OnSuccessfulScan_PrintResultsForAllScanners(t *testing.T) { + scanID, _ := getRootScan(t) + + args := []string{ + "results", "exit-code", + flag(params.ScanIDFlag), scanID, + flag(params.ScanTypes), "sast,sca", + } + + err, _ := executeCommand(t, args...) + defer deleteScan(t, scanID) + assert.NilError(t, err) +} func TestResultListJson(t *testing.T) { assertRequiredParameter(t, "Please provide a scan ID", "results", "show") From 3a347b847b04c4ee641f3d793b531c6e89bc41d0 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 8 Apr 2024 17:59:38 +0300 Subject: [PATCH 06/60] linter --- internal/commands/result.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 242ae195a..4844f78f3 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -275,7 +275,7 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return func(cmd *cobra.Command, args []string) error { scanID, _ := cmd.Flags().GetString(commonParams.ScanIDFlag) if scanID == "" { - return errors.New("Scan ID is required") + return errors.New("scan ID is required") } scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) if errorModel != nil || err != nil { From b8f3d5afcdded16ca3d1d7494443bea703763dd5 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 8 Apr 2024 18:02:50 +0300 Subject: [PATCH 07/60] linter --- internal/commands/result.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 4844f78f3..ef2026080 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -347,9 +347,8 @@ func createScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { func stringifyErrorCode(errorCode int) string { if errorCode == 0 { return "" - } else { - return strconv.Itoa(errorCode) } + return strconv.Itoa(errorCode) } func runGetBestFixLocationCommand(bflWrapper wrappers.BflWrapper) func(cmd *cobra.Command, args []string) error { From 1b9687bd62d35bf2ac867d2a7d4a77c3e16bdafd Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Tue, 9 Apr 2024 09:38:30 +0300 Subject: [PATCH 08/60] Fixed integration test --- internal/commands/result.go | 3 +++ test/integration/result_test.go | 1 + 2 files changed, 4 insertions(+) diff --git a/internal/commands/result.go b/internal/commands/result.go index aeba7438b..399e00004 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -1002,6 +1002,9 @@ func createReport(format, resultsPdfReportsWrapper wrappers.ResultsPdfWrapper, useSCALocalFlow bool, retrySBOM int) error { + if printer.IsFormat(format, printer.FormatIndentedJSON) { + return nil + } if printer.IsFormat(format, printer.FormatSarif) && isValidScanStatus(summary.Status, printer.FormatSarif) { sarifRpt := createTargetName(targetFile, targetPath, printer.FormatSarif) return exportSarifResults(sarifRpt, results) diff --git a/test/integration/result_test.go b/test/integration/result_test.go index b23917f99..3cfdd599a 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -46,6 +46,7 @@ func TestResultListJson(t *testing.T) { "show", flag(params.TargetFormatFlag), strings.Join( []string{ + printer.FormatIndentedJSON, printer.FormatJSON, printer.FormatSarif, printer.FormatSummary, From 23e0c24c4cb0ed8bfb1530dbb384b2fa5c3e2069 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 10:55:09 +0300 Subject: [PATCH 09/60] Attempt to pass test --- internal/commands/result.go | 9 +++------ internal/commands/util/printer/printer.go | 9 +-------- test/integration/result_test.go | 1 - 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 399e00004..35f28e599 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -291,18 +291,18 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co ScanID: scanResponseModel.ID, Status: string(scanResponseModel.Status), } - return printer.Print(cmd.OutOrStdout(), result, printer.FormatIndentedJSON) + return printer.Print(cmd.OutOrStdout(), result, printer.FormatJSON) } var results []interface{} scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { results = createAllFailedScannersResponse(scanResponseModel) - return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) + return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } scanTypes := sanitizeScannerNames(scanTypesFlagValue) results = createRequestedScannersResponse(scanTypes, scanResponseModel) - return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) + return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } } @@ -1002,9 +1002,6 @@ func createReport(format, resultsPdfReportsWrapper wrappers.ResultsPdfWrapper, useSCALocalFlow bool, retrySBOM int) error { - if printer.IsFormat(format, printer.FormatIndentedJSON) { - return nil - } if printer.IsFormat(format, printer.FormatSarif) && isValidScanStatus(summary.Status, printer.FormatSarif) { sarifRpt := createTargetName(targetFile, targetPath, printer.FormatSarif) return exportSarifResults(sarifRpt, results) diff --git a/internal/commands/util/printer/printer.go b/internal/commands/util/printer/printer.go index 13013e21c..f6c83a5f7 100644 --- a/internal/commands/util/printer/printer.go +++ b/internal/commands/util/printer/printer.go @@ -14,7 +14,6 @@ import ( const ( FormatJSON = "json" - FormatIndentedJSON = "indented-json" FormatSarif = "sarif" FormatSonar = "sonar" FormatSummary = "summaryHTML" @@ -32,13 +31,7 @@ const ( ) func Print(w io.Writer, view interface{}, format string) error { - if IsFormat(format, FormatIndentedJSON) { - viewJSON, err := json.MarshalIndent(view, "", " ") - if err != nil { - return err - } - _, _ = fmt.Fprintln(w, string(viewJSON)) - } else if IsFormat(format, FormatJSON) { + if IsFormat(format, FormatJSON) { viewJSON, err := json.Marshal(view) if err != nil { return err diff --git a/test/integration/result_test.go b/test/integration/result_test.go index 3cfdd599a..b23917f99 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -46,7 +46,6 @@ func TestResultListJson(t *testing.T) { "show", flag(params.TargetFormatFlag), strings.Join( []string{ - printer.FormatIndentedJSON, printer.FormatJSON, printer.FormatSarif, printer.FormatSummary, From 855642e4e0b89e0ad4d8022ba3779c5b45398e0b Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 14:24:14 +0300 Subject: [PATCH 10/60] fixed PR comments --- internal/commands/result.go | 15 ++++++++------- internal/errors/application-errors.go | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 35f28e599..baec648be 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -21,6 +21,7 @@ import ( "golang.org/x/text/cases" "golang.org/x/text/language" + applicationErrors "github.com/checkmarx/ast-cli/internal/errors" commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" @@ -277,7 +278,7 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return func(cmd *cobra.Command, args []string) error { scanID, _ := cmd.Flags().GetString(commonParams.ScanIDFlag) if scanID == "" { - return errors.New("scan ID is required") + return errors.New(applicationErrors.ScanIdRequired) } scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) if errorModel != nil || err != nil { @@ -294,7 +295,7 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return printer.Print(cmd.OutOrStdout(), result, printer.FormatJSON) } - var results []interface{} + var results []ScannerResponse scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { results = createAllFailedScannersResponse(scanResponseModel) @@ -306,8 +307,8 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co } } -func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrappers.ScanResponseModel) []interface{} { - var results []interface{} +func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { + var results []ScannerResponse for i := range scanTypes { for j := range scanResponseModel.StatusDetails { if scanTypes[i] == scanResponseModel.StatusDetails[j].Name { @@ -318,8 +319,8 @@ func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrap return results } -func createAllFailedScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []interface{} { - var results []interface{} +func createAllFailedScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { + var results []ScannerResponse for i := range scanResponseModel.StatusDetails { if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed { results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) @@ -337,7 +338,7 @@ func sanitizeScannerNames(scanTypes string) []string { return scanTypeSlice } -func createScannerResponse(statusDetails *wrappers.StatusInfo) interface{} { +func createScannerResponse(statusDetails *wrappers.StatusInfo) ScannerResponse { return ScannerResponse{ Name: statusDetails.Name, Status: statusDetails.Status, diff --git a/internal/errors/application-errors.go b/internal/errors/application-errors.go index 92aebb0c0..47b3f8e96 100644 --- a/internal/errors/application-errors.go +++ b/internal/errors/application-errors.go @@ -6,4 +6,5 @@ const ( const ( FailedToGetApplication = "Failed to get application" + ScanIdRequired = "scan ID is required" ) From c7fa38b63216737d586a142b3608316631ea9c9d Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 14:28:00 +0300 Subject: [PATCH 11/60] Fixed linter issue --- internal/commands/result.go | 2 +- internal/errors/application-errors.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index baec648be..4f1304e8d 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -278,7 +278,7 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return func(cmd *cobra.Command, args []string) error { scanID, _ := cmd.Flags().GetString(commonParams.ScanIDFlag) if scanID == "" { - return errors.New(applicationErrors.ScanIdRequired) + return errors.New(applicationErrors.ScanIDRequired) } scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) if errorModel != nil || err != nil { diff --git a/internal/errors/application-errors.go b/internal/errors/application-errors.go index 47b3f8e96..d77ac593e 100644 --- a/internal/errors/application-errors.go +++ b/internal/errors/application-errors.go @@ -6,5 +6,5 @@ const ( const ( FailedToGetApplication = "Failed to get application" - ScanIdRequired = "scan ID is required" + ScanIDRequired = "scan ID is required" ) From 1dd3365ff07fb0000e23e1545316b36413aa4626 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 15:58:58 +0300 Subject: [PATCH 12/60] Fixed CR comments --- internal/commands/result.go | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 4f1304e8d..a5a2d5c9d 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -176,7 +176,7 @@ func exitCodeSubCommand(scanWrapper wrappers.ScansWrapper) *cobra.Command { exitCodeCmd := &cobra.Command{ Use: "exit-code", Short: "Get exit code and details of a scan", - Long: "The exit-code command enables to get the exit code and failure details of a requested scan in Checkmarx One.", + Long: "The exit-code command enables you to get the exit code and failure details of a requested scan in Checkmarx One.", Example: heredoc.Doc( ` $ cx results exit-code --scan-id --scan-types @@ -281,8 +281,11 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return errors.New(applicationErrors.ScanIDRequired) } scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) - if errorModel != nil || err != nil { - _ = printer.Print(cmd.OutOrStdout(), fmt.Sprintf("Scan %s not found", scanID), printer.FormatJSON) + if err != nil { + return errors.Wrapf(err, "%s", failedGetting) + } + if errorModel != nil { + return errors.Errorf("%s: CODE: %d, %s", failedGettingScan, errorModel.Code, errorModel.Message) } if scanResponseModel.Status == wrappers.ScanCanceled || @@ -307,13 +310,11 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co } } -func createRequestedScannersResponse(scanTypes []string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { +func createRequestedScannersResponse(scanTypes map[string]string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse - for i := range scanTypes { - for j := range scanResponseModel.StatusDetails { - if scanTypes[i] == scanResponseModel.StatusDetails[j].Name { - results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[j])) - } + for _, StatusDetail := range scanResponseModel.StatusDetails { + if _, ok := scanTypes[StatusDetail.Name]; ok { + results = append(results, createScannerResponse(&StatusDetail)) } } return results @@ -329,13 +330,15 @@ func createAllFailedScannersResponse(scanResponseModel *wrappers.ScanResponseMod return results } -func sanitizeScannerNames(scanTypes string) []string { +func sanitizeScannerNames(scanTypes string) map[string]string { scanTypeSlice := strings.Split(scanTypes, ",") + scanTypeMap := make(map[string]string) for i := range scanTypeSlice { - scanTypeSlice[i] = strings.ToLower(scanTypeSlice[i]) + lowered := strings.ToLower(scanTypeSlice[i]) + scanTypeMap[lowered] = lowered } - return scanTypeSlice + return scanTypeMap } func createScannerResponse(statusDetails *wrappers.StatusInfo) ScannerResponse { From 6fbebe3ccfcb05398b0badba084b2a839915ecfb Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 16:01:28 +0300 Subject: [PATCH 13/60] fixed linter issues --- internal/commands/result.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index a5a2d5c9d..5e192350a 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -312,9 +312,9 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co func createRequestedScannersResponse(scanTypes map[string]string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse - for _, StatusDetail := range scanResponseModel.StatusDetails { + for i, StatusDetail := range scanResponseModel.StatusDetails { if _, ok := scanTypes[StatusDetail.Name]; ok { - results = append(results, createScannerResponse(&StatusDetail)) + results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) } } return results From 33636df9c09735678d9d61d510aaa81dc9e7e5b2 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 16:05:30 +0300 Subject: [PATCH 14/60] fixed documnetation --- internal/commands/result.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 5e192350a..3726c3da8 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -179,7 +179,7 @@ func exitCodeSubCommand(scanWrapper wrappers.ScansWrapper) *cobra.Command { Long: "The exit-code command enables you to get the exit code and failure details of a requested scan in Checkmarx One.", Example: heredoc.Doc( ` - $ cx results exit-code --scan-id --scan-types + $ cx results exit-code --scan-id --scan-types `, ), RunE: runGetExitCodeCommand(scanWrapper), From 11cf648b584a40d2c6a00610019f9f6e5f01508f Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 16:37:05 +0300 Subject: [PATCH 15/60] experiment to fix tests. revert later --- internal/commands/result.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 3726c3da8..670c8cbf3 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -295,18 +295,37 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co ScanID: scanResponseModel.ID, Status: string(scanResponseModel.Status), } - return printer.Print(cmd.OutOrStdout(), result, printer.FormatJSON) + //return printer.Print(cmd.OutOrStdout(), result, printer.FormatJSON) + + viewJSON, err := json.Marshal(result) + if err != nil { + return err + } + _, _ = fmt.Println(string(viewJSON)) } var results []ScannerResponse scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { results = createAllFailedScannersResponse(scanResponseModel) - return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) + + viewJSON, err := json.Marshal(results) + if err != nil { + return err + } + _, _ = fmt.Println(string(viewJSON)) + + //return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } scanTypes := sanitizeScannerNames(scanTypesFlagValue) results = createRequestedScannersResponse(scanTypes, scanResponseModel) - return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) + + viewJSON, err := json.Marshal(results) + if err != nil { + return err + } + _, _ = fmt.Println(string(viewJSON)) + //return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } } From 1419adff4233fe7f3e6b15c8ab124b0bc37c5559 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 16:40:09 +0300 Subject: [PATCH 16/60] trying to fix. revert later --- internal/commands/result.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/commands/result.go b/internal/commands/result.go index 670c8cbf3..0ea646f29 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -302,6 +302,7 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return err } _, _ = fmt.Println(string(viewJSON)) + return nil } var results []ScannerResponse @@ -315,6 +316,8 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co } _, _ = fmt.Println(string(viewJSON)) + return nil + //return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } scanTypes := sanitizeScannerNames(scanTypesFlagValue) @@ -325,6 +328,8 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return err } _, _ = fmt.Println(string(viewJSON)) + + return nil //return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } } From 46d003ec7a31c06a9be4a98f4fcab33d8518e6b2 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 17:47:24 +0300 Subject: [PATCH 17/60] Fix tests --- internal/commands/result.go | 30 +++--------------------------- test/integration/result_test.go | 1 - 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 0ea646f29..3726c3da8 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -295,42 +295,18 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co ScanID: scanResponseModel.ID, Status: string(scanResponseModel.Status), } - //return printer.Print(cmd.OutOrStdout(), result, printer.FormatJSON) - - viewJSON, err := json.Marshal(result) - if err != nil { - return err - } - _, _ = fmt.Println(string(viewJSON)) - return nil + return printer.Print(cmd.OutOrStdout(), result, printer.FormatJSON) } var results []ScannerResponse scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { results = createAllFailedScannersResponse(scanResponseModel) - - viewJSON, err := json.Marshal(results) - if err != nil { - return err - } - _, _ = fmt.Println(string(viewJSON)) - - return nil - - //return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) + return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } scanTypes := sanitizeScannerNames(scanTypesFlagValue) results = createRequestedScannersResponse(scanTypes, scanResponseModel) - - viewJSON, err := json.Marshal(results) - if err != nil { - return err - } - _, _ = fmt.Println(string(viewJSON)) - - return nil - //return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) + return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) } } diff --git a/test/integration/result_test.go b/test/integration/result_test.go index b23917f99..56f9b413c 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -31,7 +31,6 @@ func TestResultsExitCode_OnSuccessfulScan_PrintResultsForAllScanners(t *testing. } err, _ := executeCommand(t, args...) - defer deleteScan(t, scanID) assert.NilError(t, err) } func TestResultListJson(t *testing.T) { From 528867ed3176ec317828eb4e6e8d9805285818fc Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 18:01:14 +0300 Subject: [PATCH 18/60] not printing General --- internal/commands/result.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 3726c3da8..7bb2147fc 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -323,7 +323,7 @@ func createRequestedScannersResponse(scanTypes map[string]string, scanResponseMo func createAllFailedScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse for i := range scanResponseModel.StatusDetails { - if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed { + if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed && scanResponseModel.StatusDetails[i].Name != General { results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) } } From 6768b455195935f26c5b7845d92413503a1efb70 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 10 Apr 2024 18:34:55 +0300 Subject: [PATCH 19/60] Added test a completed test --- internal/commands/result_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 118df4391..7a3798041 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -35,6 +35,10 @@ func TestResultHelp(t *testing.T) { execCmdNilAssertion(t, "help", "results") } +func TestResultsExitCode_CompletedScan_PrintCorrectInfoToConsole(t *testing.T) { + execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "MOCK") +} + func TestResultsExitCode_OnFailedKicsScanner_PrintCorrectFailedScannerInfoToConsole(t *testing.T) { execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-scanner-fail") } From 10687dd41dbb53b5f3093289d5c0393981382be6 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 09:43:12 +0300 Subject: [PATCH 20/60] small improvements --- internal/commands/result.go | 17 +++++++++++------ internal/commands/util/printer/printer.go | 9 ++++++++- test/integration/result_test.go | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 7bb2147fc..af0319b39 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -17,11 +17,11 @@ import ( "github.com/checkmarx/ast-cli/internal/commands/policymanagement" "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/commands/util/printer" + applicationErrors "github.com/checkmarx/ast-cli/internal/errors" "github.com/checkmarx/ast-cli/internal/logger" "golang.org/x/text/cases" "golang.org/x/text/language" - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" @@ -295,18 +295,23 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co ScanID: scanResponseModel.ID, Status: string(scanResponseModel.Status), } - return printer.Print(cmd.OutOrStdout(), result, printer.FormatJSON) + return printer.Print(cmd.OutOrStdout(), result, printer.FormatIndentedJSON) } var results []ScannerResponse scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) if scanTypesFlagValue == "" { results = createAllFailedScannersResponse(scanResponseModel) - return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) + } else { + scanTypes := sanitizeScannerNames(scanTypesFlagValue) + results = createRequestedScannersResponse(scanTypes, scanResponseModel) } - scanTypes := sanitizeScannerNames(scanTypesFlagValue) - results = createRequestedScannersResponse(scanTypes, scanResponseModel) - return printer.Print(cmd.OutOrStdout(), results, printer.FormatJSON) + + if len(results) == 0 { + return nil + } + + return printer.Print(cmd.OutOrStdout(), results, printer.FormatIndentedJSON) } } diff --git a/internal/commands/util/printer/printer.go b/internal/commands/util/printer/printer.go index f6c83a5f7..13013e21c 100644 --- a/internal/commands/util/printer/printer.go +++ b/internal/commands/util/printer/printer.go @@ -14,6 +14,7 @@ import ( const ( FormatJSON = "json" + FormatIndentedJSON = "indented-json" FormatSarif = "sarif" FormatSonar = "sonar" FormatSummary = "summaryHTML" @@ -31,7 +32,13 @@ const ( ) func Print(w io.Writer, view interface{}, format string) error { - if IsFormat(format, FormatJSON) { + if IsFormat(format, FormatIndentedJSON) { + viewJSON, err := json.MarshalIndent(view, "", " ") + if err != nil { + return err + } + _, _ = fmt.Fprintln(w, string(viewJSON)) + } else if IsFormat(format, FormatJSON) { viewJSON, err := json.Marshal(view) if err != nil { return err diff --git a/test/integration/result_test.go b/test/integration/result_test.go index 56f9b413c..a5f547c11 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -46,6 +46,7 @@ func TestResultListJson(t *testing.T) { flag(params.TargetFormatFlag), strings.Join( []string{ printer.FormatJSON, + printer.FormatIndentedJSON, printer.FormatSarif, printer.FormatSummary, printer.FormatSummaryConsole, From d7220f1f73737cc6b062cb6c64ac616c623c26b6 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 09:52:10 +0300 Subject: [PATCH 21/60] changed assertion --- test/integration/scan_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index ceedf4b1f..6e49fa7ed 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -686,7 +686,8 @@ func TestPartialScanWithWrongPreset(t *testing.T) { } err, _ := executeCommand(t, args...) - assertError(t, err, "scan completed partially") + //assertError(t, err, "scan completed partially") + assertAstError(t, err, "scan completed partially", exitCodes.SastEngineFailedExitCode) } func TestFailedScanWithWrongPreset(t *testing.T) { From cff8250fdf926f15e0402d714ff8a9cacfd42c27 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 11:22:01 +0300 Subject: [PATCH 22/60] refactoring + changed tests --- internal/commands/result.go | 44 +++++++----- internal/commands/result_test.go | 118 ++++++++++++++++++++++++++++--- 2 files changed, 138 insertions(+), 24 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index af0319b39..8f233b54e 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -288,24 +288,9 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co return errors.Errorf("%s: CODE: %d, %s", failedGettingScan, errorModel.Code, errorModel.Message) } - if scanResponseModel.Status == wrappers.ScanCanceled || - scanResponseModel.Status == wrappers.ScanRunning || - scanResponseModel.Status == wrappers.ScanQueued { - result := ScannerResponse{ - ScanID: scanResponseModel.ID, - Status: string(scanResponseModel.Status), - } - return printer.Print(cmd.OutOrStdout(), result, printer.FormatIndentedJSON) - } - var results []ScannerResponse scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) - if scanTypesFlagValue == "" { - results = createAllFailedScannersResponse(scanResponseModel) - } else { - scanTypes := sanitizeScannerNames(scanTypesFlagValue) - results = createRequestedScannersResponse(scanTypes, scanResponseModel) - } + results = getScannerResponse(scanTypesFlagValue, scanResponseModel) if len(results) == 0 { return nil @@ -315,6 +300,30 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co } } +func getScannerResponse(scanTypesFlagValue string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { + var results []ScannerResponse + + if scanResponseModel.Status == wrappers.ScanCanceled || + scanResponseModel.Status == wrappers.ScanRunning || + scanResponseModel.Status == wrappers.ScanQueued { + result := ScannerResponse{ + ScanID: scanResponseModel.ID, + Status: string(scanResponseModel.Status), + } + results = append(results, result) + return results + } + + if scanTypesFlagValue == "" { + results = createAllFailedScannersResponse(scanResponseModel) + } else { + scanTypes := sanitizeScannerNames(scanTypesFlagValue) + results = createRequestedScannersResponse(scanTypes, scanResponseModel) + } + + return results +} + func createRequestedScannersResponse(scanTypes map[string]string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse for i, StatusDetail := range scanResponseModel.StatusDetails { @@ -1011,6 +1020,9 @@ func createReport(format, resultsPdfReportsWrapper wrappers.ResultsPdfWrapper, useSCALocalFlow bool, retrySBOM int) error { + if printer.IsFormat(format, printer.FormatIndentedJSON) { + return nil + } if printer.IsFormat(format, printer.FormatSarif) && isValidScanStatus(summary.Status, printer.FormatSarif) { sarifRpt := createTargetName(targetFile, targetPath, printer.FormatSarif) return exportSarifResults(sarifRpt, results) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 7a3798041..16cdd8d05 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -36,35 +36,137 @@ func TestResultHelp(t *testing.T) { } func TestResultsExitCode_CompletedScan_PrintCorrectInfoToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "MOCK") + model := wrappers.ScanResponseModel{ID: "MOCK", Status: wrappers.ScanCompleted, Engines: []string{params.ScaType, params.SastType, params.KicsType}} + results := getScannerResponse("", &model) + assert.Equal(t, len(results), 0, "Scanner results should be empty") } func TestResultsExitCode_OnFailedKicsScanner_PrintCorrectFailedScannerInfoToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-scanner-fail") + model := wrappers.ScanResponseModel{ + ID: "fake-scan-id-kics-scanner-fail", + Status: wrappers.ScanFailed, + StatusDetails: []wrappers.StatusInfo{ + { + Status: wrappers.ScanFailed, + Name: "kics", + Details: "error message from kics scanner", + ErrorCode: 1234, + }, + }, + } + + results := getScannerResponse("", &model) + + assert.Equal(t, len(results), 1, "Scanner results should be empty") + assert.Equal(t, results[0].Name, "kics", "") + assert.Equal(t, results[0].ErrorCode, "1234", "") } func TestResultsExitCode_OnFailedKicsAndScaScanners_PrintCorrectFailedScannersInfoToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-multiple-scanner-fails") + model := wrappers.ScanResponseModel{ + ID: "fake-scan-id-multiple-scanner-fails", + Status: wrappers.ScanFailed, + StatusDetails: []wrappers.StatusInfo{ + {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 2344}, + {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, + }, + } + + results := getScannerResponse("", &model) + + assert.Equal(t, len(results), 2, "Scanner results should be empty") + assert.Equal(t, results[0].Name, "kics", "") + assert.Equal(t, results[0].ErrorCode, "2344", "") + assert.Equal(t, results[1].Name, "sca", "") + assert.Equal(t, results[1].ErrorCode, "4343", "") } func TestResultsExitCode_OnFailedKicsAndScaScannersAndRequestedScannerIsSca_PrintCorrectFailedScannersInfoToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-multiple-scanner-fails", "--scan-types", "sca") + model := wrappers.ScanResponseModel{ + ID: "fake-scan-id-multiple-scanner-fails", + Status: wrappers.ScanFailed, + StatusDetails: []wrappers.StatusInfo{ + {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 2344}, + {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, + }, + } + + results := getScannerResponse("sca", &model) + + assert.Equal(t, len(results), 1, "Scanner results should be empty") + assert.Equal(t, results[0].Name, "sca", "") + assert.Equal(t, results[0].ErrorCode, "4343", "") } func TestResultsExitCode_OnPartialScan_PrintOnlyFailedScannersInfoToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-sca-fail-partial-id") + model := wrappers.ScanResponseModel{ + ID: "fake-scan-id-sca-fail-partial-id", + Status: wrappers.ScanPartial, + StatusDetails: []wrappers.StatusInfo{ + {Status: wrappers.ScanCompleted, Name: "sast"}, + {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, + }, + } + + results := getScannerResponse("", &model) + + assert.Equal(t, len(results), 1, "Scanner results should be empty") + assert.Equal(t, results[0].Name, "sca", "") + assert.Equal(t, results[0].ErrorCode, "4343", "") } func TestResultsExitCode_OnCanceledScan_PrintOnlyScanIDAndStatusCanceledToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-fail-sast-canceled-id") + model := wrappers.ScanResponseModel{ + ID: "fake-scan-id-kics-fail-sast-canceled-id", + Status: wrappers.ScanCanceled, + StatusDetails: []wrappers.StatusInfo{ + {Status: wrappers.ScanCompleted, Name: "general"}, + {Status: wrappers.ScanCompleted, Name: "sast"}, + {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 6455}, + }, + } + + results := getScannerResponse("", &model) + + assert.Equal(t, len(results), 1, "Scanner results should be empty") + assert.Equal(t, results[0].ScanID, "fake-scan-id-kics-fail-sast-canceled-id", "") + assert.Equal(t, results[0].Status, wrappers.ScanCanceled, "") } func TestResultsExitCode_OnCanceledScanWithRequestedSuccessfulScanner_PrintOnlyScanIDAndStatusCanceledToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-fail-sast-canceled-id", "--scan-types", "sast") + model := wrappers.ScanResponseModel{ + ID: "fake-scan-id-kics-fail-sast-canceled-id", + Status: wrappers.ScanCanceled, + StatusDetails: []wrappers.StatusInfo{ + {Status: wrappers.ScanCompleted, Name: "general"}, + {Status: wrappers.ScanCompleted, Name: "sast"}, + {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 6455}, + }, + } + + results := getScannerResponse("sast", &model) + + assert.Equal(t, len(results), 1, "Scanner results should be empty") + assert.Equal(t, results[0].ScanID, "fake-scan-id-kics-fail-sast-canceled-id", "") + assert.Equal(t, results[0].Status, wrappers.ScanCanceled, "") } func TestResultsExitCode_OnCanceledScanWithRequestedFailedScanner_PrintOnlyScanIDAndStatusCanceledToConsole(t *testing.T) { - execCmdNilAssertion(t, "results", "exit-code", "--scan-id", "fake-scan-id-kics-fail-sast-canceled-id", "--scan-types", "kics") + model := wrappers.ScanResponseModel{ + ID: "fake-scan-id-kics-fail-sast-canceled-id", + Status: wrappers.ScanCanceled, + StatusDetails: []wrappers.StatusInfo{ + {Status: wrappers.ScanCompleted, Name: "general"}, + {Status: wrappers.ScanCompleted, Name: "sast"}, + {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 6455}, + }, + } + + results := getScannerResponse("kics", &model) + + assert.Equal(t, len(results), 1, "Scanner results should be empty") + assert.Equal(t, results[0].ScanID, "fake-scan-id-kics-fail-sast-canceled-id", "") + assert.Equal(t, results[0].Status, wrappers.ScanCanceled, "") } func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { From 032cfbafe53147ef6a5cae0e66bc0acd661ce75b Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 12:53:24 +0300 Subject: [PATCH 23/60] removed deletions because rans in parallel --- test/integration/scan_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 6e49fa7ed..d00697a2c 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -191,7 +191,7 @@ func TestScaResolverArg(t *testing.T) { "sast,iac-security", viper.GetString(resolverEnvVar), ) - defer deleteProject(t, projectID) + assert.Assert( t, pollScanUntilStatus(t, scanID, wrappers.ScanCompleted, FullScanWait, ScanPollSleep), @@ -246,9 +246,6 @@ func TestIncrementalScan(t *testing.T) { func TestCancelScan(t *testing.T) { scanID, projectID := createScanSastNoWait(t, SlowRepo, map[string]string{}) - defer deleteProject(t, projectID) - defer deleteScan(t, scanID) - // canceling too quickly after creating fails the scan... time.Sleep(30 * time.Second) From f521c086a46f31c121574a8c89e8538b45a2b159 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 13:32:53 +0300 Subject: [PATCH 24/60] discard var --- test/integration/scan_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index d00697a2c..2ec632e40 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -244,7 +244,7 @@ func TestIncrementalScan(t *testing.T) { // Start a scan guaranteed to take considerable time, cancel it and assert the status func TestCancelScan(t *testing.T) { - scanID, projectID := createScanSastNoWait(t, SlowRepo, map[string]string{}) + scanID, _ := createScanSastNoWait(t, SlowRepo, map[string]string{}) // canceling too quickly after creating fails the scan... time.Sleep(30 * time.Second) From b60028993944cc41be17c70687f1ccdd3a12d575 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 14:14:37 +0300 Subject: [PATCH 25/60] returns json object is scan completed --- internal/commands/result.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 8f233b54e..7878c57d4 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -305,7 +305,8 @@ func getScannerResponse(scanTypesFlagValue string, scanResponseModel *wrappers.S if scanResponseModel.Status == wrappers.ScanCanceled || scanResponseModel.Status == wrappers.ScanRunning || - scanResponseModel.Status == wrappers.ScanQueued { + scanResponseModel.Status == wrappers.ScanQueued || + scanResponseModel.Status == wrappers.ScanCompleted { result := ScannerResponse{ ScanID: scanResponseModel.ID, Status: string(scanResponseModel.Status), From f18bef8cf36440fbff35f9814cb179fb36daab81 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 14:28:55 +0300 Subject: [PATCH 26/60] fixed unit test --- internal/commands/result_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 16cdd8d05..516a4fdc2 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -38,7 +38,9 @@ func TestResultHelp(t *testing.T) { func TestResultsExitCode_CompletedScan_PrintCorrectInfoToConsole(t *testing.T) { model := wrappers.ScanResponseModel{ID: "MOCK", Status: wrappers.ScanCompleted, Engines: []string{params.ScaType, params.SastType, params.KicsType}} results := getScannerResponse("", &model) - assert.Equal(t, len(results), 0, "Scanner results should be empty") + assert.Equal(t, len(results), 1, "") + assert.Equal(t, results[0].ScanID, "MOCK", "") + assert.Equal(t, results[0].Status, wrappers.ScanCompleted, "") } func TestResultsExitCode_OnFailedKicsScanner_PrintCorrectFailedScannerInfoToConsole(t *testing.T) { From 317c1dbc34238b79d40c32ac752ff72dc7ab7663 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 11 Apr 2024 23:10:37 +0300 Subject: [PATCH 27/60] Increased threshold --- test/integration/scan_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 2ec632e40..31a4896fa 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -336,7 +336,7 @@ func TestScanCreateWithThresholdAndReportGenerate(t *testing.T) { } cmd := createASTIntegrationTestCommand(t) - err := executeWithTimeout(cmd, 2*time.Minute, args...) + err := executeWithTimeout(cmd, 3*time.Minute, args...) assertError(t, err, "Threshold check finished with status Failed") _, fileError := os.Stat(fmt.Sprintf("%s%s.%s", "/tmp/", "results", "json")) From 1249dbc2712e0921575d89ee83543d3fac942d66 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Sun, 14 Apr 2024 14:07:23 +0300 Subject: [PATCH 28/60] Added exit code support for containers --- internal/commands/result.go | 2 +- internal/commands/scan.go | 2 ++ internal/errors/exit-codes/exit-codes.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 7878c57d4..be11e5ac7 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -179,7 +179,7 @@ func exitCodeSubCommand(scanWrapper wrappers.ScansWrapper) *cobra.Command { Long: "The exit-code command enables you to get the exit code and failure details of a requested scan in Checkmarx One.", Example: heredoc.Doc( ` - $ cx results exit-code --scan-id --scan-types + $ cx results exit-code --scan-id --scan-types `, ), RunE: runGetExitCodeCommand(scanWrapper), diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 65dc68464..456b853c2 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -2033,6 +2033,7 @@ const ( IacSecurity = "iac-security" // We get 'kics' from AST. Added for forward compatibility Kics = "kics" APISec = "apisec" + Containers = "containers" ) var errorCodesByScanner = map[string]int{ @@ -2042,6 +2043,7 @@ var errorCodesByScanner = map[string]int{ IacSecurity: exitCodes.IacSecurityEngineFailedExitCode, Kics: exitCodes.KicsEngineFailedExitCode, APISec: exitCodes.ApisecEngineFailedExitCode, + Containers: exitCodes.ContainersEngineFailedExitCode, } func runListScansCommand(scansWrapper wrappers.ScansWrapper, sastMetadataWrapper wrappers.SastMetadataWrapper) func(cmd *cobra.Command, args []string) error { diff --git a/internal/errors/exit-codes/exit-codes.go b/internal/errors/exit-codes/exit-codes.go index 0149def4a..28c07ca8a 100644 --- a/internal/errors/exit-codes/exit-codes.go +++ b/internal/errors/exit-codes/exit-codes.go @@ -7,4 +7,5 @@ const ( IacSecurityEngineFailedExitCode = 4 // Same code as kics to support forward compatibility KicsEngineFailedExitCode = 4 ApisecEngineFailedExitCode = 5 + ContainersEngineFailedExitCode = 6 ) From f1705133b532e0af1d0dc0b83e7cfd6e3fce65c1 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Sun, 14 Apr 2024 14:10:16 +0300 Subject: [PATCH 29/60] shorter test name --- internal/commands/result_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 516a4fdc2..2c8f06b98 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -83,7 +83,7 @@ func TestResultsExitCode_OnFailedKicsAndScaScanners_PrintCorrectFailedScannersIn assert.Equal(t, results[1].ErrorCode, "4343", "") } -func TestResultsExitCode_OnFailedKicsAndScaScannersAndRequestedScannerIsSca_PrintCorrectFailedScannersInfoToConsole(t *testing.T) { +func TestResultsExitCode_OnRequestedFailedScanner_PrintCorrectFailedScannerInfoToConsole(t *testing.T) { model := wrappers.ScanResponseModel{ ID: "fake-scan-id-multiple-scanner-fails", Status: wrappers.ScanFailed, From 9ac8f1a3d9bcaa8f84e1233e025ff83e4485cf87 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Sun, 14 Apr 2024 15:34:04 +0300 Subject: [PATCH 30/60] reverted threshold and re-added project and scan deletions --- test/integration/scan_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 31a4896fa..63bd93607 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -192,6 +192,8 @@ func TestScaResolverArg(t *testing.T) { viper.GetString(resolverEnvVar), ) + defer deleteProject(t, projectID) + assert.Assert( t, pollScanUntilStatus(t, scanID, wrappers.ScanCompleted, FullScanWait, ScanPollSleep), @@ -244,7 +246,10 @@ func TestIncrementalScan(t *testing.T) { // Start a scan guaranteed to take considerable time, cancel it and assert the status func TestCancelScan(t *testing.T) { - scanID, _ := createScanSastNoWait(t, SlowRepo, map[string]string{}) + scanID, projectID := createScanSastNoWait(t, SlowRepo, map[string]string{}) + + defer deleteProject(t, projectID) + defer deleteScan(t, scanID) // canceling too quickly after creating fails the scan... time.Sleep(30 * time.Second) @@ -336,7 +341,7 @@ func TestScanCreateWithThresholdAndReportGenerate(t *testing.T) { } cmd := createASTIntegrationTestCommand(t) - err := executeWithTimeout(cmd, 3*time.Minute, args...) + err := executeWithTimeout(cmd, 2*time.Minute, args...) assertError(t, err, "Threshold check finished with status Failed") _, fileError := os.Stat(fmt.Sprintf("%s%s.%s", "/tmp/", "results", "json")) From a392cb3d935be60a262f33a2b1bc852666f4ec08 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 15 Apr 2024 16:40:26 +0300 Subject: [PATCH 31/60] Removed containers. added unit tests --- internal/commands/result_test.go | 11 +++++++++++ internal/commands/scan.go | 2 -- internal/errors/exit-codes/exit-codes.go | 1 - internal/wrappers/mock/scans-mock.go | 6 +++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 2c8f06b98..b62e580f4 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/checkmarx/ast-cli/internal/commands/util/printer" + applicationErrors "github.com/checkmarx/ast-cli/internal/errors" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/checkmarx/ast-cli/internal/wrappers/mock" @@ -171,6 +172,16 @@ func TestResultsExitCode_OnCanceledScanWithRequestedFailedScanner_PrintOnlyScanI assert.Equal(t, results[0].Status, wrappers.ScanCanceled, "") } +func TestResultsExitCode_NoScanIdSent_FailCommandWithError(t *testing.T) { + err := execCmdNotNilAssertion(t, "results", "exit-code") + assert.Equal(t, err.Error(), applicationErrors.ScanIDRequired, "Wrong expected error message") +} + +func TestResultsExitCode_OnErrorScan_FailCommandWithError(t *testing.T) { + err := execCmdNotNilAssertion(t, "results", "exit-code", "--scan-id", "fake-error-id") + assert.Equal(t, err.Error(), "Failed showing a scan: fake error message", "Wrong expected error message") +} + func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sarif") // Remove generated sarif file diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 456b853c2..65dc68464 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -2033,7 +2033,6 @@ const ( IacSecurity = "iac-security" // We get 'kics' from AST. Added for forward compatibility Kics = "kics" APISec = "apisec" - Containers = "containers" ) var errorCodesByScanner = map[string]int{ @@ -2043,7 +2042,6 @@ var errorCodesByScanner = map[string]int{ IacSecurity: exitCodes.IacSecurityEngineFailedExitCode, Kics: exitCodes.KicsEngineFailedExitCode, APISec: exitCodes.ApisecEngineFailedExitCode, - Containers: exitCodes.ContainersEngineFailedExitCode, } func runListScansCommand(scansWrapper wrappers.ScansWrapper, sastMetadataWrapper wrappers.SastMetadataWrapper) func(cmd *cobra.Command, args []string) error { diff --git a/internal/errors/exit-codes/exit-codes.go b/internal/errors/exit-codes/exit-codes.go index 28c07ca8a..0149def4a 100644 --- a/internal/errors/exit-codes/exit-codes.go +++ b/internal/errors/exit-codes/exit-codes.go @@ -7,5 +7,4 @@ const ( IacSecurityEngineFailedExitCode = 4 // Same code as kics to support forward compatibility KicsEngineFailedExitCode = 4 ApisecEngineFailedExitCode = 5 - ContainersEngineFailedExitCode = 6 ) diff --git a/internal/wrappers/mock/scans-mock.go b/internal/wrappers/mock/scans-mock.go index 94c7933a9..9c4d44806 100644 --- a/internal/wrappers/mock/scans-mock.go +++ b/internal/wrappers/mock/scans-mock.go @@ -5,8 +5,8 @@ import ( "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/google/uuid" + "github.com/pkg/errors" ) type ScansMockWrapper struct { @@ -103,6 +103,10 @@ func (m *ScansMockWrapper) Get(_ map[string]string) ( func (m *ScansMockWrapper) GetByID(scanID string) (*wrappers.ScanResponseModel, *wrappers.ErrorModel, error) { fmt.Println("Called GetByID in ScansMockWrapper") + if scanID == "fake-error-id" { + return nil, nil, errors.New("fake error message") + } + if scanID == "fake-scan-id-kics-scanner-fail" { return &wrappers.ScanResponseModel{ ID: "fake-scan-id-kics-scanner-fail", From 2d6d5fb8bc85efeb4c0c79fcd00dd37af11ed461 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Mon, 15 Apr 2024 18:04:37 +0300 Subject: [PATCH 32/60] Added integration test --- test/integration/result_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/integration/result_test.go b/test/integration/result_test.go index a5f547c11..1e9d4c806 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/checkmarx/ast-cli/internal/commands/util/printer" + applicationErrors "github.com/checkmarx/ast-cli/internal/errors" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "gotest.tools/assert" @@ -33,6 +34,18 @@ func TestResultsExitCode_OnSuccessfulScan_PrintResultsForAllScanners(t *testing. err, _ := executeCommand(t, args...) assert.NilError(t, err) } + +func TestResultsExitCode_NoScanIdSent_FailCommandWithError(t *testing.T) { + _, _ = getRootScan(t) + + args := []string{ + "results", "exit-code", + flag(params.ScanTypes), "sast", + } + + err, _ := executeCommand(t, args...) + assert.ErrorContains(t, err, applicationErrors.ScanIDRequired) +} func TestResultListJson(t *testing.T) { assertRequiredParameter(t, "Please provide a scan ID", "results", "show") From d1abd62f0ca7338566df932d47ec664086773e6a Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Tue, 16 Apr 2024 00:01:49 +0300 Subject: [PATCH 33/60] removed comment --- test/integration/scan_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 63bd93607..597a14438 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -688,7 +688,6 @@ func TestPartialScanWithWrongPreset(t *testing.T) { } err, _ := executeCommand(t, args...) - //assertError(t, err, "scan completed partially") assertAstError(t, err, "scan completed partially", exitCodes.SastEngineFailedExitCode) } From 303bef261e49492f4f7f342f3d54f50e7169f505 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Tue, 16 Apr 2024 16:19:07 +0300 Subject: [PATCH 34/60] Update result.go --- internal/commands/result.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index be11e5ac7..7878c57d4 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -179,7 +179,7 @@ func exitCodeSubCommand(scanWrapper wrappers.ScansWrapper) *cobra.Command { Long: "The exit-code command enables you to get the exit code and failure details of a requested scan in Checkmarx One.", Example: heredoc.Doc( ` - $ cx results exit-code --scan-id --scan-types + $ cx results exit-code --scan-id --scan-types `, ), RunE: runGetExitCodeCommand(scanWrapper), From 7e5e6276f4b99e8fe2f744cded44e47e50a9630f Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 17 Apr 2024 11:31:56 +0300 Subject: [PATCH 35/60] cr comment fix --- internal/commands/result.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 7878c57d4..ca2e35819 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -327,9 +327,9 @@ func getScannerResponse(scanTypesFlagValue string, scanResponseModel *wrappers.S func createRequestedScannersResponse(scanTypes map[string]string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse - for i, StatusDetail := range scanResponseModel.StatusDetails { + for _, StatusDetail := range scanResponseModel.StatusDetails { if _, ok := scanTypes[StatusDetail.Name]; ok { - results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) + results = append(results, createScannerResponse(&StatusDetail)) } } return results From f54127ad318fea63bdac3089b50577922b533930 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 17 Apr 2024 13:45:37 +0300 Subject: [PATCH 36/60] fix lint issue + go fmt --- internal/commands/result.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 129674068..6a7073d84 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -326,9 +326,9 @@ func getScannerResponse(scanTypesFlagValue string, scanResponseModel *wrappers.S func createRequestedScannersResponse(scanTypes map[string]string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse - for _, StatusDetail := range scanResponseModel.StatusDetails { - if _, ok := scanTypes[StatusDetail.Name]; ok { - results = append(results, createScannerResponse(&StatusDetail)) + for i := range scanResponseModel.StatusDetails { + if _, ok := scanTypes[scanResponseModel.StatusDetails[i].Name]; ok { + results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) } } return results From 544d884f4e68fadf047ecb0cad9a9fdc89a0c1c8 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 17 Apr 2024 16:45:43 +0300 Subject: [PATCH 37/60] refactoring and modifying integration test --- internal/commands/result.go | 25 ++++++++++++++++--------- test/integration/result_test.go | 19 +++++++++++-------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 6a7073d84..ca5fb3038 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -279,18 +279,12 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co if scanID == "" { return errors.New(applicationErrors.ScanIDRequired) } - scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) + scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) + results, err := GetScannerResults(scanWrapper, scanID, scanTypesFlagValue) if err != nil { - return errors.Wrapf(err, "%s", failedGetting) - } - if errorModel != nil { - return errors.Errorf("%s: CODE: %d, %s", failedGettingScan, errorModel.Code, errorModel.Message) + return err } - var results []ScannerResponse - scanTypesFlagValue, _ := cmd.Flags().GetString(commonParams.ScanTypes) - results = getScannerResponse(scanTypesFlagValue, scanResponseModel) - if len(results) == 0 { return nil } @@ -299,6 +293,19 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co } } +func GetScannerResults(scanWrapper wrappers.ScansWrapper, scanID string, scanTypesFlagValue string) ([]ScannerResponse, error) { + scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) + if err != nil { + return nil, errors.Wrapf(err, "%s", failedGetting) + } + if errorModel != nil { + return nil, errors.Errorf("%s: CODE: %d, %s", failedGettingScan, errorModel.Code, errorModel.Message) + } + var results []ScannerResponse + results = getScannerResponse(scanTypesFlagValue, scanResponseModel) + return results, nil +} + func getScannerResponse(scanTypesFlagValue string, scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse diff --git a/test/integration/result_test.go b/test/integration/result_test.go index 0c7b8a321..69d7f34e0 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -10,10 +10,12 @@ import ( "strings" "testing" + "github.com/checkmarx/ast-cli/internal/commands" "github.com/checkmarx/ast-cli/internal/commands/util/printer" applicationErrors "github.com/checkmarx/ast-cli/internal/errors" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" + "github.com/spf13/viper" "gotest.tools/assert" ) @@ -22,17 +24,18 @@ const ( resultsDirectory = "output-results-folder/" ) -func TestResultsExitCode_OnSuccessfulScan_PrintResultsForAllScanners(t *testing.T) { +func TestResultsExitCode_OnSuccessfulScan_ShouldReturnStatusCompleted(t *testing.T) { scanID, _ := getRootScan(t) - args := []string{ - "results", "exit-code", - flag(params.ScanIDFlag), scanID, - flag(params.ScanTypes), "sast,sca", - } + scansPath := viper.GetString(params.ScansPathKey) + scansWrapper := wrappers.NewHTTPScansWrapper(scansPath) + results, _ := commands.GetScannerResults(scansWrapper, scanID, "sast,sca") - err, _ := executeCommand(t, args...) - assert.NilError(t, err) + assert.Equal(t, 1, len(results)) + assert.Equal(t, wrappers.ScanCompleted, (results[0]).Status) + assert.Equal(t, "", (results[0]).Details) + assert.Equal(t, "", (results[0]).ErrorCode) + assert.Equal(t, "", (results[0]).Name) } func TestResultsExitCode_NoScanIdSent_FailCommandWithError(t *testing.T) { From 79054de49de74f329d82ec0d06895edcde51b25c Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 17 Apr 2024 16:49:18 +0300 Subject: [PATCH 38/60] fix lint issue +go fmt --- internal/commands/result.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index ca5fb3038..f042f9ecd 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -293,7 +293,7 @@ func runGetExitCodeCommand(scanWrapper wrappers.ScansWrapper) func(cmd *cobra.Co } } -func GetScannerResults(scanWrapper wrappers.ScansWrapper, scanID string, scanTypesFlagValue string) ([]ScannerResponse, error) { +func GetScannerResults(scanWrapper wrappers.ScansWrapper, scanID, scanTypesFlagValue string) ([]ScannerResponse, error) { scanResponseModel, errorModel, err := scanWrapper.GetByID(scanID) if err != nil { return nil, errors.Wrapf(err, "%s", failedGetting) @@ -301,8 +301,7 @@ func GetScannerResults(scanWrapper wrappers.ScansWrapper, scanID string, scanTyp if errorModel != nil { return nil, errors.Errorf("%s: CODE: %d, %s", failedGettingScan, errorModel.Code, errorModel.Message) } - var results []ScannerResponse - results = getScannerResponse(scanTypesFlagValue, scanResponseModel) + results := getScannerResponse(scanTypesFlagValue, scanResponseModel) return results, nil } From 869a5134836254bcd90c8f3b0ed41aaa077751fc Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 18 Apr 2024 12:25:53 +0300 Subject: [PATCH 39/60] attempt to see if coverage is affected --- test/integration/result_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/integration/result_test.go b/test/integration/result_test.go index 69d7f34e0..ca2d9a427 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -24,6 +24,15 @@ const ( resultsDirectory = "output-results-folder/" ) +func TestResultsExitCode_OnSendingFakeScanId_ShouldReturnNotFoundError(t *testing.T) { + _, _ = getRootScan(t) + scansPath := viper.GetString(params.ScansPathKey) + scansWrapper := wrappers.NewHTTPScansWrapper(scansPath) + results, _ := commands.GetScannerResults(scansWrapper, "FakeScanId", "sast,sca") + + assert.Equal(t, nil, results) +} + func TestResultsExitCode_OnSuccessfulScan_ShouldReturnStatusCompleted(t *testing.T) { scanID, _ := getRootScan(t) From deb31a148cfc41fd49d60d20e11dd3e21d560b19 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 18 Apr 2024 13:44:05 +0300 Subject: [PATCH 40/60] Update result_test.go --- test/integration/result_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/result_test.go b/test/integration/result_test.go index ca2d9a427..e38ae43b6 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -16,6 +16,7 @@ import ( "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/spf13/viper" + testifyAssert "github.com/stretchr/testify/assert" "gotest.tools/assert" ) @@ -30,7 +31,7 @@ func TestResultsExitCode_OnSendingFakeScanId_ShouldReturnNotFoundError(t *testin scansWrapper := wrappers.NewHTTPScansWrapper(scansPath) results, _ := commands.GetScannerResults(scansWrapper, "FakeScanId", "sast,sca") - assert.Equal(t, nil, results) + testifyAssert.Nil(t, results, "results should be nil") } func TestResultsExitCode_OnSuccessfulScan_ShouldReturnStatusCompleted(t *testing.T) { From a97a653109858b6beb890e30e9d59194213a819d Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 18 Apr 2024 14:03:24 +0300 Subject: [PATCH 41/60] improved test --- test/integration/result_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/result_test.go b/test/integration/result_test.go index e38ae43b6..b1d4cf71c 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -26,7 +26,7 @@ const ( ) func TestResultsExitCode_OnSendingFakeScanId_ShouldReturnNotFoundError(t *testing.T) { - _, _ = getRootScan(t) + bindKeysToEnvAndDefault(t) scansPath := viper.GetString(params.ScansPathKey) scansWrapper := wrappers.NewHTTPScansWrapper(scansPath) results, _ := commands.GetScannerResults(scansWrapper, "FakeScanId", "sast,sca") From 2e5c04cab159c541da5683ce88c7d04bc9f63be7 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 18 Apr 2024 15:34:47 +0300 Subject: [PATCH 42/60] added test to increase coverage --- test/integration/result_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/integration/result_test.go b/test/integration/result_test.go index b1d4cf71c..084bf7776 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -49,8 +49,7 @@ func TestResultsExitCode_OnSuccessfulScan_ShouldReturnStatusCompleted(t *testing } func TestResultsExitCode_NoScanIdSent_FailCommandWithError(t *testing.T) { - _, _ = getRootScan(t) - + bindKeysToEnvAndDefault(t) args := []string{ "results", "exit-code", flag(params.ScanTypes), "sast", @@ -59,6 +58,19 @@ func TestResultsExitCode_NoScanIdSent_FailCommandWithError(t *testing.T) { err, _ := executeCommand(t, args...) assert.ErrorContains(t, err, applicationErrors.ScanIDRequired) } + +func TestResultsExitCode_FakeScanIdSent_FailCommandWithError(t *testing.T) { + bindKeysToEnvAndDefault(t) + args := []string{ + "results", "exit-code", + flag(params.ScanTypes), "sast", + flag(params.ScanIDFlag), "FakeScanId", + } + + err, _ := executeCommand(t, args...) + assert.ErrorContains(t, err, "Failed showing a scan") +} + func TestResultListJson(t *testing.T) { assertRequiredParameter(t, "Please provide a scan ID", "results", "show") From e4461853f2701b5bef58168a20bba16084a9ac2d Mon Sep 17 00:00:00 2001 From: AlvoBen <144705560+AlvoBen@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:04:20 +0300 Subject: [PATCH 43/60] CLI | Add redirected request mechanism (AST-37864) (#712) * fix redirect mechanism * check * check * add const error variables --------- Co-authored-by: AlvoBen --- go.mod | 1 + internal/errors/application-errors.go | 2 ++ internal/wrappers/client.go | 48 ++++++++++++++++++++------- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index a2e7f4914..0aa3e45dd 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 + golang.org/x/net v0.23.0 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 golang.org/x/crypto v0.22.0 golang.org/x/text v0.14.0 diff --git a/internal/errors/application-errors.go b/internal/errors/application-errors.go index 92aebb0c0..21c43adce 100644 --- a/internal/errors/application-errors.go +++ b/internal/errors/application-errors.go @@ -6,4 +6,6 @@ const ( const ( FailedToGetApplication = "Failed to get application" + RedirectURLNotFound = "redirect URL not found in response" + HTTPMethodNotFound = "HTTP method not found in request" ) diff --git a/internal/wrappers/client.go b/internal/wrappers/client.go index 7ce0453a2..724d3d4cf 100644 --- a/internal/wrappers/client.go +++ b/internal/wrappers/client.go @@ -14,6 +14,7 @@ import ( "strings" "time" + applicationErrors "github.com/checkmarx/ast-cli/internal/errors" "github.com/golang-jwt/jwt" "github.com/checkmarx/ast-cli/internal/logger" @@ -580,18 +581,7 @@ func request(client *http.Client, req *http.Request, responseBody bool) (*http.R } if resp != nil && err == nil { if hasRedirectStatusCode(resp) { - redirectURL := resp.Header.Get("Location") - if redirectURL == "" { - return nil, fmt.Errorf("redirect URL not found in response") - } - method := GetHTTPMethod(req) - if method == "" { - return nil, fmt.Errorf("method not found in request") - } - req, err = http.NewRequest(method, redirectURL, bytes.NewReader(body)) - if err != nil { - return nil, err - } + req, err = handleRedirect(resp, req, body) continue } logger.PrintResponse(resp, responseBody) @@ -603,6 +593,40 @@ func request(client *http.Client, req *http.Request, responseBody bool) (*http.R return nil, err } +func handleRedirect(resp *http.Response, req *http.Request, body []byte) (*http.Request, error) { + redirectURL := resp.Header.Get("Location") + if redirectURL == "" { + return nil, fmt.Errorf(applicationErrors.RedirectURLNotFound) + } + + method := GetHTTPMethod(req) + if method == "" { + return nil, fmt.Errorf(applicationErrors.HTTPMethodNotFound) + } + + newReq, err := recreateRequest(req, method, redirectURL, body) + if err != nil { + return nil, err + } + + return newReq, nil +} + +func recreateRequest(oldReq *http.Request, method, redirectURL string, body []byte) (*http.Request, error) { + newReq, err := http.NewRequest(method, redirectURL, io.NopCloser(bytes.NewBuffer(body))) + if err != nil { + return nil, err + } + + for key, values := range oldReq.Header { + for _, value := range values { + newReq.Header.Add(key, value) + } + } + + return newReq, nil +} + func GetHTTPMethod(req *http.Request) string { switch req.Method { case http.MethodGet: From 1027001a519d3b5e43bfa6e3e2899813835da94d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:05:22 +0000 Subject: [PATCH 44/60] Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 5 +---- go.sum | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 0aa3e45dd..d7e07d698 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 - github.com/stretchr/testify v1.8.4 - golang.org/x/net v0.23.0 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 golang.org/x/crypto v0.22.0 golang.org/x/text v0.14.0 @@ -23,7 +21,6 @@ require ( ) require ( - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -31,13 +28,13 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.uber.org/atomic v1.9.0 // indirect diff --git a/go.sum b/go.sum index ff06ec542..71fbc614c 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,9 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y= From 55060b4eee22fb33ea7f48e63a3ef7a268353fe5 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 24 Apr 2024 12:39:47 +0300 Subject: [PATCH 45/60] including general in errors list --- internal/commands/result.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index f042f9ecd..cf0941ea0 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -343,7 +343,7 @@ func createRequestedScannersResponse(scanTypes map[string]string, scanResponseMo func createAllFailedScannersResponse(scanResponseModel *wrappers.ScanResponseModel) []ScannerResponse { var results []ScannerResponse for i := range scanResponseModel.StatusDetails { - if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed && scanResponseModel.StatusDetails[i].Name != General { + if scanResponseModel.StatusDetails[i].Status == wrappers.ScanFailed { results = append(results, createScannerResponse(&scanResponseModel.StatusDetails[i])) } } From 2980abcaebe0820071e6bba95f5261ebd47113f8 Mon Sep 17 00:00:00 2001 From: AlvoBen <144705560+AlvoBen@users.noreply.github.com> Date: Sun, 28 Apr 2024 17:30:24 +0300 Subject: [PATCH 46/60] CLI | Add threshold user input validation (AST-40169) (#715) * add threshold user input check * add threshold validation before running the scan * added tests * improve error msgs * fix linter problems * resolve conversation * fix linter problems --------- Co-authored-by: AlvoBen --- internal/commands/scan.go | 62 ++++++++++++++++++------- internal/commands/scan_test.go | 85 ++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 16 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 464549c49..23ce2355a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1525,6 +1525,12 @@ func runCreateScanCommand( if timeoutMinutes < 0 { return errors.Errorf("--%s should be equal or higher than 0", commonParams.ScanTimeoutFlag) } + threshold, _ := cmd.Flags().GetString(commonParams.Threshold) + thresholdMap := parseThreshold(threshold) + err = validateThresholds(thresholdMap) + if err != nil { + return err + } scanModel, zipFilePath, err := createScanModel( cmd, uploadsWrapper, @@ -1588,7 +1594,7 @@ func runCreateScanCommand( return err } - err = applyThreshold(cmd, resultsWrapper, scanResponseModel) + err = applyThreshold(cmd, resultsWrapper, scanResponseModel, thresholdMap) if err != nil { return err } @@ -1830,14 +1836,12 @@ func applyThreshold( cmd *cobra.Command, resultsWrapper wrappers.ResultsWrapper, scanResponseModel *wrappers.ScanResponseModel, + thresholdMap map[string]int, ) error { - threshold, _ := cmd.Flags().GetString(commonParams.Threshold) - if strings.TrimSpace(threshold) == "" { + if len(thresholdMap) == 0 { return nil } - thresholdMap := parseThreshold(threshold) - summaryMap, err := getSummaryThresholdMap(resultsWrapper, scanResponseModel) if err != nil { return err @@ -1872,25 +1876,22 @@ func applyThreshold( } func parseThreshold(threshold string) map[string]int { + if strings.TrimSpace(threshold) == "" { + return nil + } thresholdMap := make(map[string]int) if threshold != "" { threshold = strings.ReplaceAll(strings.ReplaceAll(threshold, " ", ""), ",", ";") thresholdLimits := strings.Split(strings.ToLower(threshold), ";") for _, limits := range thresholdLimits { - limit := strings.Split(limits, "=") - engineName := limit[0] - engineName = strings.Replace(engineName, commonParams.KicsType, commonParams.IacType, 1) - if len(limit) > 1 { - intLimit, err := strconv.Atoi(limit[1]) - if err != nil { - log.Println("Error parsing threshold limit: ", err) - } else { - thresholdMap[engineName] = intLimit - } + engineName, intLimit, err := parseThresholdLimit(limits) + if err != nil { + log.Printf("%s", err) + } else { + thresholdMap[engineName] = intLimit } } } - return thresholdMap } @@ -2495,6 +2496,35 @@ func validateCreateScanFlags(cmd *cobra.Command) error { return nil } +func validateThresholds(thresholdMap map[string]int) error { + var errMsgBuilder strings.Builder + + for engineName, limit := range thresholdMap { + if limit < 1 { + errMsgBuilder.WriteString(errors.Errorf("Invalid value for threshold limit %s. Threshold should be greater or equal to 1.\n", engineName).Error()) + } + } + + errMsg := errMsgBuilder.String() + if errMsg != "" { + return errors.New(errMsg) + } + return nil +} + +func parseThresholdLimit(limit string) (engineName string, intLimit int, err error) { + parts := strings.Split(limit, "=") + engineName = strings.Replace(parts[0], commonParams.KicsType, commonParams.IacType, 1) + if len(parts) <= 1 { + return engineName, 0, errors.Errorf("Error parsing threshold limit: missing values\n") + } + intLimit, err = strconv.Atoi(parts[1]) + if err != nil { + err = errors.Errorf("%s: Error parsing threshold limit: %v\n", engineName, err) + } + return engineName, intLimit, err +} + func validateBooleanString(value string) error { if value == "" { return nil diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index da25cc89f..cf553b3fc 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -678,3 +678,88 @@ func TestCreateScanProjectTagsCheckResendToScan(t *testing.T) { err := executeTestCommand(cmd, baseArgs...) assert.NilError(t, err) } + +func Test_parseThresholdLimit(t *testing.T) { + type args struct { + limit string + } + tests := []struct { + name string + args args + wantEngineName string + wantIntLimit int + wantErr bool + }{ + { + name: "Test parseThresholdLimit with valid limit Success", + args: args{limit: "sast-low=1"}, + wantEngineName: "sast-low", + wantIntLimit: 1, + wantErr: false, + }, + { + name: "Test parseThresholdLimit with invalid limit Fail", + args: args{limit: "kics-medium=error"}, + wantEngineName: "iac-security-medium", + wantIntLimit: 0, + wantErr: true, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + gotEngineName, gotIntLimit, err := parseThresholdLimit(tt.args.limit) + if (err != nil) != tt.wantErr { + t.Errorf("parseThresholdLimit() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotEngineName != tt.wantEngineName { + t.Errorf("parseThresholdLimit() gotEngineName = %v, want %v", gotEngineName, tt.wantEngineName) + } + if gotIntLimit != tt.wantIntLimit { + t.Errorf("parseThresholdLimit() gotIntLimit = %v, want %v", gotIntLimit, tt.wantIntLimit) + } + }) + } +} + +func Test_validateThresholds(t *testing.T) { + tests := []struct { + name string + thresholdMap map[string]int + wantErr bool + }{ + { + name: "Valid Thresholds", + thresholdMap: map[string]int{ + "sast-medium": 5, + "sast-high": 10, + }, + wantErr: false, + }, + { + name: "Invalid Threshold - Negative Limit", + thresholdMap: map[string]int{ + "sca-medium": -3, + }, + wantErr: true, + }, + { + name: "Invalid Threshold - Zero Limit", + thresholdMap: map[string]int{ + "sca-high": 0, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + err := validateThresholds(tt.thresholdMap) + if (err != nil) != tt.wantErr { + t.Errorf("validateThresholds() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From 17c94956a840639b01300e19b26c1aad4169f95a Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Tue, 30 Apr 2024 12:27:15 +0300 Subject: [PATCH 47/60] Project Application association Issue - Workaround - AST-40286 (#714) * SAP Application association Issue - Workaround * SAP Application association Issue - Workaround * Change Group Logic * Update wait to polling application * lint * lint * Update test * Update test --- go.sum | 1 + internal/commands/groups.go | 2 +- internal/commands/project.go | 26 ++++---- internal/commands/scan.go | 107 +++++++++++++++++++++++++++------ internal/commands/scan_test.go | 4 +- 5 files changed, 104 insertions(+), 36 deletions(-) diff --git a/go.sum b/go.sum index ff06ec542..a13052d1f 100644 --- a/go.sum +++ b/go.sum @@ -85,6 +85,7 @@ golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= diff --git a/internal/commands/groups.go b/internal/commands/groups.go index 67dfd24c0..74d82ccfb 100644 --- a/internal/commands/groups.go +++ b/internal/commands/groups.go @@ -74,7 +74,7 @@ func getGroupIds(groups []*wrappers.Group) []string { return groupIds } -func assignGroupsToProject(projectID string, projectName string, groups []*wrappers.Group, +func assignGroupsToProjectNewAccessManagement(projectID string, projectName string, groups []*wrappers.Group, accessManagement wrappers.AccessManagementWrapper) error { if !wrappers.FeatureFlags[accessManagementEnabled] { return nil diff --git a/internal/commands/project.go b/internal/commands/project.go index d95638499..fba5ed9c2 100644 --- a/internal/commands/project.go +++ b/internal/commands/project.go @@ -22,18 +22,18 @@ import ( ) const ( - failedCreatingProj = "Failed creating a project" - failedUpdatingProj = "Failed updating a project" - - failedGettingProj = "Failed getting a project" - failedDeletingProj = "Failed deleting a project" - failedGettingBranches = "Failed getting branches for project" - failedFindingGroup = "Failed finding groups" - projOriginLevel = "Project" - repoConfKey = "scan.handler.git.repository" - sshConfKey = "scan.handler.git.sshKey" - mandatoryRepoURLError = "flag --repo-url is mandatory when --ssh-key is provided" - invalidRepoURL = "provided repository url doesn't need a key. Make sure you are defining the right repository or remove the flag --ssh-key" + failedCreatingProj = "Failed creating a project" + failedUpdatingProj = "Failed updating a project" + failedProjectApplicationAssociation = "Failed association project to application" + failedGettingProj = "Failed getting a project" + failedDeletingProj = "Failed deleting a project" + failedGettingBranches = "Failed getting branches for project" + failedFindingGroup = "Failed finding groups" + projOriginLevel = "Project" + repoConfKey = "scan.handler.git.repository" + sshConfKey = "scan.handler.git.sshKey" + mandatoryRepoURLError = "flag --repo-url is mandatory when --ssh-key is provided" + invalidRepoURL = "provided repository url doesn't need a key. Make sure you are defining the right repository or remove the flag --ssh-key" ) var ( @@ -291,7 +291,7 @@ func runCreateProjectCommand( return errors.Wrapf(err, "%s", failedCreatingProj) } } - err = assignGroupsToProject(projResponseModel.ID, projResponseModel.Name, groups, accessManagementWrapper) + err = assignGroupsToProjectNewAccessManagement(projResponseModel.ID, projResponseModel.Name, groups, accessManagementWrapper) if err != nil { return err } diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 23ce2355a..c3faf073a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -14,6 +14,7 @@ import ( "path" "path/filepath" "reflect" + "slices" "strconv" "strings" "time" @@ -603,6 +604,7 @@ func findProject( projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, + applicationWrapper wrappers.ApplicationsWrapper, ) (string, error) { params := make(map[string]string) params["names"] = projectName @@ -613,10 +615,10 @@ func findProject( for i := 0; i < len(resp.Projects); i++ { if resp.Projects[i].Name == projectName { - return updateProject(resp, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, projectName, applicationID) + return updateProject(resp, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationWrapper, projectName, applicationID) } } - projectID, err := createProject(projectName, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationID) + projectID, err := createProject(projectName, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationWrapper, applicationID) if err != nil { return "", err } @@ -629,18 +631,15 @@ func createProject( projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, + applicationsWrapper wrappers.ApplicationsWrapper, applicationID []string, ) (string, error) { projectGroups, _ := cmd.Flags().GetString(commonParams.ProjectGroupList) projectTags, _ := cmd.Flags().GetString(commonParams.ProjectTagList) projectPrivatePackage, _ := cmd.Flags().GetString(commonParams.ProjecPrivatePackageFlag) - groupsMap, err := createGroupsMap(projectGroups, groupsWrapper) - if err != nil { - return "", err - } + var projModel = wrappers.Project{} projModel.Name = projectName - projModel.Groups = getGroupsForRequest(groupsMap) projModel.ApplicationIds = applicationID if projectPrivatePackage != "" { @@ -654,17 +653,54 @@ func createProject( } if err == nil { projectID = resp.ID - err = assignGroupsToProject(projectID, projectName, groupsMap, accessManagementWrapper) + + if len(applicationID) > 0 { + err = verifyApplicationAssociationDone(applicationID, projectID, applicationsWrapper) + if err != nil { + return projectID, err + } + } + + if projectGroups != "" { + err = UpsertProjectGroups(groupsWrapper, &projModel, projectsWrapper, accessManagementWrapper, nil, projectGroups, projectID, projectName) + if err != nil { + return projectID, err + } + } } return projectID, err } +func verifyApplicationAssociationDone(applicationID []string, projectID string, applicationsWrapper wrappers.ApplicationsWrapper) error { + var applicationRes *wrappers.ApplicationsResponseModel + var err error + params := make(map[string]string) + params["id"] = applicationID[0] + + logger.PrintIfVerbose("polling application until project association done or timeout of 2 min") + start := time.Now() + timeout := 2 * time.Minute + for applicationRes != nil && len(applicationRes.Applications) > 0 && + !slices.Contains(applicationRes.Applications[0].ProjectIds, projectID) { + applicationRes, err = applicationsWrapper.Get(params) + if err != nil { + return err + } else if time.Since(start) < timeout { + return errors.Errorf("%s: %v", failedProjectApplicationAssociation, "timeout of 2 min for association") + } + } + + logger.PrintIfVerbose("application association done successfully") + return nil +} + func updateProject( resp *wrappers.ProjectsCollectionResponseModel, cmd *cobra.Command, projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, + applicationsWrapper wrappers.ApplicationsWrapper, projectName string, applicationID []string, @@ -703,18 +739,7 @@ func updateProject( projModel.Groups = projModelResp.Groups projModel.Tags = projModelResp.Tags projModel.ApplicationIds = projModelResp.ApplicationIds - if projectGroups != "" { - groupsMap, groupErr := createGroupsMap(projectGroups, groupsWrapper) - if groupErr != nil { - return "", errors.Errorf("%s: %v", failedUpdatingProj, groupErr) - } - logger.PrintIfVerbose("Updating project groups") - projModel.Groups = getGroupsForRequest(groupsMap) - err = assignGroupsToProject(projectID, projectName, groupsMap, accessManagementWrapper) - if err != nil { - return "", err - } - } + if projectTags != "" { logger.PrintIfVerbose("Updating project tags") projModel.Tags = createTagMap(projectTags) @@ -727,9 +752,50 @@ func updateProject( if err != nil { return "", errors.Errorf("%s: %v", failedUpdatingProj, err) } + + if len(applicationID) > 0 { + err = verifyApplicationAssociationDone(applicationID, projectID, applicationsWrapper) + if err != nil { + return projectID, err + } + } + + if projectGroups != "" { + err = UpsertProjectGroups(groupsWrapper, &projModel, projectsWrapper, accessManagementWrapper, projModelResp, projectGroups, projectID, projectName) + if err != nil { + return projectID, err + } + } return projectID, nil } +func UpsertProjectGroups(groupsWrapper wrappers.GroupsWrapper, projModel *wrappers.Project, projectsWrapper wrappers.ProjectsWrapper, + accessManagementWrapper wrappers.AccessManagementWrapper, projModelResp *wrappers.ProjectResponseModel, + projectGroups string, projectID string, projectName string) error { + groupsMap, groupErr := createGroupsMap(projectGroups, groupsWrapper) + if groupErr != nil { + return errors.Errorf("%s: %v", failedUpdatingProj, groupErr) + } + + projModel.Groups = getGroupsForRequest(groupsMap) + if projModelResp != nil { + groups := append(getGroupsForRequest(groupsMap), projModelResp.Groups...) + projModel.Groups = groups + } + + err := assignGroupsToProjectNewAccessManagement(projectID, projectName, groupsMap, accessManagementWrapper) + if err != nil { + return err + } + + logger.PrintIfVerbose("Updating project groups") + err = projectsWrapper.Update(projectID, projModel) + if err != nil { + return errors.Errorf("%s: %v", failedUpdatingProj, err) + } + return nil +} + func createApplicationIds(applicationID, existingApplicationIds []string) []string { for _, id := range applicationID { if !util.Contains(existingApplicationIds, id) { @@ -828,6 +894,7 @@ func setupScanTypeProjectAndConfig( projectsWrapper, groupsWrapper, accessManagementWrapper, + applicationsWrapper, ) if findProjectErr != nil { return findProjectErr diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index cf553b3fc..6e0f569a2 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -282,9 +282,9 @@ func TestCreateScanBranches(t *testing.T) { func TestCreateScanWithProjectGroup(t *testing.T) { err := execCmdNotNilAssertion( t, - "scan", "create", "--project-name", "invalidGroup", "-s", ".", "--project-groups", "invalidGroup", + "scan", "create", "--project-name", "invalidGroup", "-s", ".", "--branch", "main", "--project-groups", "invalidGroup", ) - assert.Assert(t, err.Error() == "Failed finding groups: [invalidGroup]", "\n the received error is:", err.Error()) + assert.Assert(t, err.Error() == "Failed updating a project: Failed finding groups: [invalidGroup]", "\n the received error is:", err.Error()) } func TestScanWorkflowMissingID(t *testing.T) { From 25bf4f5930d6f608c44feb83565a7a2e5a902f4e Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Tue, 30 Apr 2024 13:33:17 +0300 Subject: [PATCH 48/60] Update release.yml --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 436bf46ab..a10c4a6e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,6 +66,7 @@ jobs: if: inputs.dev == false run: | brew install docker + brew install colima colima start sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock - name: Test docker From e77409293449e1b018d6d960a23804eaf97047bf Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:50:57 +0300 Subject: [PATCH 49/60] Update release.yml --- .github/workflows/release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a10c4a6e7..436bf46ab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,7 +66,6 @@ jobs: if: inputs.dev == false run: | brew install docker - brew install colima colima start sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock - name: Test docker From 87dd309404b9c80658dbc36b1594683edf45500f Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 1 May 2024 11:55:00 +0300 Subject: [PATCH 50/60] Add Makefile --- Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..d1db47d8d --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +.DEFAULT_GOAL := vet + +.PHONY:fmt vet build lint +fmt: + go fmt ./... +vet: fmt + go vet ./... +build: vet + go build -o bin/cx.exe ./cmd +lint: fmt + golangci-lint run -c .golangci.yml \ No newline at end of file From a34356c8411234c69e87b4e33878b34c21188821 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 1 May 2024 13:04:35 +0300 Subject: [PATCH 51/60] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index a0473197b..dd0ea18d0 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,15 @@ export GOOS=darwin export GOARCH=amd64 go build -o ./bin/cx-mac ./cmd ``` +### Makefile +For ease of use, a Makefile is provided to build the project for all platforms. + +Install Make for Mac: https://formulae.brew.sh/formula/make + +Install Make for Windows: https://sourceforge.net/projects/gnuwin32/files/make/3.81/make-3.81.exe/download + +Run the following command to build the project: +``` make build ``` ## Contribution We appreciate feedback and contribution to the CLI! Before you get started, please see the following: From fbb9905c78a650d9ae3d32c53f10f08155d2fbfe Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Wed, 1 May 2024 18:41:28 +0300 Subject: [PATCH 52/60] go mod tidy --- go.mod | 4 +++- go.sum | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index d7e07d698..938d126de 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 + github.com/stretchr/testify v1.9.0 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 golang.org/x/crypto v0.22.0 golang.org/x/text v0.14.0 @@ -21,6 +22,7 @@ require ( ) require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -28,13 +30,13 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.uber.org/atomic v1.9.0 // indirect diff --git a/go.sum b/go.sum index 4d6ca44d0..71fbc614c 100644 --- a/go.sum +++ b/go.sum @@ -86,7 +86,6 @@ golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= From 866ff10f43b86c582d0cb3df5fb506ac344b7391 Mon Sep 17 00:00:00 2001 From: checkmarx-kobi-hagmi Date: Thu, 2 May 2024 10:36:32 +0300 Subject: [PATCH 53/60] fixed unit tests. removed unused code --- internal/commands/result_test.go | 14 ++++- internal/wrappers/mock/results-mock.go | 85 -------------------------- internal/wrappers/results-http.go | 42 ------------- internal/wrappers/results.go | 1 - 4 files changed, 12 insertions(+), 130 deletions(-) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 140f15208..ba4791b66 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -55,14 +55,18 @@ func TestResultsExitCode_OnFailedKicsScanner_PrintCorrectFailedScannerInfoToCons Details: "error message from kics scanner", ErrorCode: 1234, }, + {Status: wrappers.ScanFailed, Name: "general", Details: "timeout", ErrorCode: 1234}, }, } results := getScannerResponse("", &model) - assert.Equal(t, len(results), 1, "Scanner results should be empty") + assert.Equal(t, len(results), 2, "Scanner results should be empty") assert.Equal(t, results[0].Name, "kics", "") assert.Equal(t, results[0].ErrorCode, "1234", "") + assert.Equal(t, results[1].Name, "general", "") + assert.Equal(t, results[1].ErrorCode, "1234", "") + assert.Equal(t, results[1].Details, "timeout", "") } func TestResultsExitCode_OnFailedKicsAndScaScanners_PrintCorrectFailedScannersInfoToConsole(t *testing.T) { @@ -72,16 +76,20 @@ func TestResultsExitCode_OnFailedKicsAndScaScanners_PrintCorrectFailedScannersIn StatusDetails: []wrappers.StatusInfo{ {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 2344}, {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, + {Status: wrappers.ScanFailed, Name: "general", Details: "timeout", ErrorCode: 1234}, }, } results := getScannerResponse("", &model) - assert.Equal(t, len(results), 2, "Scanner results should be empty") + assert.Equal(t, len(results), 3, "Scanner results should be empty") assert.Equal(t, results[0].Name, "kics", "") assert.Equal(t, results[0].ErrorCode, "2344", "") assert.Equal(t, results[1].Name, "sca", "") assert.Equal(t, results[1].ErrorCode, "4343", "") + assert.Equal(t, results[2].Name, "general", "") + assert.Equal(t, results[2].ErrorCode, "1234", "") + assert.Equal(t, results[2].Details, "timeout", "") } func TestResultsExitCode_OnRequestedFailedScanner_PrintCorrectFailedScannerInfoToConsole(t *testing.T) { @@ -91,6 +99,7 @@ func TestResultsExitCode_OnRequestedFailedScanner_PrintCorrectFailedScannerInfoT StatusDetails: []wrappers.StatusInfo{ {Status: wrappers.ScanFailed, Name: "kics", Details: "error message from kics scanner", ErrorCode: 2344}, {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, + {Status: wrappers.ScanFailed, Name: "general", Details: "timeout", ErrorCode: 1234}, }, } @@ -108,6 +117,7 @@ func TestResultsExitCode_OnPartialScan_PrintOnlyFailedScannersInfoToConsole(t *t StatusDetails: []wrappers.StatusInfo{ {Status: wrappers.ScanCompleted, Name: "sast"}, {Status: wrappers.ScanFailed, Name: "sca", Details: "error message from sca scanner", ErrorCode: 4343}, + {Status: wrappers.ScanCompleted, Name: "general"}, }, } diff --git a/internal/wrappers/mock/results-mock.go b/internal/wrappers/mock/results-mock.go index 731b65d0b..61884bdf3 100644 --- a/internal/wrappers/mock/results-mock.go +++ b/internal/wrappers/mock/results-mock.go @@ -215,88 +215,3 @@ func (r ResultsMockWrapper) GetAllResultsByScanID(_ map[string]string) ( func (r ResultsMockWrapper) GetResultsURL(projectID string) (string, error) { return fmt.Sprintf("projects/%s/overview", projectID), nil } - -func (r ResultsMockWrapper) GetScanSummariesByScanIDS(params map[string]string) (*wrappers.ScanSummariesModel, *wrappers.WebError, error) { - if params["scan-ids"] == "MOCKWEBERR" { - return nil, &wrappers.WebError{ - Message: "web error", - }, nil - } - if params["scan-ids"] == "MOCKERR" { - return nil, nil, fmt.Errorf("mock error") - } - return &wrappers.ScanSummariesModel{ - ScansSummaries: []wrappers.ScanSumaries{ - { - SastCounters: wrappers.SastCounters{ - SeverityCounters: []wrappers.SeverityCounters{ - { - Severity: "info", - Counter: 1, - }, - { - Severity: "low", - Counter: 1, - }, - { - Severity: "medium", - Counter: 1, - }, - { - Severity: "high", - Counter: 1, - }, - }, - TotalCounter: 4, - FilesScannedCounter: 1, - }, - KicsCounters: wrappers.KicsCounters{ - SeverityCounters: []wrappers.SeverityCounters{ - { - Severity: "info", - Counter: 1, - }, - { - Severity: "low", - Counter: 1, - }, - { - Severity: "medium", - Counter: 1, - }, - { - Severity: "high", - Counter: 1, - }, - }, - - TotalCounter: 4, - FilesScannedCounter: 1, - }, - ScaCounters: wrappers.ScaCounters{ - SeverityCounters: []wrappers.SeverityCounters{ - { - Severity: "info", - Counter: 1, - }, - { - Severity: "low", - Counter: 1, - }, - { - Severity: "medium", - Counter: 1, - }, - { - Severity: "high", - Counter: 1, - }, - }, - - TotalCounter: 4, - FilesScannedCounter: 1, - }, - }, - }, - }, nil, nil -} diff --git a/internal/wrappers/results-http.go b/internal/wrappers/results-http.go index 116beddb7..32b8cd5c8 100644 --- a/internal/wrappers/results-http.go +++ b/internal/wrappers/results-http.go @@ -235,48 +235,6 @@ func (r *ResultsHTTPWrapper) GetResultsURL(projectID string) (string, error) { return baseURI, nil } -// GetScanSummariesByScanIDS will no longer be used because it does not support --filters flag -func (r *ResultsHTTPWrapper) GetScanSummariesByScanIDS(params map[string]string) ( - *ScanSummariesModel, - *WebError, - error, -) { - clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey) - - resp, err := SendPrivateHTTPRequestWithQueryParams(http.MethodGet, r.scanSummaryPath, params, http.NoBody, clientTimeout) - if err != nil { - return nil, nil, err - } - - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() - - decoder := json.NewDecoder(resp.Body) - - switch resp.StatusCode { - case http.StatusBadRequest, http.StatusInternalServerError: - errorModel := WebError{} - err = decoder.Decode(&errorModel) - if err != nil { - return nil, nil, errors.Wrapf(err, failedTogetScanSummaries) - } - return nil, &errorModel, nil - case http.StatusOK: - model := ScanSummariesModel{} - err = decoder.Decode(&model) - if err != nil { - return nil, nil, errors.Wrapf(err, failedToParseScanSummaries) - } - - return &model, nil, nil - default: - return nil, nil, errors.Errorf(respStatusCode, resp.StatusCode) - } -} - func DefaultMapValue(params map[string]string, key, value string) { if _, ok := params[key]; !ok { params[key] = value diff --git a/internal/wrappers/results.go b/internal/wrappers/results.go index c90664fb4..5aae15c85 100644 --- a/internal/wrappers/results.go +++ b/internal/wrappers/results.go @@ -2,7 +2,6 @@ package wrappers type ResultsWrapper interface { GetAllResultsByScanID(params map[string]string) (*ScanResultsCollection, *WebError, error) - GetScanSummariesByScanIDS(params map[string]string) (*ScanSummariesModel, *WebError, error) GetAllResultsPackageByScanID(params map[string]string) (*[]ScaPackageCollection, *WebError, error) GetAllResultsTypeByScanID(params map[string]string) (*[]ScaTypeCollection, *WebError, error) GetResultsURL(projectID string) (string, error) From 2ae7aabba5462b4df5030698e8ad370fea6a507b Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Thu, 2 May 2024 17:17:43 +0300 Subject: [PATCH 54/60] Revert "Add Makefile" (#720) --- Makefile | 11 ----------- README.md | 9 --------- 2 files changed, 20 deletions(-) delete mode 100644 Makefile diff --git a/Makefile b/Makefile deleted file mode 100644 index d1db47d8d..000000000 --- a/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -.DEFAULT_GOAL := vet - -.PHONY:fmt vet build lint -fmt: - go fmt ./... -vet: fmt - go vet ./... -build: vet - go build -o bin/cx.exe ./cmd -lint: fmt - golangci-lint run -c .golangci.yml \ No newline at end of file diff --git a/README.md b/README.md index dd0ea18d0..a0473197b 100644 --- a/README.md +++ b/README.md @@ -91,15 +91,6 @@ export GOOS=darwin export GOARCH=amd64 go build -o ./bin/cx-mac ./cmd ``` -### Makefile -For ease of use, a Makefile is provided to build the project for all platforms. - -Install Make for Mac: https://formulae.brew.sh/formula/make - -Install Make for Windows: https://sourceforge.net/projects/gnuwin32/files/make/3.81/make-3.81.exe/download - -Run the following command to build the project: -``` make build ``` ## Contribution We appreciate feedback and contribution to the CLI! Before you get started, please see the following: From 48f82c321b972388cb2d795ab1713d19f08f9eda Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Thu, 2 May 2024 17:24:11 +0300 Subject: [PATCH 55/60] Revert "Revert "Add Makefile" (#720)" (#721) This reverts commit 2ae7aabba5462b4df5030698e8ad370fea6a507b. --- Makefile | 11 +++++++++++ README.md | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..d1db47d8d --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +.DEFAULT_GOAL := vet + +.PHONY:fmt vet build lint +fmt: + go fmt ./... +vet: fmt + go vet ./... +build: vet + go build -o bin/cx.exe ./cmd +lint: fmt + golangci-lint run -c .golangci.yml \ No newline at end of file diff --git a/README.md b/README.md index a0473197b..dd0ea18d0 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,15 @@ export GOOS=darwin export GOARCH=amd64 go build -o ./bin/cx-mac ./cmd ``` +### Makefile +For ease of use, a Makefile is provided to build the project for all platforms. + +Install Make for Mac: https://formulae.brew.sh/formula/make + +Install Make for Windows: https://sourceforge.net/projects/gnuwin32/files/make/3.81/make-3.81.exe/download + +Run the following command to build the project: +``` make build ``` ## Contribution We appreciate feedback and contribution to the CLI! Before you get started, please see the following: From bd5d6582ddb8a17cc602c55e1aaf2eb32d5c74ac Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Thu, 2 May 2024 17:51:45 +0300 Subject: [PATCH 56/60] Try release (#722) * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * Update release.yml * Update release.yml * Update release.yml * Update release.yml * Update release.yml --------- Co-authored-by: tamarleviCm --- .github/workflows/release.yml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 436bf46ab..dff06176a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,7 +30,7 @@ permissions: jobs: build: - runs-on: macos-latest + runs-on: macos-13 env: AC_PASSWORD: ${{ secrets.AC_PASSWORD }} APPLE_DEVELOPER_CERTIFICATE_P12_BASE64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} @@ -60,19 +60,9 @@ jobs: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew --version - name: Install gon - run: | - brew install Bearer/tap/gon - - name: Install and start docker - if: inputs.dev == false - run: | - brew install docker - colima start - sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock - - name: Test docker - if: inputs.dev == false - run: | - docker version - docker info + run: brew install Bearer/tap/gon + - name: install docker + run: brew install docker - name: Login to Docker Hub if: inputs.dev == false uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 #v1 From f6fde8f556967d8b30ef8ab9896df30a2bfa9be2 Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Sun, 5 May 2024 12:19:30 +0300 Subject: [PATCH 57/60] Update The Release to work with VM for Docker - AST-42234 (#724) * Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update release.yml * Add Makefile * Update README.md * brew services start docker * remove flag --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: checkmarx-kobi-hagmi Co-authored-by: Noam Brendel --- .github/workflows/release.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dff06176a..dbe195a73 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,9 +60,16 @@ jobs: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew --version - name: Install gon - run: brew install Bearer/tap/gon - - name: install docker - run: brew install docker + run: | + brew install Bearer/tap/gon + - name: Setup Docker on macOS + if: inputs.dev == false + uses: douglascamata/setup-docker-macos-action@v1-alpha + - name: Test docker + if: inputs.dev == false + run: | + docker version + docker info - name: Login to Docker Hub if: inputs.dev == false uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 #v1 From 2ce9a81de0c572b7509fd0d9bdbaa2003abb5988 Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Sun, 5 May 2024 13:41:22 +0300 Subject: [PATCH 58/60] Fix project association polling issue (AST-40286) (#723) * Fix project association polling issue (AST-40286) * Update integration tests timeout to have more 2 min for polling logic * Add sleep 2 sec between polling * Fix application API * fix lint, have sleep for 1 sec * have longer timeout for tests (+2 min) * have longer timeout for tests (+4 min) * return error if timeout * fix application mock --- internal/commands/.scripts/integration_up.sh | 2 +- internal/commands/.scripts/up.sh | 2 +- internal/commands/scan.go | 37 +++++++++++++------- internal/wrappers/client.go | 1 + internal/wrappers/mock/application-mock.go | 2 +- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/internal/commands/.scripts/integration_up.sh b/internal/commands/.scripts/integration_up.sh index 7b16af05d..4193aa92d 100755 --- a/internal/commands/.scripts/integration_up.sh +++ b/internal/commands/.scripts/integration_up.sh @@ -13,7 +13,7 @@ rm -rf ScaResolver-linux64.tar.gz go test \ -tags integration \ -v \ - -timeout 90m \ + -timeout 210m \ -coverpkg github.com/checkmarx/ast-cli/internal/commands,github.com/checkmarx/ast-cli/internal/wrappers \ -coverprofile cover.out \ github.com/checkmarx/ast-cli/test/integration diff --git a/internal/commands/.scripts/up.sh b/internal/commands/.scripts/up.sh index 85ac378ca..76a800b44 100755 --- a/internal/commands/.scripts/up.sh +++ b/internal/commands/.scripts/up.sh @@ -4,4 +4,4 @@ wget https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-linux64.tar.g tar -xzvf ScaResolver-linux64.tar.gz -C /tmp rm -rf ScaResolver-linux64.tar.gz # ignore mock and wrappers packages, as they checked by integration tests -go test $(go list ./... | grep -v "mock" | grep -v "wrappers" | grep -v "bitbucketserver" | grep -v "logger") -coverprofile cover.out +go test $(go list ./... | grep -v "mock" | grep -v "wrappers" | grep -v "bitbucketserver" | grep -v "logger") -timeout 940.000s -coverprofile cover.out diff --git a/internal/commands/scan.go b/internal/commands/scan.go index c3faf073a..02b6d0530 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -620,6 +620,7 @@ func findProject( } projectID, err := createProject(projectName, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationWrapper, applicationID) if err != nil { + logger.PrintIfVerbose("error in creating project!") return "", err } return projectID, nil @@ -635,6 +636,7 @@ func createProject( applicationID []string, ) (string, error) { projectGroups, _ := cmd.Flags().GetString(commonParams.ProjectGroupList) + applicationName, _ := cmd.Flags().GetString(commonParams.ApplicationName) projectTags, _ := cmd.Flags().GetString(commonParams.ProjectTagList) projectPrivatePackage, _ := cmd.Flags().GetString(commonParams.ProjecPrivatePackageFlag) @@ -646,7 +648,9 @@ func createProject( projModel.PrivatePackage, _ = strconv.ParseBool(projectPrivatePackage) } projModel.Tags = createTagMap(projectTags) + logger.PrintIfVerbose("Creating new project") resp, errorModel, err := projectsWrapper.Create(&projModel) + projectID := "" if errorModel != nil { err = errors.Errorf(ErrorCodeFormat, failedCreatingProj, errorModel.Code, errorModel.Message) @@ -654,8 +658,8 @@ func createProject( if err == nil { projectID = resp.ID - if len(applicationID) > 0 { - err = verifyApplicationAssociationDone(applicationID, projectID, applicationsWrapper) + if applicationName != "" || len(applicationID) > 0 { + err = verifyApplicationAssociationDone(applicationName, projectID, applicationsWrapper) if err != nil { return projectID, err } @@ -671,27 +675,31 @@ func createProject( return projectID, err } -func verifyApplicationAssociationDone(applicationID []string, projectID string, applicationsWrapper wrappers.ApplicationsWrapper) error { +func verifyApplicationAssociationDone(applicationName, projectID string, applicationsWrapper wrappers.ApplicationsWrapper) error { var applicationRes *wrappers.ApplicationsResponseModel var err error params := make(map[string]string) - params["id"] = applicationID[0] + params["name"] = applicationName logger.PrintIfVerbose("polling application until project association done or timeout of 2 min") - start := time.Now() - timeout := 2 * time.Minute - for applicationRes != nil && len(applicationRes.Applications) > 0 && - !slices.Contains(applicationRes.Applications[0].ProjectIds, projectID) { + var timeoutDuration = 2 * time.Minute + timeout := time.Now().Add(timeoutDuration) + for time.Now().Before(timeout) { applicationRes, err = applicationsWrapper.Get(params) if err != nil { return err - } else if time.Since(start) < timeout { + } else if applicationRes != nil && len(applicationRes.Applications) > 0 && + slices.Contains(applicationRes.Applications[0].ProjectIds, projectID) { + logger.PrintIfVerbose("application association done successfully") + return nil + } else if time.Now().After(timeout) { return errors.Errorf("%s: %v", failedProjectApplicationAssociation, "timeout of 2 min for association") } + time.Sleep(time.Second) + logger.PrintIfVerbose("application association polling - waiting for associating to complete") } - logger.PrintIfVerbose("application association done successfully") - return nil + return errors.Errorf("%s: %v", failedProjectApplicationAssociation, "timeout of 2 min for association") } func updateProject( @@ -709,6 +717,7 @@ func updateProject( var projModel = wrappers.Project{} projectGroups, _ := cmd.Flags().GetString(commonParams.ProjectGroupList) projectTags, _ := cmd.Flags().GetString(commonParams.ProjectTagList) + applicationName, _ := cmd.Flags().GetString(commonParams.ApplicationName) projectPrivatePackage, _ := cmd.Flags().GetString(commonParams.ProjecPrivatePackageFlag) for i := 0; i < len(resp.Projects); i++ { if resp.Projects[i].Name == projectName { @@ -728,6 +737,8 @@ func updateProject( if projectPrivatePackage != "" { projModel.PrivatePackage, _ = strconv.ParseBool(projectPrivatePackage) } + + logger.PrintIfVerbose("Fetching existing Project for updating") projModelResp, errModel, err := projectsWrapper.GetByID(projectID) if errModel != nil { err = errors.Errorf(ErrorCodeFormat, failedGettingProj, errModel.Code, errModel.Message) @@ -753,8 +764,8 @@ func updateProject( return "", errors.Errorf("%s: %v", failedUpdatingProj, err) } - if len(applicationID) > 0 { - err = verifyApplicationAssociationDone(applicationID, projectID, applicationsWrapper) + if applicationName != "" || len(applicationID) > 0 { + err = verifyApplicationAssociationDone(applicationName, projectID, applicationsWrapper) if err != nil { return projectID, err } diff --git a/internal/wrappers/client.go b/internal/wrappers/client.go index 724d3d4cf..80120f304 100644 --- a/internal/wrappers/client.go +++ b/internal/wrappers/client.go @@ -447,6 +447,7 @@ func getClientCredentials(accessKeyID, accessKeySecret, astAPKey, authURI string func getClientCredentialsFromCache(tokenExpirySeconds int) string { logger.PrintIfVerbose("Checking cache for API access token.") + expired := time.Since(cachedAccessTime) > time.Duration(tokenExpirySeconds-expiryGraceSeconds)*time.Second if !expired { logger.PrintIfVerbose("Using cached API access token!") diff --git a/internal/wrappers/mock/application-mock.go b/internal/wrappers/mock/application-mock.go index dce914bc7..33c7f70fa 100644 --- a/internal/wrappers/mock/application-mock.go +++ b/internal/wrappers/mock/application-mock.go @@ -28,7 +28,7 @@ func (a ApplicationsMockWrapper) Get(params map[string]string) (*wrappers.Applic Name: "MOCK", Description: "This is a mock application", Criticality: 2, - ProjectIds: []string{"ProjectID1", "ProjectID2"}, + ProjectIds: []string{"ProjectID1", "ProjectID2", "MOCK"}, CreatedAt: time.Now(), } From 72e939030eafd9ed0338ffb18c55f996411ef271 Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Sun, 5 May 2024 14:09:09 +0300 Subject: [PATCH 59/60] update .gitignore (#727) remove path Co-authored-by: Noam Brendel --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 628b8837c..ef37eb5d7 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,8 @@ override.tf.json # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan # example: *tfplan*dist/ -/dist \ No newline at end of file +/dist + +# Ignore CLI configuration files and installation log files +**/colima-Darwin-x86_64 +**/install.log \ No newline at end of file From 5d6555477b4fe7897a4c2507b8a697b13ec81d5a Mon Sep 17 00:00:00 2001 From: Or Shamir Checkmarx <93518641+OrShamirCM@users.noreply.github.com> Date: Sun, 5 May 2024 14:20:52 +0300 Subject: [PATCH 60/60] FIx Unit Tests Timeout (#726) * Fix project association polling issue (AST-40286) * Update integration tests timeout to have more 2 min for polling logic * Add sleep 2 sec between polling * Fix application API * fix lint, have sleep for 1 sec * have longer timeout for tests (+2 min) * have longer timeout for tests (+4 min) * return error if timeout * fix application mock * delete duplicate test * open pr --------- Co-authored-by: tamarleviCm --- internal/commands/scan_test.go | 4 ---- internal/wrappers/mock/application-mock.go | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 6e0f569a2..081b4b20b 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -138,10 +138,6 @@ func TestScanCreate_ExistingProjectAndApplicationWithNoPermission_FailedToCreate assert.Assert(t, err.Error() == applicationErrors.ApplicationDoesntExistOrNoPermission) } -func TestScanCreate_ExistingApplication_CreateNewProjectUnderApplicationSuccessfully(t *testing.T) { - execCmdNilAssertion(t, "scan", "create", "--project-name", "NewProject", "--application-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") -} - func TestScanCreate_ExistingApplicationWithNoPermission_FailedToCreateScan(t *testing.T) { err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "NewProject", "--application-name", mock.NoPermissionApp, "-s", dummyRepo, "-b", "dummy_branch") assert.Assert(t, err.Error() == applicationErrors.ApplicationDoesntExistOrNoPermission) diff --git a/internal/wrappers/mock/application-mock.go b/internal/wrappers/mock/application-mock.go index 33c7f70fa..18db0e35a 100644 --- a/internal/wrappers/mock/application-mock.go +++ b/internal/wrappers/mock/application-mock.go @@ -28,7 +28,7 @@ func (a ApplicationsMockWrapper) Get(params map[string]string) (*wrappers.Applic Name: "MOCK", Description: "This is a mock application", Criticality: 2, - ProjectIds: []string{"ProjectID1", "ProjectID2", "MOCK"}, + ProjectIds: []string{"ProjectID1", "ProjectID2", "MOCK", "test_project"}, CreatedAt: time.Now(), }