1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-18 05:18:24 +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:
Giridhar Shenoy 2020-07-28 10:48:19 +02:00 committed by GitHub
parent 60796cdc59
commit 0fc131adec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 19 deletions

View File

@ -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, ",")))

View File

@ -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"}},

View File

@ -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",
},
},

View File

@ -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