refactor: add allowed values for CLI flags (#4800)

* refactor: rename Value to Default

* refactor: support allowed values for CLI flags

* docs: auto-generate

* test: fix

* test: add tests for flags
This commit is contained in:
Teppei Fukuda
2023-07-17 16:13:23 +03:00
committed by GitHub
parent 4cecd17ea5
commit aca11b95d0
38 changed files with 468 additions and 294 deletions

View File

@@ -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 the paths to the Rego policy files or to the directories containing them, 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

View File

@@ -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

View File

@@ -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
```

View File

@@ -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

View File

@@ -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

View File

@@ -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 the paths to the Rego policy files or to the directories containing them, 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

6
go.mod
View File

@@ -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

12
go.sum
View File

@@ -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=

View File

@@ -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

View File

@@ -246,12 +246,12 @@ 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
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'
@@ -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.
@@ -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{
@@ -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,
@@ -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'
@@ -1047,7 +1052,7 @@ func NewVMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
Region: &flag.Flag{
Name: "aws-region",
ConfigName: "aws.region",
Value: "",
Default: "",
Usage: "AWS region to scan",
},
},

View File

@@ -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)
})
}
}

View File

@@ -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.",
}
)

View File

@@ -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",
}
)

View File

@@ -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.",
}
)

View File

@@ -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,
}

View File

@@ -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,
}

View File

@@ -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,38 +17,43 @@ 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{},
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",
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(),
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
}

View File

@@ -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,23 @@ 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",
},
Values: []string{
"workload",
"infra",
},
@@ -47,38 +51,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)",
}
)

View File

@@ -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",
}
)

View File

@@ -10,49 +10,49 @@ 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",
}
TerraformExcludeDownloaded = Flag{
Name: "tf-exclude-downloaded-modules",
ConfigName: "misconfiguration.terraform.exclude-downloaded-modules",
Value: false,
Default: false,
Usage: "remove results for downloaded modules in .terraform folder",
}
)

View File

@@ -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,
}

View File

@@ -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.
@@ -32,8 +37,12 @@ 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
// 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
@@ -178,13 +187,21 @@ 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:
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:
@@ -203,7 +220,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
}
@@ -266,6 +283,16 @@ func getStringSlice(flag *Flag) []string {
return v
}
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)
})
}
func getInt(flag *Flag) int {
return cast.ToInt(getValue(flag))
}

View File

@@ -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",
}
)

View File

@@ -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 the paths to the Rego policy files or to the directories containing them, 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"},

View File

@@ -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",
}
)

View File

@@ -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",
}
)

View File

@@ -5,6 +5,7 @@ import (
"os"
"strings"
"github.com/samber/lo"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
@@ -26,76 +27,79 @@ var (
Name: "format",
ConfigName: "format",
Shorthand: "f",
Value: report.FormatTable,
Usage: "format (" + strings.Join(report.SupportedFormats, ", ") + ")",
Default: report.FormatTable,
Values: report.SupportedFormats,
Usage: "format",
}
ReportFormatFlag = Flag{
Name: "report",
ConfigName: "report",
Value: "all",
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",
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,
Values: dbTypes.SeverityNames,
Usage: "severities of security issues to be displayed",
}
ComplianceFlag = Flag{
Name: "compliance",
ConfigName: "scan.compliance",
Value: "",
Default: "",
Usage: "compliance report to generate",
}
)
@@ -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,16 @@ func (f *ReportFlagGroup) forceListAllPkgs(format string, listAllPkgs, dependenc
return false
}
func splitSeverity(severity []string) []dbTypes.Severity {
switch {
case len(severity) == 0:
func toSeverity(severity []string) []dbTypes.Severity {
if 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)
}
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
}

View File

@@ -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,

View File

@@ -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",
}
)

View File

@@ -1,9 +1,6 @@
package flag
import (
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/types"
)
@@ -11,28 +8,34 @@ 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(),
Values: types.Scanners{
types.VulnerabilityScanner,
types.MisconfigScanner,
types.SecretScanner,
types.LicenseScanner,
}.StringSlice(),
Aliases: []Alias{
{
Name: "security-checks",
@@ -40,36 +43,37 @@ 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",
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{},
Values: []string{"oci", "rekor"},
Usage: "[EXPERIMENTAL] try to retrieve SBOM from the specified sources",
}
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)",
}
)
@@ -136,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
}

View File

@@ -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{},

View File

@@ -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",
}
)

91
pkg/flag/value.go Normal file
View File

@@ -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
}

View File

@@ -11,16 +11,20 @@ var (
VulnTypeFlag = Flag{
Name: "vuln-type",
ConfigName: "vulnerability.type",
Value: []string{
Default: []string{
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",
ConfigName: "vulnerability.ignore-unfixed",
Value: false,
Default: false,
Usage: "display only fixed vulnerabilities",
}
)