mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 07:10:41 -08:00
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:
@@ -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
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@@ -16,10 +15,8 @@ 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()
|
||||||
Target string
|
Target string
|
||||||
@@ -28,11 +25,11 @@ type ArtifactConfig struct {
|
|||||||
// NewArtifactConfig is the factory method to return artifact config
|
// NewArtifactConfig is the factory method to return artifact config
|
||||||
func NewArtifactConfig(c *cli.Context) ArtifactConfig {
|
func NewArtifactConfig(c *cli.Context) ArtifactConfig {
|
||||||
return ArtifactConfig{
|
return 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -609,8 +609,8 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
target: "alpine:latest",
|
target: "alpine:latest",
|
||||||
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"},
|
||||||
@@ -829,9 +829,9 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
|
|
||||||
func Test_skipped(t *testing.T) {
|
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
|
||||||
@@ -841,24 +841,24 @@ 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,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
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,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
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,
|
||||||
},
|
},
|
||||||
@@ -881,15 +881,15 @@ 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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ type ScanOptions struct {
|
|||||||
ScanRemovedPackages bool
|
ScanRemovedPackages bool
|
||||||
ListAllPackages bool
|
ListAllPackages bool
|
||||||
SkipFiles []string
|
SkipFiles []string
|
||||||
SkipDirectories []string
|
SkipDirs []string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user