From fb540fd4dedd99241aca84090c8af3cf73e92784 Mon Sep 17 00:00:00 2001 From: knqyf263 Date: Wed, 5 Jul 2023 16:29:25 +0300 Subject: [PATCH 1/5] refactor: rename Value to Default --- go.mod | 6 +++--- go.sum | 12 ++++++------ magefiles/docs.go | 4 ++-- pkg/commands/app.go | 8 ++++---- pkg/flag/aws_flags.go | 12 ++++++------ pkg/flag/cache_flags.go | 14 +++++++------- pkg/flag/cloud_flags.go | 4 ++-- pkg/flag/db_flags.go | 18 +++++++++--------- pkg/flag/global_flags.go | 16 ++++++++-------- pkg/flag/image_flags.go | 12 ++++++------ pkg/flag/kubernetes_flags.go | 20 ++++++++++---------- pkg/flag/license_flags.go | 18 +++++++++--------- pkg/flag/misconf_flags.go | 14 +++++++------- pkg/flag/module_flags.go | 4 ++-- pkg/flag/options.go | 8 ++++---- pkg/flag/registry_flags.go | 6 +++--- pkg/flag/rego_flags.go | 10 +++++----- pkg/flag/remote_flags.go | 10 +++++----- pkg/flag/repo.go | 6 +++--- pkg/flag/report_flags.go | 24 ++++++++++++------------ pkg/flag/sbom_flags.go | 6 +++--- pkg/flag/scan_flags.go | 19 ++++++++++--------- pkg/flag/secret_flags.go | 2 +- pkg/flag/vulnerability_flags.go | 4 ++-- 24 files changed, 129 insertions(+), 128 deletions(-) diff --git a/go.mod b/go.mod index ba46c64f49f..bb75c89f2af 100644 --- a/go.mod +++ b/go.mod @@ -94,7 +94,7 @@ require ( go.etcd.io/bbolt v1.3.7 go.uber.org/zap v1.24.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/mod v0.11.0 + golang.org/x/mod v0.12.0 golang.org/x/sync v0.3.0 golang.org/x/term v0.9.0 golang.org/x/text v0.10.0 @@ -359,9 +359,9 @@ require ( golang.org/x/crypto v0.10.0 // indirect golang.org/x/net v0.11.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sys v0.9.0 // indirect + golang.org/x/sys v0.10.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.8.0 // indirect + golang.org/x/tools v0.10.0 // indirect google.golang.org/api v0.121.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect diff --git a/go.sum b/go.sum index 8892bd6bbba..193b065ca66 100644 --- a/go.sum +++ b/go.sum @@ -1840,8 +1840,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2093,8 +2093,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2197,8 +2197,8 @@ golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyj golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= -golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/magefiles/docs.go b/magefiles/docs.go index 8eeec03116d..e44b7147c00 100644 --- a/magefiles/docs.go +++ b/magefiles/docs.go @@ -17,8 +17,8 @@ func main() { log.Fatal(err) } // Set a dummy path for the documents - flag.CacheDirFlag.Value = "/path/to/cache" - flag.ModuleDirFlag.Value = "$HOME/.trivy/modules" + flag.CacheDirFlag.Default = "/path/to/cache" + flag.ModuleDirFlag.Default = "$HOME/.trivy/modules" cmd := commands.NewApp(ver) cmd.DisableAutoGenTag = true diff --git a/pkg/commands/app.go b/pkg/commands/app.go index b553c37e116..05318e5ac3b 100644 --- a/pkg/commands/app.go +++ b/pkg/commands/app.go @@ -246,7 +246,7 @@ func NewImageCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup := flag.NewReportFlagGroup() report := flag.ReportFormatFlag - report.Value = "summary" // override the default value as the summary is preferred for the compliance report + report.Default = "summary" // override the default value as the summary is preferred for the compliance report report.Usage = "specify a format for the compliance report." // "--report" works only with "--compliance" reportFlagGroup.ReportFormat = &report @@ -546,7 +546,7 @@ func NewClientCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { Name: "remote", ConfigName: "server.addr", Shorthand: "", - Value: "http://localhost:4954", + Default: "http://localhost:4954", Usage: "server address", } remoteFlags.ServerAddr = &remoteAddr // disable '--server' and enable '--remote' instead. @@ -880,7 +880,7 @@ func NewModuleCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { scanFlags := flag.NewScanFlagGroup() scanners := flag.ScannersFlag - scanners.Value = fmt.Sprintf( // overwrite the default value + scanners.Default = fmt.Sprintf( // overwrite the default value "%s,%s,%s,%s", types.VulnerabilityScanner, types.MisconfigScanner, @@ -1047,7 +1047,7 @@ func NewVMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { Region: &flag.Flag{ Name: "aws-region", ConfigName: "aws.region", - Value: "", + Default: "", Usage: "AWS region to scan", }, }, diff --git a/pkg/flag/aws_flags.go b/pkg/flag/aws_flags.go index 43582685e0a..95f2d756ea0 100644 --- a/pkg/flag/aws_flags.go +++ b/pkg/flag/aws_flags.go @@ -4,37 +4,37 @@ var ( awsRegionFlag = Flag{ Name: "region", ConfigName: "cloud.aws.region", - Value: "", + Default: "", Usage: "AWS Region to scan", } awsEndpointFlag = Flag{ Name: "endpoint", ConfigName: "cloud.aws.endpoint", - Value: "", + Default: "", Usage: "AWS Endpoint override", } awsServiceFlag = Flag{ Name: "service", ConfigName: "cloud.aws.service", - Value: []string{}, + Default: []string{}, Usage: "Only scan AWS Service(s) specified with this flag. Can specify multiple services using --service A --service B etc.", } awsSkipServicesFlag = Flag{ Name: "skip-service", ConfigName: "cloud.aws.skip-service", - Value: []string{}, + Default: []string{}, Usage: "Skip selected AWS Service(s) specified with this flag. Can specify multiple services using --skip-service A --skip-service B etc.", } awsAccountFlag = Flag{ Name: "account", ConfigName: "cloud.aws.account", - Value: "", + Default: "", Usage: "The AWS account to scan. It's useful to specify this when reviewing cached results for multiple accounts.", } awsARNFlag = Flag{ Name: "arn", ConfigName: "cloud.aws.arn", - Value: "", + Default: "", Usage: "The AWS ARN to show results for. Useful to filter results once a scan is cached.", } ) diff --git a/pkg/flag/cache_flags.go b/pkg/flag/cache_flags.go index 81af440f9fb..a92cd97dcc6 100644 --- a/pkg/flag/cache_flags.go +++ b/pkg/flag/cache_flags.go @@ -22,43 +22,43 @@ var ( ClearCacheFlag = Flag{ Name: "clear-cache", ConfigName: "cache.clear", - Value: false, + Default: false, Usage: "clear image caches without scanning", } CacheBackendFlag = Flag{ Name: "cache-backend", ConfigName: "cache.backend", - Value: "fs", + Default: "fs", Usage: "cache backend (e.g. redis://localhost:6379)", } CacheTTLFlag = Flag{ Name: "cache-ttl", ConfigName: "cache.ttl", - Value: time.Duration(0), + Default: time.Duration(0), Usage: "cache TTL when using redis as cache backend", } RedisTLSFlag = Flag{ Name: "redis-tls", ConfigName: "cache.redis.tls", - Value: false, + Default: false, Usage: "enable redis TLS with public certificates, if using redis as cache backend", } RedisCACertFlag = Flag{ Name: "redis-ca", ConfigName: "cache.redis.ca", - Value: "", + Default: "", Usage: "redis ca file location, if using redis as cache backend", } RedisCertFlag = Flag{ Name: "redis-cert", ConfigName: "cache.redis.cert", - Value: "", + Default: "", Usage: "redis certificate file location, if using redis as cache backend", } RedisKeyFlag = Flag{ Name: "redis-key", ConfigName: "cache.redis.key", - Value: "", + Default: "", Usage: "redis key file location, if using redis as cache backend", } ) diff --git a/pkg/flag/cloud_flags.go b/pkg/flag/cloud_flags.go index 4be13e9a81e..eed81230f6d 100644 --- a/pkg/flag/cloud_flags.go +++ b/pkg/flag/cloud_flags.go @@ -6,13 +6,13 @@ var ( cloudUpdateCacheFlag = Flag{ Name: "update-cache", ConfigName: "cloud.update-cache", - Value: false, + Default: false, Usage: "Update the cache for the applicable cloud provider instead of using cached results.", } cloudMaxCacheAgeFlag = Flag{ Name: "max-cache-age", ConfigName: "cloud.max-cache-age", - Value: time.Hour * 24, + Default: time.Hour * 24, Usage: "The maximum age of the cloud cache. Cached data will be requeried from the cloud provider if it is older than this.", } ) diff --git a/pkg/flag/db_flags.go b/pkg/flag/db_flags.go index 17f8a4a2fb3..2e5d58f3a6a 100644 --- a/pkg/flag/db_flags.go +++ b/pkg/flag/db_flags.go @@ -13,19 +13,19 @@ var ( ResetFlag = Flag{ Name: "reset", ConfigName: "reset", - Value: false, + Default: false, Usage: "remove all caches and database", } DownloadDBOnlyFlag = Flag{ Name: "download-db-only", ConfigName: "db.download-only", - Value: false, + Default: false, Usage: "download/update vulnerability database but don't run a scan", } SkipDBUpdateFlag = Flag{ Name: "skip-db-update", ConfigName: "db.skip-update", - Value: false, + Default: false, Usage: "skip updating vulnerability database", Aliases: []Alias{ { @@ -37,37 +37,37 @@ var ( DownloadJavaDBOnlyFlag = Flag{ Name: "download-java-db-only", ConfigName: "db.download-java-only", - Value: false, + Default: false, Usage: "download/update Java index database but don't run a scan", } SkipJavaDBUpdateFlag = Flag{ Name: "skip-java-db-update", ConfigName: "db.java-skip-update", - Value: false, + Default: false, Usage: "skip updating Java index database", } NoProgressFlag = Flag{ Name: "no-progress", ConfigName: "db.no-progress", - Value: false, + Default: false, Usage: "suppress progress bar", } DBRepositoryFlag = Flag{ Name: "db-repository", ConfigName: "db.repository", - Value: defaultDBRepository, + Default: defaultDBRepository, Usage: "OCI repository to retrieve trivy-db from", } JavaDBRepositoryFlag = Flag{ Name: "java-db-repository", ConfigName: "db.java-repository", - Value: defaultJavaDBRepository, + Default: defaultJavaDBRepository, Usage: "OCI repository to retrieve trivy-java-db from", } LightFlag = Flag{ Name: "light", ConfigName: "db.light", - Value: false, + Default: false, Usage: "deprecated", Deprecated: true, } diff --git a/pkg/flag/global_flags.go b/pkg/flag/global_flags.go index 560f8ff3d28..a9b5440d835 100644 --- a/pkg/flag/global_flags.go +++ b/pkg/flag/global_flags.go @@ -14,7 +14,7 @@ var ( Name: "config", ConfigName: "config", Shorthand: "c", - Value: "trivy.yaml", + Default: "trivy.yaml", Usage: "config path", Persistent: true, } @@ -22,7 +22,7 @@ var ( Name: "version", ConfigName: "version", Shorthand: "v", - Value: false, + Default: false, Usage: "show version", Persistent: true, } @@ -30,7 +30,7 @@ var ( Name: "quiet", ConfigName: "quiet", Shorthand: "q", - Value: false, + Default: false, Usage: "suppress progress bar and log output", Persistent: true, } @@ -38,35 +38,35 @@ var ( Name: "debug", ConfigName: "debug", Shorthand: "d", - Value: false, + Default: false, Usage: "debug mode", Persistent: true, } InsecureFlag = Flag{ Name: "insecure", ConfigName: "insecure", - Value: false, + Default: false, Usage: "allow insecure server connections", Persistent: true, } TimeoutFlag = Flag{ Name: "timeout", ConfigName: "timeout", - Value: time.Second * 300, // 5 mins + Default: time.Second * 300, // 5 mins Usage: "timeout", Persistent: true, } CacheDirFlag = Flag{ Name: "cache-dir", ConfigName: "cache.dir", - Value: fsutils.CacheDir(), + Default: fsutils.CacheDir(), Usage: "cache directory", Persistent: true, } GenerateDefaultConfigFlag = Flag{ Name: "generate-default-config", ConfigName: "generate-default-config", - Value: false, + Default: false, Usage: "write the default config to trivy-default.yaml", Persistent: true, } diff --git a/pkg/flag/image_flags.go b/pkg/flag/image_flags.go index 4bbe78ae9fb..876544816f4 100644 --- a/pkg/flag/image_flags.go +++ b/pkg/flag/image_flags.go @@ -18,38 +18,38 @@ var ( ImageConfigScannersFlag = Flag{ Name: "image-config-scanners", ConfigName: "image.image-config-scanners", - Value: "", Usage: "comma-separated list of what security issues to detect on container image configurations (config,secret)", + Default: []string{}, } ScanRemovedPkgsFlag = Flag{ Name: "removed-pkgs", ConfigName: "image.removed-pkgs", - Value: false, + Default: false, Usage: "detect vulnerabilities of removed packages (only for Alpine)", } InputFlag = Flag{ Name: "input", ConfigName: "image.input", - Value: "", + Default: "", Usage: "input file path instead of image name", } PlatformFlag = Flag{ Name: "platform", ConfigName: "image.platform", - Value: "", + Default: "", Usage: "set platform in the form os/arch if image is multi-platform capable", } DockerHostFlag = Flag{ Name: "docker-host", ConfigName: "image.docker.host", - Value: "", + Default: "", Usage: "unix domain socket path to use for docker scanning", } SourceFlag = Flag{ Name: "image-src", ConfigName: "image.source", - Value: ftypes.AllImageSources.StringSlice(), Usage: "image source(s) to use, in priority order (docker,containerd,podman,remote)", + Default: ftypes.AllImageSources.StringSlice(), } ) diff --git a/pkg/flag/kubernetes_flags.go b/pkg/flag/kubernetes_flags.go index bbacc6147d5..eb94d37c747 100644 --- a/pkg/flag/kubernetes_flags.go +++ b/pkg/flag/kubernetes_flags.go @@ -16,7 +16,7 @@ var ( ClusterContextFlag = Flag{ Name: "context", ConfigName: "kubernetes.context", - Value: "", + Default: "", Usage: "specify a context to scan", Aliases: []Alias{ {Name: "ctx"}, @@ -26,19 +26,19 @@ var ( Name: "namespace", ConfigName: "kubernetes.namespace", Shorthand: "n", - Value: "", + Default: "", Usage: "specify a namespace to scan", } KubeConfigFlag = Flag{ Name: "kubeconfig", ConfigName: "kubernetes.kubeconfig", - Value: "", + Default: "", Usage: "specify the kubeconfig file path to use", } ComponentsFlag = Flag{ Name: "components", ConfigName: "kubernetes.components", - Value: []string{ + Default: []string{ "workload", "infra", }, @@ -47,38 +47,38 @@ var ( K8sVersionFlag = Flag{ Name: "k8s-version", ConfigName: "kubernetes.k8s.version", - Value: "", + Default: "", Usage: "specify k8s version to validate outdated api by it (example: 1.21.0)", } ParallelFlag = Flag{ Name: "parallel", ConfigName: "kubernetes.parallel", - Value: 5, + Default: 5, Usage: "number (between 1-20) of goroutines enabled for parallel scanning", } TolerationsFlag = Flag{ Name: "tolerations", ConfigName: "kubernetes.tolerations", - Value: []string{}, + Default: []string{}, Usage: "specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)", } AllNamespaces = Flag{ Name: "all-namespaces", ConfigName: "kubernetes.all.namespaces", Shorthand: "A", - Value: false, + Default: false, Usage: "fetch resources from all cluster namespaces", } NodeCollectorNamespace = Flag{ Name: "node-collector-namespace", ConfigName: "node.collector.namespace", - Value: "trivy-temp", + Default: "trivy-temp", Usage: "specify the namespace in which the node-collector job should be deployed", } ExcludeNodes = Flag{ Name: "exclude-nodes", ConfigName: "exclude.nodes", - Value: []string{}, + Default: []string{}, Usage: "indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)", } ) diff --git a/pkg/flag/license_flags.go b/pkg/flag/license_flags.go index 3dd18eb89fc..45b70f70ad9 100644 --- a/pkg/flag/license_flags.go +++ b/pkg/flag/license_flags.go @@ -9,56 +9,56 @@ var ( LicenseFull = Flag{ Name: "license-full", ConfigName: "license.full", - Value: false, + Default: false, Usage: "eagerly look for licenses in source code headers and license files", } IgnoredLicenses = Flag{ Name: "ignored-licenses", ConfigName: "license.ignored", - Value: []string{}, + Default: []string{}, Usage: "specify a list of license to ignore", } LicenseConfidenceLevel = Flag{ Name: "license-confidence-level", ConfigName: "license.confidenceLevel", - Value: 0.9, + Default: 0.9, Usage: "specify license classifier's confidence level", } // LicenseForbidden is an option only in a config file LicenseForbidden = Flag{ ConfigName: "license.forbidden", - Value: licensing.ForbiddenLicenses, + Default: licensing.ForbiddenLicenses, Usage: "forbidden licenses", } // LicenseRestricted is an option only in a config file LicenseRestricted = Flag{ ConfigName: "license.restricted", - Value: licensing.RestrictedLicenses, + Default: licensing.RestrictedLicenses, Usage: "restricted licenses", } // LicenseReciprocal is an option only in a config file LicenseReciprocal = Flag{ ConfigName: "license.reciprocal", - Value: licensing.ReciprocalLicenses, + Default: licensing.ReciprocalLicenses, Usage: "reciprocal licenses", } // LicenseNotice is an option only in a config file LicenseNotice = Flag{ ConfigName: "license.notice", - Value: licensing.NoticeLicenses, + Default: licensing.NoticeLicenses, Usage: "notice licenses", } // LicensePermissive is an option only in a config file LicensePermissive = Flag{ ConfigName: "license.permissive", - Value: licensing.PermissiveLicenses, + Default: licensing.PermissiveLicenses, Usage: "permissive licenses", } // LicenseUnencumbered is an option only in a config file LicenseUnencumbered = Flag{ ConfigName: "license.unencumbered", - Value: licensing.UnencumberedLicenses, + Default: licensing.UnencumberedLicenses, Usage: "unencumbered licenses", } ) diff --git a/pkg/flag/misconf_flags.go b/pkg/flag/misconf_flags.go index a8f6c8d3f75..68861efb17f 100644 --- a/pkg/flag/misconf_flags.go +++ b/pkg/flag/misconf_flags.go @@ -10,43 +10,43 @@ var ( ResetPolicyBundleFlag = Flag{ Name: "reset-policy-bundle", ConfigName: "misconfiguration.reset-policy-bundle", - Value: false, + Default: false, Usage: "remove policy bundle", } IncludeNonFailuresFlag = Flag{ Name: "include-non-failures", ConfigName: "misconfiguration.include-non-failures", - Value: false, + Default: false, Usage: "include successes and exceptions, available with '--scanners config'", } HelmValuesFileFlag = Flag{ Name: "helm-values", ConfigName: "misconfiguration.helm.values", - Value: []string{}, + Default: []string{}, Usage: "specify paths to override the Helm values.yaml files", } HelmSetFlag = Flag{ Name: "helm-set", ConfigName: "misconfiguration.helm.set", - Value: []string{}, + Default: []string{}, Usage: "specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)", } HelmSetFileFlag = Flag{ Name: "helm-set-file", ConfigName: "misconfiguration.helm.set-file", - Value: []string{}, + Default: []string{}, Usage: "specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)", } HelmSetStringFlag = Flag{ Name: "helm-set-string", ConfigName: "misconfiguration.helm.set-string", - Value: []string{}, + Default: []string{}, Usage: "specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)", } TfVarsFlag = Flag{ Name: "tf-vars", ConfigName: "misconfiguration.terraform.vars", - Value: []string{}, + Default: []string{}, Usage: "specify paths to override the Terraform tfvars files", } ) diff --git a/pkg/flag/module_flags.go b/pkg/flag/module_flags.go index c7304d55957..1a84e2acbb6 100644 --- a/pkg/flag/module_flags.go +++ b/pkg/flag/module_flags.go @@ -14,14 +14,14 @@ var ( ModuleDirFlag = Flag{ Name: "module-dir", ConfigName: "module.dir", - Value: module.DefaultDir, + Default: module.DefaultDir, Usage: "specify directory to the wasm modules that will be loaded", Persistent: true, } EnableModulesFlag = Flag{ Name: "enable-modules", ConfigName: "module.enable-modules", - Value: []string{}, + Default: []string{}, Usage: "[EXPERIMENTAL] module names to enable", Persistent: true, } diff --git a/pkg/flag/options.go b/pkg/flag/options.go index 6fc76331495..0f4db20e1c0 100644 --- a/pkg/flag/options.go +++ b/pkg/flag/options.go @@ -32,8 +32,8 @@ type Flag struct { // Shorthand is a shorthand letter. Shorthand string - // Value is the default value. It must be filled to determine the flag type. - Value interface{} + // Default is the default value. It must be filled to determine the flag type. + Default any // Usage explains how to use the flag. Usage string @@ -178,7 +178,7 @@ func addFlag(cmd *cobra.Command, flag *Flag) { flags = cmd.Flags() } - switch v := flag.Value.(type) { + switch v := flag.Default.(type) { case int: flags.IntP(flag.Name, flag.Shorthand, v, flag.Usage) case string: @@ -203,7 +203,7 @@ func bind(cmd *cobra.Command, flag *Flag) error { return nil } else if flag.Name == "" { // This flag is available only in trivy.yaml - viper.SetDefault(flag.ConfigName, flag.Value) + viper.SetDefault(flag.ConfigName, flag.Default) return nil } diff --git a/pkg/flag/registry_flags.go b/pkg/flag/registry_flags.go index 060c2148d25..7aed50d5e2f 100644 --- a/pkg/flag/registry_flags.go +++ b/pkg/flag/registry_flags.go @@ -12,19 +12,19 @@ var ( UsernameFlag = Flag{ Name: "username", ConfigName: "registry.username", - Value: []string{}, + Default: []string{}, Usage: "username. Comma-separated usernames allowed.", } PasswordFlag = Flag{ Name: "password", ConfigName: "registry.password", - Value: []string{}, + Default: []string{}, Usage: "password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.", } RegistryTokenFlag = Flag{ Name: "registry-token", ConfigName: "registry.token", - Value: "", + Default: "", Usage: "registry token", } ) diff --git a/pkg/flag/rego_flags.go b/pkg/flag/rego_flags.go index ed53667ca99..bfe7ed54125 100644 --- a/pkg/flag/rego_flags.go +++ b/pkg/flag/rego_flags.go @@ -10,19 +10,19 @@ var ( SkipPolicyUpdateFlag = Flag{ Name: "skip-policy-update", ConfigName: "rego.skip-policy-update", - Value: false, + Default: false, Usage: "skip fetching rego policy updates", } TraceFlag = Flag{ Name: "trace", ConfigName: "rego.trace", - Value: false, + Default: false, Usage: "enable more verbose trace output for custom queries", } ConfigPolicyFlag = Flag{ Name: "config-policy", ConfigName: "rego.policy", - Value: []string{}, + Default: []string{}, Usage: "specify paths to the Rego policy files directory, applying config files", Aliases: []Alias{ {Name: "policy"}, @@ -31,7 +31,7 @@ var ( ConfigDataFlag = Flag{ Name: "config-data", ConfigName: "rego.data", - Value: []string{}, + Default: []string{}, Usage: "specify paths from which data for the Rego policies will be recursively loaded", Aliases: []Alias{ {Name: "data"}, @@ -40,7 +40,7 @@ var ( PolicyNamespaceFlag = Flag{ Name: "policy-namespaces", ConfigName: "rego.namespaces", - Value: []string{}, + Default: []string{}, Usage: "Rego namespaces", Aliases: []Alias{ {Name: "namespaces"}, diff --git a/pkg/flag/remote_flags.go b/pkg/flag/remote_flags.go index beca2406fa8..c06e9605087 100644 --- a/pkg/flag/remote_flags.go +++ b/pkg/flag/remote_flags.go @@ -15,31 +15,31 @@ var ( ServerTokenFlag = Flag{ Name: "token", ConfigName: "server.token", - Value: "", + Default: "", Usage: "for authentication in client/server mode", } ServerTokenHeaderFlag = Flag{ Name: "token-header", ConfigName: "server.token-header", - Value: DefaultTokenHeader, + Default: DefaultTokenHeader, Usage: "specify a header name for token in client/server mode", } ServerAddrFlag = Flag{ Name: "server", ConfigName: "server.addr", - Value: "", + Default: "", Usage: "server address in client mode", } ServerCustomHeadersFlag = Flag{ Name: "custom-headers", ConfigName: "server.custom-headers", - Value: []string{}, + Default: []string{}, Usage: "custom headers in client mode", } ServerListenFlag = Flag{ Name: "listen", ConfigName: "server.listen", - Value: "localhost:4954", + Default: "localhost:4954", Usage: "listen address in server mode", } ) diff --git a/pkg/flag/repo.go b/pkg/flag/repo.go index dfbffa8e690..6d59281ba4f 100644 --- a/pkg/flag/repo.go +++ b/pkg/flag/repo.go @@ -4,19 +4,19 @@ var ( FetchBranchFlag = Flag{ Name: "branch", ConfigName: "repository.branch", - Value: "", + Default: "", Usage: "pass the branch name to be scanned", } FetchCommitFlag = Flag{ Name: "commit", ConfigName: "repository.commit", - Value: "", + Default: "", Usage: "pass the commit hash to be scanned", } FetchTagFlag = Flag{ Name: "tag", ConfigName: "repository.tag", - Value: "", + Default: "", Usage: "pass the tag name to be scanned", } ) diff --git a/pkg/flag/report_flags.go b/pkg/flag/report_flags.go index 7023ec5a5af..95f5bc0ea1b 100644 --- a/pkg/flag/report_flags.go +++ b/pkg/flag/report_flags.go @@ -26,76 +26,76 @@ var ( Name: "format", ConfigName: "format", Shorthand: "f", - Value: report.FormatTable, Usage: "format (" + strings.Join(report.SupportedFormats, ", ") + ")", + Default: report.FormatTable, } ReportFormatFlag = Flag{ Name: "report", ConfigName: "report", - Value: "all", Usage: "specify a report format for the output. (all,summary)", + Default: "all", } TemplateFlag = Flag{ Name: "template", ConfigName: "template", Shorthand: "t", - Value: "", + Default: "", Usage: "output template", } DependencyTreeFlag = Flag{ Name: "dependency-tree", ConfigName: "dependency-tree", - Value: false, + Default: false, Usage: "[EXPERIMENTAL] show dependency origin tree of vulnerable packages", } ListAllPkgsFlag = Flag{ Name: "list-all-pkgs", ConfigName: "list-all-pkgs", - Value: false, + Default: false, Usage: "enabling the option will output all packages regardless of vulnerability", } IgnoreFileFlag = Flag{ Name: "ignorefile", ConfigName: "ignorefile", - Value: result.DefaultIgnoreFile, + Default: result.DefaultIgnoreFile, Usage: "specify .trivyignore file", } IgnorePolicyFlag = Flag{ Name: "ignore-policy", ConfigName: "ignore-policy", - Value: "", + Default: "", Usage: "specify the Rego file path to evaluate each vulnerability", } ExitCodeFlag = Flag{ Name: "exit-code", ConfigName: "exit-code", - Value: 0, + Default: 0, Usage: "specify exit code when any security issues are found", } ExitOnEOLFlag = Flag{ Name: "exit-on-eol", ConfigName: "exit-on-eol", - Value: 0, + Default: 0, Usage: "exit with the specified code when the OS reaches end of service/life", } OutputFlag = Flag{ Name: "output", ConfigName: "output", Shorthand: "o", - Value: "", + Default: "", Usage: "output file name", } SeverityFlag = Flag{ Name: "severity", ConfigName: "severity", Shorthand: "s", - Value: strings.Join(dbTypes.SeverityNames, ","), Usage: "severities of security issues to be displayed (comma separated)", + Default: dbTypes.SeverityNames, } ComplianceFlag = Flag{ Name: "compliance", ConfigName: "scan.compliance", - Value: "", + Default: "", Usage: "compliance report to generate", } ) diff --git a/pkg/flag/sbom_flags.go b/pkg/flag/sbom_flags.go index 3e5f436e190..5980e9eab59 100644 --- a/pkg/flag/sbom_flags.go +++ b/pkg/flag/sbom_flags.go @@ -10,21 +10,21 @@ var ( ArtifactTypeFlag = Flag{ Name: "artifact-type", ConfigName: "sbom.artifact-type", - Value: "", + Default: "", Usage: "deprecated", Deprecated: true, } SBOMFormatFlag = Flag{ Name: "sbom-format", ConfigName: "sbom.format", - Value: "", + Default: "", Usage: "deprecated", Deprecated: true, } VEXFlag = Flag{ Name: "vex", ConfigName: "sbom.vex", - Value: "", + Default: "", Usage: "[EXPERIMENTAL] file path to VEX", } ) diff --git a/pkg/flag/scan_flags.go b/pkg/flag/scan_flags.go index 5b4105fd9bc..68028b8bd4e 100644 --- a/pkg/flag/scan_flags.go +++ b/pkg/flag/scan_flags.go @@ -11,28 +11,29 @@ var ( SkipDirsFlag = Flag{ Name: "skip-dirs", ConfigName: "scan.skip-dirs", - Value: []string{}, + Default: []string{}, Usage: "specify the directories where the traversal is skipped", } SkipFilesFlag = Flag{ Name: "skip-files", ConfigName: "scan.skip-files", - Value: []string{}, + Default: []string{}, Usage: "specify the file paths to skip traversal", } OfflineScanFlag = Flag{ Name: "offline-scan", ConfigName: "scan.offline", - Value: false, + Default: false, Usage: "do not issue API requests to identify dependencies", } ScannersFlag = Flag{ Name: "scanners", ConfigName: "scan.scanners", - Value: types.Scanners{ + Default: types.Scanners{ types.VulnerabilityScanner, types.SecretScanner, }.StringSlice(), + }.StringSlice(), Aliases: []Alias{ { Name: "security-checks", @@ -45,31 +46,31 @@ var ( FilePatternsFlag = Flag{ Name: "file-patterns", ConfigName: "scan.file-patterns", - Value: []string{}, + Default: []string{}, Usage: "specify config file patterns", } SlowFlag = Flag{ Name: "slow", ConfigName: "scan.slow", - Value: false, + Default: false, Usage: "scan over time with lower CPU and memory utilization", } SBOMSourcesFlag = Flag{ Name: "sbom-sources", ConfigName: "scan.sbom-sources", - Value: []string{}, Usage: "[EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)", + Default: []string{}, } RekorURLFlag = Flag{ Name: "rekor-url", ConfigName: "scan.rekor-url", - Value: "https://rekor.sigstore.dev", + Default: "https://rekor.sigstore.dev", Usage: "[EXPERIMENTAL] address of rekor STL server", } IncludeDevDepsFlag = Flag{ Name: "include-dev-deps", ConfigName: "include-dev-deps", - Value: false, + Default: false, Usage: "include development dependencies in the report (supported: npm)", } ) diff --git a/pkg/flag/secret_flags.go b/pkg/flag/secret_flags.go index 9a252bd1795..0190480f813 100644 --- a/pkg/flag/secret_flags.go +++ b/pkg/flag/secret_flags.go @@ -4,7 +4,7 @@ var ( SecretConfigFlag = Flag{ Name: "secret-config", ConfigName: "secret.config", - Value: "trivy-secret.yaml", + Default: "trivy-secret.yaml", Usage: "specify a path to config file for secret scanning", } ) diff --git a/pkg/flag/vulnerability_flags.go b/pkg/flag/vulnerability_flags.go index f20c76e8da4..955ecba9de7 100644 --- a/pkg/flag/vulnerability_flags.go +++ b/pkg/flag/vulnerability_flags.go @@ -11,7 +11,7 @@ var ( VulnTypeFlag = Flag{ Name: "vuln-type", ConfigName: "vulnerability.type", - Value: []string{ + Default: []string{ types.VulnTypeOS, types.VulnTypeLibrary, }, @@ -20,7 +20,7 @@ var ( IgnoreUnfixedFlag = Flag{ Name: "ignore-unfixed", ConfigName: "vulnerability.ignore-unfixed", - Value: false, + Default: false, Usage: "display only fixed vulnerabilities", } ) From 5cae7b0dc8ea449a3790432f3ff0649e91f95af5 Mon Sep 17 00:00:00 2001 From: knqyf263 Date: Wed, 5 Jul 2023 16:30:18 +0300 Subject: [PATCH 2/5] refactor: support allowed values for CLI flags --- pkg/commands/app.go | 19 ++++--- pkg/flag/image_flags.go | 36 ++++--------- pkg/flag/kubernetes_flags.go | 4 ++ pkg/flag/options.go | 28 +++++++++- pkg/flag/report_flags.go | 40 ++++++--------- pkg/flag/scan_flags.go | 47 ++++------------- pkg/flag/value.go | 91 +++++++++++++++++++++++++++++++++ pkg/flag/vulnerability_flags.go | 6 ++- 8 files changed, 172 insertions(+), 99 deletions(-) create mode 100644 pkg/flag/value.go diff --git a/pkg/commands/app.go b/pkg/commands/app.go index 05318e5ac3b..cc9991af7d4 100644 --- a/pkg/commands/app.go +++ b/pkg/commands/app.go @@ -251,7 +251,7 @@ func NewImageCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup.ReportFormat = &report compliance := flag.ComplianceFlag - compliance.Usage += fmt.Sprintf(" (%s)", types.ComplianceDockerCIS) + compliance.Values = []string{types.ComplianceDockerCIS} reportFlagGroup.Compliance = &compliance // override usage as the accepted values differ for each subcommand. imageFlags := &flag.Flags{ @@ -330,7 +330,7 @@ func NewImageCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { func NewFilesystemCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup := flag.NewReportFlagGroup() reportFormat := flag.ReportFormatFlag - reportFormat.Usage = "specify a compliance report format for the output. (all,summary)" //@TODO: support --report summary for non compliance reports + reportFormat.Usage = "specify a compliance report format for the output" //@TODO: support --report summary for non compliance reports reportFlagGroup.ReportFormat = &reportFormat reportFlagGroup.ExitOnEOL = nil // disable '--exit-on-eol' @@ -643,7 +643,7 @@ func NewConfigCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup.ListAllPkgs = nil // disable '--list-all-pkgs' reportFlagGroup.ExitOnEOL = nil // disable '--exit-on-eol' reportFormat := flag.ReportFormatFlag - reportFormat.Usage = "specify a compliance report format for the output. (all,summary)" //@TODO: support --report summary for non compliance reports + reportFormat.Usage = "specify a compliance report format for the output" //@TODO: support --report summary for non compliance reports reportFlagGroup.ReportFormat = &reportFormat scanFlags := &flag.ScanFlagGroup{ @@ -895,16 +895,21 @@ func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup := flag.NewReportFlagGroup() compliance := flag.ComplianceFlag - compliance.Usage += fmt.Sprintf(" (%s,%s, %s, %s)", types.ComplianceK8sNsa, types.ComplianceK8sCIS, types.ComplianceK8sPSSBaseline, types.ComplianceK8sPSSRestricted) + compliance.Values = []string{ + types.ComplianceK8sNsa, + types.ComplianceK8sCIS, + types.ComplianceK8sPSSBaseline, + types.ComplianceK8sPSSRestricted, + } reportFlagGroup.Compliance = &compliance // override usage as the accepted values differ for each subcommand. reportFlagGroup.ExitOnEOL = nil // disable '--exit-on-eol' formatFlag := flag.FormatFlag - formatFlag.Usage = "format (" + strings.Join([]string{ + formatFlag.Values = []string{ r.FormatTable, r.FormatJSON, r.FormatCycloneDX, - }, ", ") + ")" + } reportFlagGroup.Format = &formatFlag k8sFlags := &flag.Flags{ @@ -968,7 +973,7 @@ func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { func NewAWSCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command { reportFlagGroup := flag.NewReportFlagGroup() compliance := flag.ComplianceFlag - compliance.Usage += fmt.Sprintf(" (%s, %s)", types.ComplianceAWSCIS12, types.ComplianceAWSCIS14) + compliance.Values = []string{types.ComplianceAWSCIS12, types.ComplianceAWSCIS14} reportFlagGroup.Compliance = &compliance // override usage as the accepted values differ for each subcommand. reportFlagGroup.ExitOnEOL = nil // disable '--exit-on-eol' diff --git a/pkg/flag/image_flags.go b/pkg/flag/image_flags.go index 876544816f4..35fb8e00137 100644 --- a/pkg/flag/image_flags.go +++ b/pkg/flag/image_flags.go @@ -2,7 +2,6 @@ package flag import ( v1 "github.com/google/go-containerregistry/pkg/v1" - "golang.org/x/exp/slices" "golang.org/x/xerrors" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" @@ -18,8 +17,12 @@ var ( ImageConfigScannersFlag = Flag{ Name: "image-config-scanners", ConfigName: "image.image-config-scanners", - Usage: "comma-separated list of what security issues to detect on container image configurations (config,secret)", Default: []string{}, + Values: types.Scanners{ + types.MisconfigScanner, + types.SecretScanner, + }.StringSlice(), + Usage: "comma-separated list of what security issues to detect on container image configurations", } ScanRemovedPkgsFlag = Flag{ Name: "removed-pkgs", @@ -48,8 +51,9 @@ var ( SourceFlag = Flag{ Name: "image-src", ConfigName: "image.source", - Usage: "image source(s) to use, in priority order (docker,containerd,podman,remote)", Default: ftypes.AllImageSources.StringSlice(), + Values: ftypes.AllImageSources.StringSlice(), + Usage: "image source(s) to use, in priority order", } ) @@ -98,16 +102,6 @@ func (f *ImageFlagGroup) Flags() []*Flag { } func (f *ImageFlagGroup) ToOptions() (ImageOptions, error) { - scanners, err := parseScanners(getStringSlice(f.ImageConfigScanners), types.AllImageConfigScanners) - if err != nil { - return ImageOptions{}, xerrors.Errorf("unable to parse image config scanners: %w", err) - } - - imageSources, err := parseImageSources(getStringSlice(f.ImageSources)) - if err != nil { - return ImageOptions{}, xerrors.Errorf("unable to parse image sources: %w", err) - } - var platform ftypes.Platform if p := getString(f.Platform); p != "" { pl, err := v1.ParsePlatform(p) @@ -122,22 +116,10 @@ func (f *ImageFlagGroup) ToOptions() (ImageOptions, error) { return ImageOptions{ Input: getString(f.Input), - ImageConfigScanners: scanners, + ImageConfigScanners: getUnderlyingStringSlice[types.Scanner](f.ImageConfigScanners), ScanRemovedPkgs: getBool(f.ScanRemovedPkgs), Platform: platform, DockerHost: getString(f.DockerHost), - ImageSources: imageSources, + ImageSources: getUnderlyingStringSlice[ftypes.ImageSource](f.ImageSources), }, nil } - -func parseImageSources(srcs []string) (ftypes.ImageSources, error) { - var imageSources ftypes.ImageSources - for _, s := range srcs { - src := ftypes.ImageSource(s) - if !slices.Contains(ftypes.AllImageSources, src) { - return nil, xerrors.Errorf("unknown image source: %s", s) - } - imageSources = append(imageSources, src) - } - return imageSources, nil -} diff --git a/pkg/flag/kubernetes_flags.go b/pkg/flag/kubernetes_flags.go index eb94d37c747..0645c45167a 100644 --- a/pkg/flag/kubernetes_flags.go +++ b/pkg/flag/kubernetes_flags.go @@ -42,6 +42,10 @@ var ( "workload", "infra", }, + Values: []string{ + "workload", + "infra", + }, Usage: "specify which components to scan", } K8sVersionFlag = Flag{ diff --git a/pkg/flag/options.go b/pkg/flag/options.go index 0f4db20e1c0..32b2e54c4b0 100644 --- a/pkg/flag/options.go +++ b/pkg/flag/options.go @@ -8,6 +8,7 @@ import ( "sync" "time" + "github.com/samber/lo" "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -21,6 +22,10 @@ import ( "github.com/aquasecurity/trivy/pkg/result" ) +type String interface { + ~string +} + type Flag struct { // Name is for CLI flag and environment variable. // If this field is empty, it will be available only in config file. @@ -35,6 +40,10 @@ type Flag struct { // Default is the default value. It must be filled to determine the flag type. Default any + // Values is a list of allowed values. + // It currently supports string flags and string slice flags only. + Values []string + // Usage explains how to use the flag. Usage string @@ -182,9 +191,17 @@ func addFlag(cmd *cobra.Command, flag *Flag) { case int: flags.IntP(flag.Name, flag.Shorthand, v, flag.Usage) case string: - flags.StringP(flag.Name, flag.Shorthand, v, flag.Usage) + usage := flag.Usage + if len(flag.Values) > 0 { + usage += fmt.Sprintf(" (%s)", strings.Join(flag.Values, ",")) + } + flags.VarP(newCustomStringValue(v, flag.Values), flag.Name, flag.Shorthand, usage) case []string: - flags.StringSliceP(flag.Name, flag.Shorthand, v, flag.Usage) + usage := flag.Usage + if len(flag.Values) > 0 { + usage += fmt.Sprintf(" (%s)", strings.Join(flag.Values, ",")) + } + flags.VarP(newCustomStringSliceValue(v, flag.Values), flag.Name, flag.Shorthand, usage) case bool: flags.BoolP(flag.Name, flag.Shorthand, v, flag.Usage) case time.Duration: @@ -266,6 +283,13 @@ func getStringSlice(flag *Flag) []string { return v } +func getUnderlyingStringSlice[T String](flag *Flag) []T { + ss := getStringSlice(flag) + return lo.Map(ss, func(s string, _ int) T { + return T(s) + }) +} + func getInt(flag *Flag) int { return cast.ToInt(getValue(flag)) } diff --git a/pkg/flag/report_flags.go b/pkg/flag/report_flags.go index 95f5bc0ea1b..56503009113 100644 --- a/pkg/flag/report_flags.go +++ b/pkg/flag/report_flags.go @@ -5,6 +5,7 @@ import ( "os" "strings" + "github.com/samber/lo" "golang.org/x/exp/slices" "golang.org/x/xerrors" @@ -26,14 +27,16 @@ var ( Name: "format", ConfigName: "format", Shorthand: "f", - Usage: "format (" + strings.Join(report.SupportedFormats, ", ") + ")", Default: report.FormatTable, + Values: report.SupportedFormats, + Usage: "format", } ReportFormatFlag = Flag{ Name: "report", ConfigName: "report", - Usage: "specify a report format for the output. (all,summary)", Default: "all", + Values: []string{"all", "summary"}, + Usage: "specify a report format for the output", } TemplateFlag = Flag{ Name: "template", @@ -89,8 +92,9 @@ var ( Name: "severity", ConfigName: "severity", Shorthand: "s", - Usage: "severities of security issues to be displayed (comma separated)", Default: dbTypes.SeverityNames, + Values: dbTypes.SeverityNames, + Usage: "severities of security issues to be displayed", } ComplianceFlag = Flag{ Name: "compliance", @@ -177,10 +181,6 @@ func (f *ReportFlagGroup) ToOptions(out io.Writer) (ReportOptions, error) { listAllPkgs := getBool(f.ListAllPkgs) output := getString(f.Output) - if format != "" && !slices.Contains(report.SupportedFormats, format) { - return ReportOptions{}, xerrors.Errorf("unknown format: %v", format) - } - if template != "" { if format == "" { log.Logger.Warn("'--template' is ignored because '--format template' is not specified. Use '--template' option with '--format template' option.") @@ -237,7 +237,7 @@ func (f *ReportFlagGroup) ToOptions(out io.Writer) (ReportOptions, error) { ExitOnEOL: getInt(f.ExitOnEOL), IgnorePolicy: getString(f.IgnorePolicy), Output: out, - Severities: splitSeverity(getStringSlice(f.Severity)), + Severities: toSeverity(getStringSlice(f.Severity)), Compliance: cs, }, nil } @@ -272,23 +272,13 @@ func (f *ReportFlagGroup) forceListAllPkgs(format string, listAllPkgs, dependenc return false } -func splitSeverity(severity []string) []dbTypes.Severity { - switch { - case len(severity) == 0: - return nil - case len(severity) == 1 && strings.Contains(severity[0], ","): // get severities from flag - severity = strings.Split(severity[0], ",") - } - - var severities []dbTypes.Severity - for _, s := range severity { - sev, err := dbTypes.NewSeverity(strings.ToUpper(s)) - if err != nil { - log.Logger.Warnf("unknown severity option: %s", err) - continue - } - severities = append(severities, sev) - } +func toSeverity(severity []string) []dbTypes.Severity { + severities := lo.Map(severity, func(s string, _ int) dbTypes.Severity { + // Note that there is no need to check the error here + // since the severity value is already validated in the flag parser. + sev, _ := dbTypes.NewSeverity(s) + return sev + }) log.Logger.Debugf("Severities: %q", severities) return severities } diff --git a/pkg/flag/scan_flags.go b/pkg/flag/scan_flags.go index 68028b8bd4e..0dd8fb1ca34 100644 --- a/pkg/flag/scan_flags.go +++ b/pkg/flag/scan_flags.go @@ -1,9 +1,6 @@ package flag import ( - "golang.org/x/exp/slices" - "golang.org/x/xerrors" - "github.com/aquasecurity/trivy/pkg/types" ) @@ -33,6 +30,11 @@ var ( types.VulnerabilityScanner, types.SecretScanner, }.StringSlice(), + Values: types.Scanners{ + types.VulnerabilityScanner, + types.MisconfigScanner, + types.SecretScanner, + types.LicenseScanner, }.StringSlice(), Aliases: []Alias{ { @@ -41,7 +43,7 @@ var ( Deprecated: true, // --security-checks was renamed to --scanners }, }, - Usage: "comma-separated list of what security issues to detect (vuln,config,secret,license)", + Usage: "comma-separated list of what security issues to detect", } FilePatternsFlag = Flag{ Name: "file-patterns", @@ -58,8 +60,9 @@ var ( SBOMSourcesFlag = Flag{ Name: "sbom-sources", ConfigName: "scan.sbom-sources", - Usage: "[EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)", Default: []string{}, + Values: []string{"oci", "rekor"}, + Usage: "[EXPERIMENTAL] try to retrieve SBOM from the specified sources", } RekorURLFlag = Flag{ Name: "rekor-url", @@ -137,47 +140,17 @@ func (f *ScanFlagGroup) ToOptions(args []string) (ScanOptions, error) { if len(args) == 1 { target = args[0] } - scanners, err := parseScanners(getStringSlice(f.Scanners), types.AllScanners) - if err != nil { - return ScanOptions{}, xerrors.Errorf("unable to parse scanners: %w", err) - } - - sbomSources := getStringSlice(f.SBOMSources) - if err = validateSBOMSources(sbomSources); err != nil { - return ScanOptions{}, xerrors.Errorf("unable to parse SBOM sources: %w", err) - } return ScanOptions{ Target: target, SkipDirs: getStringSlice(f.SkipDirs), SkipFiles: getStringSlice(f.SkipFiles), OfflineScan: getBool(f.OfflineScan), - Scanners: scanners, + Scanners: getUnderlyingStringSlice[types.Scanner](f.Scanners), FilePatterns: getStringSlice(f.FilePatterns), Slow: getBool(f.Slow), - SBOMSources: sbomSources, + SBOMSources: getStringSlice(f.SBOMSources), RekorURL: getString(f.RekorURL), IncludeDevDeps: getBool(f.IncludeDevDeps), }, nil } - -func parseScanners(scanner []string, allowedScanners []types.Scanner) (types.Scanners, error) { - var scanners types.Scanners - for _, v := range scanner { - s := types.Scanner(v) - if !slices.Contains(allowedScanners, s) { - return nil, xerrors.Errorf("unknown scanner: %s", v) - } - scanners = append(scanners, s) - } - return scanners, nil -} - -func validateSBOMSources(sbomSources []string) error { - for _, v := range sbomSources { - if !slices.Contains(types.SBOMSources, v) { - return xerrors.Errorf("unknown SBOM source: %s", v) - } - } - return nil -} diff --git a/pkg/flag/value.go b/pkg/flag/value.go new file mode 100644 index 00000000000..79081190c13 --- /dev/null +++ b/pkg/flag/value.go @@ -0,0 +1,91 @@ +package flag + +import ( + "strings" + + "golang.org/x/exp/slices" + "golang.org/x/xerrors" +) + +// -- string Value +type customStringValue struct { + value *string + allowed []string +} + +func newCustomStringValue(val string, allowed []string) *customStringValue { + return &customStringValue{ + value: &val, + allowed: allowed, + } +} + +func (s *customStringValue) Set(val string) error { + if len(s.allowed) > 0 && !slices.Contains(s.allowed, val) { + return xerrors.Errorf("must be one of %q", s.allowed) + } + s.value = &val + return nil +} +func (s *customStringValue) Type() string { + return "string" +} + +func (s *customStringValue) String() string { return *s.value } + +// -- stringSlice Value +type customStringSliceValue struct { + value *[]string + allowed []string + changed bool +} + +func newCustomStringSliceValue(val []string, allowed []string) *customStringSliceValue { + return &customStringSliceValue{ + value: &val, + allowed: allowed, + } +} + +func (s *customStringSliceValue) Set(val string) error { + values := strings.Split(val, ",") + for _, v := range values { + if len(s.allowed) > 0 && !slices.Contains(s.allowed, v) { + return xerrors.Errorf("must be one of %q", s.allowed) + } + } + if !s.changed { + *s.value = values + } else { + *s.value = append(*s.value, values...) + } + s.changed = true + return nil +} + +func (s *customStringSliceValue) Type() string { + return "stringSlice" +} + +func (s *customStringSliceValue) String() string { + if len(*s.value) == 0 { + // "[]" is not recognized as a zero value + // cf. https://github.com/spf13/pflag/blob/d5e0c0615acee7028e1e2740a11102313be88de1/flag.go#L553-L565 + return "" + } + return "[" + strings.Join(*s.value, ",") + "]" +} + +func (s *customStringSliceValue) Append(val string) error { + s.changed = true + return s.Set(val) +} + +func (s *customStringSliceValue) Replace(val []string) error { + *s.value = val + return nil +} + +func (s *customStringSliceValue) GetSlice() []string { + return *s.value +} diff --git a/pkg/flag/vulnerability_flags.go b/pkg/flag/vulnerability_flags.go index 955ecba9de7..4c4a32a2bce 100644 --- a/pkg/flag/vulnerability_flags.go +++ b/pkg/flag/vulnerability_flags.go @@ -15,7 +15,11 @@ var ( types.VulnTypeOS, types.VulnTypeLibrary, }, - Usage: "comma-separated list of vulnerability types (os,library)", + Values: []string{ + types.VulnTypeOS, + types.VulnTypeLibrary, + }, + Usage: "comma-separated list of vulnerability types", } IgnoreUnfixedFlag = Flag{ Name: "ignore-unfixed", From 9d93e01c7ec86f57e282ad5334df762aeb21c8a2 Mon Sep 17 00:00:00 2001 From: knqyf263 Date: Wed, 5 Jul 2023 16:30:42 +0300 Subject: [PATCH 3/5] docs: auto-generate --- docs/docs/references/configuration/cli/trivy_aws.md | 8 ++++---- docs/docs/references/configuration/cli/trivy_config.md | 6 +++--- .../docs/references/configuration/cli/trivy_convert.md | 6 +++--- .../references/configuration/cli/trivy_filesystem.md | 6 +++--- docs/docs/references/configuration/cli/trivy_image.md | 8 ++++---- .../references/configuration/cli/trivy_kubernetes.md | 10 +++++----- .../references/configuration/cli/trivy_repository.md | 4 ++-- docs/docs/references/configuration/cli/trivy_rootfs.md | 4 ++-- docs/docs/references/configuration/cli/trivy_sbom.md | 4 ++-- docs/docs/references/configuration/cli/trivy_vm.md | 4 ++-- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/docs/references/configuration/cli/trivy_aws.md b/docs/docs/references/configuration/cli/trivy_aws.md index 9b9b0cf66b4..d9bb624d6ce 100644 --- a/docs/docs/references/configuration/cli/trivy_aws.md +++ b/docs/docs/references/configuration/cli/trivy_aws.md @@ -67,13 +67,13 @@ trivy aws [flags] ``` --account string The AWS account to scan. It's useful to specify this when reviewing cached results for multiple accounts. --arn string The AWS ARN to show results for. Useful to filter results once a scan is cached. - --compliance string compliance report to generate (aws-cis-1.2, aws-cis-1.4) + --compliance string compliance report to generate (aws-cis-1.2,aws-cis-1.4) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --endpoint string AWS Endpoint override --exit-code int specify exit code when any security issues are found - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -87,10 +87,10 @@ trivy aws [flags] -o, --output string output file name --policy-namespaces strings Rego namespaces --region string AWS Region to scan - --report string specify a report format for the output. (all,summary) (default "all") + --report string specify a report format for the output (all,summary) (default "all") --reset-policy-bundle remove policy bundle --service strings Only scan AWS Service(s) specified with this flag. Can specify multiple services using --service A --service B etc. - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-policy-update skip fetching rego policy updates --skip-service strings Skip selected AWS Service(s) specified with this flag. Can specify multiple services using --skip-service A --skip-service B etc. -t, --template string output template diff --git a/docs/docs/references/configuration/cli/trivy_config.md b/docs/docs/references/configuration/cli/trivy_config.md index 16c2d10bd42..236f0f56864 100644 --- a/docs/docs/references/configuration/cli/trivy_config.md +++ b/docs/docs/references/configuration/cli/trivy_config.md @@ -18,7 +18,7 @@ trivy config [flags] DIR --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -36,9 +36,9 @@ trivy config [flags] DIR --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token - --report string specify a compliance report format for the output. (all,summary) (default "all") + --report string specify a compliance report format for the output (all,summary) (default "all") --reset-policy-bundle remove policy bundle - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-policy-update skip fetching rego policy updates diff --git a/docs/docs/references/configuration/cli/trivy_convert.md b/docs/docs/references/configuration/cli/trivy_convert.md index 9266fcdb334..9ef4cc5583b 100644 --- a/docs/docs/references/configuration/cli/trivy_convert.md +++ b/docs/docs/references/configuration/cli/trivy_convert.md @@ -22,14 +22,14 @@ trivy convert [flags] RESULT_JSON --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") -h, --help help for convert --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignorefile string specify .trivyignore file (default ".trivyignore") --list-all-pkgs enabling the option will output all packages regardless of vulnerability -o, --output string output file name - --report string specify a report format for the output. (all,summary) (default "all") - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + --report string specify a report format for the output (all,summary) (default "all") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) -t, --template string output template ``` diff --git a/docs/docs/references/configuration/cli/trivy_filesystem.md b/docs/docs/references/configuration/cli/trivy_filesystem.md index 462ea894f73..6c2733dc000 100644 --- a/docs/docs/references/configuration/cli/trivy_filesystem.md +++ b/docs/docs/references/configuration/cli/trivy_filesystem.md @@ -33,7 +33,7 @@ trivy filesystem [flags] PATH --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -61,14 +61,14 @@ trivy filesystem [flags] PATH --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --report string specify a compliance report format for the output. (all,summary) (default "all") + --report string specify a compliance report format for the output (all,summary) (default "all") --reset remove all caches and database --reset-policy-bundle remove policy bundle --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml") --server string server address in client mode - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md index d8e184f60a1..e78c7b6f794 100644 --- a/docs/docs/references/configuration/cli/trivy_image.md +++ b/docs/docs/references/configuration/cli/trivy_image.md @@ -50,7 +50,7 @@ trivy image [flags] IMAGE_NAME --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -60,7 +60,7 @@ trivy image [flags] IMAGE_NAME --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default ".trivyignore") - --image-config-scanners string comma-separated list of what security issues to detect on container image configurations (config,secret) + --image-config-scanners strings comma-separated list of what security issues to detect on container image configurations (config,secret) --image-src strings image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote]) --include-non-failures include successes and exceptions, available with '--scanners config' --input string input file path instead of image name @@ -82,14 +82,14 @@ trivy image [flags] IMAGE_NAME --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") --removed-pkgs detect vulnerabilities of removed packages (only for Alpine) - --report string specify a format for the compliance report. (default "summary") + --report string specify a format for the compliance report. (all,summary) (default "summary") --reset remove all caches and database --reset-policy-bundle remove policy bundle --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml") --server string server address in client mode - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index eeec316ac62..a34502db721 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -31,8 +31,8 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning - --compliance string compliance report to generate (k8s-nsa,k8s-cis, k8s-pss-baseline, k8s-pss-restricted) - --components strings specify which components to scan (default [workload,infra]) + --compliance string compliance report to generate (k8s-nsa,k8s-cis,k8s-pss-baseline,k8s-pss-restricted) + --components strings specify which components to scan (workload,infra) (default [workload,infra]) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --context string specify a context to scan @@ -43,7 +43,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --exclude-nodes strings indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev) --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns - -f, --format string format (table, json, cyclonedx) (default "table") + -f, --format string format (table,json,cyclonedx) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -72,13 +72,13 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --report string specify a report format for the output. (all,summary) (default "all") + --report string specify a report format for the output (all,summary) (default "all") --reset remove all caches and database --reset-policy-bundle remove policy bundle --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners string comma-separated list of what security issues to detect (vuln,config,secret,license) (default "vuln,config,secret,rbac") --secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml") - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal diff --git a/docs/docs/references/configuration/cli/trivy_repository.md b/docs/docs/references/configuration/cli/trivy_repository.md index 7733aa2667d..5c41d75b33f 100644 --- a/docs/docs/references/configuration/cli/trivy_repository.md +++ b/docs/docs/references/configuration/cli/trivy_repository.md @@ -31,7 +31,7 @@ trivy repository [flags] REPO_URL --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -64,7 +64,7 @@ trivy repository [flags] REPO_URL --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml") --server string server address in client mode - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal diff --git a/docs/docs/references/configuration/cli/trivy_rootfs.md b/docs/docs/references/configuration/cli/trivy_rootfs.md index 587cd5be7e5..de9a76bfd00 100644 --- a/docs/docs/references/configuration/cli/trivy_rootfs.md +++ b/docs/docs/references/configuration/cli/trivy_rootfs.md @@ -36,7 +36,7 @@ trivy rootfs [flags] ROOTDIR --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -69,7 +69,7 @@ trivy rootfs [flags] ROOTDIR --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml") --server string server address in client mode - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal diff --git a/docs/docs/references/configuration/cli/trivy_sbom.md b/docs/docs/references/configuration/cli/trivy_sbom.md index f9dc89010d1..e8dac626e7c 100644 --- a/docs/docs/references/configuration/cli/trivy_sbom.md +++ b/docs/docs/references/configuration/cli/trivy_sbom.md @@ -31,7 +31,7 @@ trivy sbom [flags] SBOM_PATH --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") -h, --help help for sbom --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities @@ -49,7 +49,7 @@ trivy sbom [flags] SBOM_PATH --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --server string server address in client mode - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal diff --git a/docs/docs/references/configuration/cli/trivy_vm.md b/docs/docs/references/configuration/cli/trivy_vm.md index 3b7a4430c14..854a7c6c490 100644 --- a/docs/docs/references/configuration/cli/trivy_vm.md +++ b/docs/docs/references/configuration/cli/trivy_vm.md @@ -34,7 +34,7 @@ trivy vm [flags] VM_IMAGE --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns - -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table") + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -61,7 +61,7 @@ trivy vm [flags] VM_IMAGE --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml") --server string server address in client mode - -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal From 67fecc1897a12afcc9e1cbaa3498c88265f77acc Mon Sep 17 00:00:00 2001 From: knqyf263 Date: Wed, 5 Jul 2023 16:47:17 +0300 Subject: [PATCH 4/5] test: fix --- pkg/flag/options.go | 3 +++ pkg/flag/report_flags.go | 3 +++ pkg/flag/report_flags_test.go | 29 +---------------------------- pkg/flag/scan_flags_test.go | 10 ---------- 4 files changed, 7 insertions(+), 38 deletions(-) diff --git a/pkg/flag/options.go b/pkg/flag/options.go index 32b2e54c4b0..ae6f076c387 100644 --- a/pkg/flag/options.go +++ b/pkg/flag/options.go @@ -285,6 +285,9 @@ func getStringSlice(flag *Flag) []string { func getUnderlyingStringSlice[T String](flag *Flag) []T { ss := getStringSlice(flag) + if len(ss) == 0 { + return nil + } return lo.Map(ss, func(s string, _ int) T { return T(s) }) diff --git a/pkg/flag/report_flags.go b/pkg/flag/report_flags.go index 56503009113..d180b916ef2 100644 --- a/pkg/flag/report_flags.go +++ b/pkg/flag/report_flags.go @@ -273,6 +273,9 @@ func (f *ReportFlagGroup) forceListAllPkgs(format string, listAllPkgs, dependenc } func toSeverity(severity []string) []dbTypes.Severity { + if len(severity) == 0 { + return nil + } severities := lo.Map(severity, func(s string, _ int) dbTypes.Severity { // Note that there is no need to check the error here // since the severity value is already validated in the flag parser. diff --git a/pkg/flag/report_flags_test.go b/pkg/flag/report_flags_test.go index e2fbab4ab98..2ff9743e5fa 100644 --- a/pkg/flag/report_flags_test.go +++ b/pkg/flag/report_flags_test.go @@ -48,33 +48,6 @@ func TestReportFlagGroup_ToOptions(t *testing.T) { Output: os.Stdout, }, }, - { - name: "happy path with a low case severity", - fields: fields{ - severities: "critical", - }, - want: flag.ReportOptions{ - Output: os.Stdout, - Severities: []dbTypes.Severity{ - dbTypes.SeverityCritical, - }, - }, - }, - { - name: "happy path with an unknown severity", - fields: fields{ - severities: "CRITICAL,INVALID", - }, - want: flag.ReportOptions{ - Output: os.Stdout, - Severities: []dbTypes.Severity{ - dbTypes.SeverityCritical, - }, - }, - wantLogs: []string{ - "unknown severity option: unknown severity: INVALID", - }, - }, { name: "happy path with an cyclonedx", fields: fields{ @@ -179,7 +152,7 @@ func TestReportFlagGroup_ToOptions(t *testing.T) { name: "happy path with compliance", fields: fields{ compliane: "@testdata/example-spec.yaml", - severities: "low", + severities: dbTypes.SeverityLow.String(), }, want: flag.ReportOptions{ Output: os.Stdout, diff --git a/pkg/flag/scan_flags_test.go b/pkg/flag/scan_flags_test.go index b2e74f28f24..1490ea3bf42 100644 --- a/pkg/flag/scan_flags_test.go +++ b/pkg/flag/scan_flags_test.go @@ -46,16 +46,6 @@ func TestScanFlagGroup_ToOptions(t *testing.T) { }, assertion: require.NoError, }, - { - name: "with wrong scanner", - fields: fields{ - scanners: "vuln,WRONG-CHECK", - }, - want: flag.ScanOptions{}, - assertion: func(t require.TestingT, err error, msgs ...interface{}) { - require.ErrorContains(t, err, "unknown scanner: WRONG-CHECK") - }, - }, { name: "without target (args)", args: []string{}, From ebe43537fee9cfd05e8b7385481c30cbbfb33d67 Mon Sep 17 00:00:00 2001 From: knqyf263 Date: Sun, 16 Jul 2023 10:59:54 +0300 Subject: [PATCH 5/5] test: add tests for flags --- pkg/commands/app_test.go | 131 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/pkg/commands/app_test.go b/pkg/commands/app_test.go index acd4c19bbce..5b4661c382e 100644 --- a/pkg/commands/app_test.go +++ b/pkg/commands/app_test.go @@ -2,10 +2,16 @@ package commands import ( "bytes" + "io" "testing" + "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + dbTypes "github.com/aquasecurity/trivy-db/pkg/types" + "github.com/aquasecurity/trivy/pkg/flag" + "github.com/aquasecurity/trivy/pkg/report" ) func Test_showVersion(t *testing.T) { @@ -161,3 +167,128 @@ Policy Bundle: }) } } + +func TestFlags(t *testing.T) { + type want struct { + format string + severities []dbTypes.Severity + } + tests := []struct { + name string + arguments []string // 1st argument is path to trivy binaries + want want + wantErr string + }{ + { + name: "happy path", + arguments: []string{ + "test", + }, + want: want{ + format: report.FormatTable, + severities: []dbTypes.Severity{ + dbTypes.SeverityUnknown, + dbTypes.SeverityLow, + dbTypes.SeverityMedium, + dbTypes.SeverityHigh, + dbTypes.SeverityCritical, + }, + }, + }, + { + name: "happy path with comma-separated severities", + arguments: []string{ + "test", + "--severity", + "LOW,MEDIUM", + }, + want: want{ + format: report.FormatTable, + severities: []dbTypes.Severity{ + dbTypes.SeverityLow, + dbTypes.SeverityMedium, + }, + }, + }, + { + name: "happy path with repeated severities", + arguments: []string{ + "test", + "--severity", + "LOW", + "--severity", + "HIGH", + }, + want: want{ + format: report.FormatTable, + severities: []dbTypes.Severity{ + dbTypes.SeverityLow, + dbTypes.SeverityHigh, + }, + }, + }, + { + name: "happy path with json", + arguments: []string{ + "test", + "--format", + "json", + "--severity", + "CRITICAL", + }, + want: want{ + format: report.FormatJSON, + severities: []dbTypes.Severity{ + dbTypes.SeverityCritical, + }, + }, + }, + { + name: "invalid format", + arguments: []string{ + "test", + "--format", + "foo", + }, + wantErr: `invalid argument "foo" for "-f, --format" flag`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + globalFlags := flag.NewGlobalFlagGroup() + rootCmd := NewRootCommand("dev", globalFlags) + rootCmd.SetErr(io.Discard) + SetOut(io.Discard) + + flags := &flag.Flags{ + ReportFlagGroup: flag.NewReportFlagGroup(), + } + cmd := &cobra.Command{ + Use: "test", + RunE: func(cmd *cobra.Command, args []string) error { + // Bind + require.NoError(t, flags.Bind(cmd)) + + options, err := flags.ToOptions("dev", args, globalFlags, nil) + require.NoError(t, err) + + assert.Equal(t, tt.want.format, options.Format) + assert.Equal(t, tt.want.severities, options.Severities) + return nil + }, + } + flags.AddFlags(cmd) + rootCmd.AddCommand(cmd) + + rootCmd.SetArgs(tt.arguments) + + err := rootCmd.Execute() + if tt.wantErr != "" { + assert.ErrorContains(t, err, tt.wantErr) + return + } + require.NoError(t, err) + }) + } +}