From efeaa274722d28f7c69ee0f9cecd840aa4092344 Mon Sep 17 00:00:00 2001 From: Alex Cohen Date: Wed, 29 Jan 2025 15:35:54 -0500 Subject: [PATCH 1/4] Remove ContainersEngineCLIEnabled Flag --- internal/commands/result.go | 8 ++--- internal/commands/result_test.go | 17 ---------- internal/commands/scan_test.go | 51 ++++++++++++------------------ internal/wrappers/feature-flags.go | 1 - test/integration/scan_test.go | 44 +++++++++----------------- 5 files changed, 38 insertions(+), 83 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 0e9cf1e9a..9bb62e8a3 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -1047,10 +1047,8 @@ func setIsSCSEnabled(featureFlagsWrapper wrappers.FeatureFlagsWrapper) { wrappers.IsSCSEnabled = scsEngineCLIEnabled.Status } -func setIsContainersEnabled(agent string, featureFlagsWrapper wrappers.FeatureFlagsWrapper) { - agentSupported := !containsIgnoreCase(containerEngineUnsupportedAgents, agent) - containerEngineCLIEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.ContainerEngineCLIEnabled) - wrappers.IsContainersEnabled = containerEngineCLIEnabled.Status && agentSupported +func setIsContainersEnabled(agent string) { + wrappers.IsContainersEnabled = !containsIgnoreCase(containerEngineUnsupportedAgents, agent) } func filterResultsByType(results *wrappers.ScanResultsCollection, excludedTypes map[string]struct{}) *wrappers.ScanResultsCollection { @@ -1109,7 +1107,7 @@ func CreateScanReport( reportList := strings.Split(reportTypes, ",") results := &wrappers.ScanResultsCollection{} setIsSCSEnabled(featureFlagsWrapper) - setIsContainersEnabled(agent, featureFlagsWrapper) + setIsContainersEnabled(agent) summary, err := convertScanToResultsSummary(scan, resultsWrapper) if err != nil { return nil, err diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 2257c8ecf..c3bdbe1ab 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -312,7 +312,6 @@ func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { } func TestRunGetResultsByScanIdSarifFormatWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sarif") // Remove generated sarif file removeFileBySuffix(t, printer.FormatSarif) @@ -334,7 +333,6 @@ func TestRunGetResultsByScanIdSonarFormat(t *testing.T) { func TestRunGetResultsByScanIdSonarFormatWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sonar") // Remove generated sonar file removeFile(t, fileName+"_"+printer.FormatSonar, printer.FormatJSON) @@ -367,7 +365,6 @@ func TestDecodeHTMLEntitiesInResults(t *testing.T) { func TestRunGetResultsByScanIdJsonFormatWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") // Remove generated json file @@ -390,7 +387,6 @@ func TestRunGetResultsByScanIdSummaryJsonFormat(t *testing.T) { func TestRunGetResultsByScanIdSummaryJsonFormatWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryJSON") // Remove generated json file @@ -406,7 +402,6 @@ func TestRunGetResultsByScanIdSummaryHtmlFormat(t *testing.T) { func TestRunGetResultsByScanIdSummaryHtmlFormatWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryHTML") // Remove generated html file @@ -425,13 +420,11 @@ func TestRunGetResultsByScanIdSummaryMarkdownFormatWithContainers(t *testing.T) func TestRunGetResultsByScanIdSummaryConsoleFormatWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryConsole") } func TestRunGetResultsByScanIdSummaryMarkdownFormat(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "markdown") // Remove generated md file removeFileBySuffix(t, "md") @@ -480,7 +473,6 @@ func TestRunGetResultsByScanIdPDFFormat(t *testing.T) { func TestRunGetResultsByScanIdPDFFormatWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "pdf") _, err := os.Stat(fmt.Sprintf("%s.%s", fileName, printer.FormatPDF)) assert.NilError(t, err, "Report file should exist for extension "+printer.FormatPDF) @@ -759,7 +751,6 @@ func TestSBOMReportXML(t *testing.T) { func TestSBOMReportJsonWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sbom") _, err := os.Stat(fmt.Sprintf("%s.%s", fileName+"_"+printer.FormatSbom, printer.FormatJSON)) assert.NilError(t, err, "Report file should exist for extension "+printer.FormatJSON) @@ -769,7 +760,6 @@ func TestSBOMReportJsonWithContainers(t *testing.T) { func TestSBOMReportXMLWithContainers(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sbom", "--report-sbom-format", "CycloneDxXml") _, err := os.Stat(fmt.Sprintf("%s.%s", fileName+"_"+printer.FormatSbom, printer.FormatXML)) assert.NilError(t, err, "Report file should exist for extension "+printer.FormatXML) @@ -785,7 +775,6 @@ func TestRunGetResultsByScanIdGLFormat(t *testing.T) { func TestRunResultsShow_ContainersFFIsOn_includeContainersResult(t *testing.T) { clearFlags() clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") assertTypePresentJSON(t, params.ContainersType, 1) // Remove generated json file @@ -793,7 +782,6 @@ func TestRunResultsShow_ContainersFFIsOn_includeContainersResult(t *testing.T) { } func TestRunResultsShow_ContainersFFIsOff_excludeContainersResult(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: false} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") assertTypePresentJSON(t, params.ContainersType, 0) // Remove generated json file @@ -801,7 +789,6 @@ func TestRunResultsShow_ContainersFFIsOff_excludeContainersResult(t *testing.T) } func TestRunResultsShow_jetbrainsIsNotSupported_excludeContainersResult(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "jetbrains") assertTypePresentJSON(t, params.ContainersType, 0) // Remove generated json file @@ -810,7 +797,6 @@ func TestRunResultsShow_jetbrainsIsNotSupported_excludeContainersResult(t *testi func TestRunResultsShow_EclipseIsNotSupported_excludeContainersResult(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "Eclipse") assertTypePresentJSON(t, params.ContainersType, 0) // Remove generated json file @@ -819,7 +805,6 @@ func TestRunResultsShow_EclipseIsNotSupported_excludeContainersResult(t *testing func TestRunResultsShow_VsCodeIsNotSupported_excludeContainersResult(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "vs code") assertTypePresentJSON(t, params.ContainersType, 0) // Remove generated json file @@ -828,7 +813,6 @@ func TestRunResultsShow_VsCodeIsNotSupported_excludeContainersResult(t *testing. func TestRunResultsShow_VisualStudioIsNotSupported_excludeContainersResult(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "Visual Studio") assertTypePresentJSON(t, params.ContainersType, 0) // Remove generated json file @@ -954,7 +938,6 @@ func assertResultsPresentSummaryJSON(t *testing.T, isResultsEnabled bool, scanTy } func TestRunGetResultsShow_ContainersFFOffAndResultsHasContainersResultsOnly_NilAssertion(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: false} execCmdNilAssertion(t, "results", "show", "--scan-id", "CONTAINERS_ONLY", "--report-format", "summaryConsole") } func TestRunGetResultsByScanIdGLSastAndAScaFormat(t *testing.T) { diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 0eeb211a8..c3d62ef32 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -147,41 +147,35 @@ func TestCreateScan(t *testing.T) { func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag"} execCmdNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) } func TestCreateScanFromZip_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "data/sources.zip", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag") } func TestCreateScanFromZip_ContainerTypeAndFilterFlags_ScanCreatedSuccessfully(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--scan-types", "container-security", "-s", "data/sources.zip", "-b", "dummy_branch", "--file-filter", "!.java") } func TestCreateScanFromFolder_InvalidContainersImagesAndNoContainerScanType_ScanCreatedSuccessfully(t *testing.T) { // When no container scan type is provided, we will ignore the container images flag and its value clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--scan-types", "sast", "--container-images", "image1,image2:tag"} execCmdNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) } func TestCreateScanFromFolder_ContainerImagesFlagWithoutValue_FailCreatingScan(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--container-images") assert.Assert(t, err.Error() == "flag needs an argument: --container-images") } func TestCreateScanFromFolder_InvalidContainerImageFormat_FailCreatingScan(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--container-images", "image1,image2:tag"} err := execCmdNotNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) assert.Assert(t, err.Error() == "Invalid value for --container-images flag. The value must be in the format :") @@ -189,7 +183,6 @@ func TestCreateScanFromFolder_InvalidContainerImageFormat_FailCreatingScan(t *te func TestCreateContainersScan_ContainerFFIsOff_FailCreatingScan(t *testing.T) { clearFlags() - mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: false} baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--scan-types", "container-security"} err := execCmdNotNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) fmt.Println(err) @@ -1891,36 +1884,32 @@ func TestAddSastScan_ScanFlags(t *testing.T) { func TestValidateScanTypes(t *testing.T) { tests := []struct { - name string - userScanTypes string - userSCSScanTypes string - allowedEngines map[string]bool - containerEngineCLIEnabled bool - expectedError string + name string + userScanTypes string + userSCSScanTypes string + allowedEngines map[string]bool + expectedError string }{ { - name: "No licenses available", - userScanTypes: "scs", - userSCSScanTypes: "sast,secret-detection", - allowedEngines: map[string]bool{"scs": false, "enterprise-secrets": false}, - containerEngineCLIEnabled: true, - expectedError: "It looks like the \"scs\" scan type does", + name: "No licenses available", + userScanTypes: "scs", + userSCSScanTypes: "sast,secret-detection", + allowedEngines: map[string]bool{"scs": false, "enterprise-secrets": false}, + expectedError: "It looks like the \"scs\" scan type does", }, { - name: "SCS license available, secret-detection not available", - userScanTypes: "scs", - userSCSScanTypes: "secret-detection", - allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": false}, - containerEngineCLIEnabled: true, - expectedError: "It looks like the \"secret-detection\" scan type does not exist", + name: "SCS license available, secret-detection not available", + userScanTypes: "scs", + userSCSScanTypes: "secret-detection", + allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": false}, + expectedError: "It looks like the \"secret-detection\" scan type does not exist", }, { - name: "All licenses available", - userScanTypes: "scs", - userSCSScanTypes: "secret-detection", - allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": true}, - containerEngineCLIEnabled: true, - expectedError: "", + name: "All licenses available", + userScanTypes: "scs", + userSCSScanTypes: "secret-detection", + allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": true}, + expectedError: "", }, } diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 6be68b174..c578980ea 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -10,7 +10,6 @@ const tenantIDClaimKey = "tenant_id" const PackageEnforcementEnabled = "PACKAGE_ENFORCEMENT_ENABLED" const CVSSV3Enabled = "CVSS_V3_ENABLED" const MinioEnabled = "MINIO_ENABLED" -const ContainerEngineCLIEnabled = "CONTAINER_ENGINE_CLI_ENABLED" const SCSEngineCLIEnabled = "NEW_2MS_SCORECARD_RESULTS_CLI_ENABLED" const NewScanReportEnabled = "NEW_SAST_SCAN_REPORT_ENABLED" const maxRetries = 3 diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index c4c7b610e..cbbe06cfd 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -372,11 +372,9 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndScanType(t *testing.T) { flag(params.BranchFlag), "dummy_branch", flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - if isFFEnabled(t, wrappers.ContainerEngineCLIEnabled) { - scanID, projectID := executeCreateScan(t, testArgs) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - } + scanID, projectID := executeCreateScan(t, testArgs) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") } func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { @@ -390,11 +388,9 @@ func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { flag(params.ScanTypes), params.ContainersTypeFlag, flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - if isFFEnabled(t, wrappers.ContainerEngineCLIEnabled) { - scanID, projectID := executeCreateScan(t, testArgs) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - } + scanID, projectID := executeCreateScan(t, testArgs) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") } func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { @@ -409,11 +405,9 @@ func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { flag(params.ScanTypes), params.ContainersTypeFlag, flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - if isFFEnabled(t, wrappers.ContainerEngineCLIEnabled) { - scanID, projectID := executeCreateScan(t, testArgs) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - } + scanID, projectID := executeCreateScan(t, testArgs) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") } func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *testing.T) { @@ -427,11 +421,9 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *tes flag(params.ScanInfoFormatFlag), printer.FormatJSON, flag(params.ScanTypes), params.ContainersTypeFlag, } - if isFFEnabled(t, wrappers.ContainerEngineCLIEnabled) { - scanID, projectID := executeCreateScan(t, testArgs) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - } + scanID, projectID := executeCreateScan(t, testArgs) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") } func TestContainerEngineScansE2E_InvalidContainerImagesFlag(t *testing.T) { @@ -444,10 +436,8 @@ func TestContainerEngineScansE2E_InvalidContainerImagesFlag(t *testing.T) { flag(params.BranchFlag), "dummy_branch", flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - if isFFEnabled(t, wrappers.ContainerEngineCLIEnabled) { - err, _ := executeCommand(t, testArgs...) - assertError(t, err, "Invalid value for --container-images flag. The value must be in the format :") - } + err, _ := executeCommand(t, testArgs...) + assertError(t, err, "Invalid value for --container-images flag. The value must be in the format :") } // Create scans from current dir, zip and url and perform assertions in executeScanAssertions @@ -869,11 +859,7 @@ func executeScanAssertions(t *testing.T, projectID, scanID string, tags map[stri } func createScan(t *testing.T, source string, tags map[string]string) (string, string) { - if isFFEnabled(t, wrappers.ContainerEngineCLIEnabled) { - return executeCreateScan(t, getCreateArgs(source, tags, "sast , sca , iac-security , api-security, container-security, scs")) - } else { - return executeCreateScan(t, getCreateArgs(source, tags, "sast , sca , iac-security , api-security, scs")) - } + return executeCreateScan(t, getCreateArgs(source, tags, "sast , sca , iac-security , api-security, container-security, scs")) } func createScanNoWait(t *testing.T, source string, tags map[string]string, projectName string) (string, string) { From 3f1361a078424a5843484f665e2da5c84ccbd2e6 Mon Sep 17 00:00:00 2001 From: Alex Cohen Date: Wed, 29 Jan 2025 15:44:51 -0500 Subject: [PATCH 2/4] Remove ContainersEngineCLIEnabled Flag --- internal/commands/result_test.go | 21 ++------------------- internal/commands/scan_test.go | 8 -------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index c3bdbe1ab..bd20bc660 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -772,21 +772,7 @@ func TestRunGetResultsByScanIdGLFormat(t *testing.T) { // Run test for gl-sast report type os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatGLSast)) } -func TestRunResultsShow_ContainersFFIsOn_includeContainersResult(t *testing.T) { - clearFlags() - clearFlags() - execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") - assertTypePresentJSON(t, params.ContainersType, 1) - // Remove generated json file - removeFileBySuffix(t, printer.FormatJSON) -} -func TestRunResultsShow_ContainersFFIsOff_excludeContainersResult(t *testing.T) { - clearFlags() - execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") - assertTypePresentJSON(t, params.ContainersType, 0) - // Remove generated json file - removeFileBySuffix(t, printer.FormatJSON) -} + func TestRunResultsShow_jetbrainsIsNotSupported_excludeContainersResult(t *testing.T) { clearFlags() execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "jetbrains") @@ -936,10 +922,7 @@ func assertResultsPresentSummaryJSON(t *testing.T, isResultsEnabled bool, scanTy assert.Assert(t, false, "%s result summary should be present", scanType) } } -func TestRunGetResultsShow_ContainersFFOffAndResultsHasContainersResultsOnly_NilAssertion(t *testing.T) { - clearFlags() - execCmdNilAssertion(t, "results", "show", "--scan-id", "CONTAINERS_ONLY", "--report-format", "summaryConsole") -} + func TestRunGetResultsByScanIdGLSastAndAScaFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "gl-sast,gl-sca") // Run test for gl-sast report type diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index c3d62ef32..5f47990af 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -181,14 +181,6 @@ func TestCreateScanFromFolder_InvalidContainerImageFormat_FailCreatingScan(t *te assert.Assert(t, err.Error() == "Invalid value for --container-images flag. The value must be in the format :") } -func TestCreateContainersScan_ContainerFFIsOff_FailCreatingScan(t *testing.T) { - clearFlags() - baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--scan-types", "container-security"} - err := execCmdNotNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) - fmt.Println(err) - assert.ErrorContains(t, err, "you would need to purchase a license") -} - func TestCreateScanWithThreshold_ShouldSuccess(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--scan-types", "sast", "--threshold", "sca-low=1 ; sast-medium=2") } From 51b3e2c6c8ef7b226e15824518ef089cdbe16d52 Mon Sep 17 00:00:00 2001 From: Alex Cohen Date: Wed, 29 Jan 2025 15:49:07 -0500 Subject: [PATCH 3/4] Remove ContainersEngineCLIEnabled Flag --- internal/commands/result_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index bd20bc660..baf233cf6 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -773,6 +773,14 @@ func TestRunGetResultsByScanIdGLFormat(t *testing.T) { os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatGLSast)) } +func TestRunResultsShow_ContainersFFIsOn_includeContainersResult(t *testing.T) { + clearFlags() + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") + assertTypePresentJSON(t, params.ContainersType, 1) + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} + func TestRunResultsShow_jetbrainsIsNotSupported_excludeContainersResult(t *testing.T) { clearFlags() execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "jetbrains") From 01b2f6d45c4b479f8244239895bcb4b0dae5d54e Mon Sep 17 00:00:00 2001 From: Alex Cohen Date: Thu, 30 Jan 2025 12:01:57 -0500 Subject: [PATCH 4/4] Handling Tar and starting cloud flow --- internal/commands/scan.go | 88 +++++++++++++++++----------------- internal/commands/scan_test.go | 5 ++ internal/params/flags.go | 1 + 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 501f6c67b..eff5b4220 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -560,7 +560,8 @@ func scanCreateSubCommand( "", fmt.Sprintf("Parameters to use in SCA resolver (requires --%s).", commonParams.ScaResolverFlag), ) - createScanCmd.PersistentFlags().String(commonParams.ContainerImagesFlag, "", "List of container images to scan, ex: manuelbcd/vulnapp:latest,debian:10. (Not supported yet)") + createScanCmd.PersistentFlags().String(commonParams.ContainerResolveLocallyFlag, "", "Execute container resolver locally.") + createScanCmd.PersistentFlags().String(commonParams.ContainerImagesFlag, "", "List of container images to scan, ex: manuelbcd/vulnapp:latest,debian:10.") createScanCmd.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types, ex: (sast,iac-security,sca,api-security)") createScanCmd.PersistentFlags().String(commonParams.TagList, "", "List of tags, ex: (tagA,tagB:val,etc)") @@ -746,7 +747,6 @@ func setupScanTypeProjectAndConfig( return err } } - containerEngineCLIEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.ContainerEngineCLIEnabled) sastConfig := addSastScan(cmd, resubmitConfig) if sastConfig != nil { @@ -764,7 +764,7 @@ func setupScanTypeProjectAndConfig( if apiSecConfig != nil { configArr = append(configArr, apiSecConfig) } - var containersConfig = addContainersScan(containerEngineCLIEnabled.Status) + var containersConfig = addContainersScan() if containersConfig != nil { configArr = append(configArr, containersConfig) } @@ -935,8 +935,8 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config, hasContain return nil } -func addContainersScan(containerEngineCLIEnabled bool) map[string]interface{} { - if !scanTypeEnabled(commonParams.ContainersType) || !containerEngineCLIEnabled { +func addContainersScan() map[string]interface{} { + if !scanTypeEnabled(commonParams.ContainersType) { return nil } containerMapConfig := make(map[string]interface{}) @@ -1071,7 +1071,6 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu var scanTypes []string var SCSScanTypes []string - containerEngineCLIEnabled, _ := featureFlagsWrapper.GetSpecificFlag(wrappers.ContainerEngineCLIEnabled) allowedEngines, err := jwtWrapper.GetAllowedEngines(featureFlagsWrapper) if err != nil { err = errors.Errorf("Error validating scan types: %v", err) @@ -1088,7 +1087,7 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu scanTypes = strings.Split(userScanTypes, ",") for _, scanType := range scanTypes { - if !allowedEngines[scanType] || (scanType == commonParams.ContainersType && !(containerEngineCLIEnabled.Status)) { + if !allowedEngines[scanType] { keys := reflect.ValueOf(allowedEngines).MapKeys() err = errors.Errorf(engineNotAllowed, scanType, scanType, keys) return err @@ -1104,9 +1103,6 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu } else { for k := range allowedEngines { - if k == commonParams.ContainersType && !(containerEngineCLIEnabled.Status) { - continue - } scanTypes = append(scanTypes, k) } } @@ -1303,7 +1299,6 @@ func isDirFiltered(filename string, filters []string) (bool, error) { } } } - return false, nil } @@ -1398,17 +1393,16 @@ func addScaResults(zipWriter *zip.Writer) error { } func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) ( - url, zipFilePath string, - err error, -) { + url, zipFilePath string, err error) { + var preSignedURL string sourceDirFilter, _ := cmd.Flags().GetString(commonParams.SourceDirFilterFlag) userIncludeFilter, _ := cmd.Flags().GetString(commonParams.IncludeFilterFlag) projectName, _ := cmd.Flags().GetString(commonParams.ProjectName) - containerEngineCLIEnabled, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.ContainerEngineCLIEnabled) - - containerScanTriggered := strings.Contains(actualScanTypes, commonParams.ContainersType) && containerEngineCLIEnabled.Status + containerScanTriggered := strings.Contains(actualScanTypes, commonParams.ContainersType) + containerResolveLocallyFlag, _ := cmd.Flags().GetString(commonParams.ContainerResolveLocallyFlag) + containerResolveLocally := strings.EqualFold(containerResolveLocallyFlag, "true") scaResolverParams, scaResolver := getScaResolverFlags(cmd) zipFilePath, directoryPath, err := definePathForZipFileOrDirectory(cmd) @@ -1419,7 +1413,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW var errorUnzippingFile error userProvidedZip := len(zipFilePath) > 0 - unzip := ((len(sourceDirFilter) > 0 || len(userIncludeFilter) > 0) || containerScanTriggered) && userProvidedZip + unzip := ((len(sourceDirFilter) > 0 || len(userIncludeFilter) > 0) || containerResolveLocally) && userProvidedZip if unzip { directoryPath, errorUnzippingFile = UnzipFile(zipFilePath) if errorUnzippingFile != nil { @@ -1429,14 +1423,29 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW if directoryPath != "" { var dirPathErr error - resolversErr := runScannerResolvers(cmd, directoryPath, projectName, containerScanTriggered, scaResolver, scaResolverParams) - if resolversErr != nil { - if unzip { - _ = cleanTempUnzipDirectory(directoryPath) + + // execute scaResolver only in sca type of scans + if strings.Contains(actualScanTypes, commonParams.ScaType) { + scaErr := runScaResolver(directoryPath, scaResolver, scaResolverParams, projectName) + if scaErr != nil { + if unzip { + _ = cleanTempUnzipDirectory(directoryPath) + } + return "", "", errors.Wrapf(scaErr, "ScaResolver error") + } + } + + if containerScanTriggered { + containerResolverError := runContainerResolver(cmd, directoryPath, containerResolveLocally) + if containerResolverError != nil { + if unzip { + _ = cleanTempUnzipDirectory(directoryPath) + } + return "", "", containerResolverError } - return "", "", resolversErr } - if isSingleContainerScanTriggered() { + + if isSingleContainerScanTriggered() && containerResolveLocally { logger.PrintIfVerbose("Single container scan triggered: compressing only the container resolution file") containerResolutionFilePath := filepath.Join(directoryPath, containerResolutionFileName) zipFilePath, dirPathErr = util.CompressFile(containerResolutionFilePath, containerResolutionFileName, directoryCreationPrefix) @@ -1462,7 +1471,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW return preSignedURL, zipFilePath, nil } -func runContainerResolver(cmd *cobra.Command, directoryPath string) error { +func runContainerResolver(cmd *cobra.Command, directoryPath string, containerResolveLocally bool) error { containerImages, _ := cmd.Flags().GetString(commonParams.ContainerImagesFlag) debug, _ := cmd.Flags().GetBool(commonParams.DebugFlag) var containerImagesList []string @@ -1476,26 +1485,11 @@ func runContainerResolver(cmd *cobra.Command, directoryPath string) error { } logger.PrintIfVerbose(fmt.Sprintf("User input container images identified: %v", strings.Join(containerImagesList, ", "))) } - containerResolverERR := containerResolver.Resolve(directoryPath, directoryPath, containerImagesList, debug) - if containerResolverERR != nil { - return containerResolverERR - } - return nil -} -func runScannerResolvers(cmd *cobra.Command, directoryPath, projectName string, containerScanTriggered bool, scaResolver, scaResolverParams string) error { - // Make sure scaResolver only runs in sca type of scans - if strings.Contains(actualScanTypes, commonParams.ScaType) { - dirPathErr := runScaResolver(directoryPath, scaResolver, scaResolverParams, projectName) - if dirPathErr != nil { - return errors.Wrapf(dirPathErr, "ScaResolver error") - } - } - - if containerScanTriggered { - containerResolverError := runContainerResolver(cmd, directoryPath) - if containerResolverError != nil { - return containerResolverError + if containerResolveLocally || len(containerImagesList) > 0 { + containerResolverERR := containerResolver.Resolve(directoryPath, directoryPath, containerImagesList, debug) + if containerResolverERR != nil { + return containerResolverERR } } return nil @@ -2743,9 +2737,13 @@ func validateCreateScanFlags(cmd *cobra.Command) error { } func validateContainerImageFormat(containerImage string) error { + if strings.HasSuffix(containerImage, ".tar") { + return nil + } + imageParts := strings.Split(containerImage, ":") if len(imageParts) != 2 || imageParts[0] == "" || imageParts[1] == "" { - return errors.Errorf("Invalid value for --container-images flag. The value must be in the format :") + return errors.Errorf("Invalid value for --container-images flag. The value must be in the format : or .tar") } return nil } diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 5f47990af..cfed12b31 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -1565,6 +1565,11 @@ func TestValidateContainerImageFormat(t *testing.T) { containerImage: "nginx:latest", expectedError: nil, }, + { + name: "Valid compressed container image format", + containerImage: "nginx.tar", + expectedError: nil, + }, { name: "Missing image name", containerImage: ":latest", diff --git a/internal/params/flags.go b/internal/params/flags.go index ae40c6527..2a9755914 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -142,6 +142,7 @@ const ( LastSastScanTime = "sca-last-sast-scan-time" ProjecPrivatePackageFlag = "project-private-package" SastRedundancyFlag = "sast-redundancy" + ContainerResolveLocallyFlag = "container-resolve-locally" ContainerImagesFlag = "container-images" ContainersTypeFlag = "container-security" VSCodeAgent = "VS Code"