You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	detectExecuteScan : Changes to include user group and handle build fails (#1775)
* changes to detectExec before master merge * changes for detectExecuteScan * self generated code added * fix syntax errors and update docu * added unit tests for fail and Group * fix failOn bug * add Groups as string array * add Groups as string array * tests and validation for groups, failOn * Updated docs and added more tests * documentation md files should not be changed * Handle merge conflicts from PR 1845 * fix merge errors Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com>
This commit is contained in:
		| @@ -52,14 +52,26 @@ func addDetectArgs(args []string, config detectExecuteScanOptions) []string { | ||||
|  | ||||
| 	args = append(args, fmt.Sprintf("--blackduck.url=%v", config.ServerURL)) | ||||
| 	args = append(args, fmt.Sprintf("--blackduck.api.token=%v", config.APIToken)) | ||||
| 	// ProjectNames, VersionName, GroupName etc can contain spaces and need to be escaped using double quotes in CLI | ||||
| 	// Hence the string need to be surrounded by \" | ||||
| 	args = append(args, fmt.Sprintf("--detect.project.name=\\\"%v\\\"", config.ProjectName)) | ||||
| 	args = append(args, fmt.Sprintf("--detect.project.version.name=\\\"%v\\\"", detectVersionName)) | ||||
|  | ||||
| 	// Groups parameter is added only when there is atleast one non-empty groupname provided | ||||
| 	if len(config.Groups) > 0 && len(config.Groups[0]) > 0 { | ||||
| 		args = append(args, fmt.Sprintf("--detect.project.user.groups=\\\"%v\\\"", strings.Join(config.Groups, "\\\",\\\""))) | ||||
| 	} | ||||
|  | ||||
| 	// Atleast 1, non-empty category to fail on must be provided | ||||
| 	if len(config.FailOn) > 0 && len(config.FailOn[0]) > 0 { | ||||
| 		args = append(args, fmt.Sprintf("--detect.policy.check.fail.on.severities=%v", strings.Join(config.FailOn, ","))) | ||||
| 	} | ||||
|  | ||||
| 	args = append(args, fmt.Sprintf("--detect.project.name=%v", config.ProjectName)) | ||||
| 	args = append(args, fmt.Sprintf("--detect.project.version.name=%v", detectVersionName)) | ||||
| 	codeLocation := config.CodeLocation | ||||
| 	if len(codeLocation) == 0 && len(config.ProjectName) > 0 { | ||||
| 		codeLocation = fmt.Sprintf("%v/%v", config.ProjectName, detectVersionName) | ||||
| 	} | ||||
| 	args = append(args, fmt.Sprintf("--detect.code.location.name=%v", codeLocation)) | ||||
| 	args = append(args, fmt.Sprintf("--detect.code.location.name=\\\"%v\\\"", codeLocation)) | ||||
|  | ||||
| 	if sliceUtils.ContainsString(config.Scanners, "signature") { | ||||
| 		args = append(args, fmt.Sprintf("--detect.blackduck.signature.scanner.paths=%v", strings.Join(config.ScanPaths, ","))) | ||||
|   | ||||
| @@ -21,11 +21,13 @@ type detectExecuteScanOptions struct { | ||||
| 	ScanPaths       []string `json:"scanPaths,omitempty"` | ||||
| 	ScanProperties  []string `json:"scanProperties,omitempty"` | ||||
| 	ServerURL       string   `json:"serverUrl,omitempty"` | ||||
| 	Groups          []string `json:"groups,omitempty"` | ||||
| 	FailOn          []string `json:"failOn,omitempty"` | ||||
| 	Version         string   `json:"version,omitempty"` | ||||
| 	VersioningModel string   `json:"versioningModel,omitempty"` | ||||
| } | ||||
|  | ||||
| // DetectExecuteScanCommand Executes Synopsis Detect scan | ||||
| // DetectExecuteScanCommand Executes Synopsys Detect scan | ||||
| func DetectExecuteScanCommand() *cobra.Command { | ||||
| 	const STEP_NAME = "detectExecuteScan" | ||||
|  | ||||
| @@ -35,8 +37,10 @@ func DetectExecuteScanCommand() *cobra.Command { | ||||
|  | ||||
| 	var createDetectExecuteScanCmd = &cobra.Command{ | ||||
| 		Use:   STEP_NAME, | ||||
| 		Short: "Executes Synopsis Detect scan", | ||||
| 		Long:  `This step executes [Synopsis Detect](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/62423113/Synopsys+Detect) scans.`, | ||||
| 		Short: "Executes Synopsys Detect scan", | ||||
| 		Long: `This step executes [Synopsys Detect](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/62423113/Synopsys+Detect) scans. | ||||
| Synopsys Detect command line utlity can be used to run various scans including BlackDuck and Polaris scans. This step allows users to run BlackDuck scans by default. | ||||
| Please configure your BlackDuck server Url using the serverUrl parameter and the API token of your user using the apiToken parameter for this step.`, | ||||
| 		PreRunE: func(cmd *cobra.Command, _ []string) error { | ||||
| 			startTime = time.Now() | ||||
| 			log.SetStepName(STEP_NAME) | ||||
| @@ -86,8 +90,10 @@ func addDetectExecuteScanFlags(cmd *cobra.Command, stepConfig *detectExecuteScan | ||||
| 	cmd.Flags().StringVar(&stepConfig.ProjectName, "projectName", os.Getenv("PIPER_projectName"), "Name of the Synopsis Detect (formerly BlackDuck) project.") | ||||
| 	cmd.Flags().StringSliceVar(&stepConfig.Scanners, "scanners", []string{`signature`}, "List of scanners to be used for Synopsis Detect (formerly BlackDuck) scan.") | ||||
| 	cmd.Flags().StringSliceVar(&stepConfig.ScanPaths, "scanPaths", []string{`.`}, "List of paths which should be scanned by the Synopsis Detect (formerly BlackDuck) scan.") | ||||
| 	cmd.Flags().StringSliceVar(&stepConfig.ScanProperties, "scanProperties", []string{`--blackduck.signature.scanner.memory=4096`, `--blackduck.timeout=6000`, `--blackduck.trust.cert=true`, `--detect.policy.check.fail.on.severities=BLOCKER,CRITICAL,MAJOR`, `--detect.report.timeout=4800`, `--logging.level.com.synopsys.integration=DEBUG`}, "Properties passed to the Synopsis Detect (formerly BlackDuck) scan. You can find details in the [Synopsis Detect documentation](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/622846/Using+Synopsys+Detect+Properties)") | ||||
| 	cmd.Flags().StringSliceVar(&stepConfig.ScanProperties, "scanProperties", []string{`--blackduck.signature.scanner.memory=4096`, `--blackduck.timeout=6000`, `--blackduck.trust.cert=true`, `--detect.report.timeout=4800`, `--logging.level.com.synopsys.integration=DEBUG`}, "Properties passed to the Synopsis Detect (formerly BlackDuck) scan. You can find details in the [Synopsis Detect documentation](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/622846/Using+Synopsys+Detect+Properties)") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "Server url to the Synopsis Detect (formerly BlackDuck) Server.") | ||||
| 	cmd.Flags().StringSliceVar(&stepConfig.Groups, "groups", []string{}, "Users groups to be assigned for the Project") | ||||
| 	cmd.Flags().StringSliceVar(&stepConfig.FailOn, "failOn", []string{`BLOCKER`}, "Mark the current build as fail based on the policy categories applied.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Version, "version", os.Getenv("PIPER_version"), "Defines the version number of the artifact being build in the pipeline. It is used as source for the Detect version.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.VersioningModel, "versioningModel", `major`, "The versioning model used for result reporting (based on the artifact version). Example 1.2.3 using `major` will result in version 1") | ||||
|  | ||||
| @@ -161,6 +167,22 @@ func detectExecuteScanMetadata() config.StepData { | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "detect/serverUrl"}}, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "groups", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "[]string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "detect/groups"}}, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "failOn", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "[]string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "detect/failOn"}}, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "version", | ||||
| 						ResourceRef: []config.ResourceReference{{Name: "commonPipelineEnvironment", Param: "artifactVersion"}}, | ||||
|   | ||||
| @@ -18,7 +18,7 @@ func TestRunDetect(t *testing.T) { | ||||
|  | ||||
| 		assert.Equal(t, ".", s.Dir, "Wrong execution directory used") | ||||
| 		assert.Equal(t, "/bin/bash", s.Shell[0], "Bash shell expected") | ||||
| 		expectedScript := "bash <(curl -s https://detect.synopsys.com/detect.sh) --blackduck.url= --blackduck.api.token= --detect.project.name= --detect.project.version.name= --detect.code.location.name=" | ||||
| 		expectedScript := "bash <(curl -s https://detect.synopsys.com/detect.sh) --blackduck.url= --blackduck.api.token= --detect.project.name=\\\"\\\" --detect.project.version.name=\\\"\\\" --detect.code.location.name=\\\"\\\"" | ||||
| 		assert.Equal(t, expectedScript, s.Calls[0]) | ||||
| 	}) | ||||
|  | ||||
| @@ -26,7 +26,7 @@ func TestRunDetect(t *testing.T) { | ||||
| 		var hasFailed bool | ||||
| 		log.Entry().Logger.ExitFunc = func(int) { hasFailed = true } | ||||
|  | ||||
| 		s := mock.ShellMockRunner{ShouldFailOnCommand: map[string]error{"bash <(curl -s https://detect.synopsys.com/detect.sh) --blackduck.url= --blackduck.api.token= --detect.project.name= --detect.project.version.name= --detect.code.location.name=": fmt.Errorf("Test Error")}} | ||||
| 		s := mock.ShellMockRunner{ShouldFailOnCommand: map[string]error{"bash <(curl -s https://detect.synopsys.com/detect.sh) --blackduck.url= --blackduck.api.token= --detect.project.name=\\\"\\\" --detect.project.version.name=\\\"\\\" --detect.code.location.name=\\\"\\\"": fmt.Errorf("Test Error")}} | ||||
| 		runDetect(detectExecuteScanOptions{}, &s) | ||||
| 		assert.True(t, hasFailed, "expected command to exit with fatal") | ||||
| 	}) | ||||
| @@ -57,9 +57,9 @@ func TestAddDetectArgs(t *testing.T) { | ||||
| 				"--scan2=2", | ||||
| 				"--blackduck.url=https://server.url", | ||||
| 				"--blackduck.api.token=apiToken", | ||||
| 				"--detect.project.name=testName", | ||||
| 				"--detect.project.version.name=1.0", | ||||
| 				"--detect.code.location.name=testName/1.0", | ||||
| 				"--detect.project.name=\\\"testName\\\"", | ||||
| 				"--detect.project.version.name=\\\"1.0\\\"", | ||||
| 				"--detect.code.location.name=\\\"testName/1.0\\\"", | ||||
| 				"--detect.blackduck.signature.scanner.paths=path1,path2", | ||||
| 			}, | ||||
| 		}, | ||||
| @@ -72,16 +72,46 @@ func TestAddDetectArgs(t *testing.T) { | ||||
| 				Version:         "1.0", | ||||
| 				VersioningModel: "major-minor", | ||||
| 				CodeLocation:    "testLocation", | ||||
| 				FailOn:          []string{"BLOCKER", "MAJOR"}, | ||||
| 				Scanners:        []string{"source"}, | ||||
| 				ScanPaths:       []string{"path1", "path2"}, | ||||
| 				Groups:          []string{"testGroup"}, | ||||
| 			}, | ||||
| 			expected: []string{ | ||||
| 				"--testProp1=1", | ||||
| 				"--blackduck.url=https://server.url", | ||||
| 				"--blackduck.api.token=apiToken", | ||||
| 				"--detect.project.name=testName", | ||||
| 				"--detect.project.version.name=1.0", | ||||
| 				"--detect.code.location.name=testLocation", | ||||
| 				"--detect.project.name=\\\"testName\\\"", | ||||
| 				"--detect.project.version.name=\\\"1.0\\\"", | ||||
| 				"--detect.project.user.groups=\\\"testGroup\\\"", | ||||
| 				"--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", | ||||
| 				"--detect.code.location.name=\\\"testLocation\\\"", | ||||
| 				"--detect.source.path=path1", | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			args: []string{"--testProp1=1"}, | ||||
| 			options: detectExecuteScanOptions{ | ||||
| 				ServerURL:       "https://server.url", | ||||
| 				APIToken:        "apiToken", | ||||
| 				ProjectName:     "testName", | ||||
| 				CodeLocation:    "testLocation", | ||||
| 				FailOn:          []string{"BLOCKER", "MAJOR"}, | ||||
| 				Scanners:        []string{"source"}, | ||||
| 				ScanPaths:       []string{"path1", "path2"}, | ||||
| 				Groups:          []string{"testGroup", "testGroup2"}, | ||||
| 				Version:         "1.0", | ||||
| 				VersioningModel: "major-minor", | ||||
| 			}, | ||||
| 			expected: []string{ | ||||
| 				"--testProp1=1", | ||||
| 				"--blackduck.url=https://server.url", | ||||
| 				"--blackduck.api.token=apiToken", | ||||
| 				"--detect.project.name=\\\"testName\\\"", | ||||
| 				"--detect.project.version.name=\\\"1.0\\\"", | ||||
| 				"--detect.project.user.groups=\\\"testGroup\\\",\\\"testGroup2\\\"", | ||||
| 				"--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", | ||||
| 				"--detect.code.location.name=\\\"testLocation\\\"", | ||||
| 				"--detect.source.path=path1", | ||||
| 			}, | ||||
| 		}, | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| metadata: | ||||
|   name: detectExecuteScan | ||||
|   description: Executes Synopsis Detect scan | ||||
|   longDescription: |- | ||||
|     This step executes [Synopsis Detect](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/62423113/Synopsys+Detect) scans. | ||||
|   description: Executes Synopsys Detect scan | ||||
|   longDescription: | | ||||
|     This step executes [Synopsys Detect](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/62423113/Synopsys+Detect) scans. | ||||
|     Synopsys Detect command line utlity can be used to run various scans including BlackDuck and Polaris scans. This step allows users to run BlackDuck scans by default. | ||||
|     Please configure your BlackDuck server Url using the serverUrl parameter and the API token of your user using the apiToken parameter for this step. | ||||
| spec: | ||||
|   inputs: | ||||
|     resources: | ||||
| @@ -86,7 +88,6 @@ spec: | ||||
|         - --blackduck.signature.scanner.memory=4096 | ||||
|         - --blackduck.timeout=6000 | ||||
|         - --blackduck.trust.cert=true | ||||
|         - --detect.policy.check.fail.on.severities=BLOCKER,CRITICAL,MAJOR | ||||
|         - --detect.report.timeout=4800 | ||||
|         - --logging.level.com.synopsys.integration=DEBUG | ||||
|         scope: | ||||
| @@ -103,6 +104,38 @@ spec: | ||||
|         - PARAMETERS | ||||
|         - STAGES | ||||
|         - STEPS | ||||
|       - name: groups | ||||
|         description: Users groups to be assigned for the Project | ||||
|         aliases: | ||||
|           - name: detect/groups | ||||
|         type: '[]string' | ||||
|         mandatory: false | ||||
|         scope: | ||||
|         - PARAMETERS | ||||
|         - STAGES | ||||
|         - STEPS | ||||
|       - name: failOn | ||||
|         description: Mark the current build as fail based on the policy categories applied. | ||||
|         longDescription: | | ||||
|           A list of policies can be provided which will be applied after the scan is completed. These policies if violated will mark the build/scan result as failed. | ||||
|           The list of accepted valed can be found at https://blackducksoftware.github.io/synopsys-detect/latest/properties/configuration/project/#fail-on-policy-violation-severities | ||||
|         aliases: | ||||
|           - name: detect/failOn | ||||
|         type: '[]string' | ||||
|         mandatory: false | ||||
|         default: | ||||
|         - BLOCKER | ||||
|         possibleValues: | ||||
|         - ALL | ||||
|         - BLOCKER | ||||
|         - CRITICAL | ||||
|         - MAJOR | ||||
|         - MINOR | ||||
|         - NONE | ||||
|         scope: | ||||
|         - PARAMETERS | ||||
|         - STAGES | ||||
|         - STEPS | ||||
|       - name: version | ||||
|         aliases: | ||||
|           - name: projectVersion | ||||
|   | ||||
		Reference in New Issue
	
	Block a user