break(cli): use StringSliceFlag for skip-dirs/files (#916)

* fix(cli): use StringSliceFlag for skip-dirs/files

* test(scanner): rename

* test(integration): fix
This commit is contained in:
Teppei Fukuda
2021-03-29 10:25:30 +03:00
committed by GitHub
parent 7221579340
commit 6d22387727
8 changed files with 46 additions and 48 deletions

View File

@@ -5,7 +5,7 @@ Trivy traversals directories and looks for all lock files by default.
If your image contains lock files which are not maintained by you, you can skip the file. If your image contains lock files which are not maintained by you, you can skip the file.
``` ```
$ trivy image --skip-files "/Gemfile.lock,/app/Pipfile.lock" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 $ trivy image --skip-files "/Gemfile.lock" --skip-files "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
``` ```
## Skip Directories ## Skip Directories
@@ -13,5 +13,5 @@ Trivy traversals directories and look for all lock files by default.
If your image contains lock files which are not maintained by you, you can skip traversal in the specific directory. If your image contains lock files which are not maintained by you, you can skip traversal in the specific directory.
``` ```
$ trivy image --skip-dirs "/usr/lib/ruby/gems,/etc" fluent/fluentd:edge $ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
``` ```

View File

@@ -413,10 +413,15 @@ func TestRun_WithTar(t *testing.T) {
} }
if len(c.testArgs.SkipFiles) != 0 { if len(c.testArgs.SkipFiles) != 0 {
osArgs = append(osArgs, "--skip-files", strings.Join(c.testArgs.SkipFiles, ",")) for _, skipFile := range c.testArgs.SkipFiles {
osArgs = append(osArgs, "--skip-files", skipFile)
} }
}
if len(c.testArgs.SkipDirs) != 0 { if len(c.testArgs.SkipDirs) != 0 {
osArgs = append(osArgs, "--skip-dirs", strings.Join(c.testArgs.SkipDirs, ",")) for _, skipDir := range c.testArgs.SkipDirs {
osArgs = append(osArgs, "--skip-dirs", skipDir)
}
} }
// Setup the output file // Setup the output file

View File

@@ -198,15 +198,15 @@ var (
EnvVars: []string{"TRIVY_LIST_ALL_PKGS"}, EnvVars: []string{"TRIVY_LIST_ALL_PKGS"},
} }
skipFiles = cli.StringFlag{ skipFiles = cli.StringSliceFlag{
Name: "skip-files", Name: "skip-files",
Usage: "specify the file path to skip traversal", Usage: "specify the file paths to skip traversal",
EnvVars: []string{"TRIVY_SKIP_FILES"}, EnvVars: []string{"TRIVY_SKIP_FILES"},
} }
skipDirectories = cli.StringFlag{ skipDirs = cli.StringSliceFlag{
Name: "skip-dirs", Name: "skip-dirs",
Usage: "specify the directory where the traversal is skipped", Usage: "specify the directories where the traversal is skipped",
EnvVars: []string{"TRIVY_SKIP_DIRS"}, EnvVars: []string{"TRIVY_SKIP_DIRS"},
} }
@@ -237,7 +237,7 @@ var (
&ignorePolicy, &ignorePolicy,
&listAllPackages, &listAllPackages,
&skipFiles, &skipFiles,
&skipDirectories, &skipDirs,
&cacheBackendFlag, &cacheBackendFlag,
} }
@@ -308,6 +308,10 @@ func setHidden(flags []cli.Flag, hidden bool) []cli.Flag {
stringFlag := *pf stringFlag := *pf
stringFlag.Hidden = hidden stringFlag.Hidden = hidden
f = &stringFlag f = &stringFlag
case *cli.StringSliceFlag:
stringSliceFlag := *pf
stringSliceFlag.Hidden = hidden
f = &stringSliceFlag
case *cli.BoolFlag: case *cli.BoolFlag:
boolFlag := *pf boolFlag := *pf
boolFlag.Hidden = hidden boolFlag.Hidden = hidden
@@ -408,7 +412,7 @@ func NewFilesystemCommand() *cli.Command {
&ignorePolicy, &ignorePolicy,
&listAllPackages, &listAllPackages,
&skipFiles, &skipFiles,
&skipDirectories, &skipDirs,
}, },
} }
} }
@@ -440,7 +444,7 @@ func NewRepositoryCommand() *cli.Command {
&ignorePolicy, &ignorePolicy,
&listAllPackages, &listAllPackages,
&skipFiles, &skipFiles,
&skipDirectories, &skipDirs,
}, },
} }
} }

View File

@@ -128,7 +128,7 @@ func scan(ctx context.Context, conf Config, initializeScanner InitializeScanner,
ScanRemovedPackages: conf.ScanRemovedPkgs, // this is valid only for image subcommand ScanRemovedPackages: conf.ScanRemovedPkgs, // this is valid only for image subcommand
ListAllPackages: conf.ListAllPkgs, ListAllPackages: conf.ListAllPkgs,
SkipFiles: conf.SkipFiles, SkipFiles: conf.SkipFiles,
SkipDirectories: conf.SkipDirectories, SkipDirs: conf.SkipDirs,
} }
log.Logger.Debugf("Vulnerability type: %s", scanOptions.VulnType) log.Logger.Debugf("Vulnerability type: %s", scanOptions.VulnType)

View File

