From 785ef78de20ab275268aeb796defc1c26710459a Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 29 Feb 2024 18:23:47 +0200 Subject: [PATCH 001/108] AST-36236 | Support Containers as New Scan Type With Realted Flags --- internal/commands/scan.go | 36 ++++++++++++++++++++++- internal/commands/scan_test.go | 20 +++++++++++++ internal/params/flags.go | 2 ++ internal/wrappers/feature-flags.go | 5 ++++ internal/wrappers/jwt-helper.go | 17 +++++++---- internal/wrappers/mock/jwt-helper-mock.go | 2 +- 6 files changed, 75 insertions(+), 7 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index b4e624909..45507ebdc 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -502,7 +502,8 @@ func scanCreateSubCommand( "", fmt.Sprintf("Parameters to use in SCA resolver (requires --%s).", commonParams.ScaResolverFlag), ) - createScanCmd.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types, ex: (sast,iac-security,sca,api-security)") + 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,container-security)") createScanCmd.PersistentFlags().String(commonParams.TagList, "", "List of tags, ex: (tagA,tagB:val,etc)") createScanCmd.PersistentFlags().StringP( commonParams.BranchFlag, commonParams.BranchFlagSh, @@ -867,6 +868,13 @@ func setupScanTypeProjectAndConfig( if apiSecConfig != nil { configArr = append(configArr, apiSecConfig) } + var containersConfig, containerConfigErr = addContainersScan(cmd) + if containersConfig != nil { + configArr = append(configArr, containersConfig) + } + if containerConfigErr != nil { + return containerConfigErr + } info["config"] = configArr *input, err = json.Marshal(info) return err @@ -1005,6 +1013,24 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config) map[string return nil } +func addContainersScan(cmd *cobra.Command) (map[string]interface{}, error) { + if !scanTypeEnabled(commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + return nil, nil + } + var containerMapConfig map[string]interface{} + containerImages, _ := cmd.Flags().GetString(commonParams.ContainerImagesFlag) + if containerImages != "" { + containerImagesList := strings.Split(containerImages, ",") + for _, containerImageName := range containerImagesList { + if err := validateContainerImageFormat(containerImageName); err != nil { + return nil, err + } + } + } + //TODO: add logic that will support the container scan + return containerMapConfig, nil +} + func addAPISecScan(cmd *cobra.Command) map[string]interface{} { if scanTypeEnabled(commonParams.APISecurityType) { apiSecMapConfig := make(map[string]interface{}) @@ -2474,6 +2500,14 @@ func validateCreateScanFlags(cmd *cobra.Command) error { return nil } +func validateContainerImageFormat(containerImage string) error { + 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 nil +} + func validateBooleanString(value string) error { if value == "" { return nil diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 3719253cb..32f2cacf3 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -124,6 +124,26 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } +func TestCreateScan_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { + execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag") +} + +func TestCreateScan_InvalidContainersImagesAndNoContainerScanType_ScanCreatedSuccessfully(t *testing.T) { + //when no container scan type is provided, we will ignore the container images flag and its value + execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--scan-types", "sast", "--container-images", "image1,image2:tag") +} + +func TestCreateScan_ContainerImagesFlagWithoutValue_FailCreatingScan(t *testing.T) { + 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 TestCreateScan_InvalidContainerImageFormat_FailCreatingScan(t *testing.T) { + err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", + "--container-images", "image1,image2:tag") + assert.Assert(t, err.Error() == "Invalid value for --container-images flag. The value must be in the format :") +} + func TestScanCreate_ExistingApplicationAndProject_CreateProjectUnderApplicationSuccessfully(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } diff --git a/internal/params/flags.go b/internal/params/flags.go index 0017b41a4..2089e586c 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -136,6 +136,7 @@ const ( LastSastScanTime = "sca-last-sast-scan-time" ProjecPrivatePackageFlag = "project-private-package" SastRedundancyFlag = "sast-redundancy" + ContainerImagesFlag = "container-images" ScaPrivatePackageVersionFlag = "sca-private-package-version" @@ -224,6 +225,7 @@ const ( SastType = "sast" KicsType = "kics" APISecurityType = "api-security" + ContainersType = "container-security" APIDocumentationFlag = "apisec-swagger-filter" IacType = "iac-security" IacLabel = "IaC Security" diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 617c0ca36..93d2477b9 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -7,6 +7,7 @@ import ( const tenantIDClaimKey = "tenant_id" const PackageEnforcementEnabled = "PACKAGE_ENFORCEMENT_ENABLED" const MinioEnabled = "MINIO_ENABLED" +const ContainerEngineCLIEnabled = "CONTAINER_ENGINE_CLI_ENABLED" var FeatureFlagsBaseMap = []CommandFlags{ { @@ -20,6 +21,10 @@ var FeatureFlagsBaseMap = []CommandFlags{ Name: MinioEnabled, Default: true, }, + { + Name: ContainerEngineCLIEnabled, + Default: true, + }, }, }, { diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index 8f29cabba..e1c5900b5 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -19,13 +19,14 @@ type JWTStruct struct { jwt.Claims } -var enabledEngines = []string{"sast", "sca", "api-security", "iac-security"} +var enabledEngines = []string{"sast", "sca", "api-security", "iac-security", "container-security"} var defaultEngines = map[string]bool{ - "sast": true, - "sca": true, - "api-security": true, - "iac-security": true, + "sast": true, + "sca": true, + "api-security": true, + "iac-security": true, + "container-security": true, } type JWTWrapper interface { @@ -50,6 +51,9 @@ func (*JWTStruct) GetAllowedEngines() (allowedEngines map[string]bool, err error allowedEngines = prepareEngines(jwtStruct.AstLicense.LicenseData.AllowedEngines) return allowedEngines, nil } + if !FeatureFlags[ContainerEngineCLIEnabled] { + delete(defaultEngines, "containers") + } return defaultEngines, nil } @@ -62,6 +66,9 @@ func prepareEngines(engines []string) map[string]bool { // Current limitation, CxOne is including non-engines in the JWT if utils.Contains(enabledEngines, strings.ToLower(engine)) { + if strings.ToLower(engine) == commonParams.ContainersType && !FeatureFlags[ContainerEngineCLIEnabled] { + continue + } m[strings.ToLower(engine)] = true } } diff --git a/internal/wrappers/mock/jwt-helper-mock.go b/internal/wrappers/mock/jwt-helper-mock.go index 994fb38bf..71e8759a0 100644 --- a/internal/wrappers/mock/jwt-helper-mock.go +++ b/internal/wrappers/mock/jwt-helper-mock.go @@ -9,7 +9,7 @@ type JWTMockWrapper struct{} // GetAllowedEngines mock for tests func (*JWTMockWrapper) GetAllowedEngines() (allowedEngines map[string]bool, err error) { allowedEngines = make(map[string]bool) - engines := []string{"sast", "iac-security", "sca", "api-security"} + engines := []string{"sast", "iac-security", "sca", "api-security", "container-security"} for _, value := range engines { allowedEngines[strings.ToLower(value)] = true } From c669f9fdb328a67d81cd2aa9a61de1940f6a2b17 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 29 Feb 2024 18:34:18 +0200 Subject: [PATCH 002/108] AST-36236 | fix lint errors --- internal/commands/scan.go | 2 +- internal/commands/scan_test.go | 2 +- internal/wrappers/jwt-helper.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 45507ebdc..d10012c19 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1027,7 +1027,7 @@ func addContainersScan(cmd *cobra.Command) (map[string]interface{}, error) { } } } - //TODO: add logic that will support the container scan + // TODO: add logic that will support the container scan return containerMapConfig, nil } diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 32f2cacf3..38afe530b 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -129,7 +129,7 @@ func TestCreateScan_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully( } func TestCreateScan_InvalidContainersImagesAndNoContainerScanType_ScanCreatedSuccessfully(t *testing.T) { - //when no container scan type is provided, we will ignore the container images flag and its value + // When no container scan type is provided, we will ignore the container images flag and its value execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--scan-types", "sast", "--container-images", "image1,image2:tag") } diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index e1c5900b5..e1b36a764 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -66,7 +66,7 @@ func prepareEngines(engines []string) map[string]bool { // Current limitation, CxOne is including non-engines in the JWT if utils.Contains(enabledEngines, strings.ToLower(engine)) { - if strings.ToLower(engine) == commonParams.ContainersType && !FeatureFlags[ContainerEngineCLIEnabled] { + if strings.EqualFold(engine, commonParams.ContainersType) && !FeatureFlags[ContainerEngineCLIEnabled] { continue } m[strings.ToLower(engine)] = true From 2cbb88327d07328cfac1bbf5353cac16cffeb362 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 5 Mar 2024 11:54:28 +0200 Subject: [PATCH 003/108] AST-36237 | added container resolver functionality --- cmd/main.go | 2 + internal/commands/root.go | 2 + internal/commands/root_test.go | 2 + internal/commands/scan.go | 51 +++++++++++++++---- internal/commands/scan_test.go | 11 ++-- internal/wrappers/container-resolver.go | 20 ++++++++ .../wrappers/mock/container-resolver-mock.go | 8 +++ internal/wrappers/scans.go | 2 + test/integration/util_command.go | 2 + 9 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 internal/wrappers/container-resolver.go create mode 100644 internal/wrappers/mock/container-resolver-mock.go diff --git a/cmd/main.go b/cmd/main.go index 8ce4a8aa5..3e193ef26 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -81,6 +81,7 @@ func main() { policyWrapper := wrappers.NewHTTPPolicyWrapper(policyEvaluationPath) sastMetadataWrapper := wrappers.NewSastIncrementalHTTPWrapper(sastMetadataPath) accessManagementWrapper := wrappers.NewAccessManagementHTTPWrapper(accessManagementPath) + containerResolverWrapper := wrappers.NewContainerResolverWrapper() astCli := commands.NewAstCLI( applicationsWrapper, @@ -112,6 +113,7 @@ func main() { policyWrapper, sastMetadataWrapper, accessManagementWrapper, + containerResolverWrapper, ) exitListener() err = astCli.Execute() diff --git a/internal/commands/root.go b/internal/commands/root.go index ff2b7796a..5fd5b2914 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -52,6 +52,7 @@ func NewAstCLI( policyWrapper wrappers.PolicyWrapper, sastMetadataWrapper wrappers.SastMetadataWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, + containerResolverWrapper wrappers.ContainerResolverWrapper, ) *cobra.Command { // Create the root rootCmd := &cobra.Command{ @@ -160,6 +161,7 @@ func NewAstCLI( policyWrapper, sastMetadataWrapper, accessManagementWrapper, + containerResolverWrapper, ) projectCmd := NewProjectCommand(applicationsWrapper, projectsWrapper, groupsWrapper, accessManagementWrapper) resultsCmd := NewResultsCommand( diff --git a/internal/commands/root_test.go b/internal/commands/root_test.go index e301c4676..39c9b514e 100644 --- a/internal/commands/root_test.go +++ b/internal/commands/root_test.go @@ -59,6 +59,7 @@ func createASTTestCommand() *cobra.Command { policyWrapper := &mock.PolicyMockWrapper{} sastMetadataWrapper := &mock.SastMetadataMockWrapper{} accessManagementWrapper := &mock.AccessManagementMockWrapper{} + containerResolverMockWrapper := &mock.ContainerResolverMockWrapper{} return NewAstCLI( applicationWrapper, @@ -90,6 +91,7 @@ func createASTTestCommand() *cobra.Command { policyWrapper, sastMetadataWrapper, accessManagementWrapper, + containerResolverMockWrapper, ) } diff --git a/internal/commands/scan.go b/internal/commands/scan.go index d10012c19..a1a385a9c 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -121,6 +121,7 @@ var ( ) aditionalParameters []string kicsErrorCodes = []string{"50", "40", "30", "20"} + containerResolver wrappers.ContainerResolverWrapper ) func NewScanCommand( @@ -139,6 +140,7 @@ func NewScanCommand( policyWrapper wrappers.PolicyWrapper, sastMetadataWrapper wrappers.SastMetadataWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, + containerResolverWrapper wrappers.ContainerResolverWrapper, ) *cobra.Command { scanCmd := &cobra.Command{ Use: "scan", @@ -166,6 +168,7 @@ func NewScanCommand( policyWrapper, accessManagementWrapper, applicationsWrapper, + containerResolverWrapper, ) listScansCmd := scanListSubCommand(scansWrapper, sastMetadataWrapper) @@ -185,6 +188,7 @@ func NewScanCommand( kicsRealtimeCmd := scanRealtimeSubCommand() scaRealtimeCmd := scarealtime.NewScaRealtimeCommand(scaRealTimeWrapper) + containerResolver = containerResolverWrapper addFormatFlagToMultipleCommands( []*cobra.Command{listScansCmd, showScanCmd, workflowScanCmd}, @@ -418,6 +422,7 @@ func scanCreateSubCommand( policyWrapper wrappers.PolicyWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, applicationsWrapper wrappers.ApplicationsWrapper, + containersResolverWrapper wrappers.ContainerResolverWrapper, ) *cobra.Command { createScanCmd := &cobra.Command{ Use: "create", @@ -448,6 +453,7 @@ func scanCreateSubCommand( policyWrapper, accessManagementWrapper, applicationsWrapper, + containersResolverWrapper, ), } createScanCmd.PersistentFlags().Bool(commonParams.AsyncFlag, false, "Do not wait for scan completion") @@ -1017,17 +1023,12 @@ func addContainersScan(cmd *cobra.Command) (map[string]interface{}, error) { if !scanTypeEnabled(commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { return nil, nil } - var containerMapConfig map[string]interface{} - containerImages, _ := cmd.Flags().GetString(commonParams.ContainerImagesFlag) - if containerImages != "" { - containerImagesList := strings.Split(containerImages, ",") - for _, containerImageName := range containerImagesList { - if err := validateContainerImageFormat(containerImageName); err != nil { - return nil, err - } - } - } - // TODO: add logic that will support the container scan + containerMapConfig := make(map[string]interface{}) + containerMapConfig[resultsMapType] = commonParams.ContainersType + + containerConfig := wrappers.ContainerConfig{} + + containerMapConfig[resultsMapValue] = &containerConfig return containerMapConfig, nil } @@ -1369,6 +1370,13 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW } } + if strings.Contains(actualScanTypes, commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + containerResolverError := runContainerResolver(cmd, directoryPath) + if containerResolverError != nil { + return "", "", containerResolverError + } + } + zipFilePath, dirPathErr = compressFolder(directoryPath, sourceDirFilter, userIncludeFilter, scaResolver) if unzip { dirRemovalErr := cleanTempUnzipDirectory(directoryPath) @@ -1386,6 +1394,26 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW return preSignedURL, zipFilePath, nil } +func runContainerResolver(cmd *cobra.Command, directoryPath string) error { + containerImages, _ := cmd.Flags().GetString(commonParams.ContainerImagesFlag) + debug, _ := cmd.Flags().GetBool(commonParams.DebugFlag) + var containerImagesList []string + + if containerImages != "" { + containerImagesList = strings.Split(strings.TrimSpace(containerImages), ",") + for _, containerImageName := range containerImagesList { + if containerImagesErr := validateContainerImageFormat(containerImageName); containerImagesErr != nil { + return containerImagesErr + } + } + } + containerResolverERR := containerResolver.Resolve(directoryPath, directoryPath, containerImagesList, debug) + if containerResolverERR != nil { + return containerResolverERR + } + return nil +} + func uploadZip(uploadsWrapper wrappers.UploadsWrapper, zipFilePath string, unzip, userProvidedZip bool) ( url, zipPath string, err error, @@ -1516,6 +1544,7 @@ func runCreateScanCommand( policyWrapper wrappers.PolicyWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, applicationsWrapper wrappers.ApplicationsWrapper, + containerResolverWrapper wrappers.ContainerResolverWrapper, ) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { err := validateScanTypes(cmd, jwtWrapper) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 38afe530b..6736d5739 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -125,12 +125,15 @@ func TestCreateScan(t *testing.T) { } func TestCreateScan_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag") + baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag"} + + execCmdNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) } func TestCreateScan_InvalidContainersImagesAndNoContainerScanType_ScanCreatedSuccessfully(t *testing.T) { // When no container scan type is provided, we will ignore the container images flag and its value - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--scan-types", "sast", "--container-images", "image1,image2:tag") + 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 TestCreateScan_ContainerImagesFlagWithoutValue_FailCreatingScan(t *testing.T) { @@ -139,8 +142,8 @@ func TestCreateScan_ContainerImagesFlagWithoutValue_FailCreatingScan(t *testing. } func TestCreateScan_InvalidContainerImageFormat_FailCreatingScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", - "--container-images", "image1,image2:tag") + 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 :") } diff --git a/internal/wrappers/container-resolver.go b/internal/wrappers/container-resolver.go new file mode 100644 index 000000000..b33e34513 --- /dev/null +++ b/internal/wrappers/container-resolver.go @@ -0,0 +1,20 @@ +package wrappers + +import ( + containersResolver "github.com/Checkmarx-Containers/containers-resolver/pkg/containerResolver" +) + +type ContainerResolverWrapper interface { + Resolve(scanPath string, resolutionFilePath string, images []string, isDebug bool) error +} + +type ContainerResolverImpl struct { +} + +func NewContainerResolverWrapper() ContainerResolverWrapper { + return &ContainerResolverImpl{} +} + +func (c *ContainerResolverImpl) Resolve(scanPath string, resolutionFilePath string, images []string, isDebug bool) error { + return containersResolver.Resolve(scanPath, resolutionFilePath, images, isDebug) +} diff --git a/internal/wrappers/mock/container-resolver-mock.go b/internal/wrappers/mock/container-resolver-mock.go new file mode 100644 index 000000000..b078a9887 --- /dev/null +++ b/internal/wrappers/mock/container-resolver-mock.go @@ -0,0 +1,8 @@ +package mock + +type ContainerResolverMockWrapper struct { +} + +func (c *ContainerResolverMockWrapper) Resolve(scanPath string, resolutionFilePath string, images []string, isDebug bool) error { + return nil +} diff --git a/internal/wrappers/scans.go b/internal/wrappers/scans.go index dd8a41119..f714b5056 100644 --- a/internal/wrappers/scans.go +++ b/internal/wrappers/scans.go @@ -139,6 +139,8 @@ type ScaConfig struct { LastSastScanTime string `json:"LastSastScanTime,omitempty"` PrivatePackageVersion string `json:"privatePackageVersion,omitempty"` } +type ContainerConfig struct { +} type APISecConfig struct { SwaggerFilter string `json:"swaggerFilter,omitempty"` } diff --git a/test/integration/util_command.go b/test/integration/util_command.go index 0ecec9c58..71372ec8c 100644 --- a/test/integration/util_command.go +++ b/test/integration/util_command.go @@ -112,6 +112,7 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command { policyWrapper := wrappers.NewHTTPPolicyWrapper(policyEvaluationPath) sastMetadataWrapper := wrappers.NewSastIncrementalHTTPWrapper(sastIncrementalPath) accessManagementWrapper := wrappers.NewAccessManagementHTTPWrapper(accessManagementPath) + containerResolverWrapper := wrappers.NewContainerResolverWrapper() astCli := commands.NewAstCLI( applicationsWrapper, @@ -143,6 +144,7 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command { policyWrapper, sastMetadataWrapper, accessManagementWrapper, + containerResolverWrapper, ) return astCli } From da608266e45e1f2e567c9a2d89a9fbc75c17b11f Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 6 Mar 2024 11:15:49 +0200 Subject: [PATCH 004/108] AST-36237 | added container resolver functionality --- internal/commands/scan.go | 64 ++++++++++++++++++++++++++++----- internal/params/flags.go | 1 + internal/wrappers/jwt-helper.go | 3 +- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index a1a385a9c..854a8c8aa 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -95,9 +95,10 @@ const ( "\nTo use this feature, you would need to purchase a license." + "\nPlease contact our support team for assistance if you believe you have already purchased a license." + "\nLicensed packages: %s" - completedPolicy = "COMPLETED" - nonePolicy = "NONE" - evaluatingPolicy = "EVALUATING" + completedPolicy = "COMPLETED" + nonePolicy = "NONE" + evaluatingPolicy = "EVALUATING" + containerResolutionFileName = "containers-resolution.json" ) var ( @@ -1120,6 +1121,23 @@ func compressFolder(sourceDir, filter, userIncludeFilter, scaResolver string) (s return outputFile.Name(), err } +func isSingleContainerScanTriggered(cmd *cobra.Command) bool { + scanTypes, _ := cmd.Flags().GetString(commonParams.ScanTypes) + var scanTypeList []string + if len(scanTypes) > 0 { + scanTypeList = strings.Split(scanTypes, ",") + } + if len(scanTypeList) == 1 && scanTypeList[0] == commonParams.ContainersType { + return true + } + //check if user license supports only container scanning + actualScanTypeList := strings.Split(actualScanTypes, ",") + if len(actualScanTypeList) == 1 && actualScanTypeList[0] == commonParams.ContainersType { + return true + } + return false +} + func getIncludeFilters(userIncludeFilter string) []string { return buildFilters(commonParams.BaseFilters, userIncludeFilter) } @@ -1337,6 +1355,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW sourceDirFilter, _ := cmd.Flags().GetString(commonParams.SourceDirFilterFlag) userIncludeFilter, _ := cmd.Flags().GetString(commonParams.IncludeFilterFlag) projectName, _ := cmd.Flags().GetString(commonParams.ProjectName) + containerScanTriggered := strings.Contains(actualScanTypes, commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] zipFilePath, directoryPath, err := definePathForZipFileOrDirectory(cmd) if err != nil { @@ -1344,9 +1363,9 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW } var errorUnzippingFile error - userProvidedZip := len(zipFilePath) > 0 - unzip := (len(sourceDirFilter) > 0 || len(userIncludeFilter) > 0) && userProvidedZip + + unzip := ((len(sourceDirFilter) > 0 || len(userIncludeFilter) > 0) || containerScanTriggered) && userProvidedZip if unzip { directoryPath, errorUnzippingFile = UnzipFile(zipFilePath) if errorUnzippingFile != nil { @@ -1370,14 +1389,20 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW } } - if strings.Contains(actualScanTypes, commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + if containerScanTriggered { containerResolverError := runContainerResolver(cmd, directoryPath) if containerResolverError != nil { + if unzip { + _ = cleanTempUnzipDirectory(directoryPath) + } return "", "", containerResolverError } } - - zipFilePath, dirPathErr = compressFolder(directoryPath, sourceDirFilter, userIncludeFilter, scaResolver) + if isSingleContainerScanTriggered(cmd) { + zipFilePath, dirPathErr = compressFile(directoryPath, containerResolutionFileName) // If only container scan is triggered, we zip only the container-resolution.json file + } else { + zipFilePath, dirPathErr = compressFolder(directoryPath, sourceDirFilter, userIncludeFilter, scaResolver) + } if unzip { dirRemovalErr := cleanTempUnzipDirectory(directoryPath) if dirRemovalErr != nil { @@ -1394,6 +1419,29 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW return preSignedURL, zipFilePath, nil } +func compressFile(sourceDir string, filename string) (string, error) { + outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") + if err != nil { + return "", errors.Wrapf(err, "Cannot source code temp file.") + } + zipWriter := zip.NewWriter(outputFile) + err = addDirFiles(zipWriter, "", sourceDir, []string{}, []string{filename}) + if err != nil { + return "", err + } + // Close the file + err = zipWriter.Close() + if err != nil { + return "", err + } + stat, err := outputFile.Stat() + if err != nil { + return "", err + } + logger.PrintIfVerbose(fmt.Sprintf("Zip size: %.2fMB\n", float64(stat.Size())/mbBytes)) + return outputFile.Name(), err +} + func runContainerResolver(cmd *cobra.Command, directoryPath string) error { containerImages, _ := cmd.Flags().GetString(commonParams.ContainerImagesFlag) debug, _ := cmd.Flags().GetBool(commonParams.DebugFlag) diff --git a/internal/params/flags.go b/internal/params/flags.go index 2089e586c..b006a47fa 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -230,6 +230,7 @@ const ( IacType = "iac-security" IacLabel = "IaC Security" APISecurityLabel = "API Security" + ContainerLabel = "Containers" ScaType = "sca" APISecType = "apisec" Success = "success" diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index e1b36a764..cb24db2f9 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -52,7 +52,7 @@ func (*JWTStruct) GetAllowedEngines() (allowedEngines map[string]bool, err error return allowedEngines, nil } if !FeatureFlags[ContainerEngineCLIEnabled] { - delete(defaultEngines, "containers") + delete(defaultEngines, commonParams.ContainersType) } return defaultEngines, nil @@ -63,6 +63,7 @@ func prepareEngines(engines []string) map[string]bool { for _, value := range engines { engine := strings.Replace(strings.ToLower(value), strings.ToLower(commonParams.APISecurityLabel), commonParams.APISecurityType, 1) engine = strings.Replace(strings.ToLower(engine), commonParams.KicsType, commonParams.IacType, 1) + engine = strings.Replace(strings.ToLower(engine), strings.ToLower(commonParams.ContainerLabel), commonParams.ContainersType, 1) // Current limitation, CxOne is including non-engines in the JWT if utils.Contains(enabledEngines, strings.ToLower(engine)) { From fda814a53dfc1ba7f7b315e17ab6f5c5e08e76d6 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 6 Mar 2024 12:23:34 +0200 Subject: [PATCH 005/108] AST-36237 | added integration tests and refactor compressFolder func --- internal/commands/scan.go | 31 +------- internal/commands/scan_test.go | 6 ++ test/integration/data/withDockerInZip.zip | Bin 0 -> 92571 bytes test/integration/scan_test.go | 92 ++++++++++++++++++++++ 4 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 test/integration/data/withDockerInZip.zip diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 854a8c8aa..6164cd8e6 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1091,14 +1091,14 @@ func scanTypeEnabled(scanType string) bool { return false } -func compressFolder(sourceDir, filter, userIncludeFilter, scaResolver string) (string, error) { +func compress(sourceDir string, filter []string, userIncludeFilter []string, scaResolver string) (string, error) { scaToolPath := scaResolver outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") if err != nil { return "", errors.Wrapf(err, "Cannot source code temp file.") } zipWriter := zip.NewWriter(outputFile) - err = addDirFiles(zipWriter, "", sourceDir, getUserFilters(filter), getIncludeFilters(userIncludeFilter)) + err = addDirFiles(zipWriter, "", sourceDir, filter, userIncludeFilter) if err != nil { return "", err } @@ -1399,9 +1399,9 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW } } if isSingleContainerScanTriggered(cmd) { - zipFilePath, dirPathErr = compressFile(directoryPath, containerResolutionFileName) // If only container scan is triggered, we zip only the container-resolution.json file + zipFilePath, dirPathErr = compress(directoryPath, []string{}, []string{containerResolutionFileName}, "") // only include the container resolution file } else { - zipFilePath, dirPathErr = compressFolder(directoryPath, sourceDirFilter, userIncludeFilter, scaResolver) + zipFilePath, dirPathErr = compress(directoryPath, getUserFilters(sourceDirFilter), getIncludeFilters(userIncludeFilter), scaResolver) } if unzip { dirRemovalErr := cleanTempUnzipDirectory(directoryPath) @@ -1419,29 +1419,6 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW return preSignedURL, zipFilePath, nil } -func compressFile(sourceDir string, filename string) (string, error) { - outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") - if err != nil { - return "", errors.Wrapf(err, "Cannot source code temp file.") - } - zipWriter := zip.NewWriter(outputFile) - err = addDirFiles(zipWriter, "", sourceDir, []string{}, []string{filename}) - if err != nil { - return "", err - } - // Close the file - err = zipWriter.Close() - if err != nil { - return "", err - } - stat, err := outputFile.Stat() - if err != nil { - return "", err - } - logger.PrintIfVerbose(fmt.Sprintf("Zip size: %.2fMB\n", float64(stat.Size())/mbBytes)) - return outputFile.Name(), err -} - func runContainerResolver(cmd *cobra.Command, directoryPath string) error { containerImages, _ := cmd.Flags().GetString(commonParams.ContainerImagesFlag) debug, _ := cmd.Flags().GetBool(commonParams.DebugFlag) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 6736d5739..919cffaab 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -147,6 +147,12 @@ func TestCreateScan_InvalidContainerImageFormat_FailCreatingScan(t *testing.T) { assert.Assert(t, err.Error() == "Invalid value for --container-images flag. The value must be in the format :") } +func TestCreateScan_NoContainerLicense_FailCreatingScan(t *testing.T) { + baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "--scan-types", "container-security", "dummy_branch"} + 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 :") +} + func TestScanCreate_ExistingApplicationAndProject_CreateProjectUnderApplicationSuccessfully(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } diff --git a/test/integration/data/withDockerInZip.zip b/test/integration/data/withDockerInZip.zip new file mode 100644 index 0000000000000000000000000000000000000000..4d4c0dfc0c748988c3fa11da07e5e50cfdbf7343 GIT binary patch literal 92571 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%0D(HaIxJ(S5e+YiHg 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 z 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 WSkOTo06-e_FNGWcSQLc Date: Wed, 6 Mar 2024 12:44:15 +0200 Subject: [PATCH 006/108] update go.mod --- go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/go.mod b/go.mod index db66c9b9d..1747c6ea3 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/checkmarx/ast-cli go 1.21.5 require ( + github.com/Checkmarx-Containers/containers-resolver v1.0.0 github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible From 02c398a6df826f5eb77cae05ec900168e54142d1 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 6 Mar 2024 13:00:34 +0200 Subject: [PATCH 007/108] update go.sum --- go.sum | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.sum b/go.sum index a113167cd..ef4df584b 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/Checkmarx-Containers/containers-resolver v1.0.0 h1:UIwdGrqIPJ2ZK7aFb2SAoy5N8jyoYLCCutAPI4fH8t4= +github.com/Checkmarx-Containers/containers-resolver v1.0.0/go.mod h1:dP07/O+vvnhagCz3f2VOwB/8u2aIpKBZcOW0a+sAVL0= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c h1:oKI4C1dXYpi0B8pltDDzp1ZRiyeILv5enbp9h4ASQ3s= From 31cb42d99ee38a6a865cebbe9a84be31b7e8ce50 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 6 Mar 2024 17:13:15 +0200 Subject: [PATCH 008/108] update functionallity --- internal/commands/result.go | 37 ++++++++++++++++++++----------------- internal/commands/scan.go | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index ced20f065..40435346e 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -357,10 +357,11 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr scaIssues := 0 kicsIssues := 0 enginesStatusCode := map[string]int{ - commonParams.SastType: 0, - commonParams.ScaType: 0, - commonParams.KicsType: 0, - commonParams.APISecType: 0, + commonParams.SastType: 0, + commonParams.ScaType: 0, + commonParams.KicsType: 0, + commonParams.APISecType: 0, + commonParams.ContainersType: 0, } if len(scanInfo.StatusDetails) > 0 { @@ -401,10 +402,11 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr BranchName: scanInfo.Branch, EnginesEnabled: scanInfo.Engines, EnginesResult: map[string]*wrappers.EngineResultSummary{ - commonParams.SastType: {StatusCode: enginesStatusCode[commonParams.SastType]}, - commonParams.ScaType: {StatusCode: enginesStatusCode[commonParams.ScaType]}, - commonParams.KicsType: {StatusCode: enginesStatusCode[commonParams.KicsType]}, - commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]}, + commonParams.SastType: {StatusCode: enginesStatusCode[commonParams.SastType]}, + commonParams.ScaType: {StatusCode: enginesStatusCode[commonParams.ScaType]}, + commonParams.KicsType: {StatusCode: enginesStatusCode[commonParams.KicsType]}, + commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]}, + commonParams.ContainersType: {StatusCode: enginesStatusCode[commonParams.ContainersType]}, }, } @@ -585,12 +587,12 @@ func printAPIsSecuritySummary(summary *wrappers.ResultSummary) { if summary.HasAPISecurityDocumentation() { fmt.Printf(" APIS DOCUMENTATION: %*d \n", defaultPaddingSize, summary.GetAPISecurityDocumentationTotal()) } - fmt.Printf(" -------------------------------------------------- \n\n") + fmt.Printf(" ------------------------------------------------------- \n\n") } func printTableRow(title string, counts *wrappers.EngineResultSummary, statusNumber int) { - formatString := " | %-4s %4d %6d %4d %4d %-9s |\n" - notAvailableFormatString := " | %-4s %4s %6s %4s %4s %5s |\n" + formatString := " | %-9s %4d %6d %4d %4d %-9s |\n" + notAvailableFormatString := " | %-9s %4s %6s %4s %4s %5s |\n" switch statusNumber { case notAvailableNumber: @@ -609,20 +611,21 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { totalMediumIssues := summary.EnginesResult.GetMediumIssues() totalLowIssues := summary.EnginesResult.GetLowIssues() totalInfoIssues := summary.EnginesResult.GetInfoIssues() - fmt.Printf(" --------------------------------------------------- \n\n") + fmt.Printf(" -------------------------------------------------------- \n\n") fmt.Printf(" Total Results: %d \n", summary.TotalIssues) - fmt.Println(" --------------------------------------------------- ") - fmt.Println(" | High Medium Low Info Status |") + fmt.Println(" -------------------------------------------------------- ") + fmt.Println(" | High Medium Low Info Status |") printTableRow("APIs", summary.EnginesResult[commonParams.APISecType], summary.EnginesResult[commonParams.APISecType].StatusCode) + printTableRow("Container", summary.EnginesResult[commonParams.ContainersType], summary.EnginesResult[commonParams.ContainersType].StatusCode) printTableRow("IAC", summary.EnginesResult[commonParams.KicsType], summary.EnginesResult[commonParams.KicsType].StatusCode) printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode) printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode) - fmt.Println(" --------------------------------------------------- ") - fmt.Printf(" | %-4s %4d %6d %4d %4d %-9s |\n", + fmt.Println(" -------------------------------------------------------- ") + fmt.Printf(" | %-9s %4d %6d %4d %4d %-9s |\n", fmt.Sprintf(boldFormat, "TOTAL"), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) - fmt.Printf(" --------------------------------------------------- \n\n") + fmt.Printf(" -------------------------------------------------------- \n\n") } func generateScanSummaryURL(summary *wrappers.ResultSummary) string { diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 6164cd8e6..c6b205526 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1365,7 +1365,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) && userProvidedZip if unzip { directoryPath, errorUnzippingFile = UnzipFile(zipFilePath) if errorUnzippingFile != nil { From 0f01d99f0981d8bf68136326f6af28621e5eb4a7 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 6 Mar 2024 17:31:34 +0200 Subject: [PATCH 009/108] update functionallity --- internal/commands/scan.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index c6b205526..6164cd8e6 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1365,7 +1365,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW var errorUnzippingFile error userProvidedZip := len(zipFilePath) > 0 - unzip := (len(sourceDirFilter) > 0 || len(userIncludeFilter) > 0) && userProvidedZip + unzip := ((len(sourceDirFilter) > 0 || len(userIncludeFilter) > 0) || containerScanTriggered) && userProvidedZip if unzip { directoryPath, errorUnzippingFile = UnzipFile(zipFilePath) if errorUnzippingFile != nil { From 747dc82a9631e4c22e3c187e788a94dd853d37ac Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:07:53 +0200 Subject: [PATCH 010/108] resolve conversation comments --- go.mod | 2 +- go.sum | 2 + internal/commands/result.go | 2 +- internal/commands/scan.go | 105 +++++++++++++----- internal/commands/scan_test.go | 18 ++- internal/wrappers/container-resolver.go | 2 +- .../wrappers/mock/container-resolver-mock.go | 17 +++ internal/wrappers/scans.go | 1 + 8 files changed, 112 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index ae4322eab..d6565ab86 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/checkmarx/ast-cli go 1.21.8 require ( - github.com/Checkmarx-Containers/containers-resolver v1.0.0 + github.com/CheckmarxDev/containers-resolver v1.0.1 github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/go.sum b/go.sum index cbb20a2c3..498e76024 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/Checkmarx-Containers/containers-resolver v1.0.0 h1:UIwdGrqIPJ2ZK7aFb2SAoy5N8jyoYLCCutAPI4fH8t4= github.com/Checkmarx-Containers/containers-resolver v1.0.0/go.mod h1:dP07/O+vvnhagCz3f2VOwB/8u2aIpKBZcOW0a+sAVL0= +github.com/CheckmarxDev/containers-resolver v1.0.1 h1:1d699fOdBiq5BcFWHAseU+fHqgd8wb3O+lDOuYS2lto= +github.com/CheckmarxDev/containers-resolver v1.0.1/go.mod h1:+sNosfLkXhzpPnYFEpGH4OeO5c06QCiY7T4XakbuP3U= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c h1:oKI4C1dXYpi0B8pltDDzp1ZRiyeILv5enbp9h4ASQ3s= diff --git a/internal/commands/result.go b/internal/commands/result.go index 40435346e..c2aeb4aec 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -624,7 +624,7 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { fmt.Println(" -------------------------------------------------------- ") fmt.Printf(" | %-9s %4d %6d %4d %4d %-9s |\n", - fmt.Sprintf(boldFormat, "TOTAL"), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) + fmt.Sprintf(color.Bold.Sprintf("TOTAL ")), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) fmt.Printf(" -------------------------------------------------------- \n\n") } diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 6164cd8e6..a044517e8 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -171,6 +171,7 @@ func NewScanCommand( applicationsWrapper, containerResolverWrapper, ) + containerResolver = containerResolverWrapper listScansCmd := scanListSubCommand(scansWrapper, sastMetadataWrapper) @@ -189,7 +190,6 @@ func NewScanCommand( kicsRealtimeCmd := scanRealtimeSubCommand() scaRealtimeCmd := scarealtime.NewScaRealtimeCommand(scaRealTimeWrapper) - containerResolver = containerResolverWrapper addFormatFlagToMultipleCommands( []*cobra.Command{listScansCmd, showScanCmd, workflowScanCmd}, @@ -1012,6 +1012,7 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config) map[string if resubmitFilter != nil && scaConfig.Filter == "" { scaConfig.Filter = resubmitFilter.(string) } + scaConfig.EnableContainersScan = !(wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && scanTypeEnabled(commonParams.ContainersType)) } } scaMapConfig[resultsMapValue] = &scaConfig @@ -1090,8 +1091,47 @@ func scanTypeEnabled(scanType string) bool { } return false } +func compressFile(sourceFilePath, targetFileName string) (string, error) { + outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") + if err != nil { + return "", errors.Wrapf(err, "Cannot source code temp file.") + } + zipWriter := zip.NewWriter(outputFile) + dat, err := ioutil.ReadFile(sourceFilePath) + if err != nil { + logger.PrintIfVerbose(fmt.Sprintf("Failed to read file: %s\n", sourceFilePath)) + return "", err + } + + folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") + if folderNameBeginsIndex == -1 { + return "", errors.New("Failed to find folder name in output file name") + } + folderName := outputFile.Name()[folderNameBeginsIndex:] + folderName = strings.TrimSuffix(folderName, ".zip") + + f, err := zipWriter.Create(filepath.Join(folderName, targetFileName)) + if err != nil { + return "", err + } + _, err = f.Write(dat) + if err != nil { + return "", err + } + // Close the file + err = zipWriter.Close() + if err != nil { + return "", err + } + stat, err := outputFile.Stat() + if err != nil { + return "", err + } + logger.PrintIfVerbose(fmt.Sprintf("Zip size: %.2fMB\n", float64(stat.Size())/mbBytes)) + return outputFile.Name(), err +} -func compress(sourceDir string, filter []string, userIncludeFilter []string, scaResolver string) (string, error) { +func compressFolder(sourceDir string, filter []string, userIncludeFilter []string, scaResolver string) (string, error) { scaToolPath := scaResolver outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") if err != nil { @@ -1356,6 +1396,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW userIncludeFilter, _ := cmd.Flags().GetString(commonParams.IncludeFilterFlag) projectName, _ := cmd.Flags().GetString(commonParams.ProjectName) containerScanTriggered := strings.Contains(actualScanTypes, commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] + scaResolverParams, scaResolver := getScaResolverFlags(cmd) zipFilePath, directoryPath, err := definePathForZipFileOrDirectory(cmd) if err != nil { @@ -1375,44 +1416,31 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW if directoryPath != "" { var dirPathErr error - - scaResolverParams, scaResolver := getScaResolverFlags(cmd) - - // 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 { - if unzip { - _ = cleanTempUnzipDirectory(directoryPath) - } - return "", "", errors.Wrapf(dirPathErr, "ScaResolver error") - } - } - - if containerScanTriggered { - containerResolverError := runContainerResolver(cmd, directoryPath) - if containerResolverError != nil { - if unzip { - _ = cleanTempUnzipDirectory(directoryPath) - } - return "", "", containerResolverError - } + resolversErr := runScannerResolvers(cmd, directoryPath, projectName, containerScanTriggered, scaResolver, scaResolverParams) + if resolversErr != nil { + _ = cleanTempUnzipDirectory(directoryPath) + return "", "", resolversErr } if isSingleContainerScanTriggered(cmd) { - zipFilePath, dirPathErr = compress(directoryPath, []string{}, []string{containerResolutionFileName}, "") // only include the container resolution file + logger.PrintIfVerbose("Single container scan triggered: compressing only the container resolution file") + containerResolutionFilePath := filepath.Join(directoryPath, containerResolutionFileName) + zipFilePath, dirPathErr = compressFile(containerResolutionFilePath, containerResolutionFileName) } else { - zipFilePath, dirPathErr = compress(directoryPath, getUserFilters(sourceDirFilter), getIncludeFilters(userIncludeFilter), scaResolver) + zipFilePath, dirPathErr = compressFolder(directoryPath, getUserFilters(sourceDirFilter), getIncludeFilters(userIncludeFilter), scaResolver) + } + + if dirPathErr != nil { + return "", "", dirPathErr } + if unzip { dirRemovalErr := cleanTempUnzipDirectory(directoryPath) if dirRemovalErr != nil { return "", "", dirRemovalErr } } - if dirPathErr != nil { - return "", "", dirPathErr - } } + if zipFilePath != "" { return uploadZip(uploadsWrapper, zipFilePath, unzip, userProvidedZip) } @@ -1431,6 +1459,7 @@ func runContainerResolver(cmd *cobra.Command, directoryPath string) error { return containerImagesErr } } + logger.PrintIfVerbose(fmt.Sprintf("User input container images identified: %v", containerImagesList)) } containerResolverERR := containerResolver.Resolve(directoryPath, directoryPath, containerImagesList, debug) if containerResolverERR != nil { @@ -1439,6 +1468,24 @@ func runContainerResolver(cmd *cobra.Command, directoryPath string) error { 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 + } + } + return nil +} + func uploadZip(uploadsWrapper wrappers.UploadsWrapper, zipFilePath string, unzip, userProvidedZip bool) ( url, zipPath string, err error, diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 919cffaab..e634de7d1 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -124,30 +124,38 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } -func TestCreateScan_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { +func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag"} execCmdNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) } -func TestCreateScan_InvalidContainersImagesAndNoContainerScanType_ScanCreatedSuccessfully(t *testing.T) { +func TestCreateScanFromZip_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { + 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) { + 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 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 TestCreateScan_ContainerImagesFlagWithoutValue_FailCreatingScan(t *testing.T) { +func TestCreateScanFromFolder_ContainerImagesFlagWithoutValue_FailCreatingScan(t *testing.T) { 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 TestCreateScan_InvalidContainerImageFormat_FailCreatingScan(t *testing.T) { +func TestCreateScanFromFolder_InvalidContainerImageFormat_FailCreatingScan(t *testing.T) { 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 :") } -func TestCreateScan_NoContainerLicense_FailCreatingScan(t *testing.T) { +func TestCreateScanFromFolder_NoContainerLicense_FailCreatingScan(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "--scan-types", "container-security", "dummy_branch"} 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 :") diff --git a/internal/wrappers/container-resolver.go b/internal/wrappers/container-resolver.go index b33e34513..4eb4aef84 100644 --- a/internal/wrappers/container-resolver.go +++ b/internal/wrappers/container-resolver.go @@ -1,7 +1,7 @@ package wrappers import ( - containersResolver "github.com/Checkmarx-Containers/containers-resolver/pkg/containerResolver" + containersResolver "github.com/CheckmarxDev/containers-resolver/pkg/containerResolver" ) type ContainerResolverWrapper interface { diff --git a/internal/wrappers/mock/container-resolver-mock.go b/internal/wrappers/mock/container-resolver-mock.go index b078a9887..2199852fa 100644 --- a/internal/wrappers/mock/container-resolver-mock.go +++ b/internal/wrappers/mock/container-resolver-mock.go @@ -1,8 +1,25 @@ package mock +import ( + "io/ioutil" + "path/filepath" +) + type ContainerResolverMockWrapper struct { } func (c *ContainerResolverMockWrapper) Resolve(scanPath string, resolutionFilePath string, images []string, isDebug bool) error { + // Create the content for the container-resolution.json file (empty JSON) + content := []byte("{}\n") + + // Construct the full path for the container-resolution.json file + resolutionFullPath := filepath.Join(scanPath, "containers-resolution.json") + + // Write the content to the container-resolution.json file + err := ioutil.WriteFile(resolutionFullPath, content, 0644) + if err != nil { + return err + } + return nil } diff --git a/internal/wrappers/scans.go b/internal/wrappers/scans.go index f714b5056..eecba1ab6 100644 --- a/internal/wrappers/scans.go +++ b/internal/wrappers/scans.go @@ -138,6 +138,7 @@ type ScaConfig struct { ExploitablePath string `json:"ExploitablePath,omitempty"` LastSastScanTime string `json:"LastSastScanTime,omitempty"` PrivatePackageVersion string `json:"privatePackageVersion,omitempty"` + EnableContainersScan bool `json:"enableContainersScan,omitempty"` } type ContainerConfig struct { } From b1d6467ed3a3188a50091ee69eefac958c451de2 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:08:56 +0200 Subject: [PATCH 011/108] resolve conversation comments --- internal/commands/result.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/commands/result.go b/internal/commands/result.go index c2aeb4aec..9a8a469d5 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -18,6 +18,7 @@ import ( "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/commands/util/printer" "github.com/checkmarx/ast-cli/internal/logger" + "github.com/gookit/color" "golang.org/x/text/cases" "golang.org/x/text/language" From 04a254f654e0833c4c1c88a835dcd865abf9b8ff Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:10:51 +0200 Subject: [PATCH 012/108] resolve conversation comments --- 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 9a8a469d5..3b19d8fa0 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -63,7 +63,6 @@ const ( scanFailedNumber = -2 scanCanceledNumber = -3 defaultPaddingSize = -13 - boldFormat = "\033[1m%s\033[0m" scanPendingMessage = "Scan triggered in asynchronous mode or still running. Click more details to get the full status." directDependencyType = "Direct Dependency" indirectDependencyType = "Transitive Dependency" @@ -562,7 +561,7 @@ func writeConsoleSummary(summary *wrappers.ResultSummary) error { } func printPoliciesSummary(summary *wrappers.ResultSummary) { - fmt.Printf(" -------------------------------------- \n") + fmt.Printf(" ------------------------------------------------------- \n") if summary.Policies.BreakBuild { fmt.Printf(" Policy Management Violation - Break Build Enabled: \n") } else { From c40d3d6dd1dc3211e4d59e04cdad9239fc99e804 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:14:30 +0200 Subject: [PATCH 013/108] fix compilation errors --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d6565ab86..ca13606ef 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/checkmarx/ast-cli -go 1.21.8 +go 1.22.0 require ( github.com/CheckmarxDev/containers-resolver v1.0.1 From 05ea5e86a0dc0fadd8ded93587dabb5326818699 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:18:16 +0200 Subject: [PATCH 014/108] fix compilation errors --- go.mod | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 226 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index ca13606ef..0539ebf8c 100644 --- a/go.mod +++ b/go.mod @@ -22,25 +22,247 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/CycloneDX/cyclonedx-go v0.8.0 // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Masterminds/squirrel v1.5.4 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/acobaugh/osrelease v0.1.0 // indirect + github.com/adrg/xdg v0.4.0 // indirect + github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65 // indirect + github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b // indirect + github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a // indirect + github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect + github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect + github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b // indirect + github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 // indirect + github.com/anchore/stereoscope v0.0.2-0.20240208195325-681f6715b0e3 // indirect + github.com/anchore/syft v0.105.0 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect + github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect + github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect + github.com/becheran/wildmatch-go v1.0.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/containerd/cgroups v1.1.0 // indirect + github.com/containerd/containerd v1.7.11 // indirect + github.com/containerd/continuity v0.4.2 // indirect + github.com/containerd/fifo v1.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/containerd/ttrpc v1.2.2 // indirect + github.com/containerd/typeurl/v2 v2.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/cli v25.0.1+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v25.0.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect + github.com/docker/go-metrics v0.0.1 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/edsrzf/mmap-go v1.1.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/facebookincubator/nvdtools v0.1.5 // indirect + github.com/fatih/color v1.14.1 // indirect + github.com/felixge/fgprof v0.9.3 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/gabriel-vasile/mimetype v1.4.0 // indirect + github.com/github/go-spdx/v2 v2.2.0 // indirect + github.com/go-errors/errors v1.4.2 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.11.0 // indirect + github.com/go-gorp/gorp/v3 v3.1.0 // indirect + github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-restruct/restruct v1.2.0-alpha // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.0.1 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-containerregistry v0.19.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/licensecheck v0.3.1 // indirect + github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/gosuri/uitable v0.0.4 // indirect + github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jinzhu/copier v0.4.0 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect + github.com/knqyf263/go-rpmdb v0.0.0-20230301153543-ba94b245509b // indirect + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/mholt/archiver/v3 v3.5.1 // indirect + github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/locker v1.0.1 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/signal v0.7.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/nwaples/rardecode v1.1.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc6 // indirect + github.com/opencontainers/runc v1.1.12 // indirect + github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect + github.com/opencontainers/selinux v1.11.0 // indirect + github.com/pborman/indent v1.2.1 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pierrec/lz4/v4 v4.1.15 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/profile v1.7.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect + github.com/rivo/uniseg v0.4.6 // indirect + github.com/rubenv/sql-migrate v1.5.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/saferwall/pe v1.5.2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect + github.com/sassoftware/go-rpmutils v0.3.0 // indirect + github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect + github.com/sergi/go-diff v1.3.1 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spdx/tools-golang v0.5.3 // 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/subosito/gotenv v1.6.0 // indirect + github.com/sylabs/sif/v2 v2.11.5 // indirect + github.com/sylabs/squashfs v0.6.1 // indirect + github.com/therootcompany/xz v1.0.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + github.com/vbatts/go-mtree v0.5.3 // indirect + github.com/vbatts/tar-split v0.11.3 // indirect + github.com/vifraa/gopom v1.0.0 // indirect + github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect + github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + github.com/xlab/treeprint v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.17.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/grpc v1.59.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + helm.sh/helm/v3 v3.14.2 // indirect + k8s.io/api v0.29.0 // indirect + k8s.io/apiextensions-apiserver v0.29.0 // indirect + k8s.io/apimachinery v0.29.0 // indirect + k8s.io/apiserver v0.29.0 // indirect + k8s.io/cli-runtime v0.29.0 // indirect + k8s.io/client-go v0.29.0 // indirect + k8s.io/component-base v0.29.0 // indirect + k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/kubectl v0.29.0 // indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + oras.land/oras-go v1.2.5 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) From 8801d9b529a15da3d9c53ac855de131243655545 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:19:13 +0200 Subject: [PATCH 015/108] fix compilation errors --- go.sum | 1455 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1433 insertions(+), 22 deletions(-) diff --git a/go.sum b/go.sum index 498e76024..4972230cf 100644 --- a/go.sum +++ b/go.sum @@ -1,115 +1,1526 @@ -github.com/Checkmarx-Containers/containers-resolver v1.0.0 h1:UIwdGrqIPJ2ZK7aFb2SAoy5N8jyoYLCCutAPI4fH8t4= -github.com/Checkmarx-Containers/containers-resolver v1.0.0/go.mod h1:dP07/O+vvnhagCz3f2VOwB/8u2aIpKBZcOW0a+sAVL0= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA= +github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CheckmarxDev/containers-resolver v1.0.1 h1:1d699fOdBiq5BcFWHAseU+fHqgd8wb3O+lDOuYS2lto= github.com/CheckmarxDev/containers-resolver v1.0.1/go.mod h1:+sNosfLkXhzpPnYFEpGH4OeO5c06QCiY7T4XakbuP3U= +github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= +github.com/CycloneDX/cyclonedx-go v0.8.0/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= +github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE= +github.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY= +github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= +github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65 h1:u9XrEabKlGPsrmRvAER+kUKkwXiJfLyqGhmOTFsXjX4= +github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65/go.mod h1:8Jr7CjmwFVcBPtkJdTpaAGHimoGJGfbExypjzOu87Og= +github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b h1:L/djgY7ZbZ/38+wUtdkk398W3PIBJLkt1N8nU/7e47A= +github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b/go.mod h1:TLcE0RE5+8oIx2/NPWem/dq1DeaMoC+fPEH7hoSzPLo= +github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw= +github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a/go.mod h1:ubLFmlsv8/DFUQrZwY5syT5/8Er3ugSr4rDFwHsE3hg= +github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb h1:iDMnx6LIjtjZ46C0akqveX83WFzhpTD3eqOthawb5vU= +github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb/go.mod h1:DmTY2Mfcv38hsHbG78xMiTDdxFtkHpgYNVDPsF2TgHk= +github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= +github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA= +github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0vW0nnNKJfJieyH/TZ9UYAnTZs5/gHTdAe8= +github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ= +github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZVsCYMrIZBpFxwV26CbsuoEh5muXD5I1Ods= +github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= +github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 h1:agoiZchSf1Nnnos1azwIg5hk5Ao9TzZNBD9++AChGEg= +github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= +github.com/anchore/stereoscope v0.0.2-0.20240208195325-681f6715b0e3 h1:gnf3+0bYP6hsk/sQHdnLpqmilVUr/y6kIxzGCP6kUWA= +github.com/anchore/stereoscope v0.0.2-0.20240208195325-681f6715b0e3/go.mod h1:o0TqYkefad6kIPtmbigFKss7P48z4bjd8Vp5Wklbf3Y= +github.com/anchore/syft v0.105.0 h1:CG6D1wF4gfwVpF0o085Ym1FaWSK7sMz3B62nOk+0wH8= +github.com/anchore/syft v0.105.0/go.mod h1:qa0A9aliWCp0xpVA4tsB/S+aM+7VB9Fvjy8aWlDhbGU= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 h1:vmXNl+HDfqqXgr0uY1UgK1GAhps8nbAAtqHNBcgyf+4= +github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46/go.mod h1:olhPNdiiAAMiSujemd1O/sc6GcyePr23f/6uGKtthNg= +github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 h1:rcEG5HI490FF0a7zuvxOxen52ddygCfNVjP0XOCMl+M= +github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492/go.mod h1:9Beu8XsUNNfzml7WBf3QmyPToP1wm1Gj/Vc5UJKqTzU= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA= +github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= +github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= +github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= +github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= +github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= +github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c h1:oKI4C1dXYpi0B8pltDDzp1ZRiyeILv5enbp9h4ASQ3s= github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c/go.mod h1:l+0rISRGaps2HWkpvKbYPE1nsNx28vBj6bKorEm1M5o= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= +github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= +github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= +github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= +github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= +github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= +github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtOs= +github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak= +github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= +github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da h1:ZOjWpVsFZ06eIhnh4mkaceTiVoktdU67+M7KDHJ268M= +github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da/go.mod h1:B3tI9iGHi4imdLi4Asdha1Sc6feLMTfPLXh9IUYmysk= +github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/cli v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbTO1lpcGSkU= +github.com/docker/cli v25.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v25.0.3+incompatible h1:D5fy/lYmY7bvZa0XTZ5/UJPljor41F+vdyJG5luQLfQ= +github.com/docker/docker v25.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= +github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/facebookincubator/flog v0.0.0-20190930132826-d2511d0ce33c/go.mod h1:QGzNH9ujQ2ZUr/CjDGZGWeDAVStrWNjHeEcjJL96Nuk= +github.com/facebookincubator/nvdtools v0.1.5 h1:jbmDT1nd6+k+rlvKhnkgMokrCAzHoASWE5LtHbX2qFQ= +github.com/facebookincubator/nvdtools v0.1.5/go.mod h1:Kh55SAWnjckS96TBSrXI99KrEKH4iB0OJby3N8GRJO4= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= +github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= +github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= +github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= +github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro= +github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/github/go-spdx/v2 v2.2.0 h1:yBBLMasHA70Ujd35OpL/OjJOWWVNXcJGbars0GinGRI= +github.com/github/go-spdx/v2 v2.2.0/go.mod h1:hMCrsFgT0QnCwn7G8gxy/MxMpy67WgZrwFeISTn0o6w= +github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4= +github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= +github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc= +github.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= +github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= +github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= +github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic= +github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs= +github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/gookit/color v1.2.5/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= +github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 h1:WdAeg/imY2JFPc/9CST4bZ80nNJbiBFCAdSZCSgrS5Y= +github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953/go.mod h1:6o+UrvuZWc4UTyBhQf0LGjW9Ld7qJxLz/OqvSOWWlEc= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/knqyf263/go-rpmdb v0.0.0-20230301153543-ba94b245509b h1:boYyvL3tbUuKcMN029mpCl7oYYJ7yIXujLj+fiW4Alc= +github.com/knqyf263/go-rpmdb v0.0.0-20230301153543-ba94b245509b/go.mod h1:9LQcoMCMQ9vrF7HcDtXfvqGO4+ddxFQ8+YF/0CVGDww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= +github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= +github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= +github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= +github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 h1:P8UmIzZMYDR+NGImiFvErt6VWfIRPuGM+vyjiEdkmIw= +github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= +github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= +github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= +github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 h1:tQRHcLQwnwrPq2j2Qra/NnyjyESBGwdeBeVdAE9kXYg= +github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5/go.mod h1:vYT9HE7WCvL64iVeZylKmCsWKfE+JZ8105iuh2Trk8g= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= +github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= +github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= +github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4= github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= +github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA= +github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= +github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= +github.com/opencontainers/image-spec v1.1.0-rc6/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= +github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w= +github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= +github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/indent v1.2.1 h1:lFiviAbISHv3Rf0jcuh489bi06hj98JsVMtIDZQb9yM= +github.com/pborman/indent v1.2.1/go.mod h1:FitS+t35kIYtB5xWTZAPhnmrxcciEEOdbyrrpz5K6Vw= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= +github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= +github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg= +github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= +github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/saferwall/pe v1.5.2 h1:h5lLtLsyxGHQ9dN6cd8EfeLEBEo5gdqJpkuw4o4vTMY= +github.com/saferwall/pe v1.5.2/go.mod h1:SNzv3cdgk8SBI0UwHfyTcdjawfdnN+nbydnEL7GZ25s= +github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= +github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA= +github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= +github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= +github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= +github.com/sassoftware/go-rpmutils v0.3.0 h1:tE4TZ8KcOXay5iIP64P291s6Qxd9MQCYhI7DU+f3gFA= +github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcucCa0DsCzE9RMfwMo= +github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ= +github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= +github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM= +github.com/spdx/tools-golang v0.5.3 h1:ialnHeEYUC4+hkm5vJm4qz2x+oEJbS0mAMFrNXdQraY= +github.com/spdx/tools-golang v0.5.3/go.mod h1:/ETOahiAo96Ob0/RAIBmFZw6XN0yTnyr/uFZm2NTMhI= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/sylabs/sif/v2 v2.11.5 h1:7ssPH3epSonsTrzbS1YxeJ9KuqAN7ISlSM61a7j/mQM= +github.com/sylabs/sif/v2 v2.11.5/go.mod h1:GBoZs9LU3e4yJH1dcZ3Akf/jsqYgy5SeguJQC+zd75Y= +github.com/sylabs/squashfs v0.6.1 h1:4hgvHnD9JGlYWwT0bPYNt9zaz23mAV3Js+VEgQoRGYQ= +github.com/sylabs/squashfs v0.6.1/go.mod h1:ZwpbPCj0ocIvMy2br6KZmix6Gzh6fsGQcCnydMF+Kx8= +github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo= +github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw= +github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= +github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY= github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y= github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/vbatts/go-mtree v0.5.3 h1:S/jYlfG8rZ+a0bhZd+RANXejy7M4Js8fq9U+XoWTd5w= +github.com/vbatts/go-mtree v0.5.3/go.mod h1:eXsdoPMdL2jcJx6HweWi9lYQxBsTp4lNhqqAjgkZUg8= +github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= +github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +github.com/vifraa/gopom v1.0.0 h1:L9XlKbyvid8PAIK8nr0lihMApJQg/12OBvMA28BcWh0= +github.com/vifraa/gopom v1.0.0/go.mod h1:oPa1dcrGrtlO37WPDBm5SqHAT+wTgF8An1Q71Z6Vv4o= +github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 h1:jIVmlAFIqV3d+DOxazTR9v+zgj8+VYuQBzPgBZvWBHA= +github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651/go.mod h1:b26F2tHLqaoRQf8DywqzVaV1MQ9yvjb0OMcNl7Nxu20= +github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 h1:0KGbf+0SMg+UFy4e1A/CPVvXn21f1qtWdeJwxZFoQG8= +github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0/go.mod h1:jLXFoL31zFaHKAAyZUh+sxiTDFe1L1ZHrcK2T1itVKA= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.20.1-0.20240228204720-0d2316b26734 h1:HutZC8sRIg57ztz3rVaQYl4yxgM+UF0Jal0kAWUSeFU= -golang.org/x/crypto v0.20.1-0.20240228204720-0d2316b26734/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= +go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak= +go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -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/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w= +golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= +helm.sh/helm/v3 v3.14.2 h1:V71fv+NGZv0icBlr+in1MJXuUIHCiPG1hW9gEBISTIA= +helm.sh/helm/v3 v3.14.2/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= +k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= +k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= +k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= +k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= +k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= +k8s.io/apiserver v0.29.0 h1:Y1xEMjJkP+BIi0GSEv1BBrf1jLU9UPfAnnGGbbDdp7o= +k8s.io/apiserver v0.29.0/go.mod h1:31n78PsRKPmfpee7/l9NYEv67u6hOL6AfcE761HapDM= +k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4= +k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk= +k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= +k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= +k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= +k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= +k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= +k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/kubectl v0.29.0 h1:Oqi48gXjikDhrBF67AYuZRTcJV4lg2l42GmvsP7FmYI= +k8s.io/kubectl v0.29.0/go.mod h1:0jMjGWIcMIQzmUaMgAzhSELv5WtHo2a8pq67DtviAJs= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= +modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA= +modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= +oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= +oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= From 89cf40dd846148f3329d8cb6200eea8528cfc08d Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:30:55 +0200 Subject: [PATCH 016/108] fix compilation errors --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 0539ebf8c..6ef3a9e8f 100644 --- a/go.mod +++ b/go.mod @@ -7,16 +7,16 @@ require ( github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 + github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.6.0 github.com/gookit/color v1.5.4 github.com/mssola/user_agent v0.6.0 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.0 - github.com/spf13/viper v1.18.2 + github.com/spf13/viper v1.17.0 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.19.0 golang.org/x/text v0.14.0 gotest.tools v2.2.0+incompatible ) @@ -233,7 +233,7 @@ require ( golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect diff --git a/go.sum b/go.sum index 4972230cf..99da71322 100644 --- a/go.sum +++ b/go.sum @@ -409,8 +409,8 @@ github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -856,8 +856,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= +github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -986,8 +986,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1200,8 +1200,8 @@ golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From beb071136a79fdf5537aa8454f4e06ff9d098c90 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 13:50:55 +0200 Subject: [PATCH 017/108] fix compilation errors --- go.mod | 2 +- go.sum | 4 ++-- internal/commands/scan_test.go | 6 ------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 6ef3a9e8f..caf956884 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/mssola/user_agent v0.6.0 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.0 - github.com/spf13/viper v1.17.0 + github.com/spf13/viper v1.18.2 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 golang.org/x/crypto v0.19.0 golang.org/x/text v0.14.0 diff --git a/go.sum b/go.sum index 99da71322..d19a0dc50 100644 --- a/go.sum +++ b/go.sum @@ -856,8 +856,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= -github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index e634de7d1..ad2d65cae 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -155,12 +155,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 TestCreateScanFromFolder_NoContainerLicense_FailCreatingScan(t *testing.T) { - baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "--scan-types", "container-security", "dummy_branch"} - 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 :") -} - func TestScanCreate_ExistingApplicationAndProject_CreateProjectUnderApplicationSuccessfully(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } From 6b8ceeb9054f4059070c8fa9342c5e83879e228c Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 14:37:00 +0200 Subject: [PATCH 018/108] fix compilation errors --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9c5f987d..0af1629d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: pull_request: env: - GO_VERSION: '1.21.8' + GO_VERSION: '1.22.0' jobs: unit-tests: From 472995db79d65c946ceaf7a793b47470df8bebc2 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 14:55:10 +0200 Subject: [PATCH 019/108] fix compilation errors --- internal/commands/scan.go | 5 +---- internal/commands/scan_test.go | 2 +- internal/wrappers/container-resolver.go | 2 +- internal/wrappers/mock/container-resolver-mock.go | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index a044517e8..d311ca36d 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -95,9 +95,6 @@ const ( "\nTo use this feature, you would need to purchase a license." + "\nPlease contact our support team for assistance if you believe you have already purchased a license." + "\nLicensed packages: %s" - completedPolicy = "COMPLETED" - nonePolicy = "NONE" - evaluatingPolicy = "EVALUATING" containerResolutionFileName = "containers-resolution.json" ) @@ -1459,7 +1456,7 @@ func runContainerResolver(cmd *cobra.Command, directoryPath string) error { return containerImagesErr } } - logger.PrintIfVerbose(fmt.Sprintf("User input container images identified: %v", containerImagesList)) + logger.PrintIfVerbose(fmt.Sprintf("User input container images identified: %v", strings.Join(containerImagesList, ", "))) } containerResolverERR := containerResolver.Resolve(directoryPath, directoryPath, containerImagesList, debug) if containerResolverERR != nil { diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index ad2d65cae..b0fac2239 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -190,7 +190,7 @@ func TestCreateScanInsideApplicationProjectExistNoPermissions(t *testing.T) { func TestCreateScanSourceDirectory(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch"} - execCmdNilAssertion(t, append(baseArgs, "-s", "data", "--file-filter", "!.java")...) + execCmdNilAssertion(t, append(baseArgs, "-s", "data/sources.zip", "--file-filter", "!.java")...) } func TestCreateScanSourceFile(t *testing.T) { diff --git a/internal/wrappers/container-resolver.go b/internal/wrappers/container-resolver.go index 4eb4aef84..f96838990 100644 --- a/internal/wrappers/container-resolver.go +++ b/internal/wrappers/container-resolver.go @@ -15,6 +15,6 @@ func NewContainerResolverWrapper() ContainerResolverWrapper { return &ContainerResolverImpl{} } -func (c *ContainerResolverImpl) Resolve(scanPath string, resolutionFilePath string, images []string, isDebug bool) error { +func (c *ContainerResolverImpl) Resolve(scanPath, resolutionFilePath string, images []string, isDebug bool) error { return containersResolver.Resolve(scanPath, resolutionFilePath, images, isDebug) } diff --git a/internal/wrappers/mock/container-resolver-mock.go b/internal/wrappers/mock/container-resolver-mock.go index 2199852fa..27cb206fc 100644 --- a/internal/wrappers/mock/container-resolver-mock.go +++ b/internal/wrappers/mock/container-resolver-mock.go @@ -8,7 +8,7 @@ import ( type ContainerResolverMockWrapper struct { } -func (c *ContainerResolverMockWrapper) Resolve(scanPath string, resolutionFilePath string, images []string, isDebug bool) error { +func (c *ContainerResolverMockWrapper) Resolve(scanPath, resolutionFilePath string, images []string, isDebug bool) error { // Create the content for the container-resolution.json file (empty JSON) content := []byte("{}\n") From 3e4d7ed4bff2acc6df710181463b0cd70b02f693 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 15:10:22 +0200 Subject: [PATCH 020/108] fix compilation errors --- .golangci.yml | 2 ++ internal/commands/scan.go | 2 +- internal/wrappers/mock/container-resolver-mock.go | 14 ++++++++++---- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index ba0a3c767..11d7b897f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,6 +7,8 @@ linters-settings: allow: - $gostd - github.com/checkmarx/ast-cli/internal + - github.com/gookit/color + - github.com/CheckmarxDev/containers-resolver/pkg/containerResolver - github.com/spf13/viper - github.com/checkmarxDev/gpt-wrapper - github.com/spf13/cobra diff --git a/internal/commands/scan.go b/internal/commands/scan.go index d311ca36d..e22633032 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1102,7 +1102,7 @@ func compressFile(sourceFilePath, targetFileName string) (string, error) { folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") if folderNameBeginsIndex == -1 { - return "", errors.New("Failed to find folder name in output file name") + return "", errors.Errorf("Failed to find folder name in output file name") } folderName := outputFile.Name()[folderNameBeginsIndex:] folderName = strings.TrimSuffix(folderName, ".zip") diff --git a/internal/wrappers/mock/container-resolver-mock.go b/internal/wrappers/mock/container-resolver-mock.go index 27cb206fc..5e1eefb5a 100644 --- a/internal/wrappers/mock/container-resolver-mock.go +++ b/internal/wrappers/mock/container-resolver-mock.go @@ -1,7 +1,7 @@ package mock import ( - "io/ioutil" + "os" "path/filepath" ) @@ -12,11 +12,17 @@ func (c *ContainerResolverMockWrapper) Resolve(scanPath, resolutionFilePath stri // Create the content for the container-resolution.json file (empty JSON) content := []byte("{}\n") - // Construct the full path for the container-resolution.json file resolutionFullPath := filepath.Join(scanPath, "containers-resolution.json") - // Write the content to the container-resolution.json file - err := ioutil.WriteFile(resolutionFullPath, content, 0644) + file, err := os.Create(resolutionFullPath) + if err != nil { + return err + } + defer func(file *os.File) { + _ = file.Close() + }(file) + + _, err = file.Write(content) if err != nil { return err } From 8ca5863c365480e019f7ddac9ac40bc54898d71f Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 15:13:46 +0200 Subject: [PATCH 021/108] fix compilation errors --- 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 3b19d8fa0..42cbb3f2d 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -624,7 +624,7 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { fmt.Println(" -------------------------------------------------------- ") fmt.Printf(" | %-9s %4d %6d %4d %4d %-9s |\n", - fmt.Sprintf(color.Bold.Sprintf("TOTAL ")), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) + color.Bold.Sprintf("TOTAL "), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) fmt.Printf(" -------------------------------------------------------- \n\n") } From da9a6e103948e4541c310c6bcd99c9325285b2c6 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 15:48:53 +0200 Subject: [PATCH 022/108] fix compilation errors --- internal/commands/scan.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index e22633032..9a6f1dd2a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -451,7 +451,6 @@ func scanCreateSubCommand( policyWrapper, accessManagementWrapper, applicationsWrapper, - containersResolverWrapper, ), } createScanCmd.PersistentFlags().Bool(commonParams.AsyncFlag, false, "Do not wait for scan completion") @@ -1613,7 +1612,6 @@ func runCreateScanCommand( policyWrapper wrappers.PolicyWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, applicationsWrapper wrappers.ApplicationsWrapper, - containerResolverWrapper wrappers.ContainerResolverWrapper, ) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { err := validateScanTypes(cmd, jwtWrapper) From f798d3c18b697407ad0620eb27074bc2fb9c3c6b Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 15:57:06 +0200 Subject: [PATCH 023/108] fix compilation errors --- internal/commands/scan.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 9a6f1dd2a..aaae8ee1b 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -166,7 +166,6 @@ func NewScanCommand( policyWrapper, accessManagementWrapper, applicationsWrapper, - containerResolverWrapper, ) containerResolver = containerResolverWrapper @@ -420,7 +419,6 @@ func scanCreateSubCommand( policyWrapper wrappers.PolicyWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, applicationsWrapper wrappers.ApplicationsWrapper, - containersResolverWrapper wrappers.ContainerResolverWrapper, ) *cobra.Command { createScanCmd := &cobra.Command{ Use: "create", From 459e342bf18dcf3fcbf158367d84b91429d252f7 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 16:11:26 +0200 Subject: [PATCH 024/108] fix compilation errors --- internal/commands/scan.go | 1 - .../wrappers/mock/container-resolver-mock.go | 23 ------------------- 2 files changed, 24 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index aaae8ee1b..085598f52 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1094,7 +1094,6 @@ func compressFile(sourceFilePath, targetFileName string) (string, error) { dat, err := ioutil.ReadFile(sourceFilePath) if err != nil { logger.PrintIfVerbose(fmt.Sprintf("Failed to read file: %s\n", sourceFilePath)) - return "", err } folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") diff --git a/internal/wrappers/mock/container-resolver-mock.go b/internal/wrappers/mock/container-resolver-mock.go index 5e1eefb5a..7696a8d5e 100644 --- a/internal/wrappers/mock/container-resolver-mock.go +++ b/internal/wrappers/mock/container-resolver-mock.go @@ -1,31 +1,8 @@ package mock -import ( - "os" - "path/filepath" -) - type ContainerResolverMockWrapper struct { } func (c *ContainerResolverMockWrapper) Resolve(scanPath, resolutionFilePath string, images []string, isDebug bool) error { - // Create the content for the container-resolution.json file (empty JSON) - content := []byte("{}\n") - - resolutionFullPath := filepath.Join(scanPath, "containers-resolution.json") - - file, err := os.Create(resolutionFullPath) - if err != nil { - return err - } - defer func(file *os.File) { - _ = file.Close() - }(file) - - _, err = file.Write(content) - if err != nil { - return err - } - return nil } From 61f910d3de5496108de2cfa353feb8a5569d887b Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 16:31:38 +0200 Subject: [PATCH 025/108] fix compilation errors --- internal/commands/scan.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index e29566442..99822d049 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1137,7 +1137,7 @@ func compressFile(sourceFilePath, targetFileName string) (string, error) { return outputFile.Name(), err } -func compressFolder(sourceDir string, filter []string, userIncludeFilter []string, scaResolver string) (string, error) { +func compressFolder(sourceDir string, filter, userIncludeFilter []string, scaResolver string) (string, error) { scaToolPath := scaResolver outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") if err != nil { From 2651e1fee1ce02757960b78607babb4ba74a63a3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 16:34:57 +0200 Subject: [PATCH 026/108] fix lint issues --- internal/commands/scan.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 99822d049..062ccba0e 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -869,7 +869,7 @@ func setupScanTypeProjectAndConfig( if apiSecConfig != nil { configArr = append(configArr, apiSecConfig) } - var containersConfig, containerConfigErr = addContainersScan(cmd) + var containersConfig, containerConfigErr = addContainersScan() if containersConfig != nil { configArr = append(configArr, containersConfig) } @@ -1028,7 +1028,7 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config) map[string return nil } -func addContainersScan(cmd *cobra.Command) (map[string]interface{}, error) { +func addContainersScan() (map[string]interface{}, error) { if !scanTypeEnabled(commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { return nil, nil } @@ -1176,7 +1176,7 @@ func isSingleContainerScanTriggered(cmd *cobra.Command) bool { if len(scanTypeList) == 1 && scanTypeList[0] == commonParams.ContainersType { return true } - //check if user license supports only container scanning + // Check if user license supports only container scanning actualScanTypeList := strings.Split(actualScanTypes, ",") if len(actualScanTypeList) == 1 && actualScanTypeList[0] == commonParams.ContainersType { return true From c41aa5af8cd139926f80770a4e6ec09bb8d6b93d Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 16:37:51 +0200 Subject: [PATCH 027/108] fix lint issues --- internal/commands/scan.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 062ccba0e..16fe0897a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -869,13 +869,10 @@ func setupScanTypeProjectAndConfig( if apiSecConfig != nil { configArr = append(configArr, apiSecConfig) } - var containersConfig, containerConfigErr = addContainersScan() + var containersConfig = addContainersScan() if containersConfig != nil { configArr = append(configArr, containersConfig) } - if containerConfigErr != nil { - return containerConfigErr - } info["config"] = configArr *input, err = json.Marshal(info) return err @@ -1028,9 +1025,9 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config) map[string return nil } -func addContainersScan() (map[string]interface{}, error) { +func addContainersScan() map[string]interface{} { if !scanTypeEnabled(commonParams.ContainersType) && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { - return nil, nil + return nil } containerMapConfig := make(map[string]interface{}) containerMapConfig[resultsMapType] = commonParams.ContainersType @@ -1038,7 +1035,7 @@ func addContainersScan() (map[string]interface{}, error) { containerConfig := wrappers.ContainerConfig{} containerMapConfig[resultsMapValue] = &containerConfig - return containerMapConfig, nil + return containerMapConfig } func addAPISecScan(cmd *cobra.Command) map[string]interface{} { From a91c3086d66752a4c197a4f3809b5f3895e533f3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 16:55:42 +0200 Subject: [PATCH 028/108] fix tests --- internal/commands/scan_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 557a9673a..a2cc4452a 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -199,7 +199,7 @@ func TestCreateScanSourceDirectory(t *testing.T) { } func TestCreateScanSourceFile(t *testing.T) { - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "data/sources.zip", "-b", "dummy_branch") + execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "./data/sources.zip", "-b", "dummy_branch") } func TestCreateScanWithTrimmedSources(t *testing.T) { From 858f7f7e251255152f5f2a09218db7e7c5ba7dc5 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 17:07:19 +0200 Subject: [PATCH 029/108] check --- internal/commands/scan_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index a2cc4452a..de638accc 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -195,11 +195,11 @@ func TestCreateScanInsideApplicationProjectExistNoPermissions(t *testing.T) { func TestCreateScanSourceDirectory(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch"} - execCmdNilAssertion(t, append(baseArgs, "-s", "data/sources.zip", "--file-filter", "!.java")...) + execCmdNilAssertion(t, append(baseArgs, "-s", "internal/commands/data/sources.zip", "--file-filter", "!.java")...) } func TestCreateScanSourceFile(t *testing.T) { - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "./data/sources.zip", "-b", "dummy_branch") + execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "sources.zip", "-b", "dummy_branch") } func TestCreateScanWithTrimmedSources(t *testing.T) { From 0a39e5cd92d054934025f34e37b5d1a7942d6cb0 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 17:16:22 +0200 Subject: [PATCH 030/108] fix tests --- internal/commands/scan_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index de638accc..851960d4f 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -195,11 +195,11 @@ func TestCreateScanInsideApplicationProjectExistNoPermissions(t *testing.T) { func TestCreateScanSourceDirectory(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch"} - execCmdNilAssertion(t, append(baseArgs, "-s", "internal/commands/data/sources.zip", "--file-filter", "!.java")...) + execCmdNilAssertion(t, append(baseArgs, "-s", "data", "--file-filter", "!.java")...) } func TestCreateScanSourceFile(t *testing.T) { - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "sources.zip", "-b", "dummy_branch") + execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "data/sources.zip", "-b", "dummy_branch") } func TestCreateScanWithTrimmedSources(t *testing.T) { From 8350ee693f110ac2262572a69a0530299aade88c Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 17:29:18 +0200 Subject: [PATCH 031/108] update go version to 1.22.1 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index caf956884..81b4aac96 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/checkmarx/ast-cli -go 1.22.0 +go 1.22.1 require ( github.com/CheckmarxDev/containers-resolver v1.0.1 From 554e4214677d6aa032623f3547ccecde9c5e79b3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 17:30:16 +0200 Subject: [PATCH 032/108] update go version to 1.22.1 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0af1629d4..1f0916276 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: pull_request: env: - GO_VERSION: '1.22.0' + GO_VERSION: '1.22.1' jobs: unit-tests: From 9d794721a85325f6e0b1cdd68a54ac1e2a3d9739 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 17:58:51 +0200 Subject: [PATCH 033/108] setup timeout for golangci --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f0916276..2a7523e0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,6 +122,7 @@ jobs: version: v1.54.2 args: -c .golangci.yml only-new-issues: true + timeout-minutes: 5 govulncheck: runs-on: ubuntu-latest name: govulncheck From 528f63fc845bfb76480ba545b84cd50db68c41ca Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 18:01:55 +0200 Subject: [PATCH 034/108] setup timeout for golangci --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a7523e0c..1f0916276 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,7 +122,6 @@ jobs: version: v1.54.2 args: -c .golangci.yml only-new-issues: true - timeout-minutes: 5 govulncheck: runs-on: ubuntu-latest name: govulncheck From ea4d64aa8be9edacf5709d688dedcdcbfb014cca Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 10 Mar 2024 18:07:05 +0200 Subject: [PATCH 035/108] set up timeout for golangci --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f0916276..7809d36fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: PR_GITHUB_NAMESPACE: "checkmarx" PR_GITHUB_REPO_NAME: "ast-cli" PR_GITHUB_NUMBER: 418 - PR_GITLAB_TOKEN : ${{ secrets.PR_GITLAB_TOKEN }} + PR_GITLAB_TOKEN: ${{ secrets.PR_GITLAB_TOKEN }} PR_GITLAB_NAMESPACE: "tiagobcx" PR_GITLAB_REPO_NAME: "testProject" PR_GITLAB_PROJECT_ID: 40227565 @@ -121,6 +121,7 @@ jobs: skip-pkg-cache: true version: v1.54.2 args: -c .golangci.yml + --timeout 5m only-new-issues: true govulncheck: runs-on: ubuntu-latest From b105ff710a07ed34497ac0c076d3eaedf075561c Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 12:04:46 +0200 Subject: [PATCH 036/108] downgrade go version check --- .github/workflows/ci.yml | 2 +- go.mod | 4 ++-- go.sum | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7809d36fb..629751790 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: pull_request: env: - GO_VERSION: '1.22.1' + GO_VERSION: '1.21.8' jobs: unit-tests: diff --git a/go.mod b/go.mod index 81b4aac96..c858ffc10 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/checkmarx/ast-cli -go 1.22.1 +go 1.21.8 require ( - github.com/CheckmarxDev/containers-resolver v1.0.1 + github.com/CheckmarxDev/containers-resolver v1.0.1-down github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/go.sum b/go.sum index d19a0dc50..084327c2e 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CheckmarxDev/containers-resolver v1.0.1-down h1:f9SWI9eAqOpP2xK02vr5REvKsN/eZ0bcqTM75RPSxcA= +github.com/CheckmarxDev/containers-resolver v1.0.1-down/go.mod h1:pzpaje1Qlrxl5BtWiMMVxAErpbWFwKsuQWNTvImHzpA= github.com/CheckmarxDev/containers-resolver v1.0.1 h1:1d699fOdBiq5BcFWHAseU+fHqgd8wb3O+lDOuYS2lto= github.com/CheckmarxDev/containers-resolver v1.0.1/go.mod h1:+sNosfLkXhzpPnYFEpGH4OeO5c06QCiY7T4XakbuP3U= github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= From 01305cf94053ae4d4da9dffb4a6f1a078d4e0137 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 15:56:57 +0200 Subject: [PATCH 037/108] fix code bug --- go.mod | 4 ++-- internal/commands/scan.go | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c858ffc10..81b4aac96 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/checkmarx/ast-cli -go 1.21.8 +go 1.22.1 require ( - github.com/CheckmarxDev/containers-resolver v1.0.1-down + github.com/CheckmarxDev/containers-resolver v1.0.1 github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 16fe0897a..611876de6 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1421,7 +1421,9 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW var dirPathErr error resolversErr := runScannerResolvers(cmd, directoryPath, projectName, containerScanTriggered, scaResolver, scaResolverParams) if resolversErr != nil { - _ = cleanTempUnzipDirectory(directoryPath) + if unzip { + _ = cleanTempUnzipDirectory(directoryPath) + } return "", "", resolversErr } if isSingleContainerScanTriggered(cmd) { From e10c3c908a2c76233846c2dc18070d46712b6579 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 16:21:24 +0200 Subject: [PATCH 038/108] add license validation --- internal/commands/scan.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 611876de6..c04d51540 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -120,6 +120,7 @@ var ( aditionalParameters []string kicsErrorCodes = []string{"50", "40", "30", "20"} containerResolver wrappers.ContainerResolverWrapper + userAllowedEngines = map[string]bool{} ) func NewScanCommand( @@ -168,6 +169,7 @@ func NewScanCommand( applicationsWrapper, ) containerResolver = containerResolverWrapper + userAllowedEngines, _ = jwtWrapper.GetAllowedEngines() listScansCmd := scanListSubCommand(scansWrapper, sastMetadataWrapper) @@ -1016,7 +1018,7 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config) map[string if resubmitFilter != nil && scaConfig.Filter == "" { scaConfig.Filter = resubmitFilter.(string) } - scaConfig.EnableContainersScan = !(wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && scanTypeEnabled(commonParams.ContainersType)) + scaConfig.EnableContainersScan = !(wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && userAllowedEngines[commonParams.ContainersType]) } } scaMapConfig[resultsMapValue] = &scaConfig @@ -1030,7 +1032,7 @@ func addContainersScan() map[string]interface{} { return nil } containerMapConfig := make(map[string]interface{}) - containerMapConfig[resultsMapType] = commonParams.ContainersType + containerMapConfig[resultsMapType] = strings.ToLower(commonParams.ContainerLabel) containerConfig := wrappers.ContainerConfig{} From 51630f07eff003897ac1d173a4efe15859e8d910 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 16:34:33 +0200 Subject: [PATCH 039/108] update go.mod and go.sum --- go.mod | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- go.sum | 14 ++-- 2 files changed, 234 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index b8a2c4dcf..b6ac4a120 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/checkmarx/ast-cli -go 1.21.8 +go 1.22.1 require ( github.com/CheckmarxDev/containers-resolver v1.0.1 @@ -22,26 +22,248 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/CycloneDX/cyclonedx-go v0.8.0 // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Masterminds/squirrel v1.5.4 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/acobaugh/osrelease v0.1.0 // indirect + github.com/adrg/xdg v0.4.0 // indirect + github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65 // indirect + github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b // indirect + github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a // indirect + github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect + github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect + github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b // indirect + github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 // indirect + github.com/anchore/stereoscope v0.0.2-0.20240208195325-681f6715b0e3 // indirect + github.com/anchore/syft v0.105.0 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect + github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect + github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect + github.com/becheran/wildmatch-go v1.0.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/containerd/cgroups v1.1.0 // indirect + github.com/containerd/containerd v1.7.11 // indirect + github.com/containerd/continuity v0.4.2 // indirect + github.com/containerd/fifo v1.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/containerd/ttrpc v1.2.2 // indirect + github.com/containerd/typeurl/v2 v2.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/cli v25.0.1+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v25.0.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect + github.com/docker/go-metrics v0.0.1 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/edsrzf/mmap-go v1.1.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/facebookincubator/nvdtools v0.1.5 // indirect + github.com/fatih/color v1.14.1 // indirect + github.com/felixge/fgprof v0.9.3 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/gabriel-vasile/mimetype v1.4.0 // indirect + github.com/github/go-spdx/v2 v2.2.0 // indirect + github.com/go-errors/errors v1.4.2 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.11.0 // indirect + github.com/go-gorp/gorp/v3 v3.1.0 // indirect + github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-restruct/restruct v1.2.0-alpha // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.0.1 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-containerregistry v0.19.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/licensecheck v0.3.1 // indirect + github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/gosuri/uitable v0.0.4 // indirect + github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jinzhu/copier v0.4.0 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect + github.com/knqyf263/go-rpmdb v0.0.0-20230301153543-ba94b245509b // indirect + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/mholt/archiver/v3 v3.5.1 // indirect + github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/locker v1.0.1 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/signal v0.7.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/nwaples/rardecode v1.1.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc6 // indirect + github.com/opencontainers/runc v1.1.12 // indirect + github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect + github.com/opencontainers/selinux v1.11.0 // indirect + github.com/pborman/indent v1.2.1 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pierrec/lz4/v4 v4.1.15 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/profile v1.7.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect + github.com/rivo/uniseg v0.4.6 // indirect + github.com/rubenv/sql-migrate v1.5.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/saferwall/pe v1.5.2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect + github.com/sassoftware/go-rpmutils v0.3.0 // indirect + github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect + github.com/sergi/go-diff v1.3.1 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spdx/tools-golang v0.5.3 // 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/subosito/gotenv v1.6.0 // indirect + github.com/sylabs/sif/v2 v2.11.5 // indirect + github.com/sylabs/squashfs v0.6.1 // indirect + github.com/therootcompany/xz v1.0.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + github.com/vbatts/go-mtree v0.5.3 // indirect + github.com/vbatts/tar-split v0.11.3 // indirect + github.com/vifraa/gopom v1.0.0 // indirect + github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect + github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + github.com/xlab/treeprint v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.17.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/grpc v1.59.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + helm.sh/helm/v3 v3.14.2 // indirect + k8s.io/api v0.29.0 // indirect + k8s.io/apiextensions-apiserver v0.29.0 // indirect + k8s.io/apimachinery v0.29.0 // indirect + k8s.io/apiserver v0.29.0 // indirect + k8s.io/cli-runtime v0.29.0 // indirect + k8s.io/client-go v0.29.0 // indirect + k8s.io/component-base v0.29.0 // indirect + k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/kubectl v0.29.0 // indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + oras.land/oras-go v1.2.5 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect -) \ No newline at end of file +) diff --git a/go.sum b/go.sum index 084327c2e..4972230cf 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,6 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CheckmarxDev/containers-resolver v1.0.1-down h1:f9SWI9eAqOpP2xK02vr5REvKsN/eZ0bcqTM75RPSxcA= -github.com/CheckmarxDev/containers-resolver v1.0.1-down/go.mod h1:pzpaje1Qlrxl5BtWiMMVxAErpbWFwKsuQWNTvImHzpA= github.com/CheckmarxDev/containers-resolver v1.0.1 h1:1d699fOdBiq5BcFWHAseU+fHqgd8wb3O+lDOuYS2lto= github.com/CheckmarxDev/containers-resolver v1.0.1/go.mod h1:+sNosfLkXhzpPnYFEpGH4OeO5c06QCiY7T4XakbuP3U= github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= @@ -411,8 +409,8 @@ github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= -github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -988,8 +986,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1202,8 +1200,8 @@ golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 16b9a2eb34313718c64f18298481b6fc0afda888 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 16:36:01 +0200 Subject: [PATCH 040/108] Revert "update go.mod and go.sum" This reverts commit 51630f07eff003897ac1d173a4efe15859e8d910. --- go.mod | 234 ++------------------------------------------------------- go.sum | 14 ++-- 2 files changed, 14 insertions(+), 234 deletions(-) diff --git a/go.mod b/go.mod index b6ac4a120..b8a2c4dcf 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/checkmarx/ast-cli -go 1.22.1 +go 1.21.8 require ( github.com/CheckmarxDev/containers-resolver v1.0.1 @@ -22,248 +22,26 @@ require ( ) require ( - dario.cat/mergo v1.0.0 // indirect - github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect - github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/BurntSushi/toml v1.3.2 // indirect - github.com/CycloneDX/cyclonedx-go v0.8.0 // indirect - github.com/DataDog/zstd v1.5.5 // indirect - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver v1.5.0 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Masterminds/squirrel v1.5.4 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect - github.com/acobaugh/osrelease v0.1.0 // indirect - github.com/adrg/xdg v0.4.0 // indirect - github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65 // indirect - github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b // indirect - github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a // indirect - github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect - github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect - github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b // indirect - github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 // indirect - github.com/anchore/stereoscope v0.0.2-0.20240208195325-681f6715b0e3 // indirect - github.com/anchore/syft v0.105.0 // indirect - github.com/andybalholm/brotli v1.0.4 // indirect - github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect - github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect - github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect - github.com/becheran/wildmatch-go v1.0.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/cloudflare/circl v1.3.7 // indirect - github.com/containerd/cgroups v1.1.0 // indirect - github.com/containerd/containerd v1.7.11 // indirect - github.com/containerd/continuity v0.4.2 // indirect - github.com/containerd/fifo v1.1.0 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect - github.com/containerd/ttrpc v1.2.2 // indirect - github.com/containerd/typeurl/v2 v2.1.1 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da // indirect - github.com/distribution/reference v0.5.0 // indirect - github.com/docker/cli v25.0.1+incompatible // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v25.0.3+incompatible // indirect - github.com/docker/docker-credential-helpers v0.7.0 // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect - github.com/docker/go-metrics v0.0.1 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/edsrzf/mmap-go v1.1.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/emirpasic/gods v1.18.1 // indirect - github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect - github.com/facebookincubator/nvdtools v0.1.5 // indirect - github.com/fatih/color v1.14.1 // indirect - github.com/felixge/fgprof v0.9.3 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.0 // indirect - github.com/github/go-spdx/v2 v2.2.0 // indirect - github.com/go-errors/errors v1.4.2 // indirect - github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.11.0 // indirect - github.com/go-gorp/gorp/v3 v3.1.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-restruct/restruct v1.2.0-alpha // indirect - github.com/gobwas/glob v0.2.3 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/btree v1.0.1 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/go-containerregistry v0.19.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/licensecheck v0.3.1 // indirect - github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/gosuri/uitable v0.0.4 // indirect - github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huandu/xstrings v1.4.0 // indirect - github.com/iancoleman/strcase v0.3.0 // indirect - github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jinzhu/copier v0.4.0 // indirect - github.com/jmoiron/sqlx v1.3.5 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/compress v1.17.4 // indirect - github.com/klauspost/pgzip v1.2.5 // indirect - github.com/knqyf263/go-rpmdb v0.0.0-20230301153543-ba94b245509b // indirect - github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect - github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect - github.com/lib/pq v1.10.9 // indirect - github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mholt/archiver/v3 v3.5.1 // indirect - github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/locker v1.0.1 // indirect - github.com/moby/spdystream v0.2.0 // indirect - github.com/moby/sys/mountinfo v0.7.1 // indirect - github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/signal v0.7.0 // indirect - github.com/moby/term v0.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/nwaples/rardecode v1.1.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc6 // indirect - github.com/opencontainers/runc v1.1.12 // indirect - github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect - github.com/opencontainers/selinux v1.11.0 // indirect - github.com/pborman/indent v1.2.1 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pierrec/lz4/v4 v4.1.15 // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/pkg/profile v1.7.0 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect - github.com/rivo/uniseg v0.4.6 // indirect - github.com/rubenv/sql-migrate v1.5.2 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/saferwall/pe v1.5.2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect - github.com/sassoftware/go-rpmutils v0.3.0 // indirect - github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect - github.com/sergi/go-diff v1.3.1 // indirect - github.com/shopspring/decimal v1.3.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skeema/knownhosts v1.2.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spdx/tools-golang v0.5.3 // 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/subosito/gotenv v1.6.0 // indirect - github.com/sylabs/sif/v2 v2.11.5 // indirect - github.com/sylabs/squashfs v0.6.1 // indirect - github.com/therootcompany/xz v1.0.1 // indirect - github.com/ulikunitz/xz v0.5.11 // indirect - github.com/vbatts/go-mtree v0.5.3 // indirect - github.com/vbatts/tar-split v0.11.3 // indirect - github.com/vifraa/gopom v1.0.0 // indirect - github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect - github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 // indirect - github.com/xanzy/ssh-agent v0.3.3 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect - github.com/xlab/treeprint v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect - go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.6.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.17.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - helm.sh/helm/v3 v3.14.2 // indirect - k8s.io/api v0.29.0 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/apimachinery v0.29.0 // indirect - k8s.io/apiserver v0.29.0 // indirect - k8s.io/cli-runtime v0.29.0 // indirect - k8s.io/client-go v0.29.0 // indirect - k8s.io/component-base v0.29.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/kubectl v0.29.0 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - oras.land/oras-go v1.2.5 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect -) +) \ No newline at end of file diff --git a/go.sum b/go.sum index 4972230cf..084327c2e 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CheckmarxDev/containers-resolver v1.0.1-down h1:f9SWI9eAqOpP2xK02vr5REvKsN/eZ0bcqTM75RPSxcA= +github.com/CheckmarxDev/containers-resolver v1.0.1-down/go.mod h1:pzpaje1Qlrxl5BtWiMMVxAErpbWFwKsuQWNTvImHzpA= github.com/CheckmarxDev/containers-resolver v1.0.1 h1:1d699fOdBiq5BcFWHAseU+fHqgd8wb3O+lDOuYS2lto= github.com/CheckmarxDev/containers-resolver v1.0.1/go.mod h1:+sNosfLkXhzpPnYFEpGH4OeO5c06QCiY7T4XakbuP3U= github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= @@ -409,8 +411,8 @@ github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -986,8 +988,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1200,8 +1202,8 @@ golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 909eee09eb7dd11154b7e41345cf1c4053239d87 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 16:39:43 +0200 Subject: [PATCH 041/108] update go.mod and go.sum --- go.mod | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- go.sum | 14 ++-- 2 files changed, 234 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index b8a2c4dcf..b6ac4a120 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/checkmarx/ast-cli -go 1.21.8 +go 1.22.1 require ( github.com/CheckmarxDev/containers-resolver v1.0.1 @@ -22,26 +22,248 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/CycloneDX/cyclonedx-go v0.8.0 // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Masterminds/squirrel v1.5.4 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/acobaugh/osrelease v0.1.0 // indirect + github.com/adrg/xdg v0.4.0 // indirect + github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65 // indirect + github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b // indirect + github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a // indirect + github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect + github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect + github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b // indirect + github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 // indirect + github.com/anchore/stereoscope v0.0.2-0.20240208195325-681f6715b0e3 // indirect + github.com/anchore/syft v0.105.0 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect + github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect + github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect + github.com/becheran/wildmatch-go v1.0.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/containerd/cgroups v1.1.0 // indirect + github.com/containerd/containerd v1.7.11 // indirect + github.com/containerd/continuity v0.4.2 // indirect + github.com/containerd/fifo v1.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/containerd/ttrpc v1.2.2 // indirect + github.com/containerd/typeurl/v2 v2.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/cli v25.0.1+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v25.0.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect + github.com/docker/go-metrics v0.0.1 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/edsrzf/mmap-go v1.1.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/facebookincubator/nvdtools v0.1.5 // indirect + github.com/fatih/color v1.14.1 // indirect + github.com/felixge/fgprof v0.9.3 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/gabriel-vasile/mimetype v1.4.0 // indirect + github.com/github/go-spdx/v2 v2.2.0 // indirect + github.com/go-errors/errors v1.4.2 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.11.0 // indirect + github.com/go-gorp/gorp/v3 v3.1.0 // indirect + github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-restruct/restruct v1.2.0-alpha // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.0.1 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-containerregistry v0.19.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/licensecheck v0.3.1 // indirect + github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/gosuri/uitable v0.0.4 // indirect + github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jinzhu/copier v0.4.0 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect + github.com/knqyf263/go-rpmdb v0.0.0-20230301153543-ba94b245509b // indirect + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/mholt/archiver/v3 v3.5.1 // indirect + github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/locker v1.0.1 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/signal v0.7.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/nwaples/rardecode v1.1.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc6 // indirect + github.com/opencontainers/runc v1.1.12 // indirect + github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect + github.com/opencontainers/selinux v1.11.0 // indirect + github.com/pborman/indent v1.2.1 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pierrec/lz4/v4 v4.1.15 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/profile v1.7.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect + github.com/rivo/uniseg v0.4.6 // indirect + github.com/rubenv/sql-migrate v1.5.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/saferwall/pe v1.5.2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect + github.com/sassoftware/go-rpmutils v0.3.0 // indirect + github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect + github.com/sergi/go-diff v1.3.1 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spdx/tools-golang v0.5.3 // 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/subosito/gotenv v1.6.0 // indirect + github.com/sylabs/sif/v2 v2.11.5 // indirect + github.com/sylabs/squashfs v0.6.1 // indirect + github.com/therootcompany/xz v1.0.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + github.com/vbatts/go-mtree v0.5.3 // indirect + github.com/vbatts/tar-split v0.11.3 // indirect + github.com/vifraa/gopom v1.0.0 // indirect + github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect + github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + github.com/xlab/treeprint v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.17.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/grpc v1.59.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + helm.sh/helm/v3 v3.14.2 // indirect + k8s.io/api v0.29.0 // indirect + k8s.io/apiextensions-apiserver v0.29.0 // indirect + k8s.io/apimachinery v0.29.0 // indirect + k8s.io/apiserver v0.29.0 // indirect + k8s.io/cli-runtime v0.29.0 // indirect + k8s.io/client-go v0.29.0 // indirect + k8s.io/component-base v0.29.0 // indirect + k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/kubectl v0.29.0 // indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + oras.land/oras-go v1.2.5 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect -) \ No newline at end of file +) diff --git a/go.sum b/go.sum index 084327c2e..4972230cf 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,6 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CheckmarxDev/containers-resolver v1.0.1-down h1:f9SWI9eAqOpP2xK02vr5REvKsN/eZ0bcqTM75RPSxcA= -github.com/CheckmarxDev/containers-resolver v1.0.1-down/go.mod h1:pzpaje1Qlrxl5BtWiMMVxAErpbWFwKsuQWNTvImHzpA= github.com/CheckmarxDev/containers-resolver v1.0.1 h1:1d699fOdBiq5BcFWHAseU+fHqgd8wb3O+lDOuYS2lto= github.com/CheckmarxDev/containers-resolver v1.0.1/go.mod h1:+sNosfLkXhzpPnYFEpGH4OeO5c06QCiY7T4XakbuP3U= github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= @@ -411,8 +409,8 @@ github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= -github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -988,8 +986,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1202,8 +1200,8 @@ golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 1b78d90c53860931a9cf140f05dc5cbc9b636699 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 16:44:58 +0200 Subject: [PATCH 042/108] update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 629751790..7809d36fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: pull_request: env: - GO_VERSION: '1.21.8' + GO_VERSION: '1.22.1' jobs: unit-tests: From 640541b77c2d130308639f4f70b21491cc080a9a Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 11 Mar 2024 17:26:47 +0200 Subject: [PATCH 043/108] update isSingleContainerScanTriggered function --- internal/commands/scan.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index c04d51540..e09693a1a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1172,15 +1172,8 @@ func isSingleContainerScanTriggered(cmd *cobra.Command) bool { if len(scanTypes) > 0 { scanTypeList = strings.Split(scanTypes, ",") } - if len(scanTypeList) == 1 && scanTypeList[0] == commonParams.ContainersType { - return true - } - // Check if user license supports only container scanning - actualScanTypeList := strings.Split(actualScanTypes, ",") - if len(actualScanTypeList) == 1 && actualScanTypeList[0] == commonParams.ContainersType { - return true - } - return false + // If the scan type is not provided, we check if user has license for container engine + return (len(scanTypeList) == 1 && scanTypeList[0] == commonParams.ContainersType) || userAllowedEngines[commonParams.ContainersType] } func getIncludeFilters(userIncludeFilter string) []string { From e4762997dd3b1df01058ef4f43d99477060fc31a Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 12 Mar 2024 16:22:49 +0200 Subject: [PATCH 044/108] moved compressFile to utils.go --- internal/commands/scan.go | 40 +--------------------------- internal/commands/util/utils.go | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index e09693a1a..4369bd422 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1097,44 +1097,6 @@ func scanTypeEnabled(scanType string) bool { } return false } -func compressFile(sourceFilePath, targetFileName string) (string, error) { - outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") - if err != nil { - return "", errors.Wrapf(err, "Cannot source code temp file.") - } - zipWriter := zip.NewWriter(outputFile) - dat, err := ioutil.ReadFile(sourceFilePath) - if err != nil { - logger.PrintIfVerbose(fmt.Sprintf("Failed to read file: %s\n", sourceFilePath)) - } - - folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") - if folderNameBeginsIndex == -1 { - return "", errors.Errorf("Failed to find folder name in output file name") - } - folderName := outputFile.Name()[folderNameBeginsIndex:] - folderName = strings.TrimSuffix(folderName, ".zip") - - f, err := zipWriter.Create(filepath.Join(folderName, targetFileName)) - if err != nil { - return "", err - } - _, err = f.Write(dat) - if err != nil { - return "", err - } - // Close the file - err = zipWriter.Close() - if err != nil { - return "", err - } - stat, err := outputFile.Stat() - if err != nil { - return "", err - } - logger.PrintIfVerbose(fmt.Sprintf("Zip size: %.2fMB\n", float64(stat.Size())/mbBytes)) - return outputFile.Name(), err -} func compressFolder(sourceDir string, filter, userIncludeFilter []string, scaResolver string) (string, error) { scaToolPath := scaResolver @@ -1424,7 +1386,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW if isSingleContainerScanTriggered(cmd) { logger.PrintIfVerbose("Single container scan triggered: compressing only the container resolution file") containerResolutionFilePath := filepath.Join(directoryPath, containerResolutionFileName) - zipFilePath, dirPathErr = compressFile(containerResolutionFilePath, containerResolutionFileName) + zipFilePath, dirPathErr = util.CompressFile(containerResolutionFilePath, containerResolutionFileName) } else { zipFilePath, dirPathErr = compressFolder(directoryPath, getUserFilters(sourceDirFilter), getIncludeFilters(userIncludeFilter), scaResolver) } diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 52e98a8f0..f2f7d46a8 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -1,14 +1,20 @@ package util import ( + "archive/zip" "fmt" + "io/ioutil" "os" + "path/filepath" "regexp" + "strings" "github.com/MakeNowJust/heredoc" "github.com/checkmarx/ast-cli/internal/commands/util/usercount" + "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/checkmarx/ast-cli/internal/wrappers/bitbucketserver" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -16,6 +22,7 @@ const ( gitURLRegex = "(?P:git|ssh|https?|git@[-\\w.]+):(\\/\\/)?(?P.*?)(\\.git)?$" sshURLRegex = "^(?P.*?)@(?P.*?):(?:(?P.*?)/)?(?P.*?/.*?)$" invalidFlag = "Value of %s is invalid" + mbBytes = 1024.0 * 1024.0 ) func NewUtilsCommand( @@ -128,3 +135,42 @@ func ReadFileAsString(path string) (string, error) { return string(content), nil } + +func CompressFile(sourceFilePath, targetFileName string) (string, error) { + outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") + if err != nil { + return "", errors.Wrapf(err, "Cannot source code temp file.") + } + zipWriter := zip.NewWriter(outputFile) + data, err := ioutil.ReadFile(sourceFilePath) + if err != nil { + logger.PrintIfVerbose(fmt.Sprintf("Failed to read file: %s\n", sourceFilePath)) + } + + folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") + if folderNameBeginsIndex == -1 { + return "", errors.Errorf("Failed to find folder name in output file name") + } + folderName := outputFile.Name()[folderNameBeginsIndex:] + folderName = strings.TrimSuffix(folderName, ".zip") + + f, err := zipWriter.Create(filepath.Join(folderName, targetFileName)) + if err != nil { + return "", err + } + _, err = f.Write(data) + if err != nil { + return "", err + } + // Close the file + err = zipWriter.Close() + if err != nil { + return "", err + } + stat, err := outputFile.Stat() + if err != nil { + return "", err + } + logger.PrintIfVerbose(fmt.Sprintf("Zip size: %.2fMB\n", float64(stat.Size())/mbBytes)) + return outputFile.Name(), err +} From 1d26a66c020399c65242f123c3ad805045980f29 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 12 Mar 2024 16:33:03 +0200 Subject: [PATCH 045/108] moved compressFile to utils.go --- internal/commands/util/utils.go | 44 +++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index f2f7d46a8..e1505899c 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -3,7 +3,7 @@ package util import ( "archive/zip" "fmt" - "io/ioutil" + "io" "os" "path/filepath" "regexp" @@ -137,15 +137,35 @@ func ReadFileAsString(path string) (string, error) { } func CompressFile(sourceFilePath, targetFileName string) (string, error) { - outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") + outputFile, err := os.CreateTemp(os.TempDir(), "cx-*.zip") if err != nil { - return "", errors.Wrapf(err, "Cannot source code temp file.") + return "", errors.Wrapf(err, "Cannot create temp file") } + defer func(outputFile *os.File) { + err := outputFile.Close() + if err != nil { + logger.PrintfIfVerbose("Failed to close file: %s", outputFile.Name()) + } + }(outputFile) + zipWriter := zip.NewWriter(outputFile) - data, err := ioutil.ReadFile(sourceFilePath) + defer func(zipWriter *zip.Writer) { + err := zipWriter.Close() + if err != nil { + logger.PrintfIfVerbose("Failed to close zip writer: %s", outputFile.Name()) + } + }(zipWriter) + + dataFile, err := os.Open(sourceFilePath) if err != nil { - logger.PrintIfVerbose(fmt.Sprintf("Failed to read file: %s\n", sourceFilePath)) + return "", errors.Wrapf(err, "Failed to open file: %s", sourceFilePath) } + defer func(dataFile *os.File) { + err := dataFile.Close() + if err != nil { + logger.PrintfIfVerbose("Failed to close file: %s", dataFile.Name()) + } + }(dataFile) folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") if folderNameBeginsIndex == -1 { @@ -158,19 +178,17 @@ func CompressFile(sourceFilePath, targetFileName string) (string, error) { if err != nil { return "", err } - _, err = f.Write(data) - if err != nil { - return "", err - } - // Close the file - err = zipWriter.Close() + + _, err = io.Copy(f, dataFile) if err != nil { return "", err } + stat, err := outputFile.Stat() if err != nil { return "", err } - logger.PrintIfVerbose(fmt.Sprintf("Zip size: %.2fMB\n", float64(stat.Size())/mbBytes)) - return outputFile.Name(), err + + fmt.Printf("Zip size: %fMB\n", float64(stat.Size())/mbBytes) + return outputFile.Name(), nil } From 8b07786917d78960fa8429184a33fc65436c8978 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 12 Mar 2024 16:33:48 +0200 Subject: [PATCH 046/108] moved compressFile to utils.go --- internal/commands/util/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index e1505899c..da627f396 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -189,6 +189,6 @@ func CompressFile(sourceFilePath, targetFileName string) (string, error) { return "", err } - fmt.Printf("Zip size: %fMB\n", float64(stat.Size())/mbBytes) + fmt.Printf("Zip size: %.3fMB\n", float64(stat.Size())/mbBytes) return outputFile.Name(), nil } From aaff702da8b6ad266d48b450ec60bd43028d8537 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 12 Mar 2024 16:50:33 +0200 Subject: [PATCH 047/108] moved compressFile to utils.go --- internal/commands/util/utils.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index da627f396..fb55aa7e3 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -142,16 +142,16 @@ func CompressFile(sourceFilePath, targetFileName string) (string, error) { return "", errors.Wrapf(err, "Cannot create temp file") } defer func(outputFile *os.File) { - err := outputFile.Close() - if err != nil { + CloseFileErr := outputFile.Close() + if CloseFileErr != nil { logger.PrintfIfVerbose("Failed to close file: %s", outputFile.Name()) } }(outputFile) zipWriter := zip.NewWriter(outputFile) defer func(zipWriter *zip.Writer) { - err := zipWriter.Close() - if err != nil { + closeZipWriterError := zipWriter.Close() + if closeZipWriterError != nil { logger.PrintfIfVerbose("Failed to close zip writer: %s", outputFile.Name()) } }(zipWriter) @@ -161,8 +161,8 @@ func CompressFile(sourceFilePath, targetFileName string) (string, error) { return "", errors.Wrapf(err, "Failed to open file: %s", sourceFilePath) } defer func(dataFile *os.File) { - err := dataFile.Close() - if err != nil { + closeDataFileError := dataFile.Close() + if closeDataFileError != nil { logger.PrintfIfVerbose("Failed to close file: %s", dataFile.Name()) } }(dataFile) From 9a33765891893c873125f89993ef17f4ef408126 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 12 Mar 2024 16:51:06 +0200 Subject: [PATCH 048/108] moved compressFile to utils.go --- internal/commands/util/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index fb55aa7e3..eb260b873 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -158,7 +158,7 @@ func CompressFile(sourceFilePath, targetFileName string) (string, error) { dataFile, err := os.Open(sourceFilePath) if err != nil { - return "", errors.Wrapf(err, "Failed to open file: %s", sourceFilePath) + logger.PrintfIfVerbose("Failed to open file: %s", sourceFilePath) } defer func(dataFile *os.File) { closeDataFileError := dataFile.Close() From 8ff427346bfe5953c19d6347d8c4a3cf7a46e0d3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 12 Mar 2024 17:11:10 +0200 Subject: [PATCH 049/108] moved compressFile to utils.go --- internal/commands/util/utils.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index eb260b873..fdb05bcc6 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -160,35 +160,36 @@ func CompressFile(sourceFilePath, targetFileName string) (string, error) { if err != nil { logger.PrintfIfVerbose("Failed to open file: %s", sourceFilePath) } - defer func(dataFile *os.File) { - closeDataFileError := dataFile.Close() - if closeDataFileError != nil { - logger.PrintfIfVerbose("Failed to close file: %s", dataFile.Name()) - } - }(dataFile) + if dataFile != nil { + defer func(dataFile *os.File) { + closeDataFileError := dataFile.Close() + if closeDataFileError != nil { + logger.PrintfIfVerbose("Failed to close file: %s", dataFile.Name()) + } + }(dataFile) + } folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") if folderNameBeginsIndex == -1 { - return "", errors.Errorf("Failed to find folder name in output file name") + logger.PrintfIfVerbose("Failed to find folder name in file: %s", outputFile.Name()) } folderName := outputFile.Name()[folderNameBeginsIndex:] folderName = strings.TrimSuffix(folderName, ".zip") f, err := zipWriter.Create(filepath.Join(folderName, targetFileName)) if err != nil { - return "", err + logger.PrintfIfVerbose("Failed to create file in zip: %s", targetFileName) } _, err = io.Copy(f, dataFile) if err != nil { - return "", err + logger.PrintfIfVerbose("Failed to copy file to zip: %s", targetFileName) } stat, err := outputFile.Stat() if err != nil { - return "", err + logger.PrintfIfVerbose("Failed to get file stat: %s", outputFile.Name()) } - fmt.Printf("Zip size: %.3fMB\n", float64(stat.Size())/mbBytes) return outputFile.Name(), nil } From f85a29b041b6835350a9a67d161179672479b0ae Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 09:41:38 +0200 Subject: [PATCH 050/108] update up.sh script to run the old version of go coverage --- internal/commands/.scripts/up.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 internal/commands/.scripts/up.sh diff --git a/internal/commands/.scripts/up.sh b/internal/commands/.scripts/up.sh old mode 100644 new mode 100755 index 7d5485431..077f473c4 --- 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 -go test ./... -coverprofile cover.out +GOEXPERIMENT=nocoverageredesign go test -cover ./... \ No newline at end of file From fa9102826a0c1c28ef29c024391db8347d49ffb4 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 09:55:26 +0200 Subject: [PATCH 051/108] update up.sh script to run the old version of go coverage --- internal/commands/.scripts/up.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/.scripts/up.sh b/internal/commands/.scripts/up.sh index 077f473c4..8ae4f0e6e 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 -GOEXPERIMENT=nocoverageredesign go test -cover ./... \ No newline at end of file +GOEXPERIMENT=nocoverageredesign go test ./... -coverprofile cover.out From e71b1457093599bffd5983990cb289520bff29ee Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 10:50:33 +0200 Subject: [PATCH 052/108] improve utils_test.go coverage --- internal/commands/util/utils_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index 7e5a52c1c..fed43fe6e 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -13,3 +13,19 @@ func TestNewUtilsCommand(t *testing.T) { nil, nil, nil, nil, nil, nil, nil) assert.Assert(t, cmd != nil, "Utils command must exist") } + +func TestCompressFile(t *testing.T) { + _, err := CompressFile("package.json", "package.json") + assert.NilError(t, err, "CompressFile must run well") +} + +// test ReadFileAsString +func TestReadFileAsString_Success(t *testing.T) { + _, err := ReadFileAsString("../data/package.json") + assert.NilError(t, err, "ReadFileAsString must run well") +} + +func TestReadFileAsString_NoFile_Fail(t *testing.T) { + _, err := ReadFileAsString("no-file-exists-with-this-name.json") + assert.Error(t, err, "open no-file-exists-with-this-name.json: no such file or directory") +} From 64d47bc116eb272c24737dc897e34f5980a2f861 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 12:05:48 +0200 Subject: [PATCH 053/108] improve utils_test.go coverage and resolve conversations --- internal/commands/scan.go | 3 +- .../commands/util/printer/printer_test.go | 17 ++++++ internal/commands/util/utils.go | 58 ++++++++++--------- internal/commands/util/utils_test.go | 17 +++++- 4 files changed, 65 insertions(+), 30 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 4369bd422..139b80d1f 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -96,6 +96,7 @@ const ( "\nPlease contact our support team for assistance if you believe you have already purchased a license." + "\nLicensed packages: %s" containerResolutionFileName = "containers-resolution.json" + directoryCreationPrefix = "cx-" ) var ( @@ -1386,7 +1387,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW if isSingleContainerScanTriggered(cmd) { logger.PrintIfVerbose("Single container scan triggered: compressing only the container resolution file") containerResolutionFilePath := filepath.Join(directoryPath, containerResolutionFileName) - zipFilePath, dirPathErr = util.CompressFile(containerResolutionFilePath, containerResolutionFileName) + zipFilePath, dirPathErr = util.CompressFile(containerResolutionFilePath, containerResolutionFileName, directoryCreationPrefix) } else { zipFilePath, dirPathErr = compressFolder(directoryPath, getUserFilters(sourceDirFilter), getIncludeFilters(userIncludeFilter), scaResolver) } diff --git a/internal/commands/util/printer/printer_test.go b/internal/commands/util/printer/printer_test.go index afe2e3e61..a63f9ab97 100644 --- a/internal/commands/util/printer/printer_test.go +++ b/internal/commands/util/printer/printer_test.go @@ -46,3 +46,20 @@ func TestPrintTable(t *testing.T) { err = Print(os.Stdout, []string{"column1", "column2", "column3"}, FormatTable) assert.NilError(t, err, "table print must run well") } + +// test is format +func TestIsFormat(t *testing.T) { + assert.Assert(t, IsFormat("json", FormatJSON), "json is a valid format") + assert.Assert(t, IsFormat("JSON", FormatJSON), "JSON is a valid format") + assert.Assert(t, IsFormat("list", FormatList), "list is a valid format") + assert.Assert(t, IsFormat("table", FormatTable), "table is a valid format") + assert.Assert(t, !IsFormat("invalid_format", FormatTable), "invalid_format is not a valid format") +} + +func TestColumnReformat(t *testing.T) { + // Test nil + columnReformat(nil) + + // Test empty + columnReformat([]*entity{}) +} diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index fdb05bcc6..6fda5e9e7 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -19,10 +19,11 @@ import ( ) const ( - gitURLRegex = "(?P:git|ssh|https?|git@[-\\w.]+):(\\/\\/)?(?P.*?)(\\.git)?$" - sshURLRegex = "^(?P.*?)@(?P.*?):(?:(?P.*?)/)?(?P.*?/.*?)$" - invalidFlag = "Value of %s is invalid" - mbBytes = 1024.0 * 1024.0 + gitURLRegex = "(?P:git|ssh|https?|git@[-\\w.]+):(\\/\\/)?(?P.*?)(\\.git)?$" + sshURLRegex = "^(?P.*?)@(?P.*?):(?:(?P.*?)/)?(?P.*?/.*?)$" + invalidFlag = "Value of %s is invalid" + mbBytes = 1024.0 * 1024.0 + directoryPrefix = "cx-" ) func NewUtilsCommand( @@ -136,38 +137,21 @@ func ReadFileAsString(path string) (string, error) { return string(content), nil } -func CompressFile(sourceFilePath, targetFileName string) (string, error) { - outputFile, err := os.CreateTemp(os.TempDir(), "cx-*.zip") +func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix ...string) (string, error) { + if len(createdDirectoryPrefix) == 0 { + createdDirectoryPrefix = append(createdDirectoryPrefix, directoryPrefix) + } + outputFile, err := os.CreateTemp(os.TempDir(), createdDirectoryPrefix[0]+"*.zip") if err != nil { return "", errors.Wrapf(err, "Cannot create temp file") } - defer func(outputFile *os.File) { - CloseFileErr := outputFile.Close() - if CloseFileErr != nil { - logger.PrintfIfVerbose("Failed to close file: %s", outputFile.Name()) - } - }(outputFile) zipWriter := zip.NewWriter(outputFile) - defer func(zipWriter *zip.Writer) { - closeZipWriterError := zipWriter.Close() - if closeZipWriterError != nil { - logger.PrintfIfVerbose("Failed to close zip writer: %s", outputFile.Name()) - } - }(zipWriter) dataFile, err := os.Open(sourceFilePath) if err != nil { logger.PrintfIfVerbose("Failed to open file: %s", sourceFilePath) } - if dataFile != nil { - defer func(dataFile *os.File) { - closeDataFileError := dataFile.Close() - if closeDataFileError != nil { - logger.PrintfIfVerbose("Failed to close file: %s", dataFile.Name()) - } - }(dataFile) - } folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") if folderNameBeginsIndex == -1 { @@ -189,7 +173,27 @@ func CompressFile(sourceFilePath, targetFileName string) (string, error) { stat, err := outputFile.Stat() if err != nil { logger.PrintfIfVerbose("Failed to get file stat: %s", outputFile.Name()) + } else { + fmt.Printf("Zip size: %.3fMB\n", float64(stat.Size())/mbBytes) } - fmt.Printf("Zip size: %.3fMB\n", float64(stat.Size())/mbBytes) + + defer DeferCloseFileAndWriter(zipWriter, dataFile, outputFile) return outputFile.Name(), nil } + +func DeferCloseFileAndWriter(writer *zip.Writer, files ...*os.File) { + for _, file := range files { + if file != nil { + err := file.Close() + if err != nil { + logger.PrintfIfVerbose("Failed to close file: %s", file.Name()) + } + } + } + if writer != nil { + err := writer.Close() + if err != nil { + logger.PrintfIfVerbose("Failed to close zip writer") + } + } +} diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index fed43fe6e..8828d9007 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -1,6 +1,7 @@ package util import ( + "os" "testing" "gotest.tools/assert" @@ -14,8 +15,13 @@ func TestNewUtilsCommand(t *testing.T) { assert.Assert(t, cmd != nil, "Utils command must exist") } -func TestCompressFile(t *testing.T) { - _, err := CompressFile("package.json", "package.json") +func TestCompressFile_Success(t *testing.T) { + _, err := CompressFile("package.json", "package.json", "cx-") + assert.NilError(t, err, "CompressFile must run well") +} + +func TestCompressFile_Fail(t *testing.T) { + _, err := CompressFile("package.json", "package.json", "cx-") assert.NilError(t, err, "CompressFile must run well") } @@ -29,3 +35,10 @@ func TestReadFileAsString_NoFile_Fail(t *testing.T) { _, err := ReadFileAsString("no-file-exists-with-this-name.json") assert.Error(t, err, "open no-file-exists-with-this-name.json: no such file or directory") } + +// test DeferCloseFileAndWriter +func TestDeferCloseFileAndWriter_OnlyFile(t *testing.T) { + file, err := os.OpenFile("../data/package.json", os.O_RDWR, 0644) + assert.NilError(t, err, "OpenFile must run well") + defer DeferCloseFileAndWriter(nil, file) +} From 74ffcf74785df22aa978aef355109aa322089c2c Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 12:20:54 +0200 Subject: [PATCH 054/108] remove unncessery defer --- internal/commands/util/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 6fda5e9e7..5f9aaac6b 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -177,7 +177,7 @@ func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix fmt.Printf("Zip size: %.3fMB\n", float64(stat.Size())/mbBytes) } - defer DeferCloseFileAndWriter(zipWriter, dataFile, outputFile) + DeferCloseFileAndWriter(zipWriter, dataFile, outputFile) return outputFile.Name(), nil } From 4d7902917b4b04c1e5ce7eb83692ccce25eb0392 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 12:27:29 +0200 Subject: [PATCH 055/108] remove unncessery defer --- internal/commands/util/utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 5f9aaac6b..9b622f46b 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -177,11 +177,11 @@ func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix fmt.Printf("Zip size: %.3fMB\n", float64(stat.Size())/mbBytes) } - DeferCloseFileAndWriter(zipWriter, dataFile, outputFile) + CloseFilesAndWriter(zipWriter, dataFile, outputFile) return outputFile.Name(), nil } -func DeferCloseFileAndWriter(writer *zip.Writer, files ...*os.File) { +func CloseFilesAndWriter(writer *zip.Writer, files ...*os.File) { for _, file := range files { if file != nil { err := file.Close() From 25371c2f1bd457a4cc284480a4097a8ba746d1a3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 12:45:06 +0200 Subject: [PATCH 056/108] remove unncessery defer --- internal/commands/util/utils_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index 8828d9007..1af9f8f8a 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -40,5 +40,5 @@ func TestReadFileAsString_NoFile_Fail(t *testing.T) { func TestDeferCloseFileAndWriter_OnlyFile(t *testing.T) { file, err := os.OpenFile("../data/package.json", os.O_RDWR, 0644) assert.NilError(t, err, "OpenFile must run well") - defer DeferCloseFileAndWriter(nil, file) + defer CloseFilesAndWriter(nil, file) } From d5d0c73f1d7930014dad493ee58b0a94c6cb28a1 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 12:49:23 +0200 Subject: [PATCH 057/108] remove unncessery defer --- internal/commands/util/utils_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index 1af9f8f8a..b95e86a72 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -40,5 +40,5 @@ func TestReadFileAsString_NoFile_Fail(t *testing.T) { func TestDeferCloseFileAndWriter_OnlyFile(t *testing.T) { file, err := os.OpenFile("../data/package.json", os.O_RDWR, 0644) assert.NilError(t, err, "OpenFile must run well") - defer CloseFilesAndWriter(nil, file) + CloseFilesAndWriter(nil, file) } From ba3c15ee7167e9e26892ea534d57f05982d32676 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 13:22:45 +0200 Subject: [PATCH 058/108] add test to utils-test --- internal/commands/util/utils.go | 6 +++--- internal/commands/util/utils_test.go | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 9b622f46b..4d74fc902 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -138,8 +138,8 @@ func ReadFileAsString(path string) (string, error) { } func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix ...string) (string, error) { - if len(createdDirectoryPrefix) == 0 { - createdDirectoryPrefix = append(createdDirectoryPrefix, directoryPrefix) + if len(createdDirectoryPrefix) == 0 || createdDirectoryPrefix[0] == "" { + createdDirectoryPrefix = []string{directoryPrefix} } outputFile, err := os.CreateTemp(os.TempDir(), createdDirectoryPrefix[0]+"*.zip") if err != nil { @@ -153,7 +153,7 @@ func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix logger.PrintfIfVerbose("Failed to open file: %s", sourceFilePath) } - folderNameBeginsIndex := strings.Index(outputFile.Name(), "cx-") + folderNameBeginsIndex := strings.Index(outputFile.Name(), createdDirectoryPrefix[0]) if folderNameBeginsIndex == -1 { logger.PrintfIfVerbose("Failed to find folder name in file: %s", outputFile.Name()) } diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index b95e86a72..122fc5faa 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -2,6 +2,7 @@ package util import ( "os" + "strings" "testing" "gotest.tools/assert" @@ -36,9 +37,15 @@ func TestReadFileAsString_NoFile_Fail(t *testing.T) { assert.Error(t, err, "open no-file-exists-with-this-name.json: no such file or directory") } -// test DeferCloseFileAndWriter func TestDeferCloseFileAndWriter_OnlyFile(t *testing.T) { file, err := os.OpenFile("../data/package.json", os.O_RDWR, 0644) assert.NilError(t, err, "OpenFile must run well") CloseFilesAndWriter(nil, file) } + +func TestCompressFile_EmptyDirectoryPrefix(t *testing.T) { + outputFileName, err := CompressFile("testfile.txt", "output.zip", "") + assert.NilError(t, err) + // Assert that the output file name contains the default prefix + assert.Assert(t, strings.Contains(outputFileName, "cx-")) +} From c03c817013ac7c2c42eed78b814a9cc62286895c Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 14:19:19 +0200 Subject: [PATCH 059/108] add test to wrapper/utils-test --- internal/commands/root.go | 29 +++++------- internal/commands/scan.go | 8 +++- internal/wrappers/utils/utils_test.go | 65 +++++++++++++++++++++++---- 3 files changed, 72 insertions(+), 30 deletions(-) diff --git a/internal/commands/root.go b/internal/commands/root.go index 483436f0f..c67558966 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -54,6 +54,7 @@ func NewAstCLI( accessManagementWrapper wrappers.AccessManagementWrapper, containerResolverWrapper wrappers.ContainerResolverWrapper, ) *cobra.Command { + setUpFeatureFlags(featureFlagsWrapper) // Create the root rootCmd := &cobra.Command{ Use: "cx [flags]", @@ -107,15 +108,6 @@ func NewAstCLI( _ = cmd.Help() os.Exit(0) } - - if requiredFeatureFlagsCheck(cmd) { - err := wrappers.HandleFeatureFlags(featureFlagsWrapper) - - if err != nil { - fmt.Println(err) - os.Exit(1) - } - } } // Link the environment variable to the CLI argument(s). _ = viper.BindPFlag(params.AccessKeyIDConfigKey, rootCmd.PersistentFlags().Lookup(params.AccessKeyIDFlag)) @@ -212,16 +204,6 @@ func NewAstCLI( return rootCmd } -func requiredFeatureFlagsCheck(cmd *cobra.Command) bool { - for _, cmdFlag := range wrappers.FeatureFlagsBaseMap { - if cmdFlag.CommandName == cmd.CommandPath() { - return true - } - } - - return false -} - const configFormatString = "%30v: %s" func PrintConfiguration() { @@ -307,3 +289,12 @@ func printByScanInfoFormat(cmd *cobra.Command, view interface{}) error { f, _ := cmd.Flags().GetString(params.ScanInfoFormatFlag) return printer.Print(cmd.OutOrStdout(), view, f) } + +func setUpFeatureFlags(featureFlagsWrapper wrappers.FeatureFlagsWrapper) { + err := wrappers.HandleFeatureFlags(featureFlagsWrapper) + + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 139b80d1f..cf6232a88 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -506,8 +506,12 @@ 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") - createScanCmd.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types, ex: (sast,iac-security,sca,api-security,container-security)") + if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + 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,container-security)") + } else { + 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)") createScanCmd.PersistentFlags().StringP( commonParams.BranchFlag, commonParams.BranchFlagSh, diff --git a/internal/wrappers/utils/utils_test.go b/internal/wrappers/utils/utils_test.go index 86ef13b97..5a6263696 100644 --- a/internal/wrappers/utils/utils_test.go +++ b/internal/wrappers/utils/utils_test.go @@ -7,12 +7,11 @@ import ( func TestCleanURL_CleansCorrectly(t *testing.T) { uri := "https://codebashing.checkmarx.com/courses/java/////lessons/sql_injection/////" - wantErr := false want := "https://codebashing.checkmarx.com/courses/java/lessons/sql_injection" got, err := CleanURL(uri) log.Println("error:", err) - if (err != nil) != wantErr { - t.Errorf("CleanURL() error = %v, wantErr %v", err, wantErr) + if (err != nil) != false { + t.Errorf("CleanURL() error = %v, wantErr %v", err, false) return } if got != want { @@ -23,12 +22,11 @@ func TestCleanURL_CleansCorrectly(t *testing.T) { func TestCleanURL_invalid_URL_escape_error(t *testing.T) { uri := "#)@($_(*#_(*@$_))%(_#@_+#@$)$_$#@_@_##}^^^}!)(()!#@(`SPPSCOK^Ç^Ç`P$_$" - wantErr := true want := "" got, err := CleanURL(uri) log.Println("error:", err) - if (err != nil) != wantErr { - t.Errorf("CleanURL() error = %v, wantErr %v", err, wantErr) + if (err != nil) != true { + t.Errorf("CleanURL() error = %v, wantErr %v", err, true) return } if got != want { @@ -36,14 +34,14 @@ func TestCleanURL_invalid_URL_escape_error(t *testing.T) { } log.Println("GOT:", got) } + func TestCleanURL_cleans_correctly2(t *testing.T) { uri := "http://localhost:42/////test//test" - wantErr := false want := "http://localhost:42/test/test" got, err := CleanURL(uri) log.Println("error:", err) - if (err != nil) != wantErr { - t.Errorf("CleanURL() error = %v, wantErr %v", err, wantErr) + if (err != nil) != false { + t.Errorf("CleanURL() error = %v, wantErr %v", err, false) return } if got != want { @@ -51,3 +49,52 @@ func TestCleanURL_cleans_correctly2(t *testing.T) { } log.Println("GOT:", got) } + +func TestContains(t *testing.T) { + testCases := []struct { + name string + input []string + str string + expected bool + }{ + { + name: "String present in slice", + input: []string{"apple", "banana", "orange"}, + str: "banana", + expected: true, + }, + { + name: "String not present in slice", + input: []string{"apple", "banana", "orange"}, + str: "grape", + expected: false, + }, + { + name: "Empty slice", + input: []string{}, + str: "test", + expected: false, + }, + { + name: "Empty string", + input: []string{"apple", "banana", "orange"}, + str: "", + expected: false, + }, + { + name: "String present multiple times", + input: []string{"apple", "banana", "orange", "banana"}, + str: "banana", + expected: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := Contains(tc.input, tc.str) + if result != tc.expected { + t.Errorf("Expected %v but got %v for input %v and string %s", tc.expected, result, tc.input, tc.str) + } + }) + } +} From 829cc6cbc3404f74cef6c075bd58bd3133123da0 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 14:23:03 +0200 Subject: [PATCH 060/108] add test to wrapper/utils-test --- internal/wrappers/utils/utils_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/wrappers/utils/utils_test.go b/internal/wrappers/utils/utils_test.go index 5a6263696..07893928d 100644 --- a/internal/wrappers/utils/utils_test.go +++ b/internal/wrappers/utils/utils_test.go @@ -90,6 +90,7 @@ func TestContains(t *testing.T) { } for _, tc := range testCases { + tc := tc // Create a local variable with the same name t.Run(tc.name, func(t *testing.T) { result := Contains(tc.input, tc.str) if result != tc.expected { From 01d9edec5f3254dcb45f0687d89d71768982ce9c Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 14:45:09 +0200 Subject: [PATCH 061/108] add tests to printer-test.go --- .../commands/util/printer/printer_test.go | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/internal/commands/util/printer/printer_test.go b/internal/commands/util/printer/printer_test.go index a63f9ab97..32e452d65 100644 --- a/internal/commands/util/printer/printer_test.go +++ b/internal/commands/util/printer/printer_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "testing" + "time" "gotest.tools/assert" ) @@ -63,3 +64,156 @@ func TestColumnReformat(t *testing.T) { // Test empty columnReformat([]*entity{}) } + +func TestParseName(t *testing.T) { + testCases := []struct { + name string + input string + expectedResult string + }{ + { + name: "Valid name", + input: "name:key", + expectedResult: "key", + }, + { + name: "Empty name", + input: "name:", + expectedResult: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Create a function using the parseName function with the test input + f := parseName(tc.input) + + // Create a property to pass to the function + prop := &property{} + + // Call the generated function + f(prop, nil) + + // Check if the key was set correctly + if prop.Key != tc.expectedResult { + t.Errorf("Expected key %s, but got %s", tc.expectedResult, prop.Key) + } + }) + } +} + +func TestParseTime(t *testing.T) { + testCases := []struct { + name string + input string + raw interface{} + expectedResult string + }{ + { + name: "Valid time with format", + input: "time:2006-01-02", + raw: time.Date(2024, 3, 14, 0, 0, 0, 0, time.UTC), + expectedResult: "2024-03-14", + }, + { + name: "Nil time pointer", + input: "time:15:04:05", + raw: (*time.Time)(nil), + expectedResult: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + f := parseTime(tc.input) + + prop := &property{} + + f(prop, tc.raw) + + if prop.Value != tc.expectedResult { + t.Errorf("Expected value %s, but got %s", tc.expectedResult, prop.Value) + } + }) + } +} + +func TestParseMaxlen(t *testing.T) { + testCases := []struct { + name string + input string + raw string + expectedResult string + }{ + { + name: "Valid maxlen", + input: "maxlen:5", + raw: "123456789", + expectedResult: "12345", + }, + { + name: "Value shorter than maxlen", + input: "maxlen:10", + raw: "12345", + expectedResult: "12345", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Create a function using the parseMaxlen function with the test input + f := parseMaxlen(tc.input) + + // Create a property to pass to the function + prop := &property{Value: tc.raw} + + // Call the generated function + f(prop, nil) + + // Check if the value was truncated correctly + if prop.Value != tc.expectedResult { + t.Errorf("Expected value %s, but got %s", tc.expectedResult, prop.Value) + } + }) + } +} + +func TestGetFormatter(t *testing.T) { + testCases := []struct { + name string + input string + raw interface{} + expectedResult string + }{ + { + name: "Maxlen formatter", + input: "maxlen:5", + raw: "123456789", + expectedResult: "12345", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Get the formatter function using the getFormatter function with the test input + f := getFormatter(tc.input) + + // Perform type assertion to ensure raw is treated as a string + rawStr, ok := tc.raw.(string) + if !ok { + t.Fatalf("Unable to assert %v as string", tc.raw) + } + + // Create a property to pass to the function + prop := &property{Value: rawStr} + + // Call the generated function + f(prop, rawStr) + + // Check if the property's value was formatted correctly + if prop.Value != tc.expectedResult { + t.Errorf("Expected value %s, but got %s", tc.expectedResult, prop.Value) + } + }) + } +} From a4366898b4d669852cd1199fc273e3ee010c22e0 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 14 Mar 2024 15:32:43 +0200 Subject: [PATCH 062/108] add tests to printer-test.go and scan.go --- internal/commands/scan_test.go | 52 +++++++++++++++++++ .../commands/util/printer/printer_test.go | 17 ++---- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 851960d4f..9b3a19d56 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -11,6 +11,7 @@ import ( commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/checkmarx/ast-cli/internal/wrappers/mock" + "github.com/pkg/errors" "gotest.tools/assert" "github.com/checkmarx/ast-cli/internal/commands/util" @@ -659,3 +660,54 @@ func TestCreateScanProjectTagsCheckResendToScan(t *testing.T) { err := executeTestCommand(cmd, baseArgs...) assert.NilError(t, err) } + +func TestValidateContainerImageFormat(t *testing.T) { + testCases := []struct { + name string + containerImage string + expectedError error + }{ + { + name: "Valid container image format", + containerImage: "nginx:latest", + expectedError: nil, + }, + { + name: "Missing image name", + containerImage: ":latest", + expectedError: errors.Errorf("Invalid value for --container-images flag. The value must be in the format :"), + }, + { + name: "Missing image tag", + containerImage: "nginx:", + expectedError: errors.Errorf("Invalid value for --container-images flag. The value must be in the format :"), + }, + { + name: "Empty image name and tag", + containerImage: ":", + expectedError: errors.Errorf("Invalid value for --container-images flag. The value must be in the format :"), + }, + { + name: "Extra colon", + containerImage: "nginx:latest:extra", + expectedError: errors.Errorf("Invalid value for --container-images flag. The value must be in the format :"), + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := validateContainerImageFormat(tc.containerImage) + if err != nil && tc.expectedError == nil { + t.Errorf("Unexpected error: %v", err) + return + } + if err != nil && tc.expectedError != nil && err.Error() != tc.expectedError.Error() { + t.Errorf("Expected error %v, but got %v", tc.expectedError, err) + } + if err == nil && tc.expectedError != nil { + t.Errorf("Expected error %v, but got nil", tc.expectedError) + } + }) + } +} diff --git a/internal/commands/util/printer/printer_test.go b/internal/commands/util/printer/printer_test.go index 32e452d65..3967421f1 100644 --- a/internal/commands/util/printer/printer_test.go +++ b/internal/commands/util/printer/printer_test.go @@ -84,17 +84,14 @@ func TestParseName(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { - // Create a function using the parseName function with the test input f := parseName(tc.input) - // Create a property to pass to the function prop := &property{} - // Call the generated function f(prop, nil) - // Check if the key was set correctly if prop.Key != tc.expectedResult { t.Errorf("Expected key %s, but got %s", tc.expectedResult, prop.Key) } @@ -124,6 +121,7 @@ func TestParseTime(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { f := parseTime(tc.input) @@ -160,17 +158,14 @@ func TestParseMaxlen(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { - // Create a function using the parseMaxlen function with the test input f := parseMaxlen(tc.input) - // Create a property to pass to the function prop := &property{Value: tc.raw} - // Call the generated function f(prop, nil) - // Check if the value was truncated correctly if prop.Value != tc.expectedResult { t.Errorf("Expected value %s, but got %s", tc.expectedResult, prop.Value) } @@ -194,23 +189,19 @@ func TestGetFormatter(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { - // Get the formatter function using the getFormatter function with the test input f := getFormatter(tc.input) - // Perform type assertion to ensure raw is treated as a string rawStr, ok := tc.raw.(string) if !ok { t.Fatalf("Unable to assert %v as string", tc.raw) } - // Create a property to pass to the function prop := &property{Value: rawStr} - // Call the generated function f(prop, rawStr) - // Check if the property's value was formatted correctly if prop.Value != tc.expectedResult { t.Errorf("Expected value %s, but got %s", tc.expectedResult, prop.Value) } From a2089b942de30fde6cafeb8c06f2972ef075ade2 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 17 Mar 2024 12:15:11 +0200 Subject: [PATCH 063/108] update container resolver version to 1.0.2 and fix compressFile function --- go.mod | 2 +- go.sum | 4 +-- internal/commands/util/utils.go | 48 +++++++++++++++++----------- internal/commands/util/utils_test.go | 40 +++++++++++++++++++---- 4 files changed, 66 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index b6ac4a120..32931ff5a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/checkmarx/ast-cli go 1.22.1 require ( - github.com/CheckmarxDev/containers-resolver v1.0.1 + github.com/CheckmarxDev/containers-resolver v1.0.2 github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/go.sum b/go.sum index 4972230cf..ca5ad2180 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CheckmarxDev/containers-resolver v1.0.1 h1:1d699fOdBiq5BcFWHAseU+fHqgd8wb3O+lDOuYS2lto= -github.com/CheckmarxDev/containers-resolver v1.0.1/go.mod h1:+sNosfLkXhzpPnYFEpGH4OeO5c06QCiY7T4XakbuP3U= +github.com/CheckmarxDev/containers-resolver v1.0.2 h1:iVxjvYtZKEtt8dkjkN6yGQ9qlk4f1AuHFYVEbK4o4s4= +github.com/CheckmarxDev/containers-resolver v1.0.2/go.mod h1:pzpaje1Qlrxl5BtWiMMVxAErpbWFwKsuQWNTvImHzpA= github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= github.com/CycloneDX/cyclonedx-go v0.8.0/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 4d74fc902..3af7f9448 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -141,17 +141,24 @@ func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix if len(createdDirectoryPrefix) == 0 || createdDirectoryPrefix[0] == "" { createdDirectoryPrefix = []string{directoryPrefix} } + outputFile, err := os.CreateTemp(os.TempDir(), createdDirectoryPrefix[0]+"*.zip") + if err != nil { return "", errors.Wrapf(err, "Cannot create temp file") } + defer CloseOutputFile(outputFile) zipWriter := zip.NewWriter(outputFile) + defer CloseZipWriter(zipWriter, outputFile) dataFile, err := os.Open(sourceFilePath) if err != nil { logger.PrintfIfVerbose("Failed to open file: %s", sourceFilePath) } + if dataFile != nil { + defer CloseDataFile(dataFile) + } folderNameBeginsIndex := strings.Index(outputFile.Name(), createdDirectoryPrefix[0]) if folderNameBeginsIndex == -1 { @@ -170,30 +177,33 @@ func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix logger.PrintfIfVerbose("Failed to copy file to zip: %s", targetFileName) } - stat, err := outputFile.Stat() - if err != nil { + return outputFile.Name(), nil +} + +func CloseOutputFile(outputFile *os.File) { + stat, statErr := outputFile.Stat() + CloseFileErr := outputFile.Close() + if CloseFileErr != nil { + logger.PrintfIfVerbose("Failed to close file: %s", outputFile.Name()) + } + if statErr != nil { logger.PrintfIfVerbose("Failed to get file stat: %s", outputFile.Name()) - } else { + } + if stat != nil { fmt.Printf("Zip size: %.3fMB\n", float64(stat.Size())/mbBytes) } - - CloseFilesAndWriter(zipWriter, dataFile, outputFile) - return outputFile.Name(), nil } -func CloseFilesAndWriter(writer *zip.Writer, files ...*os.File) { - for _, file := range files { - if file != nil { - err := file.Close() - if err != nil { - logger.PrintfIfVerbose("Failed to close file: %s", file.Name()) - } - } +func CloseZipWriter(zipWriter *zip.Writer, outputFile *os.File) { + closeZipWriterError := zipWriter.Close() + if closeZipWriterError != nil { + logger.PrintfIfVerbose("Failed to close zip writer: %s", outputFile.Name()) } - if writer != nil { - err := writer.Close() - if err != nil { - logger.PrintfIfVerbose("Failed to close zip writer") - } +} + +func CloseDataFile(dataFile *os.File) { + closeDataFileError := dataFile.Close() + if closeDataFileError != nil { + logger.PrintfIfVerbose("Failed to close file: %s", dataFile.Name()) } } diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index 122fc5faa..f24ad7535 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -1,6 +1,7 @@ package util import ( + "archive/zip" "os" "strings" "testing" @@ -37,15 +38,42 @@ func TestReadFileAsString_NoFile_Fail(t *testing.T) { assert.Error(t, err, "open no-file-exists-with-this-name.json: no such file or directory") } -func TestDeferCloseFileAndWriter_OnlyFile(t *testing.T) { - file, err := os.OpenFile("../data/package.json", os.O_RDWR, 0644) - assert.NilError(t, err, "OpenFile must run well") - CloseFilesAndWriter(nil, file) -} - func TestCompressFile_EmptyDirectoryPrefix(t *testing.T) { outputFileName, err := CompressFile("testfile.txt", "output.zip", "") assert.NilError(t, err) // Assert that the output file name contains the default prefix assert.Assert(t, strings.Contains(outputFileName, "cx-")) } + +func TestCloseOutputFile(t *testing.T) { + tempFile, err := os.CreateTemp("", "test-output-file-*.txt") + assert.NilError(t, err, "Failed to create temp file") + defer os.Remove(tempFile.Name()) + + CloseOutputFile(tempFile) + closedErr := tempFile.Close() + assert.ErrorContains(t, closedErr, "file already closed") +} + +func TestCloseZipWriter(t *testing.T) { + // Create a temporary file for testing + tempFile, err := os.CreateTemp("", "test-zip-file-*.zip") + assert.NilError(t, err, "Failed to create temp file") + defer os.Remove(tempFile.Name()) + + zipWriter := zip.NewWriter(tempFile) + + CloseZipWriter(zipWriter, tempFile) + zipClosedErr := zipWriter.Close() + assert.ErrorContains(t, zipClosedErr, "zip: writer closed twice") +} + +func TestCloseDataFile(t *testing.T) { + tempFile, err := os.CreateTemp("", "test-data-file-*.txt") + assert.NilError(t, err, "Failed to create temp file") + defer os.Remove(tempFile.Name()) + + CloseDataFile(tempFile) + closedErr := tempFile.Close() + assert.ErrorContains(t, closedErr, "file already closed") +} From e4d9d97aa57abbeb1e23b925fe56e97a1261a382 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 17 Mar 2024 15:06:57 +0200 Subject: [PATCH 064/108] fix compressFile function --- internal/commands/util/utils.go | 50 +++++++++------------ internal/commands/util/utils_test.go | 65 ++++++++++++++++++++++++---- 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 3af7f9448..3de978b02 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -3,7 +3,6 @@ package util import ( "archive/zip" "fmt" - "io" "os" "path/filepath" "regexp" @@ -19,11 +18,11 @@ import ( ) const ( - gitURLRegex = "(?P:git|ssh|https?|git@[-\\w.]+):(\\/\\/)?(?P.*?)(\\.git)?$" - sshURLRegex = "^(?P.*?)@(?P.*?):(?:(?P.*?)/)?(?P.*?/.*?)$" - invalidFlag = "Value of %s is invalid" - mbBytes = 1024.0 * 1024.0 - directoryPrefix = "cx-" + gitURLRegex = "(?P:git|ssh|https?|git@[-\\w.]+):(\\/\\/)?(?P.*?)(\\.git)?$" + sshURLRegex = "^(?P.*?)@(?P.*?):(?:(?P.*?)/)?(?P.*?/.*?)$" + invalidFlag = "Value of %s is invalid" + mbBytes = 1024.0 * 1024.0 + defaultDirectoryPrefix = "cx-" ) func NewUtilsCommand( @@ -139,7 +138,7 @@ func ReadFileAsString(path string) (string, error) { func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix ...string) (string, error) { if len(createdDirectoryPrefix) == 0 || createdDirectoryPrefix[0] == "" { - createdDirectoryPrefix = []string{directoryPrefix} + createdDirectoryPrefix = []string{defaultDirectoryPrefix} } outputFile, err := os.CreateTemp(os.TempDir(), createdDirectoryPrefix[0]+"*.zip") @@ -152,34 +151,32 @@ func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix zipWriter := zip.NewWriter(outputFile) defer CloseZipWriter(zipWriter, outputFile) - dataFile, err := os.Open(sourceFilePath) - if err != nil { - logger.PrintfIfVerbose("Failed to open file: %s", sourceFilePath) - } - if dataFile != nil { - defer CloseDataFile(dataFile) - } + dataFile, err := os.ReadFile(sourceFilePath) - folderNameBeginsIndex := strings.Index(outputFile.Name(), createdDirectoryPrefix[0]) - if folderNameBeginsIndex == -1 { - logger.PrintfIfVerbose("Failed to find folder name in file: %s", outputFile.Name()) + folderName, nameERR := extractFolderNameFromZipPath(outputFile.Name(), createdDirectoryPrefix[0]) + if nameERR != nil { + return "", nameERR } - folderName := outputFile.Name()[folderNameBeginsIndex:] - folderName = strings.TrimSuffix(folderName, ".zip") f, err := zipWriter.Create(filepath.Join(folderName, targetFileName)) if err != nil { logger.PrintfIfVerbose("Failed to create file in zip: %s", targetFileName) } - - _, err = io.Copy(f, dataFile) + _, err = f.Write(dataFile) if err != nil { - logger.PrintfIfVerbose("Failed to copy file to zip: %s", targetFileName) + logger.PrintfIfVerbose("Failed to write file to zip: %s", targetFileName) } - return outputFile.Name(), nil } +func extractFolderNameFromZipPath(outputFileName, dirPrefix string) (string, error) { + folderNameBeginsIndex := strings.Index(outputFileName, dirPrefix) + if folderNameBeginsIndex == -1 { + return "", errors.New("Failed to extract folder name from zip path: " + outputFileName + " with prefix: " + dirPrefix) + } + return strings.TrimSuffix(outputFileName[folderNameBeginsIndex:], ".zip"), nil +} + func CloseOutputFile(outputFile *os.File) { stat, statErr := outputFile.Stat() CloseFileErr := outputFile.Close() @@ -200,10 +197,3 @@ func CloseZipWriter(zipWriter *zip.Writer, outputFile *os.File) { logger.PrintfIfVerbose("Failed to close zip writer: %s", outputFile.Name()) } } - -func CloseDataFile(dataFile *os.File) { - closeDataFileError := dataFile.Close() - if closeDataFileError != nil { - logger.PrintfIfVerbose("Failed to close file: %s", dataFile.Name()) - } -} diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index f24ad7535..9523a7e0a 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -68,12 +68,61 @@ func TestCloseZipWriter(t *testing.T) { assert.ErrorContains(t, zipClosedErr, "zip: writer closed twice") } -func TestCloseDataFile(t *testing.T) { - tempFile, err := os.CreateTemp("", "test-data-file-*.txt") - assert.NilError(t, err, "Failed to create temp file") - defer os.Remove(tempFile.Name()) - - CloseDataFile(tempFile) - closedErr := tempFile.Close() - assert.ErrorContains(t, closedErr, "file already closed") +func TestExtractFolderNameFromZipPath(t *testing.T) { + type TestCase struct { + Name string + OutputFileName string + DirPrefix string + ExpectedResult string + ExpectedError string + } + testCases := []TestCase{ + { + Name: "Success: Standard Prefix", + OutputFileName: "cx-archive.zip", + DirPrefix: "cx-", + ExpectedResult: "cx-archive", + ExpectedError: "", + }, + { + Name: "Success: Custom Prefix", + OutputFileName: "my-archive.zip", + DirPrefix: "my-", + ExpectedResult: "my-archive", + ExpectedError: "", + }, + { + Name: "Failure: No Prefix Match", + OutputFileName: "archive.zip", + DirPrefix: "cx-", + ExpectedResult: "", + ExpectedError: "Failed to extract folder name from zip path: archive.zip with prefix: cx-", + }, + { + Name: "Failure: Prefix Not Found", + OutputFileName: "example.zip", + DirPrefix: "cx-", + ExpectedResult: "", + ExpectedError: "Failed to extract folder name from zip path: example.zip with prefix: cx-", + }, + { + Name: "Success: Full Name With Prefix", + OutputFileName: "cx-archive.zip", + DirPrefix: "cx-", + ExpectedResult: "cx-archive", + ExpectedError: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + folderName, err := extractFolderNameFromZipPath(tc.OutputFileName, tc.DirPrefix) + if tc.ExpectedError != "" { + assert.ErrorContains(t, err, tc.ExpectedError) + } else { + assert.NilError(t, err) + assert.Equal(t, tc.ExpectedResult, folderName) + } + }) + } } From 4e339fc55f8dd8058e08dc7e514aaac206455ac3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 17 Mar 2024 15:09:01 +0200 Subject: [PATCH 065/108] fix lint errors --- internal/commands/util/utils_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index 9523a7e0a..95f9c8090 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -115,6 +115,7 @@ func TestExtractFolderNameFromZipPath(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.Name, func(t *testing.T) { folderName, err := extractFolderNameFromZipPath(tc.OutputFileName, tc.DirPrefix) if tc.ExpectedError != "" { From 73fbab915d6a35b3f44fbe1c5d9c4a9796ac8791 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 17 Mar 2024 15:13:29 +0200 Subject: [PATCH 066/108] fix lint errors --- internal/commands/util/utils.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 3de978b02..a8984ce3c 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -151,13 +151,16 @@ func CompressFile(sourceFilePath, targetFileName string, createdDirectoryPrefix zipWriter := zip.NewWriter(outputFile) defer CloseZipWriter(zipWriter, outputFile) - dataFile, err := os.ReadFile(sourceFilePath) - folderName, nameERR := extractFolderNameFromZipPath(outputFile.Name(), createdDirectoryPrefix[0]) if nameERR != nil { return "", nameERR } + dataFile, readErr := os.ReadFile(sourceFilePath) + if readErr != nil { + logger.PrintfIfVerbose("Failed to read file: %s", sourceFilePath) + } + f, err := zipWriter.Create(filepath.Join(folderName, targetFileName)) if err != nil { logger.PrintfIfVerbose("Failed to create file in zip: %s", targetFileName) From fcbd32f19562a082ac3f8b54b60e3297eb64279a Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 17 Mar 2024 16:47:39 +0200 Subject: [PATCH 067/108] fix cleanTempZip in scan.go --- internal/commands/scan.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index cf6232a88..a70073afe 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1105,7 +1105,7 @@ func scanTypeEnabled(scanType string) bool { func compressFolder(sourceDir string, filter, userIncludeFilter []string, scaResolver string) (string, error) { scaToolPath := scaResolver - outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip") + outputFile, err := os.CreateTemp(os.TempDir(), "cx-*.zip") if err != nil { return "", errors.Wrapf(err, "Cannot source code temp file.") } @@ -1607,6 +1607,7 @@ func runCreateScanCommand( applicationsWrapper, ) if err != nil { + return errors.Errorf("%s", err) } scanResponseModel, errorModel, err := scansWrapper.Create(scanModel) @@ -1671,7 +1672,7 @@ func runCreateScanCommand( } } - cleanUpTempZip(zipFilePath) + defer cleanUpTempZip(zipFilePath) // verify break build from policy if policyResponseModel != nil && len(policyResponseModel.Policies) > 0 && policyResponseModel.BreakBuild { logger.PrintIfVerbose("Breaking the build due to policy violation") From 5bca89349723b359c4a86dd9252c9ffa209e06d1 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 19 Mar 2024 08:59:19 +0200 Subject: [PATCH 068/108] Check integration tests passing --- test/integration/scan_test.go | 170 +++++++++++++++++----------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 8de5b26bb..6ffdac8e9 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -112,97 +112,97 @@ func TestScanCreate_ApplicationDoesntExist_FailScanWithError(t *testing.T) { assertError(t, err, applicationErrors.ApplicationDoesntExistOrNoPermission) } -func TestScanCreateWithContainersEngine_WithoutContainerImagesFlagAndContainerScanType_ScanCreatedSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.BranchFlag), "dummy_branch", - } - - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} - -func TestScanCreateWithContainersEngine_ContainerImagesFlagAndContainerScanTypeSpecified_ScanCreatedSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ScanTypes), "container-security", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - } - - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} - -func TestScanCreate_ContainerImagesFlagSpecified_ScanCreatedSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - } - - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} - -func TestScanCreate_ContainerImagesAndDebugFlagsSpecified_ScanCreatedSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - flag(params.DebugFlag), - } - - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} +//func TestScanCreateWithContainersEngine_WithoutContainerImagesFlagAndContainerScanType_ScanCreatedSuccessfully(t *testing.T) { +// args := []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.BranchFlag), "dummy_branch", +// } +// +// err, _ := executeCommand(t, args...) +// assert.NilError(t, err) +//} -func TestScanCreate_ContainerImagesFlagSpecifiedAndEmptyFolderProject_ScanCreatedSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/empty-folder", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - } +//func TestScanCreateWithContainersEngine_ContainerImagesFlagAndContainerScanTypeSpecified_ScanCreatedSuccessfully(t *testing.T) { +// args := []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ScanTypes), "container-security", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// } +// +// err, _ := executeCommand(t, args...) +// assert.NilError(t, err) +//} - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} +//func TestScanCreate_ContainerImagesFlagSpecified_ScanCreatedSuccessfully(t *testing.T) { +// args := []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// } +// +// err, _ := executeCommand(t, args...) +// assert.NilError(t, err) +//} -func TestScanCreate_WithContainerTypeAndEmptyFolderProject_ScanCreatedSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/empty-folder", - flag(params.ScanTypes), "container-security", - flag(params.BranchFlag), "dummy_branch", - } +//func TestScanCreate_ContainerImagesAndDebugFlagsSpecified_ScanCreatedSuccessfully(t *testing.T) { +// args := []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// flag(params.DebugFlag), +// } +// +// err, _ := executeCommand(t, args...) +// assert.NilError(t, err) +//} - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} +//func TestScanCreate_ContainerImagesFlagSpecifiedAndEmptyFolderProject_ScanCreatedSuccessfully(t *testing.T) { +// args := []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/empty-folder", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// } +// +// err, _ := executeCommand(t, args...) +// assert.NilError(t, err) +//} -func TestScanCreateWithContainersEngine_InvalidContainerImagesFlag_ScanCreatedSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ContainerImagesFlag), "debian,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - } +//func TestScanCreate_WithContainerTypeAndEmptyFolderProject_ScanCreatedSuccessfully(t *testing.T) { +// args := []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/empty-folder", +// flag(params.ScanTypes), "container-security", +// flag(params.BranchFlag), "dummy_branch", +// } +// +// err, _ := executeCommand(t, args...) +// assert.NilError(t, err) +//} - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} +//func TestScanCreateWithContainersEngine_InvalidContainerImagesFlag_ScanCreatedSuccessfully(t *testing.T) { +// args := []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ContainerImagesFlag), "debian,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// } +// +// err, _ := executeCommand(t, args...) +// assert.NilError(t, err) +//} // Create scans from current dir, zip and url and perform assertions in executeScanAssertions func TestScansE2E(t *testing.T) { From a6f3bd2180773665812c3c8c8efb0405576aef26 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 19 Mar 2024 10:50:04 +0200 Subject: [PATCH 069/108] fix isSingleContainerScanTriggered bug and update integration test --- internal/commands/scan.go | 13 +-- test/integration/scan_test.go | 171 +++++++++++++++++----------------- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index a70073afe..3ff2f08d8 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1133,14 +1133,9 @@ func compressFolder(sourceDir string, filter, userIncludeFilter []string, scaRes return outputFile.Name(), err } -func isSingleContainerScanTriggered(cmd *cobra.Command) bool { - scanTypes, _ := cmd.Flags().GetString(commonParams.ScanTypes) - var scanTypeList []string - if len(scanTypes) > 0 { - scanTypeList = strings.Split(scanTypes, ",") - } - // If the scan type is not provided, we check if user has license for container engine - return (len(scanTypeList) == 1 && scanTypeList[0] == commonParams.ContainersType) || userAllowedEngines[commonParams.ContainersType] +func isSingleContainerScanTriggered() bool { + scanTypeList := strings.Split(actualScanTypes, ",") + return len(scanTypeList) == 1 && scanTypeList[0] == commonParams.ContainersType } func getIncludeFilters(userIncludeFilter string) []string { @@ -1388,7 +1383,7 @@ func getUploadURLFromSource(cmd *cobra.Command, uploadsWrapper wrappers.UploadsW } return "", "", resolversErr } - if isSingleContainerScanTriggered(cmd) { + if isSingleContainerScanTriggered() { logger.PrintIfVerbose("Single container scan triggered: compressing only the container resolution file") containerResolutionFilePath := filepath.Join(directoryPath, containerResolutionFileName) zipFilePath, dirPathErr = util.CompressFile(containerResolutionFilePath, containerResolutionFileName, directoryCreationPrefix) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 6ffdac8e9..e1d218787 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -112,96 +112,101 @@ func TestScanCreate_ApplicationDoesntExist_FailScanWithError(t *testing.T) { assertError(t, err, applicationErrors.ApplicationDoesntExistOrNoPermission) } -//func TestScanCreateWithContainersEngine_WithoutContainerImagesFlagAndContainerScanType_ScanCreatedSuccessfully(t *testing.T) { -// args := []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.BranchFlag), "dummy_branch", +//func TestScanCreateWithContainersEngine(t *testing.T) { +// type TestCase struct { +// Name string +// Arguments []string // } -// -// err, _ := executeCommand(t, args...) -// assert.NilError(t, err) -//} - -//func TestScanCreateWithContainersEngine_ContainerImagesFlagAndContainerScanTypeSpecified_ScanCreatedSuccessfully(t *testing.T) { -// args := []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ScanTypes), "container-security", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// } -// -// err, _ := executeCommand(t, args...) -// assert.NilError(t, err) -//} - -//func TestScanCreate_ContainerImagesFlagSpecified_ScanCreatedSuccessfully(t *testing.T) { -// args := []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// } -// -// err, _ := executeCommand(t, args...) -// assert.NilError(t, err) -//} - -//func TestScanCreate_ContainerImagesAndDebugFlagsSpecified_ScanCreatedSuccessfully(t *testing.T) { -// args := []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// flag(params.DebugFlag), +// testCases := []TestCase{ +// { +// Name: "Container images flag specified and empty folder project", +// Arguments: []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/empty-folder", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// }, +// }, +// { +// Name: "Container images flag and container scan type specified", +// Arguments: []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ScanTypes), "container-security", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// }, +// }, +// { +// Name: "Container images flag specified", +// Arguments: []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// }, +// }, +// { +// Name: "Container images and debug flags specified", +// Arguments: []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// flag(params.DebugFlag), +// }, +// }, +// { +// Name: "Container images flag specified and empty folder project", +// Arguments: []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/empty-folder", +// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// }, +// }, +// { +// Name: "Container type specified and empty folder project", +// Arguments: []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/empty-folder", +// flag(params.ScanTypes), "container-security", +// flag(params.BranchFlag), "dummy_branch", +// }, +// }, +// { +// Name: "Invalid container images flag specified", +// Arguments: []string{ +// "scan", "create", +// flag(params.ProjectName), "my-project", +// flag(params.SourcesFlag), "data/withDockerInZip.zip", +// flag(params.ContainerImagesFlag), "debian,nginx:latest", +// flag(params.BranchFlag), "dummy_branch", +// }, +// }, // } // -// err, _ := executeCommand(t, args...) -// assert.NilError(t, err) -//} - -//func TestScanCreate_ContainerImagesFlagSpecifiedAndEmptyFolderProject_ScanCreatedSuccessfully(t *testing.T) { -// args := []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/empty-folder", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", +// for _, tc := range testCases { +// tc := tc +// t.Run(tc.Name, func(t *testing.T) { +// scanID, projectID := executeCreateScan(t, tc.Arguments) +// deleteProject(t, projectID) +// executeScanAssertions(t, projectID, scanID, Tags) +// assertZipFileRemoved(t) +// }) // } -// -// err, _ := executeCommand(t, args...) -// assert.NilError(t, err) //} - -//func TestScanCreate_WithContainerTypeAndEmptyFolderProject_ScanCreatedSuccessfully(t *testing.T) { -// args := []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/empty-folder", -// flag(params.ScanTypes), "container-security", -// flag(params.BranchFlag), "dummy_branch", -// } -// -// err, _ := executeCommand(t, args...) -// assert.NilError(t, err) -//} - -//func TestScanCreateWithContainersEngine_InvalidContainerImagesFlag_ScanCreatedSuccessfully(t *testing.T) { -// args := []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ContainerImagesFlag), "debian,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// } // -// err, _ := executeCommand(t, args...) +//func assertZipFileRemoved(t *testing.T) { +// glob, err := filepath.Glob(filepath.Join(os.TempDir(), "cx*.zip")) // assert.NilError(t, err) +// assert.Equal(t, len(glob), 0, "Zip file not removed") //} // Create scans from current dir, zip and url and perform assertions in executeScanAssertions From 42fda0d42cd8f6a56baff13d1349eff3f0d1d51a Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 19 Mar 2024 13:16:10 +0200 Subject: [PATCH 070/108] uncomment containers integrations tests --- internal/commands/result.go | 1 - test/integration/scan_test.go | 192 +++++++++++++++++----------------- 2 files changed, 96 insertions(+), 97 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 42cbb3f2d..3e20d3417 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -617,7 +617,6 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { fmt.Println(" | High Medium Low Info Status |") printTableRow("APIs", summary.EnginesResult[commonParams.APISecType], summary.EnginesResult[commonParams.APISecType].StatusCode) - printTableRow("Container", summary.EnginesResult[commonParams.ContainersType], summary.EnginesResult[commonParams.ContainersType].StatusCode) printTableRow("IAC", summary.EnginesResult[commonParams.KicsType], summary.EnginesResult[commonParams.KicsType].StatusCode) printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode) printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index e1d218787..cda35bd7b 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -112,102 +112,102 @@ func TestScanCreate_ApplicationDoesntExist_FailScanWithError(t *testing.T) { assertError(t, err, applicationErrors.ApplicationDoesntExistOrNoPermission) } -//func TestScanCreateWithContainersEngine(t *testing.T) { -// type TestCase struct { -// Name string -// Arguments []string -// } -// testCases := []TestCase{ -// { -// Name: "Container images flag specified and empty folder project", -// Arguments: []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/empty-folder", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// }, -// }, -// { -// Name: "Container images flag and container scan type specified", -// Arguments: []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ScanTypes), "container-security", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// }, -// }, -// { -// Name: "Container images flag specified", -// Arguments: []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// }, -// }, -// { -// Name: "Container images and debug flags specified", -// Arguments: []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// flag(params.DebugFlag), -// }, -// }, -// { -// Name: "Container images flag specified and empty folder project", -// Arguments: []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/empty-folder", -// flag(params.ContainerImagesFlag), "debian:12,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// }, -// }, -// { -// Name: "Container type specified and empty folder project", -// Arguments: []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/empty-folder", -// flag(params.ScanTypes), "container-security", -// flag(params.BranchFlag), "dummy_branch", -// }, -// }, -// { -// Name: "Invalid container images flag specified", -// Arguments: []string{ -// "scan", "create", -// flag(params.ProjectName), "my-project", -// flag(params.SourcesFlag), "data/withDockerInZip.zip", -// flag(params.ContainerImagesFlag), "debian,nginx:latest", -// flag(params.BranchFlag), "dummy_branch", -// }, -// }, -// } -// -// for _, tc := range testCases { -// tc := tc -// t.Run(tc.Name, func(t *testing.T) { -// scanID, projectID := executeCreateScan(t, tc.Arguments) -// deleteProject(t, projectID) -// executeScanAssertions(t, projectID, scanID, Tags) -// assertZipFileRemoved(t) -// }) -// } -//} -// -//func assertZipFileRemoved(t *testing.T) { -// glob, err := filepath.Glob(filepath.Join(os.TempDir(), "cx*.zip")) -// assert.NilError(t, err) -// assert.Equal(t, len(glob), 0, "Zip file not removed") -//} +func TestScanCreateWithContainersEngine(t *testing.T) { + type TestCase struct { + Name string + Arguments []string + } + testCases := []TestCase{ + { + Name: "Container images flag specified and empty folder project", + Arguments: []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/empty-folder", + flag(params.ContainerImagesFlag), "debian:12,nginx:latest", + flag(params.BranchFlag), "dummy_branch", + }, + }, + { + Name: "Container images flag and container scan type specified", + Arguments: []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ScanTypes), "container-security", + flag(params.ContainerImagesFlag), "debian:12,nginx:latest", + flag(params.BranchFlag), "dummy_branch", + }, + }, + { + Name: "Container images flag specified", + Arguments: []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ContainerImagesFlag), "debian:12,nginx:latest", + flag(params.BranchFlag), "dummy_branch", + }, + }, + { + Name: "Container images and debug flags specified", + Arguments: []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ContainerImagesFlag), "debian:12,nginx:latest", + flag(params.BranchFlag), "dummy_branch", + flag(params.DebugFlag), + }, + }, + { + Name: "Container images flag specified and empty folder project", + Arguments: []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/empty-folder", + flag(params.ContainerImagesFlag), "debian:12,nginx:latest", + flag(params.BranchFlag), "dummy_branch", + }, + }, + { + Name: "Container type specified and empty folder project", + Arguments: []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/empty-folder", + flag(params.ScanTypes), "container-security", + flag(params.BranchFlag), "dummy_branch", + }, + }, + { + Name: "Invalid container images flag specified", + Arguments: []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ContainerImagesFlag), "debian,nginx:latest", + flag(params.BranchFlag), "dummy_branch", + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + scanID, projectID := executeCreateScan(t, tc.Arguments) + deleteProject(t, projectID) + executeScanAssertions(t, projectID, scanID, Tags) + assertZipFileRemoved(t) + }) + } +} + +func assertZipFileRemoved(t *testing.T) { + glob, err := filepath.Glob(filepath.Join(os.TempDir(), "cx*.zip")) + assert.NilError(t, err) + assert.Equal(t, len(glob), 0, "Zip file not removed") +} // Create scans from current dir, zip and url and perform assertions in executeScanAssertions func TestScansE2E(t *testing.T) { From 5835793fd48dac36cb5a3fd9b46b3145ae5a2ccc Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Wed, 20 Mar 2024 10:19:18 +0200 Subject: [PATCH 071/108] AST-37225 support containers in result show command --- internal/commands/cx_result_sonar.json | 164 ++++++++++++++++++++++++- internal/commands/result.go | 131 +++++++++++++++----- internal/commands/result_test.go | 28 +++-- internal/params/flags.go | 1 + internal/wrappers/feature-flags.go | 4 + internal/wrappers/mock/results-mock.go | 23 +++- internal/wrappers/mock/scans-mock.go | 2 +- internal/wrappers/results-json.go | 7 ++ internal/wrappers/results-summary.go | 71 ++++++----- 9 files changed, 357 insertions(+), 74 deletions(-) diff --git a/internal/commands/cx_result_sonar.json b/internal/commands/cx_result_sonar.json index d4cf0d4a1..5c4f5bc21 100644 --- a/internal/commands/cx_result_sonar.json +++ b/internal/commands/cx_result_sonar.json @@ -1 +1,163 @@ -{"issues":[{"engineId":"sast","type":"VULNERABILITY","primaryLocation":{"filePath":"dummy-file-name","textRange":{"startLine":10,"startColumn":9,"endColumn":10}},"secondaryLocations":[{"filePath":"dummy-file-name","textRange":{"startColumn":2,"endColumn":3}}]},{"engineId":"kics","type":"VULNERABILITY","primaryLocation":{"textRange":{"startColumn":1,"endColumn":2}},"secondaryLocations":null}]} +{ + "issues": [ + { + "engineId": "sast", + "ruleId": "1", + "type": "VULNERABILITY", + "primaryLocation": { + "message": "mock-query-name-1", + "filePath": "dummy-file-name-1", + "textRange": { + "startLine": 10, + "startColumn": 10, + "endColumn": 30 + } + }, + "secondaryLocations": [ + { + "message": "mock-query-name-1", + "filePath": "dummy-file-name-1", + "textRange": { + "startLine": 11, + "startColumn": 3, + "endColumn": 13 + } + } + ] + }, + { + "engineId": "sast", + "ruleId": "2", + "type": "VULNERABILITY", + "primaryLocation": { + "message": "mock-query-name-2", + "filePath": "dummy-file-name-2", + "textRange": { + "startLine": 10, + "startColumn": 10, + "endColumn": 30 + } + }, + "secondaryLocations": [ + { + "message": "mock-query-name-2", + "filePath": "dummy-file-name-2", + "textRange": { + "startLine": 11, + "startColumn": 3, + "endColumn": 13 + } + } + ] + }, + { + "engineId": "sast", + "ruleId": "3", + "type": "VULNERABILITY", + "primaryLocation": { + "message": "mock-query-name-2", + "filePath": "dummy-file-name-2", + "textRange": { + "startLine": 10, + "startColumn": 10, + "endColumn": 30 + } + }, + "secondaryLocations": [ + { + "message": "mock-query-name-2", + "filePath": "dummy-file-name-2", + "textRange": { + "startLine": 11, + "startColumn": 3, + "endColumn": 13 + } + }, + { + "message": "mock-query-name-2", + "filePath": "dummy-file-name-2", + "textRange": { + "startLine": 12, + "startColumn": 3, + "endColumn": 13 + } + } + ] + }, + { + "engineId": "sast", + "ruleId": "4", + "type": "VULNERABILITY", + "primaryLocation": { + "message": "mock-query-name-3", + "filePath": "dummy-file-name-3", + "textRange": { + "startLine": 10, + "startColumn": 10, + "endColumn": 30 + } + }, + "secondaryLocations": [ + { + "message": "mock-query-name-3", + "filePath": "dummy-file-name-3", + "textRange": { + "startLine": 11, + "startColumn": 3, + "endColumn": 13 + } + } + ] + }, + { + "engineId": "sast", + "ruleId": "5", + "type": "VULNERABILITY", + "primaryLocation": { + "message": "mock-query-name-3", + "filePath": "dummy-file-name-4", + "textRange": { + "startLine": 10, + "startColumn": 10, + "endColumn": 30 + } + }, + "secondaryLocations": [ + { + "message": "mock-query-name-3", + "filePath": "dummy-file-name-4", + "textRange": { + "startLine": 11, + "startColumn": 3, + "endColumn": 13 + } + } + ] + }, + { + "engineId": "containers", + "type": "VULNERABILITY", + "primaryLocation": { + "message": "mock-description", + "filePath": "DockerFile", + "textRange": { + "startLine": 1, + "endLine": 2, + "startColumn": 1, + "endColumn": 2 + } + }, + "secondaryLocations": null + }, + { + "engineId": "kics", + "type": "VULNERABILITY", + "primaryLocation": { + "textRange": { + "endColumn": 1 + } + }, + "secondaryLocations": null + } + ] +} diff --git a/internal/commands/result.go b/internal/commands/result.go index ced20f065..88929c18c 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -52,6 +52,11 @@ const ( lowCx = "LOW" mediumCx = "MEDIUM" highCx = "HIGH" + tableResultsFormat = " | %-10s %4d %6d %4d %4d %-9s |\n" + stringTableResultsFormat = " | %-10s %4s %6s %4s %4s %5s |\n" + TableTitleFormat = " | %-11s %4s %6s %4s %4s %6s |\n" + twoNewLines = "\n\n" + tableLine = " --------------------------------------------------------- " codeBashingKey = "cb-url" failedGettingBfl = "Failed getting BFL" notAvailableString = "-" @@ -199,6 +204,7 @@ func resultShowSubCommand( printer.FormatPDF, printer.FormatSummaryMarkdown, printer.FormatGL, + // printer.FormatSonar ?? ) resultShowCmd.PersistentFlags().String(commonParams.ReportFormatPdfToEmailFlag, "", pdfToEmailFlagDescription) resultShowCmd.PersistentFlags().String(commonParams.ReportSbomFormatFlag, defaultSbomOption, sbomReportFlagDescription) @@ -356,12 +362,18 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr sastIssues := 0 scaIssues := 0 kicsIssues := 0 + var containersIssues *int enginesStatusCode := map[string]int{ commonParams.SastType: 0, commonParams.ScaType: 0, commonParams.KicsType: 0, commonParams.APISecType: 0, } + if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + containersIssues = new(int) + *containersIssues = 0 + enginesStatusCode[commonParams.ContainerType] = 0 + } if len(scanInfo.StatusDetails) > 0 { for _, statusDetailItem := range scanInfo.StatusDetails { @@ -372,6 +384,8 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr scaIssues = notAvailableNumber } else if statusDetailItem.Name == commonParams.KicsType { kicsIssues = notAvailableNumber + } else if statusDetailItem.Name == commonParams.ContainerType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + *containersIssues = notAvailableNumber } } switch statusDetailItem.Status { @@ -383,23 +397,24 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr } } summary := &wrappers.ResultSummary{ - ScanID: scanInfo.ID, - Status: string(scanInfo.Status), - CreatedAt: scanInfo.CreatedAt.Format("2006-01-02, 15:04:05"), - ProjectID: scanInfo.ProjectID, - RiskStyle: "", - RiskMsg: "", - HighIssues: 0, - MediumIssues: 0, - LowIssues: 0, - InfoIssues: 0, - SastIssues: sastIssues, - KicsIssues: kicsIssues, - ScaIssues: scaIssues, - Tags: scanInfo.Tags, - ProjectName: scanInfo.ProjectName, - BranchName: scanInfo.Branch, - EnginesEnabled: scanInfo.Engines, + ScanID: scanInfo.ID, + Status: string(scanInfo.Status), + CreatedAt: scanInfo.CreatedAt.Format("2006-01-02, 15:04:05"), + ProjectID: scanInfo.ProjectID, + RiskStyle: "", + RiskMsg: "", + HighIssues: 0, + MediumIssues: 0, + LowIssues: 0, + InfoIssues: 0, + SastIssues: sastIssues, + KicsIssues: kicsIssues, + ScaIssues: scaIssues, + ContainersIssues: containersIssues, + Tags: scanInfo.Tags, + ProjectName: scanInfo.ProjectName, + BranchName: scanInfo.Branch, + EnginesEnabled: scanInfo.Engines, EnginesResult: map[string]*wrappers.EngineResultSummary{ commonParams.SastType: {StatusCode: enginesStatusCode[commonParams.SastType]}, commonParams.ScaType: {StatusCode: enginesStatusCode[commonParams.ScaType]}, @@ -407,7 +422,9 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]}, }, } - + if summary.ContainersEnabled() { + summary.EnginesResult[commonParams.ContainerType] = &wrappers.EngineResultSummary{StatusCode: enginesStatusCode[commonParams.ContainerType]} + } baseURI, err := resultsWrapper.GetResultsURL(summary.ProjectID) if err != nil { return nil, err @@ -451,6 +468,9 @@ func summaryReport( setNotAvailableNumberIfZero(summary, &summary.SastIssues, commonParams.SastType) setNotAvailableNumberIfZero(summary, &summary.ScaIssues, commonParams.ScaType) setNotAvailableNumberIfZero(summary, &summary.KicsIssues, commonParams.KicsType) + if summary.ContainersEnabled() { + setNotAvailableNumberIfZero(summary, summary.ContainersIssues, commonParams.ContainerType) + } setRiskMsgAndStyle(summary) setNotAvailableEnginesStatusCode(summary) @@ -494,6 +514,9 @@ func enhanceWithScanSummary(summary *wrappers.ResultSummary, results *wrappers.S summary.EnginesResult[commonParams.APISecType].High = summary.APISecurity.Risks[1] } summary.TotalIssues = summary.SastIssues + summary.ScaIssues + summary.KicsIssues + summary.GetAPISecurityDocumentationTotal() + if summary.ContainersEnabled() { + summary.TotalIssues += *summary.ContainersIssues + } } func writeHTMLSummary(targetFile string, summary *wrappers.ResultSummary) error { @@ -559,7 +582,7 @@ func writeConsoleSummary(summary *wrappers.ResultSummary) error { } func printPoliciesSummary(summary *wrappers.ResultSummary) { - fmt.Printf(" -------------------------------------- \n") + fmt.Printf(tableLine + "\n") if summary.Policies.BreakBuild { fmt.Printf(" Policy Management Violation - Break Build Enabled: \n") } else { @@ -585,22 +608,19 @@ func printAPIsSecuritySummary(summary *wrappers.ResultSummary) { if summary.HasAPISecurityDocumentation() { fmt.Printf(" APIS DOCUMENTATION: %*d \n", defaultPaddingSize, summary.GetAPISecurityDocumentationTotal()) } - fmt.Printf(" -------------------------------------------------- \n\n") + fmt.Printf(tableLine + twoNewLines) } func printTableRow(title string, counts *wrappers.EngineResultSummary, statusNumber int) { - formatString := " | %-4s %4d %6d %4d %4d %-9s |\n" - notAvailableFormatString := " | %-4s %4s %6s %4s %4s %5s |\n" - switch statusNumber { case notAvailableNumber: - fmt.Printf(notAvailableFormatString, title, notAvailableString, notAvailableString, notAvailableString, notAvailableString, notAvailableString) + fmt.Printf(stringTableResultsFormat, title, notAvailableString, notAvailableString, notAvailableString, notAvailableString, notAvailableString) case scanFailedNumber: - fmt.Printf(formatString, title, counts.High, counts.Medium, counts.Low, counts.Info, scanFailedString) + fmt.Printf(tableResultsFormat, title, counts.High, counts.Medium, counts.Low, counts.Info, scanFailedString) case scanCanceledNumber: - fmt.Printf(formatString, title, counts.High, counts.Medium, counts.Low, counts.Info, scanCanceledString) + fmt.Printf(tableResultsFormat, title, counts.High, counts.Medium, counts.Low, counts.Info, scanCanceledString) default: - fmt.Printf(formatString, title, counts.High, counts.Medium, counts.Low, counts.Info, scanSuccessString) + fmt.Printf(tableResultsFormat, title, counts.High, counts.Medium, counts.Low, counts.Info, scanSuccessString) } } @@ -609,20 +629,23 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { totalMediumIssues := summary.EnginesResult.GetMediumIssues() totalLowIssues := summary.EnginesResult.GetLowIssues() totalInfoIssues := summary.EnginesResult.GetInfoIssues() - fmt.Printf(" --------------------------------------------------- \n\n") + fmt.Printf(tableLine + twoNewLines) fmt.Printf(" Total Results: %d \n", summary.TotalIssues) - fmt.Println(" --------------------------------------------------- ") - fmt.Println(" | High Medium Low Info Status |") + fmt.Println(tableLine) + fmt.Printf(TableTitleFormat, " ", "High", "Medium", "Low", "Info", "Status") printTableRow("APIs", summary.EnginesResult[commonParams.APISecType], summary.EnginesResult[commonParams.APISecType].StatusCode) printTableRow("IAC", summary.EnginesResult[commonParams.KicsType], summary.EnginesResult[commonParams.KicsType].StatusCode) printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode) printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode) + if summary.ContainersEnabled() { + printTableRow("CONTAINERS", summary.EnginesResult[commonParams.ContainerType], summary.EnginesResult[commonParams.ContainerType].StatusCode) + } - fmt.Println(" --------------------------------------------------- ") - fmt.Printf(" | %-4s %4d %6d %4d %4d %-9s |\n", + fmt.Println(tableLine) + fmt.Printf(tableResultsFormat, fmt.Sprintf(boldFormat, "TOTAL"), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) - fmt.Printf(" --------------------------------------------------- \n\n") + fmt.Printf(tableLine + twoNewLines) } func generateScanSummaryURL(summary *wrappers.ResultSummary) string { @@ -814,6 +837,13 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { } else if engineType == commonParams.KicsType { summary.KicsIssues++ summary.TotalIssues++ + } else if engineType == commonParams.ContainerType { + if summary.ContainersEnabled() { + *summary.ContainersIssues++ + summary.TotalIssues++ + } else { + return + } } if severity == highLabel { summary.HighIssues++ @@ -1446,12 +1476,28 @@ func parseResultsSonar(results *wrappers.ScanResultsCollection) []wrappers.Sonar } else if engineType == commonParams.ScaType { sonarIssuesByLocation := parseScaSonarLocations(result) sonarIssues = append(sonarIssues, sonarIssuesByLocation...) + } else if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && engineType == commonParams.ContainerType { + auxIssue.PrimaryLocation = parseContainersSonar(result) + sonarIssues = append(sonarIssues, auxIssue) } } } return sonarIssues } +func parseContainersSonar(result *wrappers.ScanResult) wrappers.SonarLocation { + var auxLocation wrappers.SonarLocation + auxLocation.FilePath = result.ScanResultData.ImageFilePath + auxLocation.Message = result.Description + var textRange wrappers.SonarTextRange + textRange.StartColumn = 1 + textRange.EndColumn = 2 + textRange.StartLine = 1 + textRange.EndLine = 2 + auxLocation.TextRange = textRange + return auxLocation +} + func initSonarIssue(result *wrappers.ScanResult) wrappers.SonarIssues { var sonarIssue wrappers.SonarIssues sonarIssue.Severity = sonarSeverities[result.Severity] @@ -1645,6 +1691,8 @@ func findResult(result *wrappers.ScanResult) []wrappers.SarifScanResult { scanResults = parseSarifResultKics(result, scanResults) } else if result.Type == commonParams.ScaType { scanResults = parseSarifResultsSca(result, scanResults) + } else if result.Type == commonParams.ContainerType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + scanResults = parseSarifResultsContainers(result, scanResults) } if len(scanResults) > 0 { @@ -1653,6 +1701,21 @@ func findResult(result *wrappers.ScanResult) []wrappers.SarifScanResult { return nil } +func parseSarifResultsContainers(result *wrappers.ScanResult, scanResults []wrappers.SarifScanResult) []wrappers.SarifScanResult { + var scanResult = initSarifResult(result) + var scanLocation wrappers.SarifLocation + + scanLocation.PhysicalLocation.ArtifactLocation.URI = result.ScanResultData.ImageFilePath + scanLocation.PhysicalLocation.Region = &wrappers.SarifRegion{} + scanLocation.PhysicalLocation.Region.StartLine = 1 + scanLocation.PhysicalLocation.Region.StartColumn = 1 + scanLocation.PhysicalLocation.Region.EndColumn = 2 + scanResult.Locations = append(scanResult.Locations, scanLocation) + + scanResults = append(scanResults, scanResult) + return scanResults +} + func parseSarifResultsSca(result *wrappers.ScanResult, scanResults []wrappers.SarifScanResult) []wrappers.SarifScanResult { if result == nil || result.ScanResultData.ScaPackageCollection == nil || result.ScanResultData.ScaPackageCollection.Locations == nil { return scanResults @@ -1728,6 +1791,8 @@ func convertNotAvailableNumberToZero(summary *wrappers.ResultSummary) { summary.SastIssues = 0 } else if summary.ScaIssues == notAvailableNumber { summary.ScaIssues = 0 + } else if summary.ContainersEnabled() && *summary.ContainersIssues == notAvailableNumber { + *summary.ContainersIssues = 0 } } diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 148bf5db3..1c778a846 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -37,7 +37,7 @@ func TestResultHelp(t *testing.T) { func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sarif") // Remove generated sarif file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatSarif)) + removeFile(printer.FormatSarif) } func TestParseSarifEmptyResultSast(t *testing.T) { @@ -52,47 +52,57 @@ func TestRunGetResultsByScanIdSonarFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sonar") // Remove generated sonar file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatSonar)) + removeFile(printer.FormatSonar) } func TestRunGetResultsByScanIdJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") // Remove generated json file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatJSON)) + removeFile(printer.FormatJSON) } func TestRunGetResultsByScanIdJsonFormatWithSastRedundancy(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--sast-redundancy") // Remove generated json file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatJSON)) + removeFile(printer.FormatJSON) } func TestRunGetResultsByScanIdSummaryJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryJSON") // Remove generated json file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatJSON)) + removeFile(printer.FormatJSON) } func TestRunGetResultsByScanIdSummaryHtmlFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryHTML") // Remove generated html file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatHTML)) + removeFile(printer.FormatHTML) } func TestRunGetResultsByScanIdSummaryConsoleFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryConsole") } +func TestRunGetResultsByScanIdSummaryMarkdownFormat(t *testing.T) { + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "markdown") + // Remove generated md file + removeFile("md") +} + +func removeFile(suffix string) error { + return nil // os.Remove(fmt.Sprintf("%s.%s", fileName, suffix)) +} + func TestRunGetResultsByScanIdPDFFormat(t *testing.T) { 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) // Remove generated pdf file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatPDF)) + removeFile(printer.FormatPDF) } func TestRunGetResultsByScanIdWrongFormat(t *testing.T) { @@ -286,7 +296,7 @@ func TestRunGetResultsGeneratingPdfReporWithOptions(t *testing.T) { "--output-name", fileName, "--report-pdf-options", "Iac-Security,Sast,Sca,ScanSummary") defer func() { - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatPDF)) + removeFile(printer.FormatPDF) fmt.Println("test file removed!") }() assert.NilError(t, err) @@ -330,5 +340,5 @@ func TestSBOMReportXMLWithProxy(t *testing.T) { func TestRunGetResultsByScanIdGLFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "gl-sast") // Run test for gl-sast report type - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatGL)) + removeFile(printer.FormatGL) } diff --git a/internal/params/flags.go b/internal/params/flags.go index 0017b41a4..2f986e22f 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -230,6 +230,7 @@ const ( APISecurityLabel = "API Security" ScaType = "sca" APISecType = "apisec" + ContainerType = "containers" Success = "success" ) diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 617c0ca36..0dc3638e2 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -7,6 +7,7 @@ import ( const tenantIDClaimKey = "tenant_id" const PackageEnforcementEnabled = "PACKAGE_ENFORCEMENT_ENABLED" const MinioEnabled = "MINIO_ENABLED" +const ContainerEngineCLIEnabled = "CONTAINER_ENGINE_CLI_ENABLED" var FeatureFlagsBaseMap = []CommandFlags{ { @@ -25,6 +26,9 @@ var FeatureFlagsBaseMap = []CommandFlags{ { CommandName: "cx project create", }, + { + CommandName: "cx results show", + }, } var FeatureFlags = map[string]bool{} diff --git a/internal/wrappers/mock/results-mock.go b/internal/wrappers/mock/results-mock.go index 731b65d0b..696ed038b 100644 --- a/internal/wrappers/mock/results-mock.go +++ b/internal/wrappers/mock/results-mock.go @@ -51,7 +51,7 @@ func (r ResultsMockWrapper) GetAllResultsByScanID(_ map[string]string) ( var dependencyPath = wrappers.DependencyPath{ID: mock, Name: mock, Version: mock, IsResolved: true, IsDevelopment: false, Locations: nil} var dependencyArray = [][]wrappers.DependencyPath{{dependencyPath}} return &wrappers.ScanResultsCollection{ - TotalCount: 7, + TotalCount: 8, Results: []*wrappers.ScanResult{ { Type: "sast", @@ -204,6 +204,27 @@ func (r ResultsMockWrapper) GetAllResultsByScanID(_ map[string]string) ( }, }, }, + { + Type: "containers", + Severity: "medium", + ScanResultData: wrappers.ScanResultData{ + PackageName: "image-mock", + PackageVersion: "1.1", + ImageName: "image-mock", + ImageTag: "1.1", + ImageFilePath: "DockerFile", + ImageOrigin: "Docker", + PackageIdentifier: "mock", + QueryID: 12.4, + QueryName: "mock-query-name", + }, + Description: "mock-description", + VulnerabilityDetails: wrappers.VulnerabilityDetails{ + CvssScore: 4.5, + CveName: "CVE-2021-1234", + CweID: "CWE-1234", + }, + }, { Type: "kics", Severity: "low", diff --git a/internal/wrappers/mock/scans-mock.go b/internal/wrappers/mock/scans-mock.go index 088e4d9fe..5872502f1 100644 --- a/internal/wrappers/mock/scans-mock.go +++ b/internal/wrappers/mock/scans-mock.go @@ -83,7 +83,7 @@ func (m *ScansMockWrapper) GetByID(scanID string) (*wrappers.ScanResponseModel, return &wrappers.ScanResponseModel{ ID: scanID, Status: status, - Engines: []string{params.ScaType, params.SastType, params.KicsType}, + Engines: []string{params.ScaType, params.SastType, params.KicsType, params.ContainerType}, }, nil, nil } diff --git a/internal/wrappers/results-json.go b/internal/wrappers/results-json.go index 2697cd857..2d6497894 100644 --- a/internal/wrappers/results-json.go +++ b/internal/wrappers/results-json.go @@ -108,4 +108,11 @@ type ScanResultData struct { ExpectedValue string `json:"expectedValue,omitempty"` Value string `json:"value,omitempty"` Filename string `json:"filename,omitempty"` + // Added to support containers results + PackageName string `json:"packageName,omitempty"` + PackageVersion string `json:"packageVersion,omitempty"` + ImageName string `json:"imageName,omitempty"` + ImageTag string `json:"imageTag,omitempty"` + ImageFilePath string `json:"imageFilePath,omitempty"` + ImageOrigin string `json:"imageOrigin,omitempty"` } diff --git a/internal/wrappers/results-summary.go b/internal/wrappers/results-summary.go index 599111344..66da11dee 100644 --- a/internal/wrappers/results-summary.go +++ b/internal/wrappers/results-summary.go @@ -8,31 +8,32 @@ import ( ) type ResultSummary struct { - TotalIssues int - HighIssues int - MediumIssues int - LowIssues int - InfoIssues int - SastIssues int - KicsIssues int - ScaIssues int - APISecurity APISecResult - RiskStyle string - RiskMsg string - Status string - ScanID string - ScanDate string - ScanTime string - CreatedAt string - ProjectID string - BaseURI string - Tags map[string]string - ProjectName string - BranchName string - ScanInfoMessage string - EnginesEnabled []string - Policies *PolicyResponseModel - EnginesResult EnginesResultsSummary + TotalIssues int + HighIssues int + MediumIssues int + LowIssues int + InfoIssues int + SastIssues int + KicsIssues int + ScaIssues int + ContainersIssues *int `json:"ContainersIssues,omitempty"` + APISecurity APISecResult + RiskStyle string + RiskMsg string + Status string + ScanID string + ScanDate string + ScanTime string + CreatedAt string + ProjectID string + BaseURI string + Tags map[string]string + ProjectName string + BranchName string + ScanInfoMessage string + EnginesEnabled []string + Policies *PolicyResponseModel + EnginesResult EnginesResultsSummary } // nolint: govet @@ -118,7 +119,12 @@ func (r *ResultSummary) HasEngine(engine string) bool { func (r *ResultSummary) HasAPISecurity() bool { return r.HasEngine(params.APISecType) } - +func (r *ResultSummary) ContainersEnabled() bool { + return FeatureFlags[ContainerEngineCLIEnabled] +} +func (r *ResultSummary) ContainersIssuesValue() int { + return *r.ContainersIssues +} func (r *ResultSummary) getRiskFromAPISecurity(origin string) *riskDistribution { for _, risk := range r.APISecurity.RiskDistribution { if strings.EqualFold(risk.Origin, origin) { @@ -253,6 +259,9 @@ const summaryTemplateHeader = `{{define "SummaryTemplate"}} .bg-api-sec { background-color: #bdbdbd !important; } + .bg-containers { + background-color: #c8ebed !important; + } .header-row .cx-info .data .calendar-svg { margin-right: 8px; @@ -707,6 +716,9 @@ const nonAsyncSummary = `
SCA
+ {{if .ContainersEnabled}}
Containers +
+
{{end}}
@@ -714,6 +726,7 @@ const nonAsyncSummary = `
{{if lt .SastIssues 0}}N/A{{else}}{{.SastIssues}}{{end}}
{{if lt .KicsIssues 0}}N/A{{else}}{{.KicsIssues}}{{end}}
{{if lt .ScaIssues 0}}N/A{{else}}{{.ScaIssues}}{{end}}
+ {{if .ContainersEnabled}}
{{if lt .ContainersIssuesValue 0}}N/A{{else}}{{.ContainersIssuesValue}}{{end}}
{{end}}
@@ -785,9 +798,9 @@ const SummaryMarkdownCompletedTemplate = ` ### Vulnerabilities per Scan Type -| SAST | IaC Security | SCA | -|:----------:|:----------:|:---------:| -| {{if lt .SastIssues 0}}N/A{{else}}{{.SastIssues}}{{end}} | {{if lt .KicsIssues 0}}N/A{{else}}{{.KicsIssues}}{{end}} | {{if lt .ScaIssues 0}}N/A{{else}}{{.ScaIssues}}{{end}} | +| SAST | IaC Security | SCA |{{if .ContainersEnabled}} Containers |{{end}} +|:----------:|:----------:|:---------:|{{if .ContainersEnabled}} :----------:|{{end}} +| {{if lt .SastIssues 0}}N/A{{else}}{{.SastIssues}}{{end}} | {{if lt .KicsIssues 0}}N/A{{else}}{{.KicsIssues}}{{end}} | {{if lt .ScaIssues 0}}N/A{{else}}{{.ScaIssues}}{{end}} | {{if .ContainersEnabled}}{{if lt .ScaIssues 0}}N/A{{else}}{{.ContainersIssuesValue}}{{end}} | {{end}} {{if .HasAPISecurity}} ### API Security From 61102e9e5d39e15ffff3035cbd502c32a4c02c91 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Wed, 20 Mar 2024 10:33:21 +0200 Subject: [PATCH 072/108] AST-37225 remove sonar test file --- internal/commands/cx_result_sonar.json | 163 ------------------------- internal/commands/result_test.go | 29 +++-- 2 files changed, 16 insertions(+), 176 deletions(-) delete mode 100644 internal/commands/cx_result_sonar.json diff --git a/internal/commands/cx_result_sonar.json b/internal/commands/cx_result_sonar.json deleted file mode 100644 index 5c4f5bc21..000000000 --- a/internal/commands/cx_result_sonar.json +++ /dev/null @@ -1,163 +0,0 @@ -{ - "issues": [ - { - "engineId": "sast", - "ruleId": "1", - "type": "VULNERABILITY", - "primaryLocation": { - "message": "mock-query-name-1", - "filePath": "dummy-file-name-1", - "textRange": { - "startLine": 10, - "startColumn": 10, - "endColumn": 30 - } - }, - "secondaryLocations": [ - { - "message": "mock-query-name-1", - "filePath": "dummy-file-name-1", - "textRange": { - "startLine": 11, - "startColumn": 3, - "endColumn": 13 - } - } - ] - }, - { - "engineId": "sast", - "ruleId": "2", - "type": "VULNERABILITY", - "primaryLocation": { - "message": "mock-query-name-2", - "filePath": "dummy-file-name-2", - "textRange": { - "startLine": 10, - "startColumn": 10, - "endColumn": 30 - } - }, - "secondaryLocations": [ - { - "message": "mock-query-name-2", - "filePath": "dummy-file-name-2", - "textRange": { - "startLine": 11, - "startColumn": 3, - "endColumn": 13 - } - } - ] - }, - { - "engineId": "sast", - "ruleId": "3", - "type": "VULNERABILITY", - "primaryLocation": { - "message": "mock-query-name-2", - "filePath": "dummy-file-name-2", - "textRange": { - "startLine": 10, - "startColumn": 10, - "endColumn": 30 - } - }, - "secondaryLocations": [ - { - "message": "mock-query-name-2", - "filePath": "dummy-file-name-2", - "textRange": { - "startLine": 11, - "startColumn": 3, - "endColumn": 13 - } - }, - { - "message": "mock-query-name-2", - "filePath": "dummy-file-name-2", - "textRange": { - "startLine": 12, - "startColumn": 3, - "endColumn": 13 - } - } - ] - }, - { - "engineId": "sast", - "ruleId": "4", - "type": "VULNERABILITY", - "primaryLocation": { - "message": "mock-query-name-3", - "filePath": "dummy-file-name-3", - "textRange": { - "startLine": 10, - "startColumn": 10, - "endColumn": 30 - } - }, - "secondaryLocations": [ - { - "message": "mock-query-name-3", - "filePath": "dummy-file-name-3", - "textRange": { - "startLine": 11, - "startColumn": 3, - "endColumn": 13 - } - } - ] - }, - { - "engineId": "sast", - "ruleId": "5", - "type": "VULNERABILITY", - "primaryLocation": { - "message": "mock-query-name-3", - "filePath": "dummy-file-name-4", - "textRange": { - "startLine": 10, - "startColumn": 10, - "endColumn": 30 - } - }, - "secondaryLocations": [ - { - "message": "mock-query-name-3", - "filePath": "dummy-file-name-4", - "textRange": { - "startLine": 11, - "startColumn": 3, - "endColumn": 13 - } - } - ] - }, - { - "engineId": "containers", - "type": "VULNERABILITY", - "primaryLocation": { - "message": "mock-description", - "filePath": "DockerFile", - "textRange": { - "startLine": 1, - "endLine": 2, - "startColumn": 1, - "endColumn": 2 - } - }, - "secondaryLocations": null - }, - { - "engineId": "kics", - "type": "VULNERABILITY", - "primaryLocation": { - "textRange": { - "endColumn": 1 - } - }, - "secondaryLocations": null - } - ] -} diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 1c778a846..1fc31d3c7 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -37,7 +37,7 @@ func TestResultHelp(t *testing.T) { func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sarif") // Remove generated sarif file - removeFile(printer.FormatSarif) + removeFileBySuffix(printer.FormatSarif) } func TestParseSarifEmptyResultSast(t *testing.T) { @@ -50,37 +50,36 @@ func TestParseSarifEmptyResultSast(t *testing.T) { func TestRunGetResultsByScanIdSonarFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sonar") - // Remove generated sonar file - removeFile(printer.FormatSonar) + removeFile(fileName+"_"+printer.FormatSonar, printer.FormatJSON) } func TestRunGetResultsByScanIdJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") // Remove generated json file - removeFile(printer.FormatJSON) + removeFileBySuffix(printer.FormatJSON) } func TestRunGetResultsByScanIdJsonFormatWithSastRedundancy(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--sast-redundancy") // Remove generated json file - removeFile(printer.FormatJSON) + removeFileBySuffix(printer.FormatJSON) } func TestRunGetResultsByScanIdSummaryJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryJSON") // Remove generated json file - removeFile(printer.FormatJSON) + removeFileBySuffix(printer.FormatJSON) } func TestRunGetResultsByScanIdSummaryHtmlFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryHTML") // Remove generated html file - removeFile(printer.FormatHTML) + removeFileBySuffix(printer.FormatHTML) } func TestRunGetResultsByScanIdSummaryConsoleFormat(t *testing.T) { @@ -90,11 +89,15 @@ func TestRunGetResultsByScanIdSummaryConsoleFormat(t *testing.T) { func TestRunGetResultsByScanIdSummaryMarkdownFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "markdown") // Remove generated md file - removeFile("md") + removeFileBySuffix("md") +} + +func removeFileBySuffix(suffix string) error { + return removeFile(fileName, suffix) } -func removeFile(suffix string) error { - return nil // os.Remove(fmt.Sprintf("%s.%s", fileName, suffix)) +func removeFile(prefix string, suffix string) error { + return os.Remove(fmt.Sprintf("%s.%s", prefix, suffix)) } func TestRunGetResultsByScanIdPDFFormat(t *testing.T) { @@ -102,7 +105,7 @@ func TestRunGetResultsByScanIdPDFFormat(t *testing.T) { _, err := os.Stat(fmt.Sprintf("%s.%s", fileName, printer.FormatPDF)) assert.NilError(t, err, "Report file should exist for extension "+printer.FormatPDF) // Remove generated pdf file - removeFile(printer.FormatPDF) + removeFileBySuffix(printer.FormatPDF) } func TestRunGetResultsByScanIdWrongFormat(t *testing.T) { @@ -296,7 +299,7 @@ func TestRunGetResultsGeneratingPdfReporWithOptions(t *testing.T) { "--output-name", fileName, "--report-pdf-options", "Iac-Security,Sast,Sca,ScanSummary") defer func() { - removeFile(printer.FormatPDF) + removeFileBySuffix(printer.FormatPDF) fmt.Println("test file removed!") }() assert.NilError(t, err) @@ -340,5 +343,5 @@ func TestSBOMReportXMLWithProxy(t *testing.T) { func TestRunGetResultsByScanIdGLFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "gl-sast") // Run test for gl-sast report type - removeFile(printer.FormatGL) + removeFileBySuffix(printer.FormatGL) } From 43e6e68f48c147d07c88569abb55228a3bbe7eae Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Wed, 20 Mar 2024 11:13:19 +0200 Subject: [PATCH 073/108] AST-37225 UI colors in the html summery report --- internal/wrappers/results-summary.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/wrappers/results-summary.go b/internal/wrappers/results-summary.go index 66da11dee..4d0d51844 100644 --- a/internal/wrappers/results-summary.go +++ b/internal/wrappers/results-summary.go @@ -241,7 +241,7 @@ const summaryTemplateHeader = `{{define "SummaryTemplate"}} } .bg-kicks { - background-color: #008e96 !important; + background-color: #079E9E !important; } .bg-red { @@ -249,18 +249,18 @@ const summaryTemplateHeader = `{{define "SummaryTemplate"}} } .bg-sast { - background-color: #1165b4 !important; + background-color: #0356A5 !important; } .bg-sca { - background-color: #0fcdc2 !important; + background-color: #15D7D7 !important; } .bg-api-sec { background-color: #bdbdbd !important; } .bg-containers { - background-color: #c8ebed !important; + background-color: #70F9CC !important; } .header-row .cx-info .data .calendar-svg { From 51b98fc4fbe6a711df83f6ce70e7e54611700086 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Wed, 20 Mar 2024 12:46:47 +0200 Subject: [PATCH 074/108] AST-37225 lint issues --- internal/params/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/params/flags.go b/internal/params/flags.go index 2f986e22f..051b1773d 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -230,7 +230,7 @@ const ( APISecurityLabel = "API Security" ScaType = "sca" APISecType = "apisec" - ContainerType = "containers" + ContainersType = "containers" Success = "success" ) From aee66e667e9d514cbace44469922f86dc0f25111 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Wed, 20 Mar 2024 13:14:23 +0200 Subject: [PATCH 075/108] AST-37225 lint issues --- internal/commands/result.go | 31 ++++++++++++++++------------ internal/commands/result_test.go | 29 +++++++++++++------------- internal/wrappers/mock/scans-mock.go | 2 +- internal/wrappers/results-summary.go | 4 ++-- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 88929c18c..798c1a00b 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -372,7 +372,7 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { containersIssues = new(int) *containersIssues = 0 - enginesStatusCode[commonParams.ContainerType] = 0 + enginesStatusCode[commonParams.ContainersType] = 0 } if len(scanInfo.StatusDetails) > 0 { @@ -384,7 +384,7 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr scaIssues = notAvailableNumber } else if statusDetailItem.Name == commonParams.KicsType { kicsIssues = notAvailableNumber - } else if statusDetailItem.Name == commonParams.ContainerType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + } else if statusDetailItem.Name == commonParams.ContainersType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { *containersIssues = notAvailableNumber } } @@ -423,7 +423,7 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr }, } if summary.ContainersEnabled() { - summary.EnginesResult[commonParams.ContainerType] = &wrappers.EngineResultSummary{StatusCode: enginesStatusCode[commonParams.ContainerType]} + summary.EnginesResult[commonParams.ContainersType] = &wrappers.EngineResultSummary{StatusCode: enginesStatusCode[commonParams.ContainersType]} } baseURI, err := resultsWrapper.GetResultsURL(summary.ProjectID) if err != nil { @@ -469,7 +469,7 @@ func summaryReport( setNotAvailableNumberIfZero(summary, &summary.ScaIssues, commonParams.ScaType) setNotAvailableNumberIfZero(summary, &summary.KicsIssues, commonParams.KicsType) if summary.ContainersEnabled() { - setNotAvailableNumberIfZero(summary, summary.ContainersIssues, commonParams.ContainerType) + setNotAvailableNumberIfZero(summary, summary.ContainersIssues, commonParams.ContainersType) } setRiskMsgAndStyle(summary) setNotAvailableEnginesStatusCode(summary) @@ -639,7 +639,7 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode) printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode) if summary.ContainersEnabled() { - printTableRow("CONTAINERS", summary.EnginesResult[commonParams.ContainerType], summary.EnginesResult[commonParams.ContainerType].StatusCode) + printTableRow("CONTAINERS", summary.EnginesResult[commonParams.ContainersType], summary.EnginesResult[commonParams.ContainersType].StatusCode) } fmt.Println(tableLine) @@ -837,7 +837,7 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { } else if engineType == commonParams.KicsType { summary.KicsIssues++ summary.TotalIssues++ - } else if engineType == commonParams.ContainerType { + } else if engineType == commonParams.ContainersType { if summary.ContainersEnabled() { *summary.ContainersIssues++ summary.TotalIssues++ @@ -845,14 +845,19 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { return } } - if severity == highLabel { + switch severity { + case highLabel: summary.HighIssues++ - } else if severity == lowLabel { - summary.LowIssues++ - } else if severity == mediumLabel { + break + case mediumLabel: summary.MediumIssues++ - } else if severity == infoLabel { + break + case lowLabel: + summary.LowIssues++ + break + case infoLabel: summary.InfoIssues++ + break } summary.UpdateEngineResultSummary(engineType, severity) } @@ -1476,7 +1481,7 @@ func parseResultsSonar(results *wrappers.ScanResultsCollection) []wrappers.Sonar } else if engineType == commonParams.ScaType { sonarIssuesByLocation := parseScaSonarLocations(result) sonarIssues = append(sonarIssues, sonarIssuesByLocation...) - } else if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && engineType == commonParams.ContainerType { + } else if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && engineType == commonParams.ContainersType { auxIssue.PrimaryLocation = parseContainersSonar(result) sonarIssues = append(sonarIssues, auxIssue) } @@ -1691,7 +1696,7 @@ func findResult(result *wrappers.ScanResult) []wrappers.SarifScanResult { scanResults = parseSarifResultKics(result, scanResults) } else if result.Type == commonParams.ScaType { scanResults = parseSarifResultsSca(result, scanResults) - } else if result.Type == commonParams.ContainerType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + } else if result.Type == commonParams.ContainersType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { scanResults = parseSarifResultsContainers(result, scanResults) } diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 1fc31d3c7..e542ff748 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -37,7 +37,7 @@ func TestResultHelp(t *testing.T) { func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sarif") // Remove generated sarif file - removeFileBySuffix(printer.FormatSarif) + removeFileBySuffix(t, printer.FormatSarif) } func TestParseSarifEmptyResultSast(t *testing.T) { @@ -51,35 +51,35 @@ func TestParseSarifEmptyResultSast(t *testing.T) { func TestRunGetResultsByScanIdSonarFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sonar") // Remove generated sonar file - removeFile(fileName+"_"+printer.FormatSonar, printer.FormatJSON) + removeFile(t, fileName+"_"+printer.FormatSonar, printer.FormatJSON) } func TestRunGetResultsByScanIdJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") // Remove generated json file - removeFileBySuffix(printer.FormatJSON) + removeFileBySuffix(t, printer.FormatJSON) } func TestRunGetResultsByScanIdJsonFormatWithSastRedundancy(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--sast-redundancy") // Remove generated json file - removeFileBySuffix(printer.FormatJSON) + removeFileBySuffix(t, printer.FormatJSON) } func TestRunGetResultsByScanIdSummaryJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryJSON") // Remove generated json file - removeFileBySuffix(printer.FormatJSON) + removeFileBySuffix(t, printer.FormatJSON) } func TestRunGetResultsByScanIdSummaryHtmlFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryHTML") // Remove generated html file - removeFileBySuffix(printer.FormatHTML) + removeFileBySuffix(t, printer.FormatHTML) } func TestRunGetResultsByScanIdSummaryConsoleFormat(t *testing.T) { @@ -89,15 +89,16 @@ func TestRunGetResultsByScanIdSummaryConsoleFormat(t *testing.T) { func TestRunGetResultsByScanIdSummaryMarkdownFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "markdown") // Remove generated md file - removeFileBySuffix("md") + removeFileBySuffix(t, "md") } -func removeFileBySuffix(suffix string) error { - return removeFile(fileName, suffix) +func removeFileBySuffix(t *testing.T, suffix string) { + removeFile(t, fileName, suffix) } -func removeFile(prefix string, suffix string) error { - return os.Remove(fmt.Sprintf("%s.%s", prefix, suffix)) +func removeFile(t *testing.T, prefix, suffix string) { + err := os.Remove(fmt.Sprintf("%s.%s", prefix, suffix)) + assert.NilError(t, err, "Error removing file, check if report file created") } func TestRunGetResultsByScanIdPDFFormat(t *testing.T) { @@ -105,7 +106,7 @@ func TestRunGetResultsByScanIdPDFFormat(t *testing.T) { _, err := os.Stat(fmt.Sprintf("%s.%s", fileName, printer.FormatPDF)) assert.NilError(t, err, "Report file should exist for extension "+printer.FormatPDF) // Remove generated pdf file - removeFileBySuffix(printer.FormatPDF) + removeFileBySuffix(t, printer.FormatPDF) } func TestRunGetResultsByScanIdWrongFormat(t *testing.T) { @@ -299,7 +300,7 @@ func TestRunGetResultsGeneratingPdfReporWithOptions(t *testing.T) { "--output-name", fileName, "--report-pdf-options", "Iac-Security,Sast,Sca,ScanSummary") defer func() { - removeFileBySuffix(printer.FormatPDF) + removeFileBySuffix(t, printer.FormatPDF) fmt.Println("test file removed!") }() assert.NilError(t, err) @@ -343,5 +344,5 @@ func TestSBOMReportXMLWithProxy(t *testing.T) { func TestRunGetResultsByScanIdGLFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "gl-sast") // Run test for gl-sast report type - removeFileBySuffix(printer.FormatGL) + removeFile(t, "cx_result.gl-sast-report", "json") } diff --git a/internal/wrappers/mock/scans-mock.go b/internal/wrappers/mock/scans-mock.go index 5872502f1..9c9999235 100644 --- a/internal/wrappers/mock/scans-mock.go +++ b/internal/wrappers/mock/scans-mock.go @@ -83,7 +83,7 @@ func (m *ScansMockWrapper) GetByID(scanID string) (*wrappers.ScanResponseModel, return &wrappers.ScanResponseModel{ ID: scanID, Status: status, - Engines: []string{params.ScaType, params.SastType, params.KicsType, params.ContainerType}, + Engines: []string{params.ScaType, params.SastType, params.KicsType, params.ContainersType}, }, nil, nil } diff --git a/internal/wrappers/results-summary.go b/internal/wrappers/results-summary.go index 4d0d51844..b3f86b955 100644 --- a/internal/wrappers/results-summary.go +++ b/internal/wrappers/results-summary.go @@ -103,8 +103,8 @@ func (engineSummary *EngineResultSummary) Increment(level string) { } } -func (summary *ResultSummary) UpdateEngineResultSummary(engineType, severity string) { - summary.EnginesResult[engineType].Increment(severity) +func (r *ResultSummary) UpdateEngineResultSummary(engineType, severity string) { + r.EnginesResult[engineType].Increment(severity) } func (r *ResultSummary) HasEngine(engine string) bool { From 0efcb383547934a264d408bc4e0bdea7aef88e7b Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Wed, 20 Mar 2024 13:15:07 +0200 Subject: [PATCH 076/108] AST-37225 lint issues --- internal/commands/result.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 798c1a00b..90e87187a 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -848,16 +848,12 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { switch severity { case highLabel: summary.HighIssues++ - break case mediumLabel: summary.MediumIssues++ - break case lowLabel: summary.LowIssues++ - break case infoLabel: summary.InfoIssues++ - break } summary.UpdateEngineResultSummary(engineType, severity) } From 0072d21fa980a50b88164224c18d916fc6987873 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 20 Mar 2024 15:36:16 +0200 Subject: [PATCH 077/108] update containerType and containerFlagTYpe --- internal/commands/result.go | 42 +++++++++++------------ internal/commands/scan.go | 3 +- internal/params/flags.go | 4 +-- internal/wrappers/jwt-helper.go | 14 ++++---- internal/wrappers/mock/jwt-helper-mock.go | 2 +- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 3e20d3417..ced20f065 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -18,7 +18,6 @@ import ( "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/commands/util/printer" "github.com/checkmarx/ast-cli/internal/logger" - "github.com/gookit/color" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -63,6 +62,7 @@ const ( scanFailedNumber = -2 scanCanceledNumber = -3 defaultPaddingSize = -13 + boldFormat = "\033[1m%s\033[0m" scanPendingMessage = "Scan triggered in asynchronous mode or still running. Click more details to get the full status." directDependencyType = "Direct Dependency" indirectDependencyType = "Transitive Dependency" @@ -357,11 +357,10 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr scaIssues := 0 kicsIssues := 0 enginesStatusCode := map[string]int{ - commonParams.SastType: 0, - commonParams.ScaType: 0, - commonParams.KicsType: 0, - commonParams.APISecType: 0, - commonParams.ContainersType: 0, + commonParams.SastType: 0, + commonParams.ScaType: 0, + commonParams.KicsType: 0, + commonParams.APISecType: 0, } if len(scanInfo.StatusDetails) > 0 { @@ -402,11 +401,10 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr BranchName: scanInfo.Branch, EnginesEnabled: scanInfo.Engines, EnginesResult: map[string]*wrappers.EngineResultSummary{ - commonParams.SastType: {StatusCode: enginesStatusCode[commonParams.SastType]}, - commonParams.ScaType: {StatusCode: enginesStatusCode[commonParams.ScaType]}, - commonParams.KicsType: {StatusCode: enginesStatusCode[commonParams.KicsType]}, - commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]}, - commonParams.ContainersType: {StatusCode: enginesStatusCode[commonParams.ContainersType]}, + commonParams.SastType: {StatusCode: enginesStatusCode[commonParams.SastType]}, + commonParams.ScaType: {StatusCode: enginesStatusCode[commonParams.ScaType]}, + commonParams.KicsType: {StatusCode: enginesStatusCode[commonParams.KicsType]}, + commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]}, }, } @@ -561,7 +559,7 @@ func writeConsoleSummary(summary *wrappers.ResultSummary) error { } func printPoliciesSummary(summary *wrappers.ResultSummary) { - fmt.Printf(" ------------------------------------------------------- \n") + fmt.Printf(" -------------------------------------- \n") if summary.Policies.BreakBuild { fmt.Printf(" Policy Management Violation - Break Build Enabled: \n") } else { @@ -587,12 +585,12 @@ func printAPIsSecuritySummary(summary *wrappers.ResultSummary) { if summary.HasAPISecurityDocumentation() { fmt.Printf(" APIS DOCUMENTATION: %*d \n", defaultPaddingSize, summary.GetAPISecurityDocumentationTotal()) } - fmt.Printf(" ------------------------------------------------------- \n\n") + fmt.Printf(" -------------------------------------------------- \n\n") } func printTableRow(title string, counts *wrappers.EngineResultSummary, statusNumber int) { - formatString := " | %-9s %4d %6d %4d %4d %-9s |\n" - notAvailableFormatString := " | %-9s %4s %6s %4s %4s %5s |\n" + formatString := " | %-4s %4d %6d %4d %4d %-9s |\n" + notAvailableFormatString := " | %-4s %4s %6s %4s %4s %5s |\n" switch statusNumber { case notAvailableNumber: @@ -611,20 +609,20 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { totalMediumIssues := summary.EnginesResult.GetMediumIssues() totalLowIssues := summary.EnginesResult.GetLowIssues() totalInfoIssues := summary.EnginesResult.GetInfoIssues() - fmt.Printf(" -------------------------------------------------------- \n\n") + fmt.Printf(" --------------------------------------------------- \n\n") fmt.Printf(" Total Results: %d \n", summary.TotalIssues) - fmt.Println(" -------------------------------------------------------- ") - fmt.Println(" | High Medium Low Info Status |") + fmt.Println(" --------------------------------------------------- ") + fmt.Println(" | High Medium Low Info Status |") printTableRow("APIs", summary.EnginesResult[commonParams.APISecType], summary.EnginesResult[commonParams.APISecType].StatusCode) printTableRow("IAC", summary.EnginesResult[commonParams.KicsType], summary.EnginesResult[commonParams.KicsType].StatusCode) printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode) printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode) - fmt.Println(" -------------------------------------------------------- ") - fmt.Printf(" | %-9s %4d %6d %4d %4d %-9s |\n", - color.Bold.Sprintf("TOTAL "), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) - fmt.Printf(" -------------------------------------------------------- \n\n") + fmt.Println(" --------------------------------------------------- ") + fmt.Printf(" | %-4s %4d %6d %4d %4d %-9s |\n", + fmt.Sprintf(boldFormat, "TOTAL"), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) + fmt.Printf(" --------------------------------------------------- \n\n") } func generateScanSummaryURL(summary *wrappers.ResultSummary) string { diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 3ff2f08d8..7acfc579b 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1037,7 +1037,7 @@ func addContainersScan() map[string]interface{} { return nil } containerMapConfig := make(map[string]interface{}) - containerMapConfig[resultsMapType] = strings.ToLower(commonParams.ContainerLabel) + containerMapConfig[resultsMapType] = commonParams.ContainersType containerConfig := wrappers.ContainerConfig{} @@ -1072,6 +1072,7 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper) error if len(userScanTypes) > 0 { userScanTypes = strings.ReplaceAll(strings.ToLower(userScanTypes), " ", "") userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.KicsType, commonParams.IacType, 1) + userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.ContainersFlagType, commonParams.ContainersType, 1) scanTypes = strings.Split(userScanTypes, ",") for _, scanType := range scanTypes { diff --git a/internal/params/flags.go b/internal/params/flags.go index b006a47fa..d7a49ebc8 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -225,12 +225,12 @@ const ( SastType = "sast" KicsType = "kics" APISecurityType = "api-security" - ContainersType = "container-security" + ContainersType = "containers" + ContainersFlagType = "container-security" APIDocumentationFlag = "apisec-swagger-filter" IacType = "iac-security" IacLabel = "IaC Security" APISecurityLabel = "API Security" - ContainerLabel = "Containers" ScaType = "sca" APISecType = "apisec" Success = "success" diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index cb24db2f9..1a8fe21c7 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -19,14 +19,14 @@ type JWTStruct struct { jwt.Claims } -var enabledEngines = []string{"sast", "sca", "api-security", "iac-security", "container-security"} +var enabledEngines = []string{"sast", "sca", "api-security", "iac-security", "containers"} var defaultEngines = map[string]bool{ - "sast": true, - "sca": true, - "api-security": true, - "iac-security": true, - "container-security": true, + "sast": true, + "sca": true, + "api-security": true, + "iac-security": true, + "containers": true, } type JWTWrapper interface { @@ -63,7 +63,6 @@ func prepareEngines(engines []string) map[string]bool { for _, value := range engines { engine := strings.Replace(strings.ToLower(value), strings.ToLower(commonParams.APISecurityLabel), commonParams.APISecurityType, 1) engine = strings.Replace(strings.ToLower(engine), commonParams.KicsType, commonParams.IacType, 1) - engine = strings.Replace(strings.ToLower(engine), strings.ToLower(commonParams.ContainerLabel), commonParams.ContainersType, 1) // Current limitation, CxOne is including non-engines in the JWT if utils.Contains(enabledEngines, strings.ToLower(engine)) { @@ -73,6 +72,7 @@ func prepareEngines(engines []string) map[string]bool { m[strings.ToLower(engine)] = true } } + FeatureFlags[ContainerEngineCLIEnabled] = true return m } diff --git a/internal/wrappers/mock/jwt-helper-mock.go b/internal/wrappers/mock/jwt-helper-mock.go index 71e8759a0..a616438bb 100644 --- a/internal/wrappers/mock/jwt-helper-mock.go +++ b/internal/wrappers/mock/jwt-helper-mock.go @@ -9,7 +9,7 @@ type JWTMockWrapper struct{} // GetAllowedEngines mock for tests func (*JWTMockWrapper) GetAllowedEngines() (allowedEngines map[string]bool, err error) { allowedEngines = make(map[string]bool) - engines := []string{"sast", "iac-security", "sca", "api-security", "container-security"} + engines := []string{"sast", "iac-security", "sca", "api-security", "containers"} for _, value := range engines { allowedEngines[strings.ToLower(value)] = true } From 38168282517d0c5fa1ef55743e5e2ecac044f3da Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 20 Mar 2024 16:26:58 +0200 Subject: [PATCH 078/108] fix scaConfig.EnableContainersScan initialization --- internal/commands/scan.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 7acfc579b..0ca3bdad0 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1013,6 +1013,7 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config) map[string scaConfig.Filter, _ = cmd.Flags().GetString(commonParams.ScaFilterFlag) scaConfig.LastSastScanTime, _ = cmd.Flags().GetString(commonParams.LastSastScanTime) scaConfig.PrivatePackageVersion, _ = cmd.Flags().GetString(commonParams.ScaPrivatePackageVersionFlag) + scaConfig.EnableContainersScan = !(wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && userAllowedEngines[commonParams.ContainersType]) exploitablePath, _ := cmd.Flags().GetString(commonParams.ExploitablePathFlag) if exploitablePath != "" { scaConfig.ExploitablePath = strings.ToLower(exploitablePath) @@ -1023,7 +1024,6 @@ func addScaScan(cmd *cobra.Command, resubmitConfig []wrappers.Config) map[string if resubmitFilter != nil && scaConfig.Filter == "" { scaConfig.Filter = resubmitFilter.(string) } - scaConfig.EnableContainersScan = !(wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && userAllowedEngines[commonParams.ContainersType]) } } scaMapConfig[resultsMapValue] = &scaConfig From ee25cb36ce2596eb35a7b5e151117464bf441a2b Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 21 Mar 2024 10:51:42 +0200 Subject: [PATCH 079/108] change containersTypeFlag position --- internal/commands/scan.go | 2 +- internal/params/flags.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 0ca3bdad0..dae88448c 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1072,7 +1072,7 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper) error if len(userScanTypes) > 0 { userScanTypes = strings.ReplaceAll(strings.ToLower(userScanTypes), " ", "") userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.KicsType, commonParams.IacType, 1) - userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.ContainersFlagType, commonParams.ContainersType, 1) + userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.ContainersTypeFlag, commonParams.ContainersType, 1) scanTypes = strings.Split(userScanTypes, ",") for _, scanType := range scanTypes { diff --git a/internal/params/flags.go b/internal/params/flags.go index d7a49ebc8..2da055460 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -137,6 +137,7 @@ const ( ProjecPrivatePackageFlag = "project-private-package" SastRedundancyFlag = "sast-redundancy" ContainerImagesFlag = "container-images" + ContainersTypeFlag = "container-security" ScaPrivatePackageVersionFlag = "sca-private-package-version" @@ -226,7 +227,6 @@ const ( KicsType = "kics" APISecurityType = "api-security" ContainersType = "containers" - ContainersFlagType = "container-security" APIDocumentationFlag = "apisec-swagger-filter" IacType = "iac-security" IacLabel = "IaC Security" From 29602c0f4c78057cc568b7edacb8cfba88861416 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Thu, 21 Mar 2024 11:19:51 +0200 Subject: [PATCH 080/108] containers type --- internal/params/flags.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/params/flags.go b/internal/params/flags.go index cc20d6181..051b1773d 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -224,7 +224,6 @@ const ( SastType = "sast" KicsType = "kics" APISecurityType = "api-security" - ContainersType = "containers" APIDocumentationFlag = "apisec-swagger-filter" IacType = "iac-security" IacLabel = "IaC Security" From 160a0f562af904649ffeebc29bcec7c79a3ecb81 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Thu, 21 Mar 2024 11:49:29 +0200 Subject: [PATCH 081/108] delete default initialization to ContainerEngineCliEnabled flag --- internal/wrappers/jwt-helper.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index 1a8fe21c7..e328c1df9 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -72,7 +72,6 @@ func prepareEngines(engines []string) map[string]bool { m[strings.ToLower(engine)] = true } } - FeatureFlags[ContainerEngineCLIEnabled] = true return m } From 0524afe644eb7d4dd53682fb032b937958a734fd Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Thu, 21 Mar 2024 15:44:24 +0200 Subject: [PATCH 082/108] show containers only for supported agents --- internal/commands/result.go | 35 +++++++++++++++++----------- internal/commands/scan.go | 2 ++ internal/wrappers/results-summary.go | 4 +++- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 90e87187a..02e0c25e0 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -143,6 +143,10 @@ var sonarSeverities = map[string]string{ highCx: highSonar, } +var containerSupportedAgents = []string{ + commonParams.DefaultAgent, +} + func NewResultsCommand( resultsWrapper wrappers.ResultsWrapper, scanWrapper wrappers.ScansWrapper, @@ -369,7 +373,7 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr commonParams.KicsType: 0, commonParams.APISecType: 0, } - if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + if wrappers.IsContainersEnabled { containersIssues = new(int) *containersIssues = 0 enginesStatusCode[commonParams.ContainersType] = 0 @@ -384,7 +388,7 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr scaIssues = notAvailableNumber } else if statusDetailItem.Name == commonParams.KicsType { kicsIssues = notAvailableNumber - } else if statusDetailItem.Name == commonParams.ContainersType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + } else if statusDetailItem.Name == commonParams.ContainersType && wrappers.IsContainersEnabled { *containersIssues = notAvailableNumber } } @@ -422,7 +426,7 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]}, }, } - if summary.ContainersEnabled() { + if wrappers.IsContainersEnabled { summary.EnginesResult[commonParams.ContainersType] = &wrappers.EngineResultSummary{StatusCode: enginesStatusCode[commonParams.ContainersType]} } baseURI, err := resultsWrapper.GetResultsURL(summary.ProjectID) @@ -468,7 +472,7 @@ func summaryReport( setNotAvailableNumberIfZero(summary, &summary.SastIssues, commonParams.SastType) setNotAvailableNumberIfZero(summary, &summary.ScaIssues, commonParams.ScaType) setNotAvailableNumberIfZero(summary, &summary.KicsIssues, commonParams.KicsType) - if summary.ContainersEnabled() { + if wrappers.IsContainersEnabled { setNotAvailableNumberIfZero(summary, summary.ContainersIssues, commonParams.ContainersType) } setRiskMsgAndStyle(summary) @@ -514,7 +518,7 @@ func enhanceWithScanSummary(summary *wrappers.ResultSummary, results *wrappers.S summary.EnginesResult[commonParams.APISecType].High = summary.APISecurity.Risks[1] } summary.TotalIssues = summary.SastIssues + summary.ScaIssues + summary.KicsIssues + summary.GetAPISecurityDocumentationTotal() - if summary.ContainersEnabled() { + if wrappers.IsContainersEnabled { summary.TotalIssues += *summary.ContainersIssues } } @@ -638,7 +642,7 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { printTableRow("IAC", summary.EnginesResult[commonParams.KicsType], summary.EnginesResult[commonParams.KicsType].StatusCode) printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode) printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode) - if summary.ContainersEnabled() { + if wrappers.IsContainersEnabled { printTableRow("CONTAINERS", summary.EnginesResult[commonParams.ContainersType], summary.EnginesResult[commonParams.ContainersType].StatusCode) } @@ -674,6 +678,7 @@ func runGetResultCommand( useSCALocalFlow, _ := cmd.Flags().GetBool(commonParams.ReportSbomFormatLocalFlowFlag) retrySBOM, _ := cmd.Flags().GetInt(commonParams.RetrySBOMFlag) sastRedundancy, _ := cmd.Flags().GetBool(commonParams.SastRedundancyFlag) + agent, _ := cmd.Flags().GetString(commonParams.AgentFlag) scanID, _ := cmd.Flags().GetString(commonParams.ScanIDFlag) if scanID == "" { @@ -706,7 +711,6 @@ func runGetResultCommand( } else { logger.PrintIfVerbose("Skipping policy evaluation") } - if sastRedundancy { params[commonParams.SastRedundancyFlag] = "" } @@ -726,6 +730,7 @@ func runGetResultCommand( formatSbomOptions, targetFile, targetPath, + agent, params) } } @@ -769,7 +774,10 @@ func runGetCodeBashingCommand( return nil } } - +func setIsContainersEnabled(agent string) { + agentSupported := contains(containerSupportedAgents, agent) + wrappers.IsContainersEnabled = wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && agentSupported +} func CreateScanReport( resultsWrapper wrappers.ResultsWrapper, risksOverviewWrapper wrappers.RisksOverviewWrapper, @@ -785,11 +793,12 @@ func CreateScanReport( formatSbomOptions, targetFile, targetPath string, + agent string, params map[string]string, ) error { reportList := strings.Split(reportTypes, ",") results := &wrappers.ScanResultsCollection{} - + setIsContainersEnabled(agent) summary, err := convertScanToResultsSummary(scan, resultsWrapper) if err != nil { return err @@ -838,7 +847,7 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { summary.KicsIssues++ summary.TotalIssues++ } else if engineType == commonParams.ContainersType { - if summary.ContainersEnabled() { + if wrappers.IsContainersEnabled { *summary.ContainersIssues++ summary.TotalIssues++ } else { @@ -1477,7 +1486,7 @@ func parseResultsSonar(results *wrappers.ScanResultsCollection) []wrappers.Sonar } else if engineType == commonParams.ScaType { sonarIssuesByLocation := parseScaSonarLocations(result) sonarIssues = append(sonarIssues, sonarIssuesByLocation...) - } else if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && engineType == commonParams.ContainersType { + } else if wrappers.IsContainersEnabled && engineType == commonParams.ContainersType { auxIssue.PrimaryLocation = parseContainersSonar(result) sonarIssues = append(sonarIssues, auxIssue) } @@ -1692,7 +1701,7 @@ func findResult(result *wrappers.ScanResult) []wrappers.SarifScanResult { scanResults = parseSarifResultKics(result, scanResults) } else if result.Type == commonParams.ScaType { scanResults = parseSarifResultsSca(result, scanResults) - } else if result.Type == commonParams.ContainersType && wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + } else if result.Type == commonParams.ContainersType && wrappers.IsContainersEnabled { scanResults = parseSarifResultsContainers(result, scanResults) } @@ -1792,7 +1801,7 @@ func convertNotAvailableNumberToZero(summary *wrappers.ResultSummary) { summary.SastIssues = 0 } else if summary.ScaIssues == notAvailableNumber { summary.ScaIssues = 0 - } else if summary.ContainersEnabled() && *summary.ContainersIssues == notAvailableNumber { + } else if wrappers.IsContainersEnabled && *summary.ContainersIssues == notAvailableNumber { *summary.ContainersIssues = 0 } } diff --git a/internal/commands/scan.go b/internal/commands/scan.go index f3b7b098a..c61ccd931 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -1784,6 +1784,7 @@ func createReportsAfterScan( formatSbomOptions, _ := cmd.Flags().GetString(commonParams.ReportSbomFormatFlag) useSCALocalFlow, _ := cmd.Flags().GetBool(commonParams.ReportSbomFormatLocalFlowFlag) retrySBOM, _ := cmd.Flags().GetInt(commonParams.RetrySBOMFlag) + agent, _ := cmd.Flags().GetString(commonParams.AgentFlag) params, err := getFilters(cmd) if err != nil { @@ -1814,6 +1815,7 @@ func createReportsAfterScan( formatSbomOptions, targetFile, targetPath, + agent, params, ) } diff --git a/internal/wrappers/results-summary.go b/internal/wrappers/results-summary.go index b3f86b955..8c40573be 100644 --- a/internal/wrappers/results-summary.go +++ b/internal/wrappers/results-summary.go @@ -58,6 +58,8 @@ type EngineResultSummary struct { type EnginesResultsSummary map[string]*EngineResultSummary +var IsContainersEnabled bool + func (engineSummary *EnginesResultsSummary) GetHighIssues() int { highIssues := 0 for _, v := range *engineSummary { @@ -120,7 +122,7 @@ func (r *ResultSummary) HasAPISecurity() bool { return r.HasEngine(params.APISecType) } func (r *ResultSummary) ContainersEnabled() bool { - return FeatureFlags[ContainerEngineCLIEnabled] + return IsContainersEnabled } func (r *ResultSummary) ContainersIssuesValue() int { return *r.ContainersIssues From 098b3279e4fdf3d3020269437cbabac1f398236f Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 24 Mar 2024 09:38:30 +0200 Subject: [PATCH 083/108] added featurflagWrapper to scanCommand constructor --- internal/commands/root.go | 30 ++++++++++++++++++++---------- internal/commands/scan.go | 9 +++++++++ test/integration/scan_test.go | 5 ++--- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/internal/commands/root.go b/internal/commands/root.go index c67558966..b91621571 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -54,7 +54,6 @@ func NewAstCLI( accessManagementWrapper wrappers.AccessManagementWrapper, containerResolverWrapper wrappers.ContainerResolverWrapper, ) *cobra.Command { - setUpFeatureFlags(featureFlagsWrapper) // Create the root rootCmd := &cobra.Command{ Use: "cx [flags]", @@ -108,7 +107,16 @@ func NewAstCLI( _ = cmd.Help() os.Exit(0) } + if requiredFeatureFlagsCheck(cmd) { + err := wrappers.HandleFeatureFlags(featureFlagsWrapper) + + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } } + // Link the environment variable to the CLI argument(s). _ = viper.BindPFlag(params.AccessKeyIDConfigKey, rootCmd.PersistentFlags().Lookup(params.AccessKeyIDFlag)) _ = viper.BindPFlag(params.AccessKeySecretConfigKey, rootCmd.PersistentFlags().Lookup(params.AccessKeySecretFlag)) @@ -154,6 +162,7 @@ func NewAstCLI( sastMetadataWrapper, accessManagementWrapper, containerResolverWrapper, + featureFlagsWrapper, ) projectCmd := NewProjectCommand(applicationsWrapper, projectsWrapper, groupsWrapper, accessManagementWrapper) resultsCmd := NewResultsCommand( @@ -214,6 +223,16 @@ func PrintConfiguration() { } } +func requiredFeatureFlagsCheck(cmd *cobra.Command) bool { + for _, cmdFlag := range wrappers.FeatureFlagsBaseMap { + if cmdFlag.CommandName == cmd.CommandPath() { + return true + } + } + + return false +} + func getFilters(cmd *cobra.Command) (map[string]string, error) { filters, err := cmd.Flags().GetStringSlice(params.FilterFlag) if err != nil { @@ -289,12 +308,3 @@ func printByScanInfoFormat(cmd *cobra.Command, view interface{}) error { f, _ := cmd.Flags().GetString(params.ScanInfoFormatFlag) return printer.Print(cmd.OutOrStdout(), view, f) } - -func setUpFeatureFlags(featureFlagsWrapper wrappers.FeatureFlagsWrapper) { - err := wrappers.HandleFeatureFlags(featureFlagsWrapper) - - if err != nil { - fmt.Println(err) - os.Exit(1) - } -} diff --git a/internal/commands/scan.go b/internal/commands/scan.go index dae88448c..c2e6a6f2a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -141,6 +141,7 @@ func NewScanCommand( sastMetadataWrapper wrappers.SastMetadataWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, containerResolverWrapper wrappers.ContainerResolverWrapper, + featureFlagWrapper wrappers.FeatureFlagsWrapper, ) *cobra.Command { scanCmd := &cobra.Command{ Use: "scan", @@ -168,6 +169,7 @@ func NewScanCommand( policyWrapper, accessManagementWrapper, applicationsWrapper, + featureFlagWrapper, ) containerResolver = containerResolverWrapper userAllowedEngines, _ = jwtWrapper.GetAllowedEngines() @@ -422,6 +424,7 @@ func scanCreateSubCommand( policyWrapper wrappers.PolicyWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, applicationsWrapper wrappers.ApplicationsWrapper, + featureFlagWrapper wrappers.FeatureFlagsWrapper, ) *cobra.Command { createScanCmd := &cobra.Command{ Use: "create", @@ -506,6 +509,12 @@ func scanCreateSubCommand( "", fmt.Sprintf("Parameters to use in SCA resolver (requires --%s).", commonParams.ScaResolverFlag), ) + if len(wrappers.FeatureFlags) == 0 { + featureFlagErr := wrappers.HandleFeatureFlags(featureFlagWrapper) + if featureFlagErr != nil { + log.Fatal(featureFlagErr) + } + } if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { 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,container-security)") diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index cda35bd7b..58ae889c6 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -113,11 +113,10 @@ func TestScanCreate_ApplicationDoesntExist_FailScanWithError(t *testing.T) { } func TestScanCreateWithContainersEngine(t *testing.T) { - type TestCase struct { + testCases := []struct { Name string Arguments []string - } - testCases := []TestCase{ + }{ { Name: "Container images flag specified and empty folder project", Arguments: []string{ From b0875513b4174132c8ff69d3b0ffbc60080d99f4 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Sun, 24 Mar 2024 10:33:26 +0200 Subject: [PATCH 084/108] bold Total --- 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 02e0c25e0..9687c18b2 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -648,7 +648,7 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { fmt.Println(tableLine) fmt.Printf(tableResultsFormat, - fmt.Sprintf(boldFormat, "TOTAL"), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) + fmt.Sprintf(boldFormat, "TOTAL "), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) fmt.Printf(tableLine + twoNewLines) } From 21b4505f4ae3c093ea01771663a950a01a363df1 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Sun, 24 Mar 2024 12:11:40 +0200 Subject: [PATCH 085/108] tests --- internal/commands/result.go | 15 +++++++++++ internal/commands/result_test.go | 44 +++++++++++++++++++++++++++++++- test/integration/scan_test.go | 2 +- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 9687c18b2..858236445 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -1079,9 +1079,24 @@ func enrichScaResults( // Compute SAST results redundancy resultsModel = ComputeRedundantSastResults(resultsModel) } + if util.Contains(scan.Engines, commonParams.ContainersType) && !wrappers.IsContainersEnabled { + resultsModel = removeContainerResults(resultsModel) + } return resultsModel, nil } +func removeContainerResults(model *wrappers.ScanResultsCollection) *wrappers.ScanResultsCollection { + var newResults []*wrappers.ScanResult + for _, result := range model.Results { + if result.Type != commonParams.ContainersType { + newResults = append(newResults, result) + } + } + model.Results = newResults + model.TotalCount = uint(len(newResults)) + return model +} + func exportSarifResults(targetFile string, results *wrappers.ScanResultsCollection) error { var err error var resultsJSON []byte diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index e542ff748..02cc0544c 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -1,8 +1,9 @@ -//go:build !integration +//go:build integration package commands import ( + "encoding/json" "fmt" "os" "testing" @@ -10,6 +11,7 @@ import ( "github.com/checkmarx/ast-cli/internal/commands/util/printer" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" + "github.com/checkmarx/ast-cli/internal/wrappers/mock" "gotest.tools/assert" ) @@ -346,3 +348,43 @@ func TestRunGetResultsByScanIdGLFormat(t *testing.T) { // Run test for gl-sast report type removeFile(t, "cx_result.gl-sast-report", "json") } +func TestRunResultsShow_ContainersFFIsOn_includeContainersResult(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") + assertContainersPresent(t, true) + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} +func TestRunResultsShow_ContainersFFIsOff_excludeContainersResult(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: false}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") + assertContainersPresent(t, false) + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} +func TestRunResultsShow_AgentIsNotSupported_excludeContainersResult(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "jet-brains") + assertContainersPresent(t, false) + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} + +func assertContainersPresent(t *testing.T, hasContainersPresent bool) { + bytes, err := os.ReadFile(fileName + "." + printer.FormatJSON) + assert.NilError(t, err, "Error reading file") + // Unmarshal the JSON data into the ScanResultsCollection struct + var scanResultsCollection *wrappers.ScanResultsCollection + err = json.Unmarshal(bytes, &scanResultsCollection) + assert.NilError(t, err, "Error unmarshalling JSON data") + for _, scanResult := range scanResultsCollection.Results { + if !hasContainersPresent && scanResult.Type == params.ContainersType { + assert.Assert(t, false, "Containers result should not be present") + } else if hasContainersPresent && scanResult.Type == params.ContainersType { + return + } + } + if hasContainersPresent { + assert.Assert(t, false, "Containers result should be present") + } +} diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index c8b6055de..2f3d0d4a7 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -463,7 +463,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) { - return executeCreateScan(t, getCreateArgs(source, tags, "sast , sca , iac-security , api-security ")) + return executeCreateScan(t, getCreateArgs(source, tags, "sast , sca , iac-security , api-security ")) } func createScanNoWait(t *testing.T, source string, tags map[string]string) (string, string) { From 4b85af32e0b4068ddf8183e4a14650bc03938899 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Sun, 24 Mar 2024 17:54:46 +0200 Subject: [PATCH 086/108] remove default initialization of ContainerEngineCLIEnabled --- internal/wrappers/feature-flags.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 93d2477b9..21c5fe877 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -21,10 +21,6 @@ var FeatureFlagsBaseMap = []CommandFlags{ Name: MinioEnabled, Default: true, }, - { - Name: ContainerEngineCLIEnabled, - Default: true, - }, }, }, { From a7f41e6fff367902d86501ee5486702d0fbca6fb Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 25 Mar 2024 11:08:24 +0200 Subject: [PATCH 087/108] upgrade container resolver to version 1.0.3 --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 32931ff5a..a63c50880 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/checkmarx/ast-cli go 1.22.1 require ( - github.com/CheckmarxDev/containers-resolver v1.0.2 + github.com/CheckmarxDev/containers-resolver v1.0.3 github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible @@ -72,7 +72,7 @@ require ( github.com/distribution/reference v0.5.0 // indirect github.com/docker/cli v25.0.1+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v25.0.3+incompatible // indirect + github.com/docker/docker v25.0.5+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect diff --git a/go.sum b/go.sum index ca5ad2180..89f46a94f 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CheckmarxDev/containers-resolver v1.0.2 h1:iVxjvYtZKEtt8dkjkN6yGQ9qlk4f1AuHFYVEbK4o4s4= -github.com/CheckmarxDev/containers-resolver v1.0.2/go.mod h1:pzpaje1Qlrxl5BtWiMMVxAErpbWFwKsuQWNTvImHzpA= +github.com/CheckmarxDev/containers-resolver v1.0.3 h1:OELrWejUfdNLQAahrn28SoNgfzmoUuq5S9/mt3l6sWg= +github.com/CheckmarxDev/containers-resolver v1.0.3/go.mod h1:f8Xc7jBhlsmMh/XZHMhhLB6gTTIllzr5RgZE5GLwi+U= github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= github.com/CycloneDX/cyclonedx-go v0.8.0/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= @@ -246,8 +246,8 @@ github.com/docker/cli v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbT github.com/docker/cli v25.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v25.0.3+incompatible h1:D5fy/lYmY7bvZa0XTZ5/UJPljor41F+vdyJG5luQLfQ= -github.com/docker/docker v25.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= +github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= From 6f74c7d29ab81b8203e16b293aebe06dd8b75e0d Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 25 Mar 2024 11:34:32 +0200 Subject: [PATCH 088/108] update unitests --- internal/commands/scan_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 9b3a19d56..6b79f9185 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -126,31 +126,37 @@ func TestCreateScan(t *testing.T) { } func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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 + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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 :") From a6b3bc20caaf7da844c0324fe0cfc844dffd02e3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Mon, 25 Mar 2024 16:49:12 +0200 Subject: [PATCH 089/108] update tests --- internal/commands/scan.go | 6 ++ test/integration/scan_test.go | 157 ++++++++++++++++------------------ 2 files changed, 78 insertions(+), 85 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index c2e6a6f2a..2a922c9ca 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -515,6 +515,12 @@ func scanCreateSubCommand( log.Fatal(featureFlagErr) } } + if len(wrappers.FeatureFlags) == 0 { + featureFlagErr := wrappers.HandleFeatureFlags(featureFlagWrapper) + if featureFlagErr != nil { + log.Fatal(featureFlagErr) + } + } if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { 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,container-security)") diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 58ae889c6..7040cc834 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -112,94 +112,81 @@ func TestScanCreate_ApplicationDoesntExist_FailScanWithError(t *testing.T) { assertError(t, err, applicationErrors.ApplicationDoesntExistOrNoPermission) } -func TestScanCreateWithContainersEngine(t *testing.T) { - testCases := []struct { - Name string - Arguments []string - }{ - { - Name: "Container images flag specified and empty folder project", - Arguments: []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/empty-folder", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - }, - }, - { - Name: "Container images flag and container scan type specified", - Arguments: []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ScanTypes), "container-security", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - }, - }, - { - Name: "Container images flag specified", - Arguments: []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - }, - }, - { - Name: "Container images and debug flags specified", - Arguments: []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - flag(params.DebugFlag), - }, - }, - { - Name: "Container images flag specified and empty folder project", - Arguments: []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/empty-folder", - flag(params.ContainerImagesFlag), "debian:12,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - }, - }, - { - Name: "Container type specified and empty folder project", - Arguments: []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/empty-folder", - flag(params.ScanTypes), "container-security", - flag(params.BranchFlag), "dummy_branch", - }, - }, - { - Name: "Invalid container images flag specified", - Arguments: []string{ - "scan", "create", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/withDockerInZip.zip", - flag(params.ContainerImagesFlag), "debian,nginx:latest", - flag(params.BranchFlag), "dummy_branch", - }, - }, +func TestContainerEngineScansE2E_ContainerImagesFlagAndScanType(t *testing.T) { + testArgs := []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ScanTypes), "container-security", + flag(params.ContainerImagesFlag), "nginx:alpine,debian:9", + flag(params.BranchFlag), "dummy_branch", + flag(params.ApikeyOverrideFlag), + } + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + executeScanAssertions(t, projectID, scanID, Tags) + assertZipFileRemoved(t) +} + +func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { + testArgs := []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ContainerImagesFlag), "nginx:alpine", + flag(params.BranchFlag), "dummy_branch", + flag(params.ApikeyOverrideFlag), + } + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + executeScanAssertions(t, projectID, scanID, Tags) + assertZipFileRemoved(t) +} + +func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { + testArgs := []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ContainerImagesFlag), "nginx:alpine", + flag(params.BranchFlag), "dummy_branch", + flag(params.DebugFlag), + flag(params.ApikeyOverrideFlag), + } + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + executeScanAssertions(t, projectID, scanID, Tags) + assertZipFileRemoved(t) +} + +func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *testing.T) { + testArgs := []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/empty-folder", + flag(params.ContainerImagesFlag), "nginx:alpine,debian:9", + flag(params.BranchFlag), "dummy_branch", + flag(params.ApikeyOverrideFlag), } + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + executeScanAssertions(t, projectID, scanID, Tags) + assertZipFileRemoved(t) +} - for _, tc := range testCases { - tc := tc - t.Run(tc.Name, func(t *testing.T) { - scanID, projectID := executeCreateScan(t, tc.Arguments) - deleteProject(t, projectID) - executeScanAssertions(t, projectID, scanID, Tags) - assertZipFileRemoved(t) - }) +func TestContainerEngineScansE2E_InvalidContainerImagesFlag(t *testing.T) { + testArgs := []string{ + "scan", "create", + flag(params.ProjectName), "my-project", + flag(params.SourcesFlag), "data/withDockerInZip.zip", + flag(params.ContainerImagesFlag), "nginx:alpine,debian:9", + flag(params.BranchFlag), "dummy_branch", + flag(params.ApikeyOverrideFlag), } + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + executeScanAssertions(t, projectID, scanID, Tags) + assertZipFileRemoved(t) } func assertZipFileRemoved(t *testing.T) { From daa034719826a1000b241682685ea3ead3d6e163 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 09:28:52 +0200 Subject: [PATCH 090/108] upgrade container-resolver version and changed test zip file for container scan tests --- go.mod | 2 +- go.sum | 4 +- internal/commands/scan_test.go | 1 - test/integration/data/Dockerfile-mysql571.zip | Bin 0 -> 647 bytes test/integration/data/withDockerInZip.zip | Bin 92571 -> 0 bytes test/integration/scan_test.go | 41 ++++++++++-------- 6 files changed, 27 insertions(+), 21 deletions(-) create mode 100644 test/integration/data/Dockerfile-mysql571.zip delete mode 100644 test/integration/data/withDockerInZip.zip diff --git a/go.mod b/go.mod index a63c50880..7b2efee9a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/checkmarx/ast-cli go 1.22.1 require ( - github.com/CheckmarxDev/containers-resolver v1.0.3 + github.com/CheckmarxDev/containers-resolver v1.0.4 github.com/MakeNowJust/heredoc v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/go.sum b/go.sum index 89f46a94f..513be8a80 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CheckmarxDev/containers-resolver v1.0.3 h1:OELrWejUfdNLQAahrn28SoNgfzmoUuq5S9/mt3l6sWg= -github.com/CheckmarxDev/containers-resolver v1.0.3/go.mod h1:f8Xc7jBhlsmMh/XZHMhhLB6gTTIllzr5RgZE5GLwi+U= +github.com/CheckmarxDev/containers-resolver v1.0.4 h1:iIYPKIrh0s6yaCxRn0ltgzssz6QVQyyZMuaP+aOejA8= +github.com/CheckmarxDev/containers-resolver v1.0.4/go.mod h1:f8Xc7jBhlsmMh/XZHMhhLB6gTTIllzr5RgZE5GLwi+U= github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= github.com/CycloneDX/cyclonedx-go v0.8.0/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 6b79f9185..e409f25e3 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -128,7 +128,6 @@ func TestCreateScan(t *testing.T) { func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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)...) } diff --git a/test/integration/data/Dockerfile-mysql571.zip b/test/integration/data/Dockerfile-mysql571.zip new file mode 100644 index 0000000000000000000000000000000000000000..48612463146400d90764c58d9f57e721de4e030b GIT binary patch literal 647 zcmWIWW@Zs#-~hr?v3tW9pg<5vb1^6|xa22irxvAU=A?#(@G`K+q?M$^0WpX!t>9*0 zWckX-zyQ?Gz);Nn>3isjwK{rdHX2dSgmRVnji|a zDn8!V(b+#ZLSHW)hpk1Jwk9WtCZ{JPC4BJp3H!hw))COaG(mz{T|nBb+WQruB=jADXO}z^5jp=nUyaE{yJ2$ zF|x5~w#=Gy4%_`4$~%sXP9^UH!B^SAQXEk^SS_ z=Am;EQ+G_R%YC@3U+(p`BiVB2F3z9m<1<0zm9#{}jL6wDXUv{4bEaB!bM352kx6Gk zLC4OaDWxU$0vL>-01NPDWD;RU#2a!jgW?SamNbG`IKmT4ETWr>Y$qs^U|>mOHjqhH Wlm&RRvVn|Y0>a%udK=I?3=9AqEW{`P literal 0 HcmV?d00001 diff --git a/test/integration/data/withDockerInZip.zip b/test/integration/data/withDockerInZip.zip deleted file mode 100644 index 4d4c0dfc0c748988c3fa11da07e5e50cfdbf7343..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92571 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%0D(HaIxJ(S5e+YiHg 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 z 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 WSkOTo06-e_FNGWcSQLc:") } func assertZipFileRemoved(t *testing.T) { From a7df6d2842a686d53f2d0a14b26698b5118aa5d2 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Tue, 26 Mar 2024 10:30:53 +0200 Subject: [PATCH 091/108] tests --- internal/commands/result_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 02cc0544c..9e31170cc 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -370,7 +370,7 @@ func TestRunResultsShow_AgentIsNotSupported_excludeContainersResult(t *testing.T removeFileBySuffix(t, printer.FormatJSON) } -func assertContainersPresent(t *testing.T, hasContainersPresent bool) { +func assertContainersPresent(t *testing.T, isContainersEnabled bool) { bytes, err := os.ReadFile(fileName + "." + printer.FormatJSON) assert.NilError(t, err, "Error reading file") // Unmarshal the JSON data into the ScanResultsCollection struct @@ -378,13 +378,13 @@ func assertContainersPresent(t *testing.T, hasContainersPresent bool) { err = json.Unmarshal(bytes, &scanResultsCollection) assert.NilError(t, err, "Error unmarshalling JSON data") for _, scanResult := range scanResultsCollection.Results { - if !hasContainersPresent && scanResult.Type == params.ContainersType { + if !isContainersEnabled && scanResult.Type == params.ContainersType { assert.Assert(t, false, "Containers result should not be present") - } else if hasContainersPresent && scanResult.Type == params.ContainersType { + } else if isContainersEnabled && scanResult.Type == params.ContainersType { return } } - if hasContainersPresent { + if isContainersEnabled { assert.Assert(t, false, "Containers result should be present") } } From 2c135eeb6fbcfcea537cb3453e9f520d07320760 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 10:31:26 +0200 Subject: [PATCH 092/108] fix containerEngine FF handling --- internal/wrappers/feature-flags.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 21c5fe877..93d2477b9 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -21,6 +21,10 @@ var FeatureFlagsBaseMap = []CommandFlags{ Name: MinioEnabled, Default: true, }, + { + Name: ContainerEngineCLIEnabled, + Default: true, + }, }, }, { From 6c5cffbc305816824c6830a7a476f2516baece6e Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 10:36:54 +0200 Subject: [PATCH 093/108] fix containerEngine FF handling --- internal/commands/scan.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 2a922c9ca..c2e6a6f2a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -515,12 +515,6 @@ func scanCreateSubCommand( log.Fatal(featureFlagErr) } } - if len(wrappers.FeatureFlags) == 0 { - featureFlagErr := wrappers.HandleFeatureFlags(featureFlagWrapper) - if featureFlagErr != nil { - log.Fatal(featureFlagErr) - } - } if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { 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,container-security)") From 21c81c21146124543c0848419673f3334482954b Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 10:54:27 +0200 Subject: [PATCH 094/108] fix containerEngine FF handling --- internal/wrappers/feature-flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 93d2477b9..ad1938337 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -23,7 +23,7 @@ var FeatureFlagsBaseMap = []CommandFlags{ }, { Name: ContainerEngineCLIEnabled, - Default: true, + Default: false, }, }, }, From e4596826849a10b9de5590eff2f7ddd19c1f6d10 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 11:13:57 +0200 Subject: [PATCH 095/108] fix containerEngine FF handling --- internal/commands/scan.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index c2e6a6f2a..868afda32 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -512,7 +512,7 @@ func scanCreateSubCommand( if len(wrappers.FeatureFlags) == 0 { featureFlagErr := wrappers.HandleFeatureFlags(featureFlagWrapper) if featureFlagErr != nil { - log.Fatal(featureFlagErr) + logger.PrintIfVerbose("Failed to get feature flags") } } if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { From 7db192cf89d3cf0e1bd79fdeeac78f3c5d225f45 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 12:42:07 +0200 Subject: [PATCH 096/108] fix containerEngine FF handling --- internal/wrappers/feature-flags.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index ad1938337..21c5fe877 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -21,10 +21,6 @@ var FeatureFlagsBaseMap = []CommandFlags{ Name: MinioEnabled, Default: true, }, - { - Name: ContainerEngineCLIEnabled, - Default: false, - }, }, }, { From 2789aced251a3834e651217537d8541dfd8a8c60 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Tue, 26 Mar 2024 13:32:09 +0200 Subject: [PATCH 097/108] adding test and fixes --- internal/commands/result.go | 1 - internal/commands/result_test.go | 4 ++++ internal/wrappers/mock/results-mock.go | 31 +++++++++++++++++++++++++- test/integration/result_test.go | 2 -- test/integration/scan_test.go | 2 +- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 858236445..803fccfab 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -208,7 +208,6 @@ func resultShowSubCommand( printer.FormatPDF, printer.FormatSummaryMarkdown, printer.FormatGL, - // printer.FormatSonar ?? ) resultShowCmd.PersistentFlags().String(commonParams.ReportFormatPdfToEmailFlag, "", pdfToEmailFlagDescription) resultShowCmd.PersistentFlags().String(commonParams.ReportSbomFormatFlag, defaultSbomOption, sbomReportFlagDescription) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 9e31170cc..9c488e2aa 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -388,3 +388,7 @@ func assertContainersPresent(t *testing.T, isContainersEnabled bool) { assert.Assert(t, false, "Containers result should be present") } } +func TestRunGetResultsShow_ContainersFFOffAndResultsHasContainersResultsOnly_NilAssertion(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: false}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "CONTAINERS_ONLY", "--report-format", "summaryConsole") +} diff --git a/internal/wrappers/mock/results-mock.go b/internal/wrappers/mock/results-mock.go index 696ed038b..c9c5e5b14 100644 --- a/internal/wrappers/mock/results-mock.go +++ b/internal/wrappers/mock/results-mock.go @@ -42,11 +42,40 @@ func (r ResultsMockWrapper) GetAllResultsPackageByScanID(params map[string]strin return &scaPackages, nil, nil } -func (r ResultsMockWrapper) GetAllResultsByScanID(_ map[string]string) ( +func (r ResultsMockWrapper) GetAllResultsByScanID(params map[string]string) ( *wrappers.ScanResultsCollection, *wrappers.WebError, error, ) { + if params["scan-id"] == "CONTAINERS_ONLY" { + return &wrappers.ScanResultsCollection{ + TotalCount: 8, + Results: []*wrappers.ScanResult{ + { + Type: "containers", + Severity: "medium", + ScanResultData: wrappers.ScanResultData{ + PackageName: "image-mock", + PackageVersion: "1.1", + ImageName: "image-mock", + ImageTag: "1.1", + ImageFilePath: "DockerFile", + ImageOrigin: "Docker", + PackageIdentifier: "mock", + QueryID: 12.4, + QueryName: "mock-query-name", + }, + Description: "mock-description", + VulnerabilityDetails: wrappers.VulnerabilityDetails{ + CvssScore: 4.5, + CveName: "CVE-2021-1234", + CweID: "CWE-1234", + }, + }, + }, + }, nil, nil + + } const mock = "mock" var dependencyPath = wrappers.DependencyPath{ID: mock, Name: mock, Version: mock, IsResolved: true, IsDevelopment: false, Locations: nil} var dependencyArray = [][]wrappers.DependencyPath{{dependencyPath}} diff --git a/test/integration/result_test.go b/test/integration/result_test.go index b3711da84..b667d0f97 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -23,11 +23,9 @@ const ( // Create a scan and test getting its results func TestResultListJson(t *testing.T) { - assertRequiredParameter(t, "Please provide a scan ID", "results", "show") scanID, _ := getRootScan(t) - outputBuffer := executeCmdNilAssertion( t, "Getting results should pass", "results", diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 2f3d0d4a7..5de4baa0a 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -463,7 +463,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) { - return executeCreateScan(t, getCreateArgs(source, tags, "sast , sca , iac-security , api-security ")) + return executeCreateScan(t, getCreateArgs(source, tags, "sast , sca , iac-security , api-security , container-security ")) } func createScanNoWait(t *testing.T, source string, tags map[string]string) (string, string) { From bfb3db850c3ca14fa2984e2ff983dde240dcfba4 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Tue, 26 Mar 2024 13:41:04 +0200 Subject: [PATCH 098/108] lint issues --- internal/wrappers/mock/results-mock.go | 69 ++++++++++---------------- 1 file changed, 25 insertions(+), 44 deletions(-) diff --git a/internal/wrappers/mock/results-mock.go b/internal/wrappers/mock/results-mock.go index c9c5e5b14..3af261886 100644 --- a/internal/wrappers/mock/results-mock.go +++ b/internal/wrappers/mock/results-mock.go @@ -42,6 +42,28 @@ func (r ResultsMockWrapper) GetAllResultsPackageByScanID(params map[string]strin return &scaPackages, nil, nil } +var containersResults = &wrappers.ScanResult{ + Type: "containers", + Severity: "medium", + ScanResultData: wrappers.ScanResultData{ + PackageName: "image-mock", + PackageVersion: "1.1", + ImageName: "image-mock", + ImageTag: "1.1", + ImageFilePath: "DockerFile", + ImageOrigin: "Docker", + PackageIdentifier: "mock", + QueryID: 12.4, + QueryName: "mock-query-name", + }, + Description: "mock-description", + VulnerabilityDetails: wrappers.VulnerabilityDetails{ + CvssScore: 4.5, + CveName: "CVE-2021-1234", + CweID: "CWE-1234", + }, +} + func (r ResultsMockWrapper) GetAllResultsByScanID(params map[string]string) ( *wrappers.ScanResultsCollection, *wrappers.WebError, @@ -49,32 +71,11 @@ func (r ResultsMockWrapper) GetAllResultsByScanID(params map[string]string) ( ) { if params["scan-id"] == "CONTAINERS_ONLY" { return &wrappers.ScanResultsCollection{ - TotalCount: 8, + TotalCount: 1, Results: []*wrappers.ScanResult{ - { - Type: "containers", - Severity: "medium", - ScanResultData: wrappers.ScanResultData{ - PackageName: "image-mock", - PackageVersion: "1.1", - ImageName: "image-mock", - ImageTag: "1.1", - ImageFilePath: "DockerFile", - ImageOrigin: "Docker", - PackageIdentifier: "mock", - QueryID: 12.4, - QueryName: "mock-query-name", - }, - Description: "mock-description", - VulnerabilityDetails: wrappers.VulnerabilityDetails{ - CvssScore: 4.5, - CveName: "CVE-2021-1234", - CweID: "CWE-1234", - }, - }, + containersResults, }, }, nil, nil - } const mock = "mock" var dependencyPath = wrappers.DependencyPath{ID: mock, Name: mock, Version: mock, IsResolved: true, IsDevelopment: false, Locations: nil} @@ -233,27 +234,7 @@ func (r ResultsMockWrapper) GetAllResultsByScanID(params map[string]string) ( }, }, }, - { - Type: "containers", - Severity: "medium", - ScanResultData: wrappers.ScanResultData{ - PackageName: "image-mock", - PackageVersion: "1.1", - ImageName: "image-mock", - ImageTag: "1.1", - ImageFilePath: "DockerFile", - ImageOrigin: "Docker", - PackageIdentifier: "mock", - QueryID: 12.4, - QueryName: "mock-query-name", - }, - Description: "mock-description", - VulnerabilityDetails: wrappers.VulnerabilityDetails{ - CvssScore: 4.5, - CveName: "CVE-2021-1234", - CweID: "CWE-1234", - }, - }, + containersResults, { Type: "kics", Severity: "low", From 347878d241ce21eaeb040ce4aa41102367b46d9e Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Tue, 26 Mar 2024 15:45:41 +0200 Subject: [PATCH 099/108] test with ff=on --- internal/commands/result.go | 2 +- internal/commands/result_test.go | 76 ++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 803fccfab..7264416b2 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -647,7 +647,7 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) { fmt.Println(tableLine) fmt.Printf(tableResultsFormat, - fmt.Sprintf(boldFormat, "TOTAL "), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) + "TOTAL", totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) fmt.Printf(tableLine + twoNewLines) } diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 9c488e2aa..c70c1e54c 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -41,6 +41,12 @@ func TestRunGetResultsByScanIdSarifFormat(t *testing.T) { // Remove generated sarif file removeFileBySuffix(t, printer.FormatSarif) } +func TestRunGetResultsByScanIdSarifFormatWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sarif") + // Remove generated sarif file + removeFileBySuffix(t, printer.FormatSarif) +} func TestParseSarifEmptyResultSast(t *testing.T) { emptyResult := &wrappers.ScanResult{} @@ -56,6 +62,13 @@ func TestRunGetResultsByScanIdSonarFormat(t *testing.T) { removeFile(t, fileName+"_"+printer.FormatSonar, printer.FormatJSON) } +func TestRunGetResultsByScanIdSonarFormatWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{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) +} + func TestRunGetResultsByScanIdJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") @@ -63,6 +76,14 @@ func TestRunGetResultsByScanIdJsonFormat(t *testing.T) { removeFileBySuffix(t, printer.FormatJSON) } +func TestRunGetResultsByScanIdJsonFormatWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json") + + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} + func TestRunGetResultsByScanIdJsonFormatWithSastRedundancy(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--sast-redundancy") @@ -77,6 +98,14 @@ func TestRunGetResultsByScanIdSummaryJsonFormat(t *testing.T) { removeFileBySuffix(t, printer.FormatJSON) } +func TestRunGetResultsByScanIdSummaryJsonFormatWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryJSON") + + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} + func TestRunGetResultsByScanIdSummaryHtmlFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryHTML") @@ -84,11 +113,31 @@ func TestRunGetResultsByScanIdSummaryHtmlFormat(t *testing.T) { removeFileBySuffix(t, printer.FormatHTML) } +func TestRunGetResultsByScanIdSummaryHtmlFormatWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryHTML") + + // Remove generated html file + removeFileBySuffix(t, printer.FormatHTML) +} + func TestRunGetResultsByScanIdSummaryConsoleFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryConsole") } +func TestRunGetResultsByScanIdSummaryMarkdownFormatWithContainers(t *testing.T) { + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "markdown") + // Remove generated md file + removeFileBySuffix(t, "md") +} + +func TestRunGetResultsByScanIdSummaryConsoleFormatWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryConsole") +} + func TestRunGetResultsByScanIdSummaryMarkdownFormat(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "markdown") // Remove generated md file removeFileBySuffix(t, "md") @@ -111,6 +160,15 @@ func TestRunGetResultsByScanIdPDFFormat(t *testing.T) { removeFileBySuffix(t, printer.FormatPDF) } +func TestRunGetResultsByScanIdPDFFormatWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{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) + // Remove generated pdf file + removeFileBySuffix(t, printer.FormatPDF) +} + func TestRunGetResultsByScanIdWrongFormat(t *testing.T) { err := execCmdNotNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "invalidFormat") assert.Equal(t, err.Error(), "bad report format invalidFormat", "Wrong expected error message") @@ -335,6 +393,24 @@ func TestSBOMReportXML(t *testing.T) { os.Remove(fmt.Sprintf("%s.%s", fileName+"_"+printer.FormatSbom, printer.FormatXML)) } +func TestSBOMReportJsonWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{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) + // Remove generated json file + os.Remove(fmt.Sprintf("%s.%s", fileName+"_"+printer.FormatSbom, printer.FormatJSON)) +} + +func TestSBOMReportXMLWithContainers(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{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) + // Remove generated json file + os.Remove(fmt.Sprintf("%s.%s", fileName+"_"+printer.FormatSbom, printer.FormatXML)) +} + func TestSBOMReportXMLWithProxy(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "sbom", "--report-sbom-format", "CycloneDxXml", "--report-sbom-local-flow") _, err := os.Stat(fmt.Sprintf("%s.%s", fileName+"_"+printer.FormatSbom, printer.FormatXML)) From 08c693216f3241408c315fceade707b908822c96 Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Tue, 26 Mar 2024 16:27:46 +0200 Subject: [PATCH 100/108] fix test coverage --- 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 c70c1e54c..4156d102d 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -1,4 +1,4 @@ -//go:build integration +//go:build !integration package commands From 437e4b4656919cffc333b32f791a88d4f1532ade Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 16:36:58 +0200 Subject: [PATCH 101/108] check unit tests --- internal/commands/scan_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index e409f25e3..52b716491 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -125,16 +125,16 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } -func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "data/sources.zip", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag") -} +//func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { +// mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { +// mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} From e3d79868394ce652a73f0507efd7303874f75b65 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 16:52:17 +0200 Subject: [PATCH 102/108] check unit tests --- internal/commands/scan_test.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 52b716491..f44cace02 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -125,16 +125,15 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } -//func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { -// mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { -// mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} -// execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "data/sources.zip", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag") -//} +// func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { +// mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} From 008cad2ddbcce2dd6961c47ab27b6139398cdad3 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 17:07:35 +0200 Subject: [PATCH 103/108] check unit tests --- internal/commands/scan_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index f44cace02..985cc4f1d 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -132,7 +132,8 @@ func TestCreateScan(t *testing.T) { // } func TestCreateScanFromZip_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", "data/sources.zip", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag") + baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag"} + execCmdNilAssertion(t, append(baseArgs, "-s", "data/sources.zip")...) } func TestCreateScanFromZip_ContainerTypeAndFilterFlags_ScanCreatedSuccessfully(t *testing.T) { From bfcd0e362beb72b08734576a68361b7cb6c42563 Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 17:22:11 +0200 Subject: [PATCH 104/108] check unit tests --- internal/commands/scan_test.go | 14 +++++++------- test/integration/scan_test.go | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 985cc4f1d..e409f25e3 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -125,15 +125,15 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } -// func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { -// mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { +func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "--container-images", "image1:latest,image2:tag"} - execCmdNilAssertion(t, append(baseArgs, "-s", "data/sources.zip")...) + execCmdNilAssertion(t, append(baseArgs, "-s", blankSpace+"."+blankSpace)...) +} + +func TestCreateScanFromZip_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 7d7a94044..7c5d0ad06 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -134,7 +134,7 @@ func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { testArgs := []string{ "scan", "create", flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/Dockerfile-mysql571.zip", + flag(params.SourcesFlag), "data/insecure.zip", flag(params.ContainerImagesFlag), "nginx:alpine", flag(params.BranchFlag), "dummy_branch", flag(params.ApikeyOverrideFlag), @@ -151,8 +151,8 @@ func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { testArgs := []string{ "scan", "create", flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), "data/Dockerfile-mysql571.zip", - flag(params.ContainerImagesFlag), "nginx:alpine", + flag(params.SourcesFlag), "data/insecure.zip", + flag(params.ContainerImagesFlag), "mysql:5.7", flag(params.BranchFlag), "dummy_branch", flag(params.DebugFlag), flag(params.ApikeyOverrideFlag), @@ -170,7 +170,7 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *tes "scan", "create", flag(params.ProjectName), "my-project", flag(params.SourcesFlag), "data/empty-folder", - flag(params.ContainerImagesFlag), "nginx:alpine,debian:9", + flag(params.ContainerImagesFlag), "mysql:5.7", flag(params.BranchFlag), "dummy_branch", flag(params.ApikeyOverrideFlag), flag(params.ScanInfoFormatFlag), printer.FormatJSON, From 0a31598332e5c873ffcf45cdfdc4f08a5f09ff0c Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 26 Mar 2024 19:34:11 +0200 Subject: [PATCH 105/108] finish tests --- internal/commands/scan_test.go | 11 ----------- test/integration/scan_test.go | 12 ++++-------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index e409f25e3..cc346979c 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -125,17 +125,6 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } -func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--scan-types", "container-security", "-s", "data/sources.zip", "-b", "dummy_branch", "--file-filter", "!.java") diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 7c5d0ad06..47d0973d6 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -120,11 +120,10 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndScanType(t *testing.T) { flag(params.ScanTypes), "container-security", flag(params.ContainerImagesFlag), "nginx:alpine,debian:9", flag(params.BranchFlag), "dummy_branch", - flag(params.ApikeyOverrideFlag), flag(params.ScanInfoFormatFlag), printer.FormatJSON, } scanID, projectID := executeCreateScan(t, testArgs) - //defer deleteProject(t, projectID) + defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") assertZipFileRemoved(t) @@ -137,11 +136,10 @@ func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { flag(params.SourcesFlag), "data/insecure.zip", flag(params.ContainerImagesFlag), "nginx:alpine", flag(params.BranchFlag), "dummy_branch", - flag(params.ApikeyOverrideFlag), flag(params.ScanInfoFormatFlag), printer.FormatJSON, } scanID, projectID := executeCreateScan(t, testArgs) - //defer deleteProject(t, projectID) + defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") assertZipFileRemoved(t) @@ -155,11 +153,10 @@ func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { flag(params.ContainerImagesFlag), "mysql:5.7", flag(params.BranchFlag), "dummy_branch", flag(params.DebugFlag), - flag(params.ApikeyOverrideFlag), flag(params.ScanInfoFormatFlag), printer.FormatJSON, } scanID, projectID := executeCreateScan(t, testArgs) - //defer deleteProject(t, projectID) + defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") assertZipFileRemoved(t) @@ -172,11 +169,10 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *tes flag(params.SourcesFlag), "data/empty-folder", flag(params.ContainerImagesFlag), "mysql:5.7", flag(params.BranchFlag), "dummy_branch", - flag(params.ApikeyOverrideFlag), flag(params.ScanInfoFormatFlag), printer.FormatJSON, } scanID, projectID := executeCreateScan(t, testArgs) - //defer deleteProject(t, projectID) + defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") assertZipFileRemoved(t) From 1395fa3378fef17257978212eb711a190220dd6e Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Wed, 27 Mar 2024 11:15:49 +0200 Subject: [PATCH 106/108] initialized feature flags in root.go --- internal/commands/root.go | 24 +++++++----------------- internal/commands/scan.go | 9 --------- internal/commands/scan_test.go | 11 +++++++++++ 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/internal/commands/root.go b/internal/commands/root.go index b91621571..ab7a18254 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -74,7 +74,7 @@ func NewAstCLI( ), }, } - + setUpFeatureFlags(featureFlagsWrapper) // Load default flags rootCmd.PersistentFlags().Bool(params.DebugFlag, false, params.DebugUsage) rootCmd.PersistentFlags().String(params.AccessKeyIDFlag, "", params.AccessKeyIDFlagUsage) @@ -107,14 +107,6 @@ func NewAstCLI( _ = cmd.Help() os.Exit(0) } - if requiredFeatureFlagsCheck(cmd) { - err := wrappers.HandleFeatureFlags(featureFlagsWrapper) - - if err != nil { - fmt.Println(err) - os.Exit(1) - } - } } // Link the environment variable to the CLI argument(s). @@ -162,7 +154,6 @@ func NewAstCLI( sastMetadataWrapper, accessManagementWrapper, containerResolverWrapper, - featureFlagsWrapper, ) projectCmd := NewProjectCommand(applicationsWrapper, projectsWrapper, groupsWrapper, accessManagementWrapper) resultsCmd := NewResultsCommand( @@ -223,14 +214,13 @@ func PrintConfiguration() { } } -func requiredFeatureFlagsCheck(cmd *cobra.Command) bool { - for _, cmdFlag := range wrappers.FeatureFlagsBaseMap { - if cmdFlag.CommandName == cmd.CommandPath() { - return true - } - } +func setUpFeatureFlags(featureFlagsWrapper wrappers.FeatureFlagsWrapper) { + err := wrappers.HandleFeatureFlags(featureFlagsWrapper) - return false + if err != nil { + fmt.Println(err) + os.Exit(1) + } } func getFilters(cmd *cobra.Command) (map[string]string, error) { diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 868afda32..dae88448c 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -141,7 +141,6 @@ func NewScanCommand( sastMetadataWrapper wrappers.SastMetadataWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, containerResolverWrapper wrappers.ContainerResolverWrapper, - featureFlagWrapper wrappers.FeatureFlagsWrapper, ) *cobra.Command { scanCmd := &cobra.Command{ Use: "scan", @@ -169,7 +168,6 @@ func NewScanCommand( policyWrapper, accessManagementWrapper, applicationsWrapper, - featureFlagWrapper, ) containerResolver = containerResolverWrapper userAllowedEngines, _ = jwtWrapper.GetAllowedEngines() @@ -424,7 +422,6 @@ func scanCreateSubCommand( policyWrapper wrappers.PolicyWrapper, accessManagementWrapper wrappers.AccessManagementWrapper, applicationsWrapper wrappers.ApplicationsWrapper, - featureFlagWrapper wrappers.FeatureFlagsWrapper, ) *cobra.Command { createScanCmd := &cobra.Command{ Use: "create", @@ -509,12 +506,6 @@ func scanCreateSubCommand( "", fmt.Sprintf("Parameters to use in SCA resolver (requires --%s).", commonParams.ScaResolverFlag), ) - if len(wrappers.FeatureFlags) == 0 { - featureFlagErr := wrappers.HandleFeatureFlags(featureFlagWrapper) - if featureFlagErr != nil { - logger.PrintIfVerbose("Failed to get feature flags") - } - } if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { 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,container-security)") diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index cc346979c..e409f25e3 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -125,6 +125,17 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } +func TestCreateScanFromFolder_ContainersImagesAndDefaultScanTypes_ScanCreatedSuccessfully(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", 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) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "CONTAINER_ENGINE_CLI_ENABLED", Status: true}} execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--scan-types", "container-security", "-s", "data/sources.zip", "-b", "dummy_branch", "--file-filter", "!.java") From 6bddf3fa089632a811e1ca325b863fb6372f07ec Mon Sep 17 00:00:00 2001 From: AlvoBen Date: Tue, 2 Apr 2024 11:36:13 +0300 Subject: [PATCH 107/108] add featureflag check to tests --- test/integration/scan_test.go | 60 +++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 47d0973d6..eca5d4ee7 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -113,6 +113,7 @@ func TestScanCreate_ApplicationDoesntExist_FailScanWithError(t *testing.T) { } func TestContainerEngineScansE2E_ContainerImagesFlagAndScanType(t *testing.T) { + createASTIntegrationTestCommand(t) testArgs := []string{ "scan", "create", flag(params.ProjectName), "my-project", @@ -122,14 +123,17 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndScanType(t *testing.T) { flag(params.BranchFlag), "dummy_branch", flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - scanID, projectID := executeCreateScan(t, testArgs) - defer deleteProject(t, projectID) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) + if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") + assertZipFileRemoved(t) + } } func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { + createASTIntegrationTestCommand(t) testArgs := []string{ "scan", "create", flag(params.ProjectName), "my-project", @@ -138,14 +142,17 @@ func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { flag(params.BranchFlag), "dummy_branch", flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - scanID, projectID := executeCreateScan(t, testArgs) - defer deleteProject(t, projectID) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) + if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") + assertZipFileRemoved(t) + } } func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { + createASTIntegrationTestCommand(t) testArgs := []string{ "scan", "create", flag(params.ProjectName), "my-project", @@ -155,14 +162,17 @@ func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { flag(params.DebugFlag), flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - scanID, projectID := executeCreateScan(t, testArgs) - defer deleteProject(t, projectID) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) + if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") + assertZipFileRemoved(t) + } } func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *testing.T) { + createASTIntegrationTestCommand(t) testArgs := []string{ "scan", "create", flag(params.ProjectName), "my-project", @@ -171,25 +181,29 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *tes flag(params.BranchFlag), "dummy_branch", flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - scanID, projectID := executeCreateScan(t, testArgs) - defer deleteProject(t, projectID) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) + if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + scanID, projectID := executeCreateScan(t, testArgs) + defer deleteProject(t, projectID) + assert.Assert(t, scanID != "", "Scan ID should not be empty") + assert.Assert(t, projectID != "", "Project ID should not be empty") + assertZipFileRemoved(t) + } } func TestContainerEngineScansE2E_InvalidContainerImagesFlag(t *testing.T) { + createASTIntegrationTestCommand(t) testArgs := []string{ "scan", "create", flag(params.ProjectName), "my-project", flag(params.SourcesFlag), "data/Dockerfile-mysql571.zip", flag(params.ContainerImagesFlag), "nginx:", flag(params.BranchFlag), "dummy_branch", - flag(params.ApikeyOverrideFlag), flag(params.ScanInfoFormatFlag), printer.FormatJSON, } - err, _ := executeCommand(t, testArgs...) - assertError(t, err, "Invalid value for --container-images flag. The value must be in the format :") + if wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] { + err, _ := executeCommand(t, testArgs...) + assertError(t, err, "Invalid value for --container-images flag. The value must be in the format :") + } } func assertZipFileRemoved(t *testing.T) { From 64e9d3d24e6ab1aec526b02c4cf51fcb962a2eda Mon Sep 17 00:00:00 2001 From: tamarleviCm Date: Sun, 19 May 2024 14:17:12 +0300 Subject: [PATCH 108/108] filter unsupported agents --- internal/commands/result.go | 6 +++--- internal/commands/result_test.go | 28 ++++++++++++++++++++++++++-- internal/commands/scan.go | 9 +++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/internal/commands/result.go b/internal/commands/result.go index 7264416b2..dafd49589 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -143,8 +143,8 @@ var sonarSeverities = map[string]string{ highCx: highSonar, } -var containerSupportedAgents = []string{ - commonParams.DefaultAgent, +var containerEngineUnsupportedAgents = []string{ + "Jetbrains", "VS Code", "Visual Studio", "Eclipse", } func NewResultsCommand( @@ -774,7 +774,7 @@ func runGetCodeBashingCommand( } } func setIsContainersEnabled(agent string) { - agentSupported := contains(containerSupportedAgents, agent) + agentSupported := !containsIgnoreCase(containerEngineUnsupportedAgents, agent) wrappers.IsContainersEnabled = wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && agentSupported } func CreateScanReport( diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 4156d102d..565a7ce17 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -438,9 +438,33 @@ func TestRunResultsShow_ContainersFFIsOff_excludeContainersResult(t *testing.T) // Remove generated json file removeFileBySuffix(t, printer.FormatJSON) } -func TestRunResultsShow_AgentIsNotSupported_excludeContainersResult(t *testing.T) { +func TestRunResultsShow_jetbrainsIsNotSupported_excludeContainersResult(t *testing.T) { mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} - execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "jet-brains") + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "jetbrains") + assertContainersPresent(t, false) + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} + +func TestRunResultsShow_EclipseIsNotSupported_excludeContainersResult(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "Eclipse") + assertContainersPresent(t, false) + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} + +func TestRunResultsShow_VsCodeIsNotSupported_excludeContainersResult(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "vs code") + assertContainersPresent(t, false) + // Remove generated json file + removeFileBySuffix(t, printer.FormatJSON) +} + +func TestRunResultsShow_VisualStudioIsNotSupported_excludeContainersResult(t *testing.T) { + mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: wrappers.ContainerEngineCLIEnabled, Status: true}} + execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--agent", "Visual Studio") assertContainersPresent(t, false) // Remove generated json file removeFileBySuffix(t, printer.FormatJSON) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 7f553731c..50cc3093d 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -2382,6 +2382,15 @@ func contains(s []string, str string) bool { return false } +func containsIgnoreCase(s []string, str string) bool { + for _, v := range s { + if strings.EqualFold(str, v) { + return true + } + } + return false +} + func readKicsResultsFile(tempDir string) (wrappers.KicsResultsCollection, error) { // Open and read the file from the temp folder var resultsModel wrappers.KicsResultsCollection