mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-23 07:29:00 -08:00
BREAKING: support exclude kinds/namespaces and include kinds/namespaces (#6323)
Signed-off-by: chenk <hen.keinan@gmail.com>
This commit is contained in:
@@ -2,32 +2,33 @@
|
|||||||
|
|
||||||
[EXPERIMENTAL] Scan kubernetes cluster
|
[EXPERIMENTAL] Scan kubernetes cluster
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Default context in kube configuration will be used unless specified
|
||||||
|
|
||||||
```
|
```
|
||||||
trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: pods, pod/NAME }
|
trivy kubernetes [flags] [CONTEXT]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```
|
```
|
||||||
# cluster scanning
|
# cluster scanning
|
||||||
$ trivy k8s --report summary cluster
|
$ trivy k8s --report summary
|
||||||
|
|
||||||
# namespace scanning:
|
# cluster scanning with specific namespace:
|
||||||
$ trivy k8s -n kube-system --report summary all
|
$ trivy k8s --include-namespaces kube-system --report summary
|
||||||
|
|
||||||
|
# cluster with specific context:
|
||||||
|
$ trivy k8s kind-kind --report summary
|
||||||
|
|
||||||
# resources scanning:
|
|
||||||
$ trivy k8s --report=summary deploy
|
|
||||||
$ trivy k8s --namespace=kube-system --report=summary deploy,configmaps
|
|
||||||
|
|
||||||
# resource scanning:
|
|
||||||
$ trivy k8s deployment/orion
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-A, --all-namespaces fetch resources from all cluster namespaces
|
|
||||||
--burst int specify the maximum burst for throttle (default 10)
|
--burst int specify the maximum burst for throttle (default 10)
|
||||||
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
||||||
--cache-ttl duration cache TTL when using redis as cache backend
|
--cache-ttl duration cache TTL when using redis as cache backend
|
||||||
@@ -36,11 +37,12 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg:
|
|||||||
--components strings specify which components to scan (workload,infra) (default [workload,infra])
|
--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-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
|
--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
|
|
||||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
||||||
--dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages
|
--dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages
|
||||||
--download-db-only download/update vulnerability database but don't run a scan
|
--download-db-only download/update vulnerability database but don't run a scan
|
||||||
--download-java-db-only download/update Java index database but don't run a scan
|
--download-java-db-only download/update Java index database but don't run a scan
|
||||||
|
--exclude-kinds strings indicate the kinds exclude from scanning (example: node)
|
||||||
|
--exclude-namespaces strings indicate the namespaces excluded from scanning (example: kube-system)
|
||||||
--exclude-nodes strings indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)
|
--exclude-nodes strings indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)
|
||||||
--exclude-owned exclude resources that have an owner reference
|
--exclude-owned exclude resources that have an owner reference
|
||||||
--exit-code int specify exit code when any security issues are found
|
--exit-code int specify exit code when any security issues are found
|
||||||
@@ -58,13 +60,14 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg:
|
|||||||
--ignore-unfixed display only fixed vulnerabilities
|
--ignore-unfixed display only fixed vulnerabilities
|
||||||
--ignorefile string specify .trivyignore file (default ".trivyignore")
|
--ignorefile string specify .trivyignore file (default ".trivyignore")
|
||||||
--image-src strings image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])
|
--image-src strings image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])
|
||||||
|
--include-kinds strings indicate the kinds included in scanning (example: node)
|
||||||
|
--include-namespaces strings indicate the namespaces included in scanning (example: kube-system)
|
||||||
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
|
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
|
||||||
--java-db-repository string OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db:1")
|
--java-db-repository string OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db:1")
|
||||||
--k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0)
|
--k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0)
|
||||||
--kubeconfig string specify the kubeconfig file path to use
|
--kubeconfig string specify the kubeconfig file path to use
|
||||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability
|
--list-all-pkgs enabling the option will output all packages regardless of vulnerability
|
||||||
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
|
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
|
||||||
-n, --namespace string specify a namespace to scan
|
|
||||||
--no-progress suppress progress bar
|
--no-progress suppress progress bar
|
||||||
--node-collector-imageref string indicate the image reference for the node-collector scan job (default "ghcr.io/aquasecurity/node-collector:0.0.9")
|
--node-collector-imageref string indicate the image reference for the node-collector scan job (default "ghcr.io/aquasecurity/node-collector:0.0.9")
|
||||||
--node-collector-namespace string specify the namespace in which the node-collector job should be deployed (default "trivy-temp")
|
--node-collector-namespace string specify the namespace in which the node-collector job should be deployed (default "trivy-temp")
|
||||||
|
|||||||
22
go.mod
22
go.mod
@@ -26,7 +26,7 @@ require (
|
|||||||
github.com/aquasecurity/trivy-aws v0.8.0
|
github.com/aquasecurity/trivy-aws v0.8.0
|
||||||
github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d
|
github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d
|
||||||
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48
|
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48
|
||||||
github.com/aquasecurity/trivy-kubernetes v0.6.3
|
github.com/aquasecurity/trivy-kubernetes v0.6.6
|
||||||
github.com/aquasecurity/trivy-policies v0.10.0
|
github.com/aquasecurity/trivy-policies v0.10.0
|
||||||
github.com/aws/aws-sdk-go-v2 v1.26.1
|
github.com/aws/aws-sdk-go-v2 v1.26.1
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.10
|
github.com/aws/aws-sdk-go-v2/config v1.27.10
|
||||||
@@ -50,8 +50,8 @@ require (
|
|||||||
github.com/go-openapi/strfmt v0.23.0
|
github.com/go-openapi/strfmt v0.23.0
|
||||||
github.com/go-redis/redis/v8 v8.11.5
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||||
github.com/golang/protobuf v1.5.3
|
github.com/golang/protobuf v1.5.4
|
||||||
github.com/google/go-containerregistry v0.19.0
|
github.com/google/go-containerregistry v0.19.1
|
||||||
github.com/google/licenseclassifier/v2 v2.0.0
|
github.com/google/licenseclassifier/v2 v2.0.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/google/wire v0.6.0
|
github.com/google/wire v0.6.0
|
||||||
@@ -105,7 +105,7 @@ require (
|
|||||||
github.com/xeipuuv/gojsonschema v1.2.0
|
github.com/xeipuuv/gojsonschema v1.2.0
|
||||||
github.com/xlab/treeprint v1.2.0
|
github.com/xlab/treeprint v1.2.0
|
||||||
go.etcd.io/bbolt v1.3.9
|
go.etcd.io/bbolt v1.3.9
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||||
golang.org/x/mod v0.16.0
|
golang.org/x/mod v0.16.0
|
||||||
golang.org/x/net v0.23.0
|
golang.org/x/net v0.23.0
|
||||||
@@ -115,7 +115,7 @@ require (
|
|||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
|
||||||
google.golang.org/protobuf v1.33.0
|
google.golang.org/protobuf v1.33.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
k8s.io/api v0.29.1
|
k8s.io/api v0.29.3
|
||||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661
|
k8s.io/utils v0.0.0-20231127182322-b307cd553661
|
||||||
modernc.org/sqlite v1.29.7
|
modernc.org/sqlite v1.29.7
|
||||||
)
|
)
|
||||||
@@ -177,7 +177,7 @@ require (
|
|||||||
github.com/antchfx/xpath v1.2.3 // indirect
|
github.com/antchfx/xpath v1.2.3 // indirect
|
||||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
github.com/aws/aws-sdk-go v1.49.21 // indirect
|
github.com/aws/aws-sdk-go v1.51.16 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
|
||||||
@@ -411,14 +411,14 @@ require (
|
|||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
k8s.io/apiextensions-apiserver v0.29.0 // indirect
|
k8s.io/apiextensions-apiserver v0.29.0 // indirect
|
||||||
k8s.io/apimachinery v0.29.1 // indirect
|
k8s.io/apimachinery v0.29.3 // indirect
|
||||||
k8s.io/apiserver v0.29.0 // indirect
|
k8s.io/apiserver v0.29.0 // indirect
|
||||||
k8s.io/cli-runtime v0.29.0 // indirect
|
k8s.io/cli-runtime v0.29.3 // indirect
|
||||||
k8s.io/client-go v0.29.0 // indirect
|
k8s.io/client-go v0.29.3 // indirect
|
||||||
k8s.io/component-base v0.29.0 // indirect
|
k8s.io/component-base v0.29.3 // indirect
|
||||||
k8s.io/klog/v2 v2.120.0 // indirect
|
k8s.io/klog/v2 v2.120.0 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
||||||
k8s.io/kubectl v0.29.0 // indirect
|
k8s.io/kubectl v0.29.3 // indirect
|
||||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||||
modernc.org/libc v1.49.3 // indirect
|
modernc.org/libc v1.49.3 // indirect
|
||||||
modernc.org/mathutil v1.6.0 // indirect
|
modernc.org/mathutil v1.6.0 // indirect
|
||||||
|
|||||||
40
go.sum
40
go.sum
@@ -349,8 +349,8 @@ github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTU
|
|||||||
github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs=
|
github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs=
|
||||||
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI=
|
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI=
|
||||||
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8=
|
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8=
|
||||||
github.com/aquasecurity/trivy-kubernetes v0.6.3 h1:Hmo0pefXRsyVYsii62WUQyt3xMHjm37ipPESeWM/LNA=
|
github.com/aquasecurity/trivy-kubernetes v0.6.6 h1:90Y3FH7Mrh+M06+RyLhl26HA06kWbhvTWwKWpt9jE0M=
|
||||||
github.com/aquasecurity/trivy-kubernetes v0.6.3/go.mod h1:v6B8SO2ep718ccGbbjhpzMn6p27IijS+dMb+MeYz3jQ=
|
github.com/aquasecurity/trivy-kubernetes v0.6.6/go.mod h1:+NJBTgQErUmq21Ag71q/EuXZKIP+/OJvBAR0G+YUkKo=
|
||||||
github.com/aquasecurity/trivy-policies v0.10.0 h1:QONOsIFi6+WyB+7NGMBQeCgMFcRg6RV9dTBBpeOFDxU=
|
github.com/aquasecurity/trivy-policies v0.10.0 h1:QONOsIFi6+WyB+7NGMBQeCgMFcRg6RV9dTBBpeOFDxU=
|
||||||
github.com/aquasecurity/trivy-policies v0.10.0/go.mod h1:7WU0GTUqtQxqQ+FV3JAy7lskQQZU6lp7Mz1i8GEapFw=
|
github.com/aquasecurity/trivy-policies v0.10.0/go.mod h1:7WU0GTUqtQxqQ+FV3JAy7lskQQZU6lp7Mz1i8GEapFw=
|
||||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||||
@@ -366,8 +366,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
|
|||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
||||||
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||||
github.com/aws/aws-sdk-go v1.49.21 h1:Rl8KW6HqkwzhATwvXhyr7vD4JFUMi7oXGAw9SrxxIFY=
|
github.com/aws/aws-sdk-go v1.51.16 h1:vnWKK8KjbftEkuPX8bRj3WHsLy1uhotn0eXptpvrxJI=
|
||||||
github.com/aws/aws-sdk-go v1.49.21/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
github.com/aws/aws-sdk-go v1.51.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA=
|
github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
|
github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to=
|
||||||
@@ -948,8 +948,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
|||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
@@ -981,8 +981,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
|||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw=
|
github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw=
|
||||||
github.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic=
|
github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY=
|
||||||
github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
|
github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
@@ -2476,32 +2476,32 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
|||||||
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||||
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||||
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
||||||
k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw=
|
k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
|
||||||
k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ=
|
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
|
||||||
k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0=
|
k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0=
|
||||||
k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc=
|
k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc=
|
||||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||||
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||||
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||||
k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc=
|
k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU=
|
||||||
k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
|
k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU=
|
||||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||||
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
|
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
|
||||||
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
|
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
|
||||||
k8s.io/apiserver v0.29.0 h1:Y1xEMjJkP+BIi0GSEv1BBrf1jLU9UPfAnnGGbbDdp7o=
|
k8s.io/apiserver v0.29.0 h1:Y1xEMjJkP+BIi0GSEv1BBrf1jLU9UPfAnnGGbbDdp7o=
|
||||||
k8s.io/apiserver v0.29.0/go.mod h1:31n78PsRKPmfpee7/l9NYEv67u6hOL6AfcE761HapDM=
|
k8s.io/apiserver v0.29.0/go.mod h1:31n78PsRKPmfpee7/l9NYEv67u6hOL6AfcE761HapDM=
|
||||||
k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4=
|
k8s.io/cli-runtime v0.29.3 h1:r68rephmmytoywkw2MyJ+CxjpasJDQY7AGc3XY2iv1k=
|
||||||
k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk=
|
k8s.io/cli-runtime v0.29.3/go.mod h1:aqVUsk86/RhaGJwDhHXH0jcdqBrgdF3bZWk4Z9D4mkM=
|
||||||
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||||
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
|
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
|
||||||
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
|
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
|
||||||
k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8=
|
k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
|
||||||
k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38=
|
k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
|
||||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||||
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
|
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
|
||||||
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
|
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
|
||||||
k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s=
|
k8s.io/component-base v0.29.3 h1:Oq9/nddUxlnrCuuR2K/jp6aflVvc0uDvxMzAWxnGzAo=
|
||||||
k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M=
|
k8s.io/component-base v0.29.3/go.mod h1:Yuj33XXjuOk2BAaHsIGHhCKZQAgYKhqIxIjIr2UXYio=
|
||||||
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
|
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
|
||||||
k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||||
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||||
@@ -2514,8 +2514,8 @@ k8s.io/klog/v2 v2.120.0/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
|||||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
||||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
||||||
k8s.io/kubectl v0.29.0 h1:Oqi48gXjikDhrBF67AYuZRTcJV4lg2l42GmvsP7FmYI=
|
k8s.io/kubectl v0.29.3 h1:RuwyyIU42MAISRIePaa8Q7A3U74Q9P4MoJbDFz9o3us=
|
||||||
k8s.io/kubectl v0.29.0/go.mod h1:0jMjGWIcMIQzmUaMgAzhSELv5WtHo2a8pq67DtviAJs=
|
k8s.io/kubectl v0.29.3/go.mod h1:yCxfY1dbwgVdEt2zkJ6d5NNLOhhWgTyrqACIoFhpdd4=
|
||||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
|
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func TestK8s(t *testing.T) {
|
|||||||
"--cache-dir",
|
"--cache-dir",
|
||||||
cacheDir,
|
cacheDir,
|
||||||
"k8s",
|
"k8s",
|
||||||
"cluster",
|
"kind-kind-test",
|
||||||
"--report",
|
"--report",
|
||||||
"summary",
|
"summary",
|
||||||
"-q",
|
"-q",
|
||||||
@@ -39,10 +39,6 @@ func TestK8s(t *testing.T) {
|
|||||||
"5m0s",
|
"5m0s",
|
||||||
"--format",
|
"--format",
|
||||||
"json",
|
"json",
|
||||||
"--components",
|
|
||||||
"workload",
|
|
||||||
"--context",
|
|
||||||
"kind-kind-test",
|
|
||||||
"--output",
|
"--output",
|
||||||
outputFile,
|
outputFile,
|
||||||
}
|
}
|
||||||
@@ -79,12 +75,10 @@ func TestK8s(t *testing.T) {
|
|||||||
outputFile := filepath.Join(t.TempDir(), "output.json")
|
outputFile := filepath.Join(t.TempDir(), "output.json")
|
||||||
osArgs := []string{
|
osArgs := []string{
|
||||||
"k8s",
|
"k8s",
|
||||||
"cluster",
|
"kind-kind-test",
|
||||||
"--format",
|
"--format",
|
||||||
"cyclonedx",
|
"cyclonedx",
|
||||||
"-q",
|
"-q",
|
||||||
"--context",
|
|
||||||
"kind-kind-test",
|
|
||||||
"--output",
|
"--output",
|
||||||
outputFile,
|
outputFile,
|
||||||
}
|
}
|
||||||
@@ -111,51 +105,5 @@ func TestK8s(t *testing.T) {
|
|||||||
assert.True(t, lo.SomeBy(*got.Dependencies, func(r cdx.Dependency) bool {
|
assert.True(t, lo.SomeBy(*got.Dependencies, func(r cdx.Dependency) bool {
|
||||||
return len(*r.Dependencies) > 0
|
return len(*r.Dependencies) > 0
|
||||||
}))
|
}))
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("specific resource scan", func(t *testing.T) {
|
|
||||||
// Set up the output file
|
|
||||||
outputFile := filepath.Join(t.TempDir(), "output.json")
|
|
||||||
|
|
||||||
osArgs := []string{
|
|
||||||
"k8s",
|
|
||||||
"-n",
|
|
||||||
"default",
|
|
||||||
"deployments/nginx-deployment",
|
|
||||||
"-q",
|
|
||||||
"--timeout",
|
|
||||||
"5m0s",
|
|
||||||
"--format",
|
|
||||||
"json",
|
|
||||||
"--components",
|
|
||||||
"workload",
|
|
||||||
"--context",
|
|
||||||
"kind-kind-test",
|
|
||||||
"--output",
|
|
||||||
outputFile,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run Trivy
|
|
||||||
err := execute(osArgs)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
var got report.Report
|
|
||||||
f, err := os.Open(outputFile)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
err = json.NewDecoder(f).Decode(&got)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Flatten findings
|
|
||||||
results := lo.FlatMap(got.Resources, func(resource report.Resource, _ int) []types.Result {
|
|
||||||
return resource.Results
|
|
||||||
})
|
|
||||||
|
|
||||||
// Has vulnerabilities
|
|
||||||
assert.True(t, lo.SomeBy(results, func(r types.Result) bool {
|
|
||||||
return len(r.Vulnerabilities) > 0
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -934,22 +934,21 @@ func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
|||||||
VulnerabilityFlagGroup: flag.NewVulnerabilityFlagGroup(),
|
VulnerabilityFlagGroup: flag.NewVulnerabilityFlagGroup(),
|
||||||
}
|
}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "kubernetes [flags] { cluster | all | specific resources like kubectl. eg: pods, pod/NAME }",
|
Use: "kubernetes [flags] [CONTEXT]",
|
||||||
Aliases: []string{"k8s"},
|
Aliases: []string{"k8s"},
|
||||||
GroupID: groupScanning,
|
GroupID: groupScanning,
|
||||||
Short: "[EXPERIMENTAL] Scan kubernetes cluster",
|
Short: "[EXPERIMENTAL] Scan kubernetes cluster",
|
||||||
|
Long: `Default context in kube configuration will be used unless specified`,
|
||||||
Example: ` # cluster scanning
|
Example: ` # cluster scanning
|
||||||
$ trivy k8s --report summary cluster
|
$ trivy k8s --report summary
|
||||||
|
|
||||||
# namespace scanning:
|
# cluster scanning with specific namespace:
|
||||||
$ trivy k8s -n kube-system --report summary all
|
$ trivy k8s --include-namespaces kube-system --report summary
|
||||||
|
|
||||||
|
# cluster with specific context:
|
||||||
|
$ trivy k8s kind-kind --report summary
|
||||||
|
|
||||||
# resources scanning:
|
|
||||||
$ trivy k8s --report=summary deploy
|
|
||||||
$ trivy k8s --namespace=kube-system --report=summary deploy,configmaps
|
|
||||||
|
|
||||||
# resource scanning:
|
|
||||||
$ trivy k8s deployment/orion
|
|
||||||
`,
|
`,
|
||||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := k8sFlags.Bind(cmd); err != nil {
|
if err := k8sFlags.Bind(cmd); err != nil {
|
||||||
@@ -1236,7 +1235,7 @@ func validateArgs(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 && viper.GetString(flag.InputFlag.ConfigName) == "" {
|
if len(args) == 0 && viper.GetString(flag.InputFlag.ConfigName) == "" && cmd.Name() != "kubernetes" {
|
||||||
if err := cmd.Help(); err != nil {
|
if err := cmd.Help(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,20 +10,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ClusterContextFlag = Flag[string]{
|
|
||||||
Name: "context",
|
|
||||||
ConfigName: "kubernetes.context",
|
|
||||||
Usage: "specify a context to scan",
|
|
||||||
Aliases: []Alias{
|
|
||||||
{Name: "ctx"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
K8sNamespaceFlag = Flag[string]{
|
|
||||||
Name: "namespace",
|
|
||||||
ConfigName: "kubernetes.namespace",
|
|
||||||
Shorthand: "n",
|
|
||||||
Usage: "specify a namespace to scan",
|
|
||||||
}
|
|
||||||
KubeConfigFlag = Flag[string]{
|
KubeConfigFlag = Flag[string]{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
ConfigName: "kubernetes.kubeconfig",
|
ConfigName: "kubernetes.kubeconfig",
|
||||||
@@ -52,12 +38,6 @@ var (
|
|||||||
ConfigName: "kubernetes.tolerations",
|
ConfigName: "kubernetes.tolerations",
|
||||||
Usage: "specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)",
|
Usage: "specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)",
|
||||||
}
|
}
|
||||||
AllNamespaces = Flag[bool]{
|
|
||||||
Name: "all-namespaces",
|
|
||||||
ConfigName: "kubernetes.all-namespaces",
|
|
||||||
Shorthand: "A",
|
|
||||||
Usage: "fetch resources from all cluster namespaces",
|
|
||||||
}
|
|
||||||
NodeCollectorNamespace = Flag[string]{
|
NodeCollectorNamespace = Flag[string]{
|
||||||
Name: "node-collector-namespace",
|
Name: "node-collector-namespace",
|
||||||
ConfigName: "kubernetes.node-collector.namespace",
|
ConfigName: "kubernetes.node-collector.namespace",
|
||||||
@@ -80,6 +60,27 @@ var (
|
|||||||
ConfigName: "kubernetes.exclude.nodes",
|
ConfigName: "kubernetes.exclude.nodes",
|
||||||
Usage: "indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)",
|
Usage: "indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExcludeKinds = Flag[[]string]{
|
||||||
|
Name: "exclude-kinds",
|
||||||
|
ConfigName: "kubernetes.excludeKinds",
|
||||||
|
Usage: "indicate the kinds exclude from scanning (example: node)",
|
||||||
|
}
|
||||||
|
IncludeKinds = Flag[[]string]{
|
||||||
|
Name: "include-kinds",
|
||||||
|
ConfigName: "kubernetes.includeKinds",
|
||||||
|
Usage: "indicate the kinds included in scanning (example: node)",
|
||||||
|
}
|
||||||
|
ExcludeNamespaces = Flag[[]string]{
|
||||||
|
Name: "exclude-namespaces",
|
||||||
|
ConfigName: "kubernetes.excludeNamespaces",
|
||||||
|
Usage: "indicate the namespaces excluded from scanning (example: kube-system)",
|
||||||
|
}
|
||||||
|
IncludeNamespaces = Flag[[]string]{
|
||||||
|
Name: "include-namespaces",
|
||||||
|
ConfigName: "kubernetes.includeNamespaces",
|
||||||
|
Usage: "indicate the namespaces included in scanning (example: kube-system)",
|
||||||
|
}
|
||||||
QPS = Flag[float64]{
|
QPS = Flag[float64]{
|
||||||
Name: "qps",
|
Name: "qps",
|
||||||
ConfigName: "kubernetes.qps",
|
ConfigName: "kubernetes.qps",
|
||||||
@@ -95,49 +96,52 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type K8sFlagGroup struct {
|
type K8sFlagGroup struct {
|
||||||
ClusterContext *Flag[string]
|
|
||||||
Namespace *Flag[string]
|
|
||||||
KubeConfig *Flag[string]
|
KubeConfig *Flag[string]
|
||||||
Components *Flag[[]string]
|
Components *Flag[[]string]
|
||||||
K8sVersion *Flag[string]
|
K8sVersion *Flag[string]
|
||||||
Tolerations *Flag[[]string]
|
Tolerations *Flag[[]string]
|
||||||
NodeCollectorImageRef *Flag[string]
|
NodeCollectorImageRef *Flag[string]
|
||||||
AllNamespaces *Flag[bool]
|
|
||||||
NodeCollectorNamespace *Flag[string]
|
NodeCollectorNamespace *Flag[string]
|
||||||
ExcludeOwned *Flag[bool]
|
ExcludeOwned *Flag[bool]
|
||||||
ExcludeNodes *Flag[[]string]
|
ExcludeNodes *Flag[[]string]
|
||||||
|
ExcludeKinds *Flag[[]string]
|
||||||
|
IncludeKinds *Flag[[]string]
|
||||||
|
ExcludeNamespaces *Flag[[]string]
|
||||||
|
IncludeNamespaces *Flag[[]string]
|
||||||
QPS *Flag[float64]
|
QPS *Flag[float64]
|
||||||
Burst *Flag[int]
|
Burst *Flag[int]
|
||||||
}
|
}
|
||||||
|
|
||||||
type K8sOptions struct {
|
type K8sOptions struct {
|
||||||
ClusterContext string
|
|
||||||
Namespace string
|
|
||||||
KubeConfig string
|
KubeConfig string
|
||||||
Components []string
|
Components []string
|
||||||
K8sVersion string
|
K8sVersion string
|
||||||
Tolerations []corev1.Toleration
|
Tolerations []corev1.Toleration
|
||||||
NodeCollectorImageRef string
|
NodeCollectorImageRef string
|
||||||
AllNamespaces bool
|
|
||||||
NodeCollectorNamespace string
|
NodeCollectorNamespace string
|
||||||
ExcludeOwned bool
|
ExcludeOwned bool
|
||||||
ExcludeNodes map[string]string
|
ExcludeNodes map[string]string
|
||||||
|
ExcludeKinds []string
|
||||||
|
IncludeKinds []string
|
||||||
|
ExcludeNamespaces []string
|
||||||
|
IncludeNamespaces []string
|
||||||
QPS float32
|
QPS float32
|
||||||
Burst int
|
Burst int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewK8sFlagGroup() *K8sFlagGroup {
|
func NewK8sFlagGroup() *K8sFlagGroup {
|
||||||
return &K8sFlagGroup{
|
return &K8sFlagGroup{
|
||||||
ClusterContext: ClusterContextFlag.Clone(),
|
|
||||||
Namespace: K8sNamespaceFlag.Clone(),
|
|
||||||
KubeConfig: KubeConfigFlag.Clone(),
|
KubeConfig: KubeConfigFlag.Clone(),
|
||||||
Components: ComponentsFlag.Clone(),
|
Components: ComponentsFlag.Clone(),
|
||||||
K8sVersion: K8sVersionFlag.Clone(),
|
K8sVersion: K8sVersionFlag.Clone(),
|
||||||
Tolerations: TolerationsFlag.Clone(),
|
Tolerations: TolerationsFlag.Clone(),
|
||||||
AllNamespaces: AllNamespaces.Clone(),
|
|
||||||
NodeCollectorNamespace: NodeCollectorNamespace.Clone(),
|
NodeCollectorNamespace: NodeCollectorNamespace.Clone(),
|
||||||
ExcludeOwned: ExcludeOwned.Clone(),
|
ExcludeOwned: ExcludeOwned.Clone(),
|
||||||
ExcludeNodes: ExcludeNodes.Clone(),
|
ExcludeNodes: ExcludeNodes.Clone(),
|
||||||
|
ExcludeKinds: ExcludeKinds.Clone(),
|
||||||
|
IncludeKinds: IncludeKinds.Clone(),
|
||||||
|
ExcludeNamespaces: ExcludeNamespaces.Clone(),
|
||||||
|
IncludeNamespaces: IncludeNamespaces.Clone(),
|
||||||
NodeCollectorImageRef: NodeCollectorImageRef.Clone(),
|
NodeCollectorImageRef: NodeCollectorImageRef.Clone(),
|
||||||
QPS: QPS.Clone(),
|
QPS: QPS.Clone(),
|
||||||
Burst: Burst.Clone(),
|
Burst: Burst.Clone(),
|
||||||
@@ -150,17 +154,18 @@ func (f *K8sFlagGroup) Name() string {
|
|||||||
|
|
||||||
func (f *K8sFlagGroup) Flags() []Flagger {
|
func (f *K8sFlagGroup) Flags() []Flagger {
|
||||||
return []Flagger{
|
return []Flagger{
|
||||||
f.ClusterContext,
|
|
||||||
f.Namespace,
|
|
||||||
f.KubeConfig,
|
f.KubeConfig,
|
||||||
f.Components,
|
f.Components,
|
||||||
f.K8sVersion,
|
f.K8sVersion,
|
||||||
f.Tolerations,
|
f.Tolerations,
|
||||||
f.AllNamespaces,
|
|
||||||
f.NodeCollectorNamespace,
|
f.NodeCollectorNamespace,
|
||||||
f.ExcludeOwned,
|
f.ExcludeOwned,
|
||||||
f.ExcludeNodes,
|
f.ExcludeNodes,
|
||||||
f.NodeCollectorImageRef,
|
f.NodeCollectorImageRef,
|
||||||
|
f.ExcludeKinds,
|
||||||
|
f.IncludeKinds,
|
||||||
|
f.ExcludeNamespaces,
|
||||||
|
f.IncludeNamespaces,
|
||||||
f.QPS,
|
f.QPS,
|
||||||
f.Burst,
|
f.Burst,
|
||||||
}
|
}
|
||||||
@@ -185,20 +190,27 @@ func (f *K8sFlagGroup) ToOptions() (K8sOptions, error) {
|
|||||||
}
|
}
|
||||||
exludeNodeLabels[excludeNodeParts[0]] = excludeNodeParts[1]
|
exludeNodeLabels[excludeNodeParts[0]] = excludeNodeParts[1]
|
||||||
}
|
}
|
||||||
|
if len(f.ExcludeNamespaces.Value()) > 0 && len(f.IncludeNamespaces.Value()) > 0 {
|
||||||
|
return K8sOptions{}, fmt.Errorf("include-namespaces and exclude-namespaces flags cannot be used together")
|
||||||
|
}
|
||||||
|
if len(f.ExcludeKinds.Value()) > 0 && len(f.IncludeKinds.Value()) > 0 {
|
||||||
|
return K8sOptions{}, fmt.Errorf("include-kinds and exclude-kinds flags cannot be used together")
|
||||||
|
}
|
||||||
|
|
||||||
return K8sOptions{
|
return K8sOptions{
|
||||||
ClusterContext: f.ClusterContext.Value(),
|
|
||||||
Namespace: f.Namespace.Value(),
|
|
||||||
KubeConfig: f.KubeConfig.Value(),
|
KubeConfig: f.KubeConfig.Value(),
|
||||||
Components: f.Components.Value(),
|
Components: f.Components.Value(),
|
||||||
K8sVersion: f.K8sVersion.Value(),
|
K8sVersion: f.K8sVersion.Value(),
|
||||||
Tolerations: tolerations,
|
Tolerations: tolerations,
|
||||||
AllNamespaces: f.AllNamespaces.Value(),
|
|
||||||
NodeCollectorNamespace: f.NodeCollectorNamespace.Value(),
|
NodeCollectorNamespace: f.NodeCollectorNamespace.Value(),
|
||||||
ExcludeOwned: f.ExcludeOwned.Value(),
|
ExcludeOwned: f.ExcludeOwned.Value(),
|
||||||
ExcludeNodes: exludeNodeLabels,
|
ExcludeNodes: exludeNodeLabels,
|
||||||
NodeCollectorImageRef: f.NodeCollectorImageRef.Value(),
|
NodeCollectorImageRef: f.NodeCollectorImageRef.Value(),
|
||||||
QPS: float32(f.QPS.Value()),
|
QPS: float32(f.QPS.Value()),
|
||||||
|
ExcludeKinds: f.ExcludeKinds.Value(),
|
||||||
|
IncludeKinds: f.IncludeKinds.Value(),
|
||||||
|
ExcludeNamespaces: f.ExcludeNamespaces.Value(),
|
||||||
|
IncludeNamespaces: f.IncludeNamespaces.Value(),
|
||||||
Burst: f.Burst.Value(),
|
Burst: f.Burst.Value(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package commands
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@@ -16,9 +15,6 @@ import (
|
|||||||
|
|
||||||
// clusterRun runs scan on kubernetes cluster
|
// clusterRun runs scan on kubernetes cluster
|
||||||
func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) error {
|
func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) error {
|
||||||
// TODO: replace with log.Logger
|
|
||||||
logger, _ := zap.NewProduction()
|
|
||||||
|
|
||||||
if err := validateReportArguments(opts); err != nil {
|
if err := validateReportArguments(opts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -26,13 +22,20 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err
|
|||||||
var err error
|
var err error
|
||||||
switch opts.Format {
|
switch opts.Format {
|
||||||
case types.FormatCycloneDX:
|
case types.FormatCycloneDX:
|
||||||
artifacts, err = trivyk8s.New(cluster, logger.Sugar()).ListClusterBomInfo(ctx)
|
artifacts, err = trivyk8s.New(cluster).ListClusterBomInfo(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get k8s artifacts with node info error: %w", err)
|
return xerrors.Errorf("get k8s artifacts with node info error: %w", err)
|
||||||
}
|
}
|
||||||
case types.FormatJSON, types.FormatTable:
|
case types.FormatJSON, types.FormatTable:
|
||||||
|
k8sOpts := []trivyk8s.K8sOption{
|
||||||
|
trivyk8s.WithExcludeNamespaces(opts.ExcludeNamespaces),
|
||||||
|
trivyk8s.WithIncludeNamespaces(opts.IncludeNamespaces),
|
||||||
|
trivyk8s.WithExcludeKinds(opts.ExcludeKinds),
|
||||||
|
trivyk8s.WithIncludeKinds(opts.IncludeKinds),
|
||||||
|
trivyk8s.WithExcludeOwned(opts.ExcludeOwned),
|
||||||
|
}
|
||||||
if opts.Scanners.AnyEnabled(types.MisconfigScanner) && slices.Contains(opts.Components, "infra") {
|
if opts.Scanners.AnyEnabled(types.MisconfigScanner) && slices.Contains(opts.Components, "infra") {
|
||||||
artifacts, err = trivyk8s.New(cluster, logger.Sugar(), trivyk8s.WithExcludeOwned(opts.ExcludeOwned)).ListArtifactAndNodeInfo(ctx,
|
artifacts, err = trivyk8s.New(cluster, k8sOpts...).ListArtifactAndNodeInfo(ctx,
|
||||||
trivyk8s.WithScanJobNamespace(opts.NodeCollectorNamespace),
|
trivyk8s.WithScanJobNamespace(opts.NodeCollectorNamespace),
|
||||||
trivyk8s.WithIgnoreLabels(opts.ExcludeNodes),
|
trivyk8s.WithIgnoreLabels(opts.ExcludeNodes),
|
||||||
trivyk8s.WithScanJobImageRef(opts.NodeCollectorImageRef),
|
trivyk8s.WithScanJobImageRef(opts.NodeCollectorImageRef),
|
||||||
@@ -41,7 +44,7 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err
|
|||||||
return xerrors.Errorf("get k8s artifacts with node info error: %w", err)
|
return xerrors.Errorf("get k8s artifacts with node info error: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
artifacts, err = trivyk8s.New(cluster, logger.Sugar()).ListArtifacts(ctx)
|
artifacts, err = trivyk8s.New(cluster, k8sOpts...).ListArtifacts(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get k8s artifacts error: %w", err)
|
return xerrors.Errorf("get k8s artifacts error: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"go.uber.org/zap"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy-kubernetes/pkg/k8s"
|
|
||||||
"github.com/aquasecurity/trivy-kubernetes/pkg/trivyk8s"
|
|
||||||
"github.com/aquasecurity/trivy/pkg/flag"
|
|
||||||
)
|
|
||||||
|
|
||||||
// namespaceRun runs scan on kubernetes cluster
|
|
||||||
func namespaceRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) error {
|
|
||||||
// TODO: replace with slog.Logger
|
|
||||||
logger, _ := zap.NewProduction()
|
|
||||||
|
|
||||||
if err := validateReportArguments(opts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var trivyk trivyk8s.TrivyK8S
|
|
||||||
if opts.AllNamespaces {
|
|
||||||
trivyk = trivyk8s.New(cluster, logger.Sugar()).AllNamespaces()
|
|
||||||
} else {
|
|
||||||
trivyk = trivyk8s.New(cluster, logger.Sugar()).Namespace(getNamespace(opts, cluster.GetCurrentNamespace()))
|
|
||||||
}
|
|
||||||
|
|
||||||
artifacts, err := trivyk.ListArtifacts(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("get k8s artifacts error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
runner := newRunner(opts, cluster.GetCurrentContext())
|
|
||||||
return runner.run(ctx, artifacts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamespace(opts flag.Options, currentNamespace string) string {
|
|
||||||
if opts.K8sOptions.Namespace != "" {
|
|
||||||
return opts.K8sOptions.Namespace
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentNamespace
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/flag"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_getNamespace(t *testing.T) {
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
currentNamespace string
|
|
||||||
opts flag.Options
|
|
||||||
want string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "--namespace=custom",
|
|
||||||
currentNamespace: "default",
|
|
||||||
opts: flag.Options{
|
|
||||||
K8sOptions: flag.K8sOptions{
|
|
||||||
Namespace: "custom",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: "custom",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "no namespaces passed",
|
|
||||||
currentNamespace: "default",
|
|
||||||
opts: flag.Options{
|
|
||||||
K8sOptions: flag.K8sOptions{
|
|
||||||
Namespace: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: "default",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
got := getNamespace(test.opts, test.currentNamespace)
|
|
||||||
assert.Equal(t, test.want, got)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.uber.org/zap"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
|
||||||
"github.com/aquasecurity/trivy-kubernetes/pkg/k8s"
|
|
||||||
"github.com/aquasecurity/trivy-kubernetes/pkg/trivyk8s"
|
|
||||||
"github.com/aquasecurity/trivy/pkg/flag"
|
|
||||||
)
|
|
||||||
|
|
||||||
// resourceRun runs scan on kubernetes cluster
|
|
||||||
func resourceRun(ctx context.Context, args []string, opts flag.Options, cluster k8s.Cluster) error {
|
|
||||||
kind, name, err := extractKindAndName(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
runner := newRunner(opts, cluster.GetCurrentContext())
|
|
||||||
|
|
||||||
var trivyk trivyk8s.TrivyK8S
|
|
||||||
|
|
||||||
// TODO: replace with slog.Logger
|
|
||||||
logger, _ := zap.NewProduction()
|
|
||||||
trivyk = trivyk8s.New(cluster, logger.Sugar(), trivyk8s.WithExcludeOwned(opts.ExcludeOwned))
|
|
||||||
|
|
||||||
if opts.AllNamespaces {
|
|
||||||
trivyk = trivyk.AllNamespaces()
|
|
||||||
} else {
|
|
||||||
trivyk = trivyk.Namespace(getNamespace(opts, cluster.GetCurrentNamespace()))
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == "" { // pods or configmaps etc
|
|
||||||
if err = validateReportArguments(opts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
targets, err := trivyk.Resources(kind).ListArtifacts(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return runner.run(ctx, targets)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pod/NAME or pod NAME etc
|
|
||||||
artifact, err := trivyk.GetArtifact(ctx, kind, name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return runner.run(ctx, []*artifacts.Artifact{artifact})
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractKindAndName(args []string) (string, string, error) {
|
|
||||||
switch len(args) {
|
|
||||||
case 1:
|
|
||||||
s := strings.Split(args[0], "/")
|
|
||||||
if len(s) != 2 {
|
|
||||||
return args[0], "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return s[0], s[1], nil
|
|
||||||
case 2:
|
|
||||||
return args[0], args[1], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", "", xerrors.Errorf("can't parse arguments %v. Please run `trivy k8s` for usage.", args)
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_extractKindAndName(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args []string
|
|
||||||
expectedKind string
|
|
||||||
expectedName string
|
|
||||||
expectedError string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "one argument only",
|
|
||||||
args: []string{"deploy"},
|
|
||||||
expectedKind: "deploy",
|
|
||||||
expectedName: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "one argument only, multiple targets",
|
|
||||||
args: []string{"deploy,configmaps"},
|
|
||||||
expectedKind: "deploy,configmaps",
|
|
||||||
expectedName: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bar separated",
|
|
||||||
args: []string{"deploy/orion"},
|
|
||||||
expectedKind: "deploy",
|
|
||||||
expectedName: "orion",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "space separated",
|
|
||||||
args: []string{"deploy", "lua"},
|
|
||||||
expectedKind: "deploy",
|
|
||||||
expectedName: "lua",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "multiple arguments separated",
|
|
||||||
args: []string{"test", "test", "test"},
|
|
||||||
expectedError: "can't parse arguments [test test test]. Please run `trivy k8s` for usage.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
kind, name, err := extractKindAndName(test.args)
|
|
||||||
|
|
||||||
if len(test.expectedError) > 0 {
|
|
||||||
assert.Error(t, err, test.expectedError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, test.expectedKind, kind)
|
|
||||||
assert.Equal(t, test.expectedName, name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,48 +20,30 @@ import (
|
|||||||
"github.com/aquasecurity/trivy/pkg/types"
|
"github.com/aquasecurity/trivy/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
clusterArtifact = "cluster"
|
|
||||||
allArtifact = "all"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Run runs a k8s scan
|
// Run runs a k8s scan
|
||||||
func Run(ctx context.Context, args []string, opts flag.Options) error {
|
func Run(ctx context.Context, args []string, opts flag.Options) error {
|
||||||
ctx, cancel := context.WithTimeout(ctx, opts.Timeout)
|
clusterOptions := []k8s.ClusterOption{
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
ctx = log.WithContextPrefix(ctx, "k8s")
|
|
||||||
|
|
||||||
cluster, err := k8s.GetCluster(
|
|
||||||
k8s.WithContext(opts.K8sOptions.ClusterContext),
|
|
||||||
k8s.WithKubeConfig(opts.K8sOptions.KubeConfig),
|
k8s.WithKubeConfig(opts.K8sOptions.KubeConfig),
|
||||||
k8s.WithBurst(opts.K8sOptions.Burst),
|
k8s.WithBurst(opts.K8sOptions.Burst),
|
||||||
k8s.WithQPS(opts.K8sOptions.QPS),
|
k8s.WithQPS(opts.K8sOptions.QPS),
|
||||||
)
|
}
|
||||||
|
if len(args) > 0 {
|
||||||
|
clusterOptions = append(clusterOptions, k8s.WithContext(args[0]))
|
||||||
|
}
|
||||||
|
cluster, err := k8s.GetCluster(clusterOptions...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed getting k8s cluster: %w", err)
|
return xerrors.Errorf("failed getting k8s cluster: %w", err)
|
||||||
}
|
}
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, opts.Timeout)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
cancel()
|
||||||
if errors.Is(err, context.DeadlineExceeded) {
|
if errors.Is(err, context.DeadlineExceeded) {
|
||||||
log.Warn("Increase --timeout value")
|
log.WarnContext(ctx, "Increase --timeout value")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
opts.K8sVersion = cluster.GetClusterVersion()
|
opts.K8sVersion = cluster.GetClusterVersion()
|
||||||
switch args[0] {
|
return clusterRun(ctx, opts, cluster)
|
||||||
case clusterArtifact:
|
|
||||||
return clusterRun(ctx, opts, cluster)
|
|
||||||
case allArtifact:
|
|
||||||
if opts.Format == types.FormatCycloneDX {
|
|
||||||
return xerrors.Errorf("KBOM with CycloneDX format is not supported for all namespace scans")
|
|
||||||
}
|
|
||||||
return namespaceRun(ctx, opts, cluster)
|
|
||||||
default: // resourceArtifact
|
|
||||||
if opts.Format == types.FormatCycloneDX {
|
|
||||||
return xerrors.Errorf("KBOM with CycloneDX format is not supported for resource scans")
|
|
||||||
}
|
|
||||||
return resourceRun(ctx, args, opts, cluster)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type runner struct {
|
type runner struct {
|
||||||
@@ -71,8 +53,8 @@ type runner struct {
|
|||||||
|
|
||||||
func newRunner(flagOpts flag.Options, cluster string) *runner {
|
func newRunner(flagOpts flag.Options, cluster string) *runner {
|
||||||
return &runner{
|
return &runner{
|
||||||
flagOpts: flagOpts,
|
flagOpts,
|
||||||
cluster: cluster,
|
cluster,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +68,7 @@ func (r *runner) run(ctx context.Context, artifacts []*k8sArtifacts.Artifact) er
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := runner.Close(ctx); err != nil {
|
if err := runner.Close(ctx); err != nil {
|
||||||
log.ErrorContext(ctx, "Failed to close runner", log.Err(err))
|
log.ErrorContext(ctx, "failed to close runner: %s", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user