@@ -2,7 +2,6 @@ package config
import ( import (
"os" "os"
"strings"
"time" "time"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@@ -16,9 +15,7 @@ type ArtifactConfig struct {
Timeout time.Duration Timeout time.Duration
ClearCache bool ClearCache bool
skipDirectories string SkipDirs []string
SkipDirectories []string
skipFiles string
SkipFiles []string SkipFiles []string
// this field is populated in Init() // this field is populated in Init()
@@ -31,8 +28,8 @@ func NewArtifactConfig(c *cli.Context) ArtifactConfig {
Input: c.String("input"), Input: c.String("input"),
Timeout: c.Duration("timeout"), Timeout: c.Duration("timeout"),
ClearCache: c.Bool("clear-cache"), ClearCache: c.Bool("clear-cache"),
skipFiles: c.String("skip-files"), SkipFiles: c.StringSlice("skip-files"),
skipDirectories: c.String("skip-dirs"), SkipDirs: c.StringSlice("skip-dirs"),
} }
} }
@@ -51,13 +48,5 @@ func (c *ArtifactConfig) Init(ctx *cli.Context, logger *zap.SugaredLogger) (err
c.Target = ctx.Args().First() c.Target = ctx.Args().First()
} }
if c.skipDirectories != "" {
c.SkipDirectories = strings.Split(c.skipDirectories, ",")
}
if c.skipFiles != "" {
c.SkipFiles = strings.Split(c.skipFiles, ",")
}
return nil return nil
} }

View File

@@ -167,7 +167,7 @@ func (s Scanner) scanLibrary(apps []ftypes.Application, options types.ScanOption
if len(app.Libraries) == 0 { if len(app.Libraries) == 0 {
continue continue
} }
if skipped(app.FilePath, options.SkipFiles, options.SkipDirectories) { if skipped(app.FilePath, options.SkipFiles, options.SkipDirs) {
continue continue
} }
@@ -210,7 +210,7 @@ func (s Scanner) scanLibrary(apps []ftypes.Application, options types.ScanOption
return results, nil return results, nil
} }
func skipped(filePath string, skipFiles, skipDirectories []string) bool { func skipped(filePath string, skipFiles, skipDirs []string) bool {
for _, skipFile := range skipFiles { for _, skipFile := range skipFiles {
skipFile = strings.TrimLeft(filepath.Clean(skipFile), string(os.PathSeparator)) skipFile = strings.TrimLeft(filepath.Clean(skipFile), string(os.PathSeparator))
if filePath == skipFile { if filePath == skipFile {
@@ -218,7 +218,7 @@ func skipped(filePath string, skipFiles, skipDirectories []string) bool {
} }
} }
for _, skipDir := range skipDirectories { for _, skipDir := range skipDirs {
skipDir = strings.TrimLeft(filepath.Clean(skipDir), string(os.PathSeparator)) skipDir = strings.TrimLeft(filepath.Clean(skipDir), string(os.PathSeparator))
rel, err := filepath.Rel(skipDir, filePath) rel, err := filepath.Rel(skipDir, filePath)
if err != nil { if err != nil {

View File

@@ -610,7 +610,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{ options: types.ScanOptions{
VulnType: []string{"library"}, VulnType: []string{"library"},
SkipDirectories: []string{"/usr/lib/ruby/gems"}, SkipDirs: []string{"/usr/lib/ruby/gems"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},
@@ -831,7 +831,7 @@ func Test_skipped(t *testing.T) {
type args struct { type args struct {
filePath string filePath string
skipFiles []string skipFiles []string
skipDirectories []string skipDirs []string
} }
tests := []struct { tests := []struct {
name string name string
@@ -842,7 +842,7 @@ func Test_skipped(t *testing.T) {
name: "no skip directory", name: "no skip directory",
args: args{ args: args{
filePath: "app/Gemfile.lock", filePath: "app/Gemfile.lock",
skipDirectories: []string{}, skipDirs: []string{},
}, },
want: false, want: false,
}, },
@@ -850,7 +850,7 @@ func Test_skipped(t *testing.T) {
name: "skip directory with the leading slash", name: "skip directory with the leading slash",
args: args{ args: args{
filePath: "app/Gemfile.lock", filePath: "app/Gemfile.lock",
skipDirectories: []string{"/app"}, skipDirs: []string{"/app"},
}, },
want: true, want: true,
}, },
@@ -858,7 +858,7 @@ func Test_skipped(t *testing.T) {
name: "skip directory without a slash", name: "skip directory without a slash",
args: args{ args: args{
filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock", filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock",
skipDirectories: []string{"/usr/lib/ruby"}, skipDirs: []string{"/usr/lib/ruby"},
}, },
want: true, want: true,
}, },
@@ -882,14 +882,14 @@ func Test_skipped(t *testing.T) {
name: "not skipped", name: "not skipped",
args: args{ args: args{
filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock", filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock",
skipDirectories: []string{"lib/ruby"}, skipDirs: []string{"lib/ruby"},
}, },
want: false, want: false,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := skipped(tt.args.filePath, tt.args.skipFiles, tt.args.skipDirectories) got := skipped(tt.args.filePath, tt.args.skipFiles, tt.args.skipDirs)
assert.Equal(t, tt.want, got) assert.Equal(t, tt.want, got)
}) })
} }

View File

@@ -6,5 +6,5 @@ type ScanOptions struct {
ScanRemovedPackages bool ScanRemovedPackages bool
ListAllPackages bool ListAllPackages bool
SkipFiles []string SkipFiles []string
SkipDirectories []string SkipDirs []string
} }