From c15448b4e0690a718718a77fc46ce3bc59813448 Mon Sep 17 00:00:00 2001 From: Leonard Heilos Date: Tue, 30 May 2023 16:00:02 +0200 Subject: [PATCH] feat(whitesourceExecuteScan): allow to specify InstallCommand (#4376) * feat(whitesourceExecuteScan) allow to specify InstallCommand * reorder imports --------- Co-authored-by: sumeet patil Co-authored-by: Andrei Kireev --- cmd/whitesourceExecuteScan.go | 9 +++ cmd/whitesourceExecuteScan_generated.go | 2 +- cmd/whitesourceExecuteScan_test.go | 61 +++++++++++++++++++ pkg/whitesource/scanOptions.go | 2 + .../metadata/whitesourceExecuteScan.yaml | 2 +- 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/cmd/whitesourceExecuteScan.go b/cmd/whitesourceExecuteScan.go index 802f126b6..740e1ff0c 100644 --- a/cmd/whitesourceExecuteScan.go +++ b/cmd/whitesourceExecuteScan.go @@ -478,6 +478,7 @@ func wsScanOptions(config *ScanOptions) *ws.ScanOptions { AgentURL: config.AgentURL, ServiceURL: config.ServiceURL, ScanPath: config.ScanPath, + InstallCommand: config.InstallCommand, Verbose: GeneralConfig.Verbose, } } @@ -487,6 +488,14 @@ func wsScanOptions(config *ScanOptions) *ws.ScanOptions { func executeScan(config *ScanOptions, scan *ws.Scan, utils whitesourceUtils) error { options := wsScanOptions(config) + if options.InstallCommand != "" { + installCommandTokens := strings.Split(config.InstallCommand, " ") + if err := utils.RunExecutable(installCommandTokens[0], installCommandTokens[1:]...); err != nil { + log.SetErrorCategory(log.ErrorCustom) + return errors.Wrapf(err, "failed to execute install command: %v", config.InstallCommand) + } + } + // Execute scan with Unified Agent jar file if err := scan.ExecuteUAScan(options, utils); err != nil { return errors.Wrapf(err, "failed to execute Unified Agent scan") diff --git a/cmd/whitesourceExecuteScan_generated.go b/cmd/whitesourceExecuteScan_generated.go index 280827b40..5b0c246a7 100644 --- a/cmd/whitesourceExecuteScan_generated.go +++ b/cmd/whitesourceExecuteScan_generated.go @@ -329,7 +329,7 @@ func addWhitesourceExecuteScanFlags(cmd *cobra.Command, stepConfig *whitesourceE cmd.Flags().StringSliceVar(&stepConfig.Excludes, "excludes", []string{}, "List of file path patterns to exclude in the scan.") cmd.Flags().BoolVar(&stepConfig.FailOnSevereVulnerabilities, "failOnSevereVulnerabilities", true, "Whether to fail the step on severe vulnerabilties or not") cmd.Flags().StringSliceVar(&stepConfig.Includes, "includes", []string{}, "List of file path patterns to include in the scan.") - cmd.Flags().StringVar(&stepConfig.InstallCommand, "installCommand", os.Getenv("PIPER_installCommand"), "[NOT IMPLEMENTED] Install command that can be used to populate the default docker image for some scenarios.") + cmd.Flags().StringVar(&stepConfig.InstallCommand, "installCommand", os.Getenv("PIPER_installCommand"), "Install command that can be used to populate the default docker image for some scenarios.") cmd.Flags().StringVar(&stepConfig.JreDownloadURL, "jreDownloadUrl", `https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.2/sapmachine-jre-11.0.2_linux-x64_bin.tar.gz`, "URL used for downloading the Java Runtime Environment (JRE) required to run the WhiteSource Unified Agent.") cmd.Flags().BoolVar(&stepConfig.LicensingVulnerabilities, "licensingVulnerabilities", true, "[NOT IMPLEMENTED] Whether license compliance is considered and reported as part of the assessment.") cmd.Flags().StringVar(&stepConfig.OrgToken, "orgToken", os.Getenv("PIPER_orgToken"), "WhiteSource token identifying your organization.") diff --git a/cmd/whitesourceExecuteScan_test.go b/cmd/whitesourceExecuteScan_test.go index 98bbd24bf..77c724902 100644 --- a/cmd/whitesourceExecuteScan_test.go +++ b/cmd/whitesourceExecuteScan_test.go @@ -16,6 +16,7 @@ import ( "github.com/SAP/jenkins-library/pkg/reporting" "github.com/SAP/jenkins-library/pkg/versioning" ws "github.com/SAP/jenkins-library/pkg/whitesource" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/google/go-github/v45/github" @@ -143,6 +144,66 @@ func TestRunWhitesourceExecuteScan(t *testing.T) { } assert.True(t, utilsMock.HasWrittenFile(filepath.Join(ws.ReportsDirectory, "mock-project - 1-vulnerability-report.pdf"))) assert.True(t, utilsMock.HasWrittenFile(filepath.Join(ws.ReportsDirectory, "mock-project - 1-vulnerability-report.pdf"))) + assert.Equal(t, 3, len(utilsMock.ExecMockRunner.Calls), "no InstallCommand must be executed") + }) + t.Run("executes the InstallCommand prior to the scan", func(t *testing.T) { + ctx := context.Background() + // init + config := ScanOptions{ + BuildDescriptorFile: "my-mta.yml", + VersioningModel: "major", + AgentDownloadURL: "https://whitesource.com/agent.jar", + VulnerabilityReportFormat: "pdf", + Reporting: true, + AgentFileName: "ua.jar", + ProductName: "mock-product", + ProjectToken: "mock-project-token", + InstallCommand: "echo hello world", + } + utilsMock := newWhitesourceUtilsMock() + utilsMock.AddFile("wss-generated-file.config", []byte("key=value")) + lastUpdatedDate := time.Now().Format(ws.DateTimeLayout) + systemMock := ws.NewSystemMock(lastUpdatedDate) + systemMock.Alerts = []ws.Alert{} + scan := newWhitesourceScan(&config) + cpe := whitesourceExecuteScanCommonPipelineEnvironment{} + influx := whitesourceExecuteScanInflux{} + // test + err := runWhitesourceExecuteScan(ctx, &config, scan, utilsMock, systemMock, &cpe, &influx) + // assert + assert.NoError(t, err) + assert.Equal(t, 4, len(utilsMock.ExecMockRunner.Calls), "InstallCommand not executed") + assert.Equal(t, mock.ExecCall{Exec: "echo", Params: []string{"hello", "world"}}, utilsMock.ExecMockRunner.Calls[0], "run command/params of InstallCommand incorrect") + }) + t.Run("fails if the InstallCommand fails", func(t *testing.T) { + ctx := context.Background() + // init + config := ScanOptions{ + BuildDescriptorFile: "my-mta.yml", + VersioningModel: "major", + AgentDownloadURL: "https://whitesource.com/agent.jar", + VulnerabilityReportFormat: "pdf", + Reporting: true, + AgentFileName: "ua.jar", + ProductName: "mock-product", + ProjectToken: "mock-project-token", + InstallCommand: "echo this-will-fail", + } + utilsMock := newWhitesourceUtilsMock() + utilsMock.AddFile("wss-generated-file.config", []byte("key=value")) + lastUpdatedDate := time.Now().Format(ws.DateTimeLayout) + systemMock := ws.NewSystemMock(lastUpdatedDate) + systemMock.Alerts = []ws.Alert{} + scan := newWhitesourceScan(&config) + cpe := whitesourceExecuteScanCommonPipelineEnvironment{} + influx := whitesourceExecuteScanInflux{} + utilsMock.ExecMockRunner.ShouldFailOnCommand = map[string]error{ + "echo this-will-fail": errors.New("error case"), + } + // test + err := runWhitesourceExecuteScan(ctx, &config, scan, utilsMock, systemMock, &cpe, &influx) + // assert + assert.EqualError(t, err, "failed to execute WhiteSource scan: failed to execute Scan: failed to execute install command: echo this-will-fail: error case") }) } diff --git a/pkg/whitesource/scanOptions.go b/pkg/whitesource/scanOptions.go index ff9475b07..6cdcd29e5 100644 --- a/pkg/whitesource/scanOptions.go +++ b/pkg/whitesource/scanOptions.go @@ -44,5 +44,7 @@ type ScanOptions struct { ScanPath string + InstallCommand string + Verbose bool } diff --git a/resources/metadata/whitesourceExecuteScan.yaml b/resources/metadata/whitesourceExecuteScan.yaml index 93d8480fa..1b450e3ff 100644 --- a/resources/metadata/whitesourceExecuteScan.yaml +++ b/resources/metadata/whitesourceExecuteScan.yaml @@ -234,7 +234,7 @@ spec: - STEPS - name: installCommand type: string - description: "[NOT IMPLEMENTED] Install command that can be used to populate the default docker image for some scenarios." + description: "Install command that can be used to populate the default docker image for some scenarios." scope: - PARAMETERS - STAGES