You've already forked sap-jenkins-library
mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-09-16 09:26:22 +02:00
feat(detect): add flag containerScan to detect step (#5312)
Co-authored-by: Manjunath <43342804+manjunathSurendrakumar@users.noreply.github.com>
This commit is contained in:
@@ -257,21 +257,24 @@ func runDetect(ctx context.Context, config detectExecuteScanOptions, utils detec
|
||||
|
||||
blackduckSystem := newBlackduckSystem(config)
|
||||
|
||||
args := []string{"./detect.sh"}
|
||||
args, err = addDetectArgs(args, config, utils, blackduckSystem, NO_VERSION_SUFFIX, NO_VERSION_SUFFIX)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
script := strings.Join(args, " ")
|
||||
|
||||
envs := []string{"BLACKDUCK_SKIP_PHONE_HOME=true"}
|
||||
envs = append(envs, config.CustomEnvironmentVariables...)
|
||||
|
||||
utils.SetDir(".")
|
||||
utils.SetEnv(envs)
|
||||
|
||||
err = mapDetectError(utils.RunShell("bash", script), config, utils)
|
||||
if config.ScanContainerDistro != "" {
|
||||
// When containerScan is set to true, only the container scan will be executed
|
||||
if !config.ContainerScan {
|
||||
args := []string{"./detect.sh"}
|
||||
args, err = addDetectArgs(args, config, utils, blackduckSystem, NO_VERSION_SUFFIX, NO_VERSION_SUFFIX)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
script := strings.Join(args, " ")
|
||||
err = mapDetectError(utils.RunShell("bash", script), config, utils)
|
||||
}
|
||||
|
||||
if config.ScanContainerDistro != "" || config.ContainerScan {
|
||||
imageError := mapDetectError(runDetectImages(ctx, config, utils, blackduckSystem, influx, blackduckSystem), config, utils)
|
||||
if imageError != nil {
|
||||
if err != nil {
|
||||
@@ -622,6 +625,11 @@ func addDetectArgsImages(args []string, config detectExecuteScanOptions, utils d
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
if config.ContainerScan {
|
||||
args = append(args, "--detect.tools=CONTAINER_SCAN")
|
||||
args = append(args, fmt.Sprintf("--detect.container.scan.file.path=./%s", imageTar))
|
||||
return args, nil
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf("--detect.docker.tar=./%s", imageTar))
|
||||
args = append(args, "--detect.target.type=IMAGE")
|
||||
|
@@ -79,6 +79,7 @@ type detectExecuteScanOptions struct {
|
||||
RepositoryPassword string `json:"repositoryPassword,omitempty" validate:"required_if=ScanContainerDistro ubuntu ScanContainerDistro centos ScanContainerDistro alpine"`
|
||||
UseDetect8 bool `json:"useDetect8,omitempty"`
|
||||
UseDetect9 bool `json:"useDetect9,omitempty"`
|
||||
ContainerScan bool `json:"containerScan,omitempty"`
|
||||
}
|
||||
|
||||
type detectExecuteScanInflux struct {
|
||||
@@ -358,6 +359,7 @@ func addDetectExecuteScanFlags(cmd *cobra.Command, stepConfig *detectExecuteScan
|
||||
cmd.Flags().StringVar(&stepConfig.RepositoryPassword, "repositoryPassword", os.Getenv("PIPER_repositoryPassword"), "Used accessing for the images to be scanned (typically filled by CPE)")
|
||||
cmd.Flags().BoolVar(&stepConfig.UseDetect8, "useDetect8", false, "This flag enables the use of the supported version 8 of the Detect script instead of default version 10")
|
||||
cmd.Flags().BoolVar(&stepConfig.UseDetect9, "useDetect9", false, "This flag enables the use of the supported version 9 of the Detect script instead of default version 10")
|
||||
cmd.Flags().BoolVar(&stepConfig.ContainerScan, "containerScan", false, "When set to true, Container Scanning will be used instead of Docker Inspector as the Detect tool for scanning images, and all other detect tools will be ignored in the scan")
|
||||
|
||||
cmd.MarkFlagRequired("token")
|
||||
cmd.MarkFlagRequired("projectName")
|
||||
@@ -967,6 +969,15 @@ func detectExecuteScanMetadata() config.StepData {
|
||||
Aliases: []config.Alias{{Name: "detect/useDetect9"}},
|
||||
Default: false,
|
||||
},
|
||||
{
|
||||
Name: "containerScan",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "bool",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "detect/containerScan"}},
|
||||
Default: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
Containers: []config.Container{
|
||||
|
@@ -376,6 +376,22 @@ func TestRunDetect(t *testing.T) {
|
||||
expectedParam2 := "--detect.docker.tar=./bar_bazz_latest.tar --detect.target.type=IMAGE --detect.tools.excluded=DETECTOR --detect.docker.passthrough.shared.dir.path.local=/opt/blackduck/blackduck-imageinspector/shared/ --detect.docker.passthrough.shared.dir.path.imageinspector=/opt/blackduck/blackduck-imageinspector/shared --detect.docker.passthrough.imageinspector.service.distro.default=ubuntu --detect.docker.passthrough.imageinspector.service.start=false --detect.docker.passthrough.output.include.squashedimage=false --detect.docker.passthrough.imageinspector.service.url=http://localhost:8082"
|
||||
assert.Contains(t, utilsMock.Calls[2], expectedParam2)
|
||||
})
|
||||
|
||||
t.Run("container scan only", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
utilsMock := newDetectTestUtilsBundle(false)
|
||||
utilsMock.AddFile("detect.sh", []byte(""))
|
||||
err := runDetect(ctx, detectExecuteScanOptions{
|
||||
ContainerScan: true,
|
||||
ImageNameTags: []string{"foo/bar:latest"},
|
||||
}, utilsMock, &detectExecuteScanInflux{})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(utilsMock.Calls), "Only one detect script call should have been executed")
|
||||
assert.Contains(t, utilsMock.Calls[0], "--detect.tools=CONTAINER_SCAN", "Container scan tool should be specified")
|
||||
assert.Contains(t, utilsMock.Calls[0], "--detect.container.scan.file.path=./foo_bar_latest.tar", "Container scan file path should be specified")
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddDetectArgs(t *testing.T) {
|
||||
@@ -578,86 +594,6 @@ func TestAddDetectArgs(t *testing.T) {
|
||||
"--detect.tools=DETECTOR",
|
||||
},
|
||||
},
|
||||
{
|
||||
args: []string{"--testProp1=1"},
|
||||
options: detectExecuteScanOptions{
|
||||
ServerURL: "https://server.url",
|
||||
Token: "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",
|
||||
DependencyPath: "pathx",
|
||||
Unmap: true,
|
||||
IncludedPackageManagers: []string{"maven", "GRADLE"},
|
||||
ExcludedPackageManagers: []string{"npm", "NUGET"},
|
||||
MavenExcludedScopes: []string{"TEST", "compile"},
|
||||
DetectTools: []string{"DETECTOR"},
|
||||
},
|
||||
expected: []string{
|
||||
"--testProp1=1",
|
||||
"--detect.excluded.directories=.pipeline/*",
|
||||
"--detect.project.codelocation.unmap=true",
|
||||
"--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.force.success.on.skip=true\"",
|
||||
"--detect.blackduck.signature.scanner.paths=path1,path2",
|
||||
"--detect.source.path=pathx",
|
||||
"--detect.included.detector.types=MAVEN,GRADLE",
|
||||
"--detect.excluded.detector.types=NPM,NUGET",
|
||||
"--detect.maven.excluded.scopes=test,compile",
|
||||
"--detect.tools=DETECTOR",
|
||||
},
|
||||
},
|
||||
{
|
||||
args: []string{"--testProp1=1"},
|
||||
options: detectExecuteScanOptions{
|
||||
ServerURL: "https://server.url",
|
||||
Token: "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",
|
||||
DependencyPath: "pathx",
|
||||
Unmap: true,
|
||||
IncludedPackageManagers: []string{"maven", "GRADLE"},
|
||||
ExcludedPackageManagers: []string{"npm", "NUGET"},
|
||||
MavenExcludedScopes: []string{"TEST", "compile"},
|
||||
DetectTools: []string{"DETECTOR"},
|
||||
},
|
||||
expected: []string{
|
||||
"--testProp1=1",
|
||||
"--detect.excluded.directories=.pipeline/*",
|
||||
"--detect.project.codelocation.unmap=true",
|
||||
"--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.force.success.on.skip=true\"",
|
||||
"--detect.blackduck.signature.scanner.paths=path1,path2",
|
||||
"--detect.source.path=pathx",
|
||||
"--detect.included.detector.types=MAVEN,GRADLE",
|
||||
"--detect.excluded.detector.types=NPM,NUGET",
|
||||
"--detect.maven.excluded.scopes=test,compile",
|
||||
"--detect.tools=DETECTOR",
|
||||
},
|
||||
},
|
||||
{
|
||||
args: []string{"--testProp1=1"},
|
||||
options: detectExecuteScanOptions{
|
||||
@@ -1009,3 +945,69 @@ func TestGetVulnerabilitiesWithComponents(t *testing.T) {
|
||||
assert.Equal(t, vulnerableComponentLog4j, vulnerabilityLog4j2.Component)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddDetectArgsImages(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("with docker inspector", func(t *testing.T) {
|
||||
args := []string{"./detect.sh"}
|
||||
config := detectExecuteScanOptions{
|
||||
ServerURL: "https://server.url",
|
||||
Token: "apiToken",
|
||||
ProjectName: "testProject",
|
||||
Version: "1.0",
|
||||
ScanContainerDistro: "ubuntu",
|
||||
}
|
||||
utils := newDetectTestUtilsBundle(false)
|
||||
sys := newBlackduckMockSystem(config)
|
||||
|
||||
result, err := addDetectArgsImages(args, config, utils, &sys, "test.tar")
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, result, "--detect.docker.tar=./test.tar")
|
||||
assert.Contains(t, result, "--detect.target.type=IMAGE")
|
||||
assert.Contains(t, result, "--detect.tools.excluded=DETECTOR")
|
||||
})
|
||||
|
||||
t.Run("with container scan", func(t *testing.T) {
|
||||
args := []string{"./detect.sh"}
|
||||
config := detectExecuteScanOptions{
|
||||
ServerURL: "https://server.url",
|
||||
Token: "apiToken",
|
||||
ProjectName: "testProject",
|
||||
Version: "1.0",
|
||||
ContainerScan: true,
|
||||
}
|
||||
utils := newDetectTestUtilsBundle(false)
|
||||
sys := newBlackduckMockSystem(config)
|
||||
|
||||
result, err := addDetectArgsImages(args, config, utils, &sys, "test.tar")
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, result, "--detect.tools=CONTAINER_SCAN")
|
||||
assert.Contains(t, result, "--detect.container.scan.file.path=./test.tar")
|
||||
assert.NotContains(t, result, "--detect.docker.tar=./test.tar")
|
||||
assert.NotContains(t, result, "--detect.target.type=IMAGE")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRunDetectWithContainerScanAndDistro(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("both containerScan and scanContainerDistro set", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
utilsMock := newDetectTestUtilsBundle(false)
|
||||
utilsMock.AddFile("detect.sh", []byte(""))
|
||||
err := runDetect(ctx, detectExecuteScanOptions{
|
||||
ContainerScan: true,
|
||||
ScanContainerDistro: "ubuntu",
|
||||
ImageNameTags: []string{"foo/bar:latest"},
|
||||
}, utilsMock, &detectExecuteScanInflux{})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(utilsMock.Calls), "Only one detect script call should have been executed")
|
||||
assert.Contains(t, utilsMock.Calls[0], "--detect.tools=CONTAINER_SCAN", "Container scan tool should be specified")
|
||||
assert.Contains(t, utilsMock.Calls[0], "--detect.container.scan.file.path=./foo_bar_latest.tar", "Container scan file path should be specified")
|
||||
assert.NotContains(t, utilsMock.Calls[0], "--detect.docker.passthrough.imageinspector.service.distro.default=ubuntu",
|
||||
"Docker inspector parameters should not be included when containerScan is true")
|
||||
})
|
||||
}
|
||||
|
@@ -675,6 +675,16 @@ spec:
|
||||
- STAGES
|
||||
- STEPS
|
||||
default: false
|
||||
- name: containerScan
|
||||
description: "When set to true, Container Scanning will be used instead of Docker Inspector as the Detect tool for scanning images, and all other detect tools will be ignored in the scan"
|
||||
aliases:
|
||||
- name: detect/containerScan
|
||||
type: bool
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
default: false
|
||||
outputs:
|
||||
resources:
|
||||
- name: influx
|
||||
|
Reference in New Issue
Block a user