Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 526c9a6

Browse files
committed
add support of --fail-on Snyk flag
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
1 parent e92e093 commit 526c9a6

5 files changed

Lines changed: 71 additions & 0 deletions

File tree

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,23 @@ Licenses: enabled
222222
Tested 200 dependencies for known issues, found 157 issues.
223223
```
224224

225+
If your image has unfixed issues, and you need to bypass the error code, you can use the `--fail-on` flag.
226+
```console
227+
$ docker scan --fail-on=upgradable docker-scan:e2e
228+
...
229+
Organization: docker-desktop-test
230+
Package manager: deb
231+
Project name: docker-image|docker-scan
232+
Docker image: docker-scan:e2e
233+
Platform: linux/amd64
234+
Licenses: enabled
235+
236+
Tested 200 dependencies for known issues, found 158 issues.
237+
238+
echo $?
239+
0
240+
```
241+
225242
### Provider Authentication
226243

227244
If you have an existing Snyk account, you can directly use your auth token

cmd/docker-scan/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ type options struct {
6969
showVersion bool
7070
forceOptIn bool
7171
forceOptOut bool
72+
failOn string
7273
}
7374

7475
func newScanCmd(ctx context.Context, dockerCli command.Cli) *cobra.Command {
@@ -97,6 +98,7 @@ func newScanCmd(ctx context.Context, dockerCli command.Cli) *cobra.Command {
9798
cmd.Flags().BoolVar(&flags.showVersion, "version", false, "Display version of the scan plugin")
9899
cmd.Flags().BoolVar(&flags.forceOptIn, "accept-license", false, "Accept using a third party scanning provider")
99100
cmd.Flags().BoolVar(&flags.forceOptOut, "reject-license", false, "Reject using a third party scanning provider")
101+
cmd.Flags().StringVar(&flags.failOn, "fail-on", "", "Only fail when there are vulnerabilities that can be fixed (all|upgradable|patchable)")
100102

101103
return cmd
102104
}
@@ -126,6 +128,12 @@ func configureProvider(ctx context.Context, dockerCli command.Streams, flags opt
126128
if flags.dependencyTree {
127129
opts = append(opts, provider.WithDependencyTree())
128130
}
131+
if flags.failOn != "" {
132+
if flags.failOn != "all" && flags.failOn != "upgradable" && flags.failOn != "patchable" {
133+
return nil, fmt.Errorf("--fail-on takes only 'all', 'upgradable' or 'patchable' values")
134+
}
135+
opts = append(opts, provider.WithFailOn(flags.failOn))
136+
}
129137
return provider.NewSnykProvider(opts...)
130138
}
131139

e2e/scan_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,42 @@ func TestScanWithDependencies(t *testing.T) {
261261
assert.Assert(t, strings.Contains(output, "vulnerability found"))
262262
}
263263

264+
func TestScanWithFailOn(t *testing.T) {
265+
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
266+
t.Skip("Can't run on this ci platform (windows containers or no engine installed)")
267+
}
268+
_, cleanFunction := createSnykConfFile(t, os.Getenv("E2E_TEST_AUTH_TOKEN"))
269+
defer cleanFunction()
270+
271+
cmd, configDir, cleanup := dockerCli.createTestCmd()
272+
defer cleanup()
273+
274+
createScanConfigFile(t, configDir)
275+
276+
cmd.Command = dockerCli.Command("scan", "--accept-license", "--fail-on", "upgradable", ImageWithVulnerabilities)
277+
output := icmd.RunCmd(cmd).Assert(t, icmd.Expected{ExitCode: 0}).Combined()
278+
assert.Assert(t, strings.Contains(output, "alpine:3.10.0")) // beginning of the dependency tree
279+
assert.Assert(t, cmp.Regexp("found .* issues", output))
280+
}
281+
282+
func TestScanWithFailOnBadValue(t *testing.T) {
283+
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
284+
t.Skip("Can't run on this ci platform (windows containers or no engine installed)")
285+
}
286+
_, cleanFunction := createSnykConfFile(t, os.Getenv("E2E_TEST_AUTH_TOKEN"))
287+
defer cleanFunction()
288+
289+
cmd, configDir, cleanup := dockerCli.createTestCmd()
290+
defer cleanup()
291+
292+
createScanConfigFile(t, configDir)
293+
294+
cmd.Command = dockerCli.Command("scan", "--accept-license", "--fail-on", "unsupportedValue", ImageWithVulnerabilities)
295+
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
296+
ExitCode: 1,
297+
Err: "--fail-on takes only 'all', 'upgradable' or 'patchable' values"})
298+
}
299+
264300
func createSnykConfFile(t *testing.T, token string) (*fs.Dir, func()) {
265301
content := fmt.Sprintf(`{"api" : "%s"}`, token)
266302
homeDir := fs.NewDir(t, t.Name(),

e2e/testdata/plugin-usage.golden

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Options:
88
--dependency-tree Show dependency tree with scan results
99
--exclude-base Exclude base image from vulnerability scanning
1010
(requires --file)
11+
--fail-on string Only fail when there are vulnerabilities that
12+
can be fixed (all|upgradable|patchable)
1113
-f, --file string Dockerfile associated with image, provides more
1214
detailed results
1315
--json Output results in JSON format

internal/provider/snyk.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ func WithDependencyTree() SnykProviderOps {
136136
}
137137
}
138138

139+
// WithFailOn only fail when there are vulnerabilities that can be fixed
140+
func WithFailOn(failOn string) SnykProviderOps {
141+
return func(provider *snykProvider) error {
142+
provider.flags = append(provider.flags, "--fail-on="+failOn)
143+
return nil
144+
}
145+
}
146+
139147
func (s *snykProvider) Authenticate(token string) error {
140148
if token != "" {
141149
if _, err := uuid.Parse(token); err != nil {

0 commit comments

Comments
 (0)