mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 15:16:33 -08:00
feat(k8s): cyclonedx kbom support (#4557)
* feat: cyclonedx kbom support Signed-off-by: chenk <hen.keinan@gmail.com> * feat: cyclonedx kbom support Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * chore: update sum db Signed-off-by: chenk <hen.keinan@gmail.com> * chore: update sum db Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * chore: update sumdb Signed-off-by: chenk <hen.keinan@gmail.com> * chore: update sumdb Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> * feat: kubernetes bill of materials Signed-off-by: chenk <hen.keinan@gmail.com> --------- Signed-off-by: chenk <hen.keinan@gmail.com>
This commit is contained in:
@@ -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, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (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)
|
||||
|
||||
@@ -343,3 +343,16 @@ Trivy has a native [Kubernetes Operator][operator] which continuously scans your
|
||||
[operator]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
|
||||
[crd]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
|
||||
[trivy-operator]: https://aquasecurity.github.io/trivy-operator/latest
|
||||
|
||||
## SBOM
|
||||
|
||||
Trivy supports the generation of Kubernetes Bill of Materials (KBOM) for kubernetes cluster control plane components, node components and addons.
|
||||
|
||||
## KBOM
|
||||
|
||||
KBOM, Kubernetes Bill of Materials, is a manifest of all the important components that make up your Kubernetes cluster – Control plane components, Node Components, and Addons, including their versions and images. Which “api-server” version are you currently running? Which flavor of “kubelet” is running on each node? What kind of etcd or storage are you currently using? And most importantly – are there any vulnerabilities known to affect these components? These are all questions that KBOM can help you answer.
|
||||
Trivy can generate KBOM in CycloneDX format:
|
||||
|
||||
```sh
|
||||
trivy k8s cluster --format cyclonedx
|
||||
```
|
||||
58
go.mod
58
go.mod
@@ -13,7 +13,7 @@ require (
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/alicebob/miniredis/v2 v2.30.3
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
|
||||
github.com/aquasecurity/defsec v0.89.0
|
||||
github.com/aquasecurity/defsec v0.89.1-0.20230616215656-269528cc9b42
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230614075854-30b52f543be9
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
|
||||
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798
|
||||
@@ -25,7 +25,7 @@ require (
|
||||
github.com/aquasecurity/tml v0.6.1
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20230515061101-378ab9ed302c
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728
|
||||
github.com/aquasecurity/trivy-kubernetes v0.5.4
|
||||
github.com/aquasecurity/trivy-kubernetes v0.5.7-0.20230619083756-6eb60789faeb
|
||||
github.com/aws/aws-sdk-go v1.44.245
|
||||
github.com/aws/aws-sdk-go-v2 v1.18.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.25
|
||||
@@ -67,6 +67,7 @@ require (
|
||||
github.com/masahiro331/go-vmdk-parser v0.0.0-20221225061455-612096e4bbbd
|
||||
github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/moby/buildkit v0.11.5
|
||||
github.com/open-policy-agent/opa v0.45.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
@@ -101,7 +102,7 @@ require (
|
||||
google.golang.org/protobuf v1.30.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gotest.tools v2.2.0+incompatible
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/api v0.27.2
|
||||
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5
|
||||
modernc.org/sqlite v1.20.3
|
||||
)
|
||||
@@ -126,8 +127,8 @@ require (
|
||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.3 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.10.0-rc.7 // indirect
|
||||
github.com/OneOfOne/xxhash v1.2.8 // indirect
|
||||
@@ -226,16 +227,16 @@ require (
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.4.1 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.0.2 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.0.5 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.21.4 // indirect
|
||||
github.com/go-openapi/errors v0.20.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.1 // indirect
|
||||
github.com/go-openapi/loads v0.21.2 // indirect
|
||||
github.com/go-openapi/spec v0.20.9 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
@@ -264,7 +265,7 @@ require (
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.14.1 // indirect
|
||||
github.com/huandu/xstrings v1.3.3 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/imdario/mergo v0.3.15 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
@@ -280,7 +281,7 @@ require (
|
||||
github.com/liamg/iamgo v0.0.9 // indirect
|
||||
github.com/liamg/jfather v0.0.7 // indirect
|
||||
github.com/liamg/memoryfs v1.4.3 // indirect
|
||||
github.com/lib/pq v1.10.7 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
@@ -294,7 +295,6 @@ require (
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/patternmatcher v0.5.0 // indirect
|
||||
@@ -328,11 +328,11 @@ require (
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rubenv/sql-migrate v1.2.0 // indirect
|
||||
github.com/rubenv/sql-migrate v1.3.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/skeema/knownhosts v1.1.1 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@@ -371,17 +371,16 @@ require (
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gotest.tools/v3 v3.1.0 // indirect
|
||||
helm.sh/helm/v3 v3.11.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.26.0 // indirect
|
||||
k8s.io/apimachinery v0.26.3 // indirect
|
||||
k8s.io/apiserver v0.26.2 // indirect
|
||||
k8s.io/cli-runtime v0.26.3 // indirect
|
||||
k8s.io/client-go v0.26.3 // indirect
|
||||
k8s.io/component-base v0.26.3 // indirect
|
||||
helm.sh/helm/v3 v3.12.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.27.2 // indirect
|
||||
k8s.io/apimachinery v0.27.2 // indirect
|
||||
k8s.io/apiserver v0.27.2 // indirect
|
||||
k8s.io/cli-runtime v0.27.2 // indirect
|
||||
k8s.io/client-go v0.27.2 // indirect
|
||||
k8s.io/component-base v0.27.2 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
k8s.io/kubectl v0.26.3 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
|
||||
k8s.io/kubectl v0.27.2 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
@@ -392,13 +391,12 @@ require (
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.0.1 // indirect
|
||||
oras.land/oras-go v1.2.2 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.12.1 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/kustomize/api v0.13.2 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
// v1.2.0 is taken from github.com/open-policy-agent/opa v0.42.0
|
||||
// v1.2.0 incompatible with github.com/docker/docker v23.0.0-rc.1+incompatible
|
||||
replace oras.land/oras-go => oras.land/oras-go v1.1.1
|
||||
// oras 1.2.2 is incompatible with github.com/docker/docker v23.0.0-rc.1+incompatible
|
||||
replace oras.land/oras-go => oras.land/oras-go v1.2.3
|
||||
|
||||
152
go.sum
152
go.sum
@@ -242,19 +242,19 @@ github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIa
|
||||
github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs=
|
||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||
github.com/Masterminds/squirrel v1.5.3 h1:YPpoceAcxuzIljlr5iWpNKaql7hLeG1KLSrhvdHpkZc=
|
||||
github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
|
||||
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
@@ -292,6 +292,7 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/O
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||
github.com/a8m/expect v1.0.0/go.mod h1:4IwSCMumY49ScypDnjNbYEjgVeqy1/U2cEs3Lat96eA=
|
||||
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
|
||||
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
@@ -320,8 +321,8 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM=
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8=
|
||||
github.com/aquasecurity/defsec v0.89.0 h1:5B0mJYraNa2n5zlYuShqOwRt5kqFXdVfGPRYiZJPDuw=
|
||||
github.com/aquasecurity/defsec v0.89.0/go.mod h1:te+KhIV8w1pDIjTsUQwlc6xRn8gC7f+TJUiFhLlcEHM=
|
||||
github.com/aquasecurity/defsec v0.89.1-0.20230616215656-269528cc9b42 h1:PGoTTb5b40hZGW+fHVLFWwUkxWQJp8HKJMf82SR61Q8=
|
||||
github.com/aquasecurity/defsec v0.89.1-0.20230616215656-269528cc9b42/go.mod h1:3AgfRdHLPbT9kcAMaj6f9LX7WgihbNta8sPycrSqHTw=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230614075854-30b52f543be9 h1:HbSquJbXpWwv8wuoXXb0mZWzsUhDUIgFpjln4woH9YA=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230614075854-30b52f543be9/go.mod h1:fEMyM+83y5N9m0Deh0bmTGiiNwpceUtBA67s7WXOfvM=
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=
|
||||
@@ -346,14 +347,15 @@ github.com/aquasecurity/trivy-db v0.0.0-20230515061101-378ab9ed302c h1:mFMfHmb5G
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20230515061101-378ab9ed302c/go.mod h1:s7x7CTxYeiFf6gPOakSsg4mCD93au4dbYplG4h0FGrs=
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 h1:0eS+V7SXHgqoT99tV1mtMW6HL4HdoB9qGLMCb1fZp8A=
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.5.4 h1:1UwEjcIxkY+VixlV734zixStq7oNjy5C4qJ5wy1mXU8=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.5.4/go.mod h1:rc2mGtn71vS+FDVXS3RjEpWXR+nph6GBS6fXdqhitFc=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.5.7-0.20230619083756-6eb60789faeb h1:5htNYck1farYXZrNfTuAgfULRQJnK73eQ+1Rj1CE8tA=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.5.7-0.20230619083756-6eb60789faeb/go.mod h1:GCm7uq++jz7Ij8cA9mAorpKJ9/qSBCl7v6EKYA8DxJ8=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
@@ -769,13 +771,15 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwC
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/foxcpp/go-mockdns v0.0.0-20210729171921-fb145fc6f897 h1:E52jfcE64UG42SwLmrW0QByONfGynWuzBvm86BoB9z8=
|
||||
github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
@@ -788,8 +792,8 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4=
|
||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
|
||||
@@ -800,8 +804,8 @@ github.com/go-git/go-git/v5 v5.7.0/go.mod h1:coJHKEOk5kUClpsNlXrUvPrDxY3w3gjHvhc
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gorp/gorp/v3 v3.0.2 h1:ULqJXIekoqMx29FI5ekXXFoH1dT2Vc8UhnRzBg+Emz4=
|
||||
github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY=
|
||||
github.com/go-gorp/gorp/v3 v3.0.5 h1:PUjzYdYu3HBOh8LE+UUmRG2P0IRDak9XMeGNvaeq4Ow=
|
||||
github.com/go-gorp/gorp/v3 v3.0.5/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
||||
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
@@ -826,13 +830,15 @@ github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2uj
|
||||
github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
|
||||
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
|
||||
github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro=
|
||||
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
|
||||
@@ -862,11 +868,10 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||
@@ -1124,14 +1129,16 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
|
||||
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
|
||||
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU=
|
||||
@@ -1203,7 +1210,9 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
@@ -1225,9 +1234,9 @@ github.com/liamg/jfather v0.0.7/go.mod h1:xXBGiBoiZ6tmHhfy5Jzw8sugzajwYdi6VosIpB
|
||||
github.com/liamg/memoryfs v1.4.3 h1:+ChjcuPRYpjJSulD13PXDNR3JeJ5HUYKjLHyWVK0bqU=
|
||||
github.com/liamg/memoryfs v1.4.3/go.mod h1:z7mfqXFQS8eSeBBsFjYLlxYRMRyiPktytvYCYTb3BSk=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc=
|
||||
@@ -1269,6 +1278,7 @@ github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlW
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
@@ -1277,6 +1287,7 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@@ -1287,10 +1298,9 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
@@ -1303,7 +1313,7 @@ github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7Xn
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/cli v1.1.4/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ=
|
||||
github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
@@ -1369,6 +1379,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/nelsam/hel/v2 v2.3.2/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w=
|
||||
github.com/nelsam/hel/v2 v2.3.3/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
@@ -1385,13 +1397,13 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
|
||||
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
|
||||
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
|
||||
github.com/open-policy-agent/opa v0.45.0 h1:P5nuhVRtR+e58fk3CMMbiqr6ZFyWQPNOC3otsorGsFs=
|
||||
github.com/open-policy-agent/opa v0.45.0/go.mod h1:/OnsYljNEWJ6DXeFOOnoGn8CvwZGMUS4iRqzYdJvmBI=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@@ -1461,8 +1473,10 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg=
|
||||
github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/poy/onpar v0.0.0-20200406201722-06f95a1c68e8/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
|
||||
github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
|
||||
github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
@@ -1513,10 +1527,12 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rubenv/sql-migrate v1.2.0 h1:fOXMPLMd41sK7Tg75SXDec15k3zg5WNV6SjuDRiNfcU=
|
||||
github.com/rubenv/sql-migrate v1.2.0/go.mod h1:Z5uVnq7vrIrPmHbVFfR4YLHRZquxeHpckCnRq0P/K9Y=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rubenv/sql-migrate v1.3.1 h1:Vx+n4Du8X8VTYuXbhNxdEUoh6wiJERA0GlWocR5FrbA=
|
||||
github.com/rubenv/sql-migrate v1.3.1/go.mod h1:YzG/Vh82CwyhTFXy+Mf5ahAiiEOpAlHurg+23VEzcsk=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@@ -1537,8 +1553,9 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
|
||||
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sigstore/rekor v1.2.1 h1:cEI4qn9IBvM7EkPQYl3YzCwCw97Mx8O2nHrv02XiI8U=
|
||||
github.com/sigstore/rekor v1.2.1/go.mod h1:zcFO54qIg2G1/i0sE/nvmELUOng/n0MPjTszRYByVPo=
|
||||
@@ -1572,10 +1589,12 @@ github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
@@ -1698,8 +1717,6 @@ github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0
|
||||
github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0=
|
||||
github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
@@ -1774,6 +1791,7 @@ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
@@ -1887,6 +1905,7 @@ golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfS
|
||||
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
@@ -2062,9 +2081,11 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
@@ -2073,6 +2094,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
|
||||
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=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
@@ -2088,6 +2110,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
@@ -2142,6 +2165,7 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
@@ -2455,16 +2479,16 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
gotest.tools/v3 v3.1.0 h1:rVV8Tcg/8jHUkPUorwjaMTtemIMVXfIPKiOqnhEhakk=
|
||||
gotest.tools/v3 v3.1.0/go.mod h1:fHy7eyTmJFO5bQbUsEGQ1v4m2J3Jz9eWL54TP2/ZuYQ=
|
||||
helm.sh/helm/v3 v3.11.1 h1:cmL9fFohOoNQf+wnp2Wa0OhNFH0KFnSzEkVxi3fcc3I=
|
||||
helm.sh/helm/v3 v3.11.1/go.mod h1:z/Bu/BylToGno/6dtNGuSmjRqxKq5gaH+FU0BPO+AQ8=
|
||||
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
||||
helm.sh/helm/v3 v3.12.1 h1:lzU7etZX24A6BTMXYQF3bFq0ECfD8s+fKlNBBL8AbEc=
|
||||
helm.sh/helm/v3 v3.12.1/go.mod h1:qhmSY9kcX7yH1xebe+FDMZa7E5NAeZ+LvK5j1gSln48=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -2475,32 +2499,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.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
||||
k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU=
|
||||
k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE=
|
||||
k8s.io/apiextensions-apiserver v0.26.0 h1:Gy93Xo1eg2ZIkNX/8vy5xviVSxwQulsnUdQ00nEdpDo=
|
||||
k8s.io/apiextensions-apiserver v0.26.0/go.mod h1:7ez0LTiyW5nq3vADtK6C3kMESxadD51Bh6uz3JOlqWQ=
|
||||
k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo=
|
||||
k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4=
|
||||
k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo=
|
||||
k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ=
|
||||
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.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||
k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k=
|
||||
k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
|
||||
k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg=
|
||||
k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
||||
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.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
|
||||
k8s.io/apiserver v0.26.2 h1:Pk8lmX4G14hYqJd1poHGC08G03nIHVqdJMR0SD3IH3o=
|
||||
k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8=
|
||||
k8s.io/cli-runtime v0.26.3 h1:3ULe0oI28xmgeLMVXIstB+ZL5CTGvWSMVMLeHxitIuc=
|
||||
k8s.io/cli-runtime v0.26.3/go.mod h1:5YEhXLV4kLt/OSy9yQwtSSNZU2Z7aTEYta1A+Jg4VC4=
|
||||
k8s.io/apiserver v0.27.2 h1:p+tjwrcQEZDrEorCZV2/qE8osGTINPuS5ZNqWAvKm5E=
|
||||
k8s.io/apiserver v0.27.2/go.mod h1:EsOf39d75rMivgvvwjJ3OW/u9n1/BmUMK5otEOJrb1Y=
|
||||
k8s.io/cli-runtime v0.27.2 h1:9HI8gfReNujKXt16tGOAnb8b4NZ5E+e0mQQHKhFGwYw=
|
||||
k8s.io/cli-runtime v0.27.2/go.mod h1:9UecpyPDTkhiYY4d9htzRqN+rKomJgyb4wi0OfrmCjw=
|
||||
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.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
|
||||
k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s=
|
||||
k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ=
|
||||
k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE=
|
||||
k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ=
|
||||
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.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
|
||||
k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g=
|
||||
k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E=
|
||||
k8s.io/component-base v0.27.2 h1:neju+7s/r5O4x4/txeUONNTS9r1HsPbyoPBAtHsDCpo=
|
||||
k8s.io/component-base v0.27.2/go.mod h1:5UPk7EjfgrfgRIuDBFtsEFAe4DAvP3U+M8RTzoSJkpo=
|
||||
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.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
@@ -2511,10 +2535,10 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
|
||||
k8s.io/kubectl v0.26.3 h1:bZ5SgFyeEXw6XTc1Qji0iNdtqAC76lmeIIQULg2wNXM=
|
||||
k8s.io/kubectl v0.26.3/go.mod h1:02+gv7Qn4dupzN3fi/9OvqqdW+uG/4Zi56vc4Zmsp1g=
|
||||
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
|
||||
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
|
||||
k8s.io/kubectl v0.27.2 h1:sSBM2j94MHBFRWfHIWtEXWCicViQzZsb177rNsKBhZg=
|
||||
k8s.io/kubectl v0.27.2/go.mod h1:GCOODtxPcrjh+EC611MqREkU8RjYBh10ldQCQ6zpFKw=
|
||||
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-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk=
|
||||
@@ -2543,19 +2567,19 @@ modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
|
||||
oras.land/oras-go v1.1.1 h1:gI00ftziRivKXaw1BdMeEoIA4uBgga33iVlOsEwefFs=
|
||||
oras.land/oras-go v1.1.1/go.mod h1:n2TE1ummt9MUyprGhT+Q7kGZUF4kVUpYysPFxeV2IpQ=
|
||||
oras.land/oras-go v1.2.3 h1:v8PJl+gEAntI1pJ/LCrDgsuk+1PKVavVEPsYIHFE5uY=
|
||||
oras.land/oras-go v1.2.3/go.mod h1:M/uaPdYklze0Vf3AakfarnpoEckvw0ESbRdN8Z1vdJg=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM=
|
||||
sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s=
|
||||
sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk=
|
||||
sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/kustomize/api v0.13.2 h1:kejWfLeJhUsTGioDoFNJET5LQe/ajzXhJGYoU+pJsiA=
|
||||
sigs.k8s.io/kustomize/api v0.13.2/go.mod h1:DUp325VVMFVcQSq+ZxyDisA8wtldwHxLZbr1g94UHsw=
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.1 h1:c8iibius7l24G2wVAGZn/Va2wNys03GXLjYVIcFVxKA=
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.1/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
|
||||
@@ -8,18 +8,20 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
cdx "github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/report"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/report"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
// Note: the test required k8s (kind) cluster installed.
|
||||
// "mage test:k8s" will run this test.
|
||||
|
||||
func TestK8s(t *testing.T) {
|
||||
t.Run("misconfig and vulnerability scan", func(t *testing.T) {
|
||||
// Set up the output file
|
||||
outputFile := filepath.Join(t.TempDir(), "output.json")
|
||||
|
||||
@@ -67,4 +69,44 @@ func TestK8s(t *testing.T) {
|
||||
assert.True(t, lo.SomeBy(results, func(r types.Result) bool {
|
||||
return len(r.Misconfigurations) > 0
|
||||
}))
|
||||
})
|
||||
t.Run("kbom cycloneDx", func(t *testing.T) {
|
||||
// Set up the output file
|
||||
outputFile := filepath.Join(t.TempDir(), "output.json")
|
||||
osArgs := []string{
|
||||
"k8s",
|
||||
"cluster",
|
||||
"--format",
|
||||
"cyclonedx",
|
||||
"-q",
|
||||
"--context",
|
||||
"kind-kind-test",
|
||||
"--output",
|
||||
outputFile,
|
||||
}
|
||||
|
||||
// Run Trivy
|
||||
err := execute(osArgs)
|
||||
require.NoError(t, err)
|
||||
|
||||
var got *cdx.BOM
|
||||
f, err := os.Open(outputFile)
|
||||
require.NoError(t, err)
|
||||
defer f.Close()
|
||||
|
||||
err = json.NewDecoder(f).Decode(&got)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, got.Metadata.Component.Name, "kind-kind-test")
|
||||
assert.Equal(t, got.Metadata.Component.Type, cdx.ComponentType("container"))
|
||||
|
||||
// Has components
|
||||
assert.True(t, len(*got.Components) > 0)
|
||||
|
||||
// Has dependecies
|
||||
assert.True(t, lo.SomeBy(*got.Dependencies, func(r cdx.Dependency) bool {
|
||||
return len(*r.Dependencies) > 0
|
||||
}))
|
||||
|
||||
})
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/module"
|
||||
"github.com/aquasecurity/trivy/pkg/plugin"
|
||||
"github.com/aquasecurity/trivy/pkg/policy"
|
||||
r "github.com/aquasecurity/trivy/pkg/report"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
@@ -896,6 +897,10 @@ func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||
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{r.FormatTable, r.FormatJSON, r.FormatCycloneDX}, ", ") + ")"
|
||||
reportFlagGroup.Format = &formatFlag
|
||||
|
||||
k8sFlags := &flag.Flags{
|
||||
CacheFlagGroup: flag.NewCacheFlagGroup(),
|
||||
DBFlagGroup: flag.NewDBFlagGroup(),
|
||||
|
||||
@@ -117,10 +117,15 @@ func (o *Options) Align() {
|
||||
}
|
||||
|
||||
// Vulnerability scanning is disabled by default for CycloneDX.
|
||||
if o.Format == report.FormatCycloneDX && !viper.IsSet(ScannersFlag.ConfigName) {
|
||||
if o.Format == report.FormatCycloneDX && !viper.IsSet(ScannersFlag.ConfigName) && len(o.K8sOptions.Components) == 0 { // remove K8sOptions.Components validation check when vuln scan is supported for k8s report with cycloneDX
|
||||
log.Logger.Info(`"--format cyclonedx" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.`)
|
||||
o.Scanners = nil
|
||||
}
|
||||
|
||||
if o.Format == report.FormatCycloneDX && len(o.K8sOptions.Components) > 0 {
|
||||
log.Logger.Info(`"k8s with --format cyclonedx" disable security scanning`)
|
||||
o.Scanners = nil
|
||||
}
|
||||
}
|
||||
|
||||
// RegistryOpts returns options for OCI registries
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/trivyk8s"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/report"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
@@ -21,6 +22,13 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err
|
||||
}
|
||||
var artifacts []*artifacts.Artifact
|
||||
var err error
|
||||
switch opts.Format {
|
||||
case report.FormatCycloneDX:
|
||||
artifacts, err = trivyk8s.New(cluster, log.Logger).ListBomInfo(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get k8s artifacts with node info error: %w", err)
|
||||
}
|
||||
case report.FormatJSON, report.FormatTable:
|
||||
if opts.Scanners.AnyEnabled(types.MisconfigScanner) && slices.Contains(opts.Components, "infra") {
|
||||
artifacts, err = trivyk8s.New(cluster, log.Logger).ListArtifactAndNodeInfo(ctx, opts.NodeCollectorNamespace, opts.ExcludeNodes, opts.Tolerations...)
|
||||
if err != nil {
|
||||
@@ -32,6 +40,9 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err
|
||||
return xerrors.Errorf("get k8s artifacts error: %w", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return xerrors.Errorf(`unknown format %q. Use "json" or "table" or "cyclonedx"`, opts.Format)
|
||||
}
|
||||
|
||||
runner := newRunner(opts, cluster.GetCurrentContext())
|
||||
return runner.run(ctx, artifacts)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/commands/operation"
|
||||
cr "github.com/aquasecurity/trivy/pkg/compliance/report"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
k8sRep "github.com/aquasecurity/trivy/pkg/k8s"
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/report"
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/scanner"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
@@ -88,8 +89,8 @@ func (r *runner) run(ctx context.Context, artifacts []*artifacts.Artifact) error
|
||||
}
|
||||
r.flagOpts.ScanOptions.Scanners = scanners
|
||||
}
|
||||
|
||||
rpt, err := s.Scan(ctx, artifacts)
|
||||
var rpt report.Report
|
||||
rpt, err = s.Scan(ctx, artifacts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("k8s scan error: %w", err)
|
||||
}
|
||||
@@ -110,13 +111,14 @@ func (r *runner) run(ctx context.Context, artifacts []*artifacts.Artifact) error
|
||||
})
|
||||
}
|
||||
|
||||
if err := report.Write(rpt, report.Option{
|
||||
if err := k8sRep.Write(rpt, report.Option{
|
||||
Format: r.flagOpts.Format,
|
||||
Report: r.flagOpts.ReportFormat,
|
||||
Output: r.flagOpts.Output,
|
||||
Severities: r.flagOpts.Severities,
|
||||
Components: r.flagOpts.Components,
|
||||
Scanners: r.flagOpts.ScanOptions.Scanners,
|
||||
APIVersion: r.flagOpts.AppVersion,
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("unable to write results: %w", err)
|
||||
}
|
||||
|
||||
30
pkg/k8s/report/cyclonedx.go
Normal file
30
pkg/k8s/report/cyclonedx.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
cdx "github.com/CycloneDX/cyclonedx-go"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core"
|
||||
)
|
||||
|
||||
// CycloneDXWriter implements types.Writer
|
||||
type CycloneDXWriter struct {
|
||||
encoder cdx.BOMEncoder
|
||||
marshaler *core.CycloneDX
|
||||
}
|
||||
|
||||
// NewCycloneDXWriter constract new CycloneDXWriter
|
||||
func NewCycloneDXWriter(output io.Writer, format cdx.BOMFileFormat, appVersion string, opts ...core.Option) CycloneDXWriter {
|
||||
encoder := cdx.NewBOMEncoder(output, format)
|
||||
encoder.SetPretty(true)
|
||||
return CycloneDXWriter{
|
||||
encoder: encoder,
|
||||
marshaler: core.NewCycloneDX(appVersion, opts...),
|
||||
}
|
||||
}
|
||||
|
||||
func (w CycloneDXWriter) Write(component *core.Component) error {
|
||||
bom := w.marshaler.Marshal(component)
|
||||
return w.encoder.Encode(bom)
|
||||
}
|
||||
@@ -19,18 +19,19 @@ func (jw JSONWriter) Write(report Report) error {
|
||||
var err error
|
||||
|
||||
switch jw.Report {
|
||||
case allReport:
|
||||
case AllReport:
|
||||
output, err = json.MarshalIndent(report, "", " ")
|
||||
case summaryReport:
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to write json: %w", err)
|
||||
}
|
||||
case SummaryReport:
|
||||
output, err = json.MarshalIndent(report.consolidate(), "", " ")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to write json: %w", err)
|
||||
}
|
||||
default:
|
||||
return xerrors.Errorf(`report %q not supported. Use "summary" or "all"`, jw.Report)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to marshal json: %w", err)
|
||||
}
|
||||
|
||||
if _, err = fmt.Fprintln(jw.Output, string(output)); err != nil {
|
||||
return xerrors.Errorf("failed to write json: %w", err)
|
||||
}
|
||||
|
||||
@@ -7,22 +7,18 @@ import (
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
||||
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/report/table"
|
||||
"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
const (
|
||||
allReport = "all"
|
||||
summaryReport = "summary"
|
||||
|
||||
tableFormat = "table"
|
||||
jsonFormat = "json"
|
||||
AllReport = "all"
|
||||
SummaryReport = "summary"
|
||||
|
||||
workloadComponent = "workload"
|
||||
infraComponent = "infra"
|
||||
@@ -36,6 +32,7 @@ type Option struct {
|
||||
ColumnHeading []string
|
||||
Scanners types.Scanners
|
||||
Components []string
|
||||
APIVersion string
|
||||
}
|
||||
|
||||
// Report represents a kubernetes scan report
|
||||
@@ -43,6 +40,7 @@ type Report struct {
|
||||
SchemaVersion int `json:",omitempty"`
|
||||
ClusterName string
|
||||
Resources []Resource `json:",omitempty"`
|
||||
RootComponent *core.Component `json:"-"`
|
||||
name string
|
||||
}
|
||||
|
||||
@@ -125,54 +123,16 @@ type Writer interface {
|
||||
Write(Report) error
|
||||
}
|
||||
|
||||
// Write writes the results in the give format
|
||||
func Write(report Report, option Option) error {
|
||||
report.printErrors()
|
||||
|
||||
switch option.Format {
|
||||
case jsonFormat:
|
||||
jwriter := JSONWriter{
|
||||
Output: option.Output,
|
||||
Report: option.Report,
|
||||
}
|
||||
return jwriter.Write(report)
|
||||
case tableFormat:
|
||||
separatedReports := separateMisconfigReports(report, option.Scanners, option.Components)
|
||||
|
||||
if option.Report == summaryReport {
|
||||
target := fmt.Sprintf("Summary Report for %s", report.ClusterName)
|
||||
table.RenderTarget(option.Output, target, table.IsOutputToTerminal(option.Output))
|
||||
}
|
||||
|
||||
for _, r := range separatedReports {
|
||||
writer := &TableWriter{
|
||||
Output: option.Output,
|
||||
Report: option.Report,
|
||||
Severities: option.Severities,
|
||||
ColumnHeading: ColumnHeading(option.Scanners, option.Components, r.columns),
|
||||
}
|
||||
|
||||
if err := writer.Write(r.report); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
default:
|
||||
return xerrors.Errorf(`unknown format %q. Use "json" or "table"`, option.Format)
|
||||
}
|
||||
}
|
||||
|
||||
type reports struct {
|
||||
report Report
|
||||
columns []string
|
||||
Report Report
|
||||
Columns []string
|
||||
}
|
||||
|
||||
// separateMisconfigReports returns 3 reports based on scanners and components flags,
|
||||
// SeparateMisconfigReports returns 3 reports based on scanners and components flags,
|
||||
// - misconfiguration report
|
||||
// - rbac report
|
||||
// - infra checks report
|
||||
func separateMisconfigReports(k8sReport Report, scanners types.Scanners, components []string) []reports {
|
||||
func SeparateMisconfigReports(k8sReport Report, scanners types.Scanners, components []string) []reports {
|
||||
|
||||
workloadMisconfig := make([]Resource, 0)
|
||||
infraMisconfig := make([]Resource, 0)
|
||||
@@ -221,21 +181,21 @@ func separateMisconfigReports(k8sReport Report, scanners types.Scanners, compone
|
||||
len(workloadMisconfig) > 0) ||
|
||||
len(workloadVulnerabilities) > 0 {
|
||||
r = append(r, reports{
|
||||
report: workloadReport,
|
||||
columns: WorkloadColumns(),
|
||||
Report: workloadReport,
|
||||
Columns: WorkloadColumns(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if scanners.Enabled(types.RBACScanner) && len(rbacAssessment) > 0 {
|
||||
r = append(r, reports{
|
||||
report: Report{
|
||||
Report: Report{
|
||||
SchemaVersion: 0,
|
||||
ClusterName: k8sReport.ClusterName,
|
||||
Resources: rbacAssessment,
|
||||
name: "RBAC Assessment",
|
||||
},
|
||||
columns: RoleColumns(),
|
||||
Columns: RoleColumns(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -244,13 +204,13 @@ func separateMisconfigReports(k8sReport Report, scanners types.Scanners, compone
|
||||
len(infraMisconfig) > 0 {
|
||||
|
||||
r = append(r, reports{
|
||||
report: Report{
|
||||
Report: Report{
|
||||
SchemaVersion: 0,
|
||||
ClusterName: k8sReport.ClusterName,
|
||||
Resources: infraMisconfig,
|
||||
name: "Infra Assessment",
|
||||
},
|
||||
columns: InfraColumns(),
|
||||
Columns: InfraColumns(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -293,7 +253,7 @@ func CreateResource(artifact *artifacts.Artifact, report types.Report, err error
|
||||
return r
|
||||
}
|
||||
|
||||
func (r Report) printErrors() {
|
||||
func (r Report) PrintErrors() {
|
||||
for _, resource := range r.Resources {
|
||||
if resource.Error != "" {
|
||||
log.Logger.Errorf("Error during vulnerabilities or misconfiguration scan: %s", resource.Error)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -564,238 +561,15 @@ func Test_separateMisconfigReports(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
reports := separateMisconfigReports(tt.k8sReport, tt.scanners, tt.components)
|
||||
reports := SeparateMisconfigReports(tt.k8sReport, tt.scanners, tt.components)
|
||||
assert.Equal(t, len(tt.expectedReports), len(reports))
|
||||
|
||||
for i := range reports {
|
||||
assert.Equal(t, len(tt.expectedReports[i].Resources), len(reports[i].report.Resources))
|
||||
assert.Equal(t, len(tt.expectedReports[i].Resources), len(reports[i].Report.Resources))
|
||||
for j, m := range tt.expectedReports[i].Resources {
|
||||
assert.Equal(t, m.Kind, reports[i].report.Resources[j].Kind)
|
||||
assert.Equal(t, m.Kind, reports[i].Report.Resources[j].Kind)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportWrite_Summary(t *testing.T) {
|
||||
allSeverities := []dbTypes.Severity{
|
||||
dbTypes.SeverityUnknown,
|
||||
dbTypes.SeverityLow,
|
||||
dbTypes.SeverityMedium,
|
||||
dbTypes.SeverityHigh,
|
||||
dbTypes.SeverityCritical,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
report Report
|
||||
opt Option
|
||||
scanners types.Scanners
|
||||
components []string
|
||||
severities []dbTypes.Severity
|
||||
expectedOutput string
|
||||
}{
|
||||
{
|
||||
name: "Only config, all serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Resources: []Resource{deployOrionWithMisconfigs},
|
||||
},
|
||||
scanners: types.Scanners{types.MisconfigScanner},
|
||||
components: []string{workloadComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌───────────┬──────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Misconfigurations │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼──────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Deploy/orion │ 1 │ 2 │ 1 │ 2 │ 1 │
|
||||
└───────────┴──────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "Only vuln, all serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Resources: []Resource{deployOrionWithVulns},
|
||||
},
|
||||
scanners: types.Scanners{types.VulnerabilityScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌───────────┬──────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Vulnerabilities │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼──────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Deploy/orion │ 2 │ 1 │ 2 │ 1 │ 1 │
|
||||
└───────────┴──────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "Only rbac, all serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Resources: []Resource{roleWithMisconfig},
|
||||
},
|
||||
scanners: types.Scanners{types.RBACScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
RBAC Assessment
|
||||
┌───────────┬─────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ RBAC Assessment │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼─────────────────────────────────────────────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Role/system::leader-locking-kube-controller-manager │ │ │ 1 │ │ │
|
||||
└───────────┴─────────────────────────────────────────────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "Only secret, all serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Resources: []Resource{deployLuaWithSecrets},
|
||||
},
|
||||
scanners: types.Scanners{types.SecretScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌───────────┬────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Secrets │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Deploy/lua │ 1 │ │ 1 │ │ │
|
||||
└───────────┴────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "apiserver, only infra and serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Resources: []Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
scanners: types.Scanners{types.MisconfigScanner},
|
||||
components: []string{infraComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Infra Assessment
|
||||
┌─────────────┬────────────────────┬─────────────────────────────┐
|
||||
│ Namespace │ Resource │ Kubernetes Infra Assessment │
|
||||
│ │ ├─────┬─────┬─────┬─────┬─────┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ 1 │ 1 │ │
|
||||
└─────────────┴────────────────────┴─────┴─────┴─────┴─────┴─────┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "apiserver, vuln,config,secret and serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Resources: []Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
scanners: types.Scanners{
|
||||
types.VulnerabilityScanner,
|
||||
types.MisconfigScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
components: []string{workloadComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌─────────────┬────────────────────┬───────────────────┬───────────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Vulnerabilities │ Misconfigurations │ Secrets │
|
||||
│ │ ├───┬───┬───┬───┬───┼───┬───┬───┬───┬───┼───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ │ │ │ │ 1 │ 1 │ 1 │ │ │ │ │ │ │
|
||||
└─────────────┴────────────────────┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "apiserver, all scanners and serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Resources: []Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
scanners: types.Scanners{
|
||||
types.MisconfigScanner,
|
||||
types.VulnerabilityScanner,
|
||||
types.RBACScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌─────────────┬────────────────────┬───────────────────┬───────────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Vulnerabilities │ Misconfigurations │ Secrets │
|
||||
│ │ ├───┬───┬───┬───┬───┼───┬───┬───┬───┬───┼───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ │ │ │ │ 1 │ 1 │ 1 │ │ │ │ │ │ │
|
||||
└─────────────┴────────────────────┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN
|
||||
|
||||
|
||||
Infra Assessment
|
||||
┌─────────────┬────────────────────┬─────────────────────────────┐
|
||||
│ Namespace │ Resource │ Kubernetes Infra Assessment │
|
||||
│ │ ├─────┬─────┬─────┬─────┬─────┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ 1 │ 1 │ │
|
||||
└─────────────┴────────────────────┴─────┴─────┴─────┴─────┴─────┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
output := bytes.Buffer{}
|
||||
|
||||
opt := Option{
|
||||
Format: "table",
|
||||
Report: "summary",
|
||||
Output: &output,
|
||||
Scanners: tc.scanners,
|
||||
Severities: tc.severities,
|
||||
Components: tc.components,
|
||||
}
|
||||
|
||||
Write(tc.report, opt)
|
||||
|
||||
assert.Equal(t, tc.expectedOutput, stripAnsi(output.String()), tc.name)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
|
||||
|
||||
var ansiRegexp = regexp.MustCompile(ansi)
|
||||
|
||||
func stripAnsi(str string) string {
|
||||
return strings.TrimSpace(ansiRegexp.ReplaceAllString(str, ""))
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func InfraColumns() []string {
|
||||
|
||||
func (tw TableWriter) Write(report Report) error {
|
||||
switch tw.Report {
|
||||
case allReport:
|
||||
case AllReport:
|
||||
t := pkgReport.Writer{Output: tw.Output, Severities: tw.Severities, ShowMessageOnce: &sync.Once{}}
|
||||
for _, r := range report.Resources {
|
||||
if r.Report.Results.Failed() {
|
||||
@@ -51,7 +51,7 @@ func (tw TableWriter) Write(report Report) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
case summaryReport:
|
||||
case SummaryReport:
|
||||
writer := NewSummaryWriter(tw.Output, tw.Severities, tw.ColumnHeading)
|
||||
return writer.Write(report)
|
||||
default:
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
ms "github.com/mitchellh/mapstructure"
|
||||
"github.com/package-url/packageurl-go"
|
||||
|
||||
"github.com/aquasecurity/go-version/pkg/version"
|
||||
|
||||
cdx "github.com/CycloneDX/cyclonedx-go"
|
||||
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/bom"
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/digest"
|
||||
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/report"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/parallel"
|
||||
"github.com/aquasecurity/trivy/pkg/purl"
|
||||
rep "github.com/aquasecurity/trivy/pkg/report"
|
||||
cyc "github.com/aquasecurity/trivy/pkg/sbom/cyclonedx"
|
||||
"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core"
|
||||
"github.com/aquasecurity/trivy/pkg/scanner/local"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
@@ -47,6 +64,17 @@ func (s *Scanner) Scan(ctx context.Context, artifactsData []*artifacts.Artifact)
|
||||
log.Fatal(xerrors.Errorf("can't enable logger error: %w", err))
|
||||
}
|
||||
}()
|
||||
|
||||
if s.opts.Format == rep.FormatCycloneDX {
|
||||
rootComponent, err := clusterInfoToReportResources(artifactsData, s.cluster)
|
||||
if err != nil {
|
||||
return report.Report{}, err
|
||||
}
|
||||
return report.Report{
|
||||
SchemaVersion: 0,
|
||||
RootComponent: rootComponent,
|
||||
}, nil
|
||||
}
|
||||
var resources []report.Resource
|
||||
|
||||
type scanResult struct {
|
||||
@@ -89,6 +117,7 @@ func (s *Scanner) Scan(ctx context.Context, artifactsData []*artifacts.Artifact)
|
||||
ClusterName: s.cluster,
|
||||
Resources: resources,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *Scanner) scanVulns(ctx context.Context, artifact *artifacts.Artifact) ([]report.Resource, error) {
|
||||
@@ -143,3 +172,169 @@ func (s *Scanner) filter(ctx context.Context, r types.Report, artifact *artifact
|
||||
}
|
||||
return report.CreateResource(artifact, r, nil), nil
|
||||
}
|
||||
|
||||
const (
|
||||
golang = "golang"
|
||||
oci = "oci"
|
||||
kubelet = "k8s.io/kubelet"
|
||||
pod = "PodInfo"
|
||||
nodeInfo = "NodeInfo"
|
||||
nodeCoreComponents = "node-core-components"
|
||||
)
|
||||
|
||||
func clusterInfoToReportResources(allArtifact []*artifacts.Artifact, clusterName string) (*core.Component, error) {
|
||||
coreComponents := make([]*core.Component, 0)
|
||||
for _, artifact := range allArtifact {
|
||||
switch artifact.Kind {
|
||||
case pod:
|
||||
var comp bom.Component
|
||||
err := ms.Decode(artifact.RawResource, &comp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
imageComponents := make([]*core.Component, 0)
|
||||
for _, c := range comp.Containers {
|
||||
name := fmt.Sprintf("%s/%s", c.Registry, c.Repository)
|
||||
cDigest := c.Digest
|
||||
if strings.Index(c.Digest, string(digest.SHA256)) == -1 {
|
||||
cDigest = fmt.Sprintf("%s:%s", string(digest.SHA256), cDigest)
|
||||
}
|
||||
version := sanitizedVersion(c.Version)
|
||||
|
||||
imagePURL, err := purl.NewPackageURL(purl.TypeOCI, types.Metadata{
|
||||
RepoDigests: []string{
|
||||
fmt.Sprintf("%s@%s", name, cDigest),
|
||||
},
|
||||
}, ftypes.Package{})
|
||||
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to create PURL: %w", err)
|
||||
}
|
||||
imageComponents = append(imageComponents, &core.Component{
|
||||
PackageURL: &imagePURL,
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: name,
|
||||
Version: cDigest,
|
||||
Properties: map[string]string{
|
||||
cyc.PropertyPkgID: fmt.Sprintf("%s:%s", name, version),
|
||||
cyc.PropertyPkgType: oci,
|
||||
},
|
||||
})
|
||||
}
|
||||
rootComponent := &core.Component{
|
||||
Name: comp.Name,
|
||||
Type: cdx.ComponentTypeApplication,
|
||||
Properties: comp.Properties,
|
||||
Components: imageComponents,
|
||||
}
|
||||
coreComponents = append(coreComponents, rootComponent)
|
||||
case nodeInfo:
|
||||
var nf bom.NodeInfo
|
||||
err := ms.Decode(artifact.RawResource, &nf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
coreComponents = append(coreComponents, nodeComponent(nf))
|
||||
default:
|
||||
return nil, fmt.Errorf("resource kind %s is not supported", artifact.Kind)
|
||||
}
|
||||
}
|
||||
rootComponent := &core.Component{
|
||||
Name: clusterName,
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Components: coreComponents,
|
||||
}
|
||||
return rootComponent, nil
|
||||
}
|
||||
|
||||
func sanitizedVersion(version string) string {
|
||||
return strings.TrimPrefix(version, "v")
|
||||
}
|
||||
|
||||
func osNameVersion(name string) (string, string) {
|
||||
var buffer bytes.Buffer
|
||||
var v string
|
||||
var err error
|
||||
parts := strings.Split(name, " ")
|
||||
for _, p := range parts {
|
||||
_, err = version.Parse(p)
|
||||
if err != nil {
|
||||
buffer.WriteString(p + " ")
|
||||
continue
|
||||
}
|
||||
v = p
|
||||
break
|
||||
}
|
||||
return strings.ToLower(strings.TrimSpace(buffer.String())), v
|
||||
}
|
||||
|
||||
func runtimeNameVersion(name string) (string, string) {
|
||||
parts := strings.Split(name, "://")
|
||||
if len(parts) == 2 {
|
||||
name := parts[0]
|
||||
switch parts[0] {
|
||||
case "cri-o":
|
||||
name = "github.com/cri-o/cri-o"
|
||||
case "containerd":
|
||||
name = "github.com/containerd/containerd"
|
||||
case "cri-dockerd":
|
||||
name = "github.com/Mirantis/cri-dockerd"
|
||||
}
|
||||
return name, parts[1]
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func nodeComponent(nf bom.NodeInfo) *core.Component {
|
||||
osName, osVersion := osNameVersion(nf.OsImage)
|
||||
runtimeName, runtimeVersion := runtimeNameVersion(nf.ContainerRuntimeVersion)
|
||||
kubeletVersion := sanitizedVersion(nf.KubeletVersion)
|
||||
return &core.Component{
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: nf.NodeName,
|
||||
Properties: nf.Properties,
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeOS,
|
||||
Name: osName,
|
||||
Version: osVersion,
|
||||
Properties: map[string]string{
|
||||
"Class": types.ClassOSPkg,
|
||||
"Type": osName,
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeApplication,
|
||||
Name: nodeCoreComponents,
|
||||
Properties: map[string]string{
|
||||
"Class": types.ClassLangPkg,
|
||||
"Type": golang,
|
||||
},
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeLibrary,
|
||||
Name: kubelet,
|
||||
Version: kubeletVersion,
|
||||
Properties: map[string]string{
|
||||
cyc.PropertyPkgType: golang,
|
||||
},
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: *packageurl.NewPackageURL(golang, "", kubelet, kubeletVersion, packageurl.Qualifiers{}, ""),
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeLibrary,
|
||||
Name: runtimeName,
|
||||
Version: runtimeVersion,
|
||||
Properties: map[string]string{
|
||||
cyc.PropertyPkgType: golang,
|
||||
},
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: *packageurl.NewPackageURL(golang, "", runtimeName, runtimeVersion, packageurl.Qualifiers{}, ""),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
246
pkg/k8s/scanner/scanner_test.go
Normal file
246
pkg/k8s/scanner/scanner_test.go
Normal file
@@ -0,0 +1,246 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
cdx "github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/purl"
|
||||
"github.com/package-url/packageurl-go"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
|
||||
cyc "github.com/aquasecurity/trivy/pkg/sbom/cyclonedx"
|
||||
"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestK8sClusterInfoReport(t *testing.T) {
|
||||
flagOpts := flag.Options{ReportOptions: flag.ReportOptions{Format: "cyclonedx"}}
|
||||
tests := []struct {
|
||||
name string
|
||||
clusterName string
|
||||
artifacts []*artifacts.Artifact
|
||||
want *core.Component
|
||||
}{
|
||||
{
|
||||
name: "test cluster info with resources",
|
||||
clusterName: "test-cluster",
|
||||
artifacts: []*artifacts.Artifact{
|
||||
{
|
||||
Namespace: "kube-system",
|
||||
Kind: "PodInfo",
|
||||
Name: "kube-apiserver-kind-control-plane",
|
||||
RawResource: map[string]interface{}{
|
||||
"Containers": []interface{}{map[string]interface{}{
|
||||
"Digest": "18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
|
||||
"ID": "kube-apiserver:v1.21.1",
|
||||
"Registry": "k8s.gcr.io",
|
||||
"Repository": "kube-apiserver",
|
||||
"Version": "v1.21.1",
|
||||
},
|
||||
},
|
||||
"Properties": map[string]string{
|
||||
"ControlPlaneComponents": "kube-apiserver",
|
||||
},
|
||||
"Name": "kube-apiserver-kind-control-plane",
|
||||
"Namespace": "kube-system",
|
||||
},
|
||||
},
|
||||
{
|
||||
Kind: "NodeInfo",
|
||||
Name: "kind-control-plane",
|
||||
RawResource: map[string]interface{}{
|
||||
"ContainerRuntimeVersion": "containerd://1.5.2",
|
||||
"Hostname": "kind-control-plane",
|
||||
"KubeProxyVersion": "6.2.13-300.fc38.aarch64",
|
||||
"KubeletVersion": "v1.21.1",
|
||||
"NodeName": "kind-control-plane",
|
||||
"OsImage": "Ubuntu 21.04",
|
||||
"Properties": map[string]string{
|
||||
"Architecture": "arm64",
|
||||
"HostName": "kind-control-plane",
|
||||
"KernelVersion": "6.2.15-300.fc38.aarch64",
|
||||
"NodeRole": "master",
|
||||
"OperatingSystem": "linux",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &core.Component{
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: "test-cluster",
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeApplication,
|
||||
Name: "kube-apiserver-kind-control-plane",
|
||||
Properties: map[string]string{
|
||||
"ControlPlaneComponents": "kube-apiserver",
|
||||
},
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: "k8s.gcr.io/kube-apiserver",
|
||||
Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: packageurl.PackageURL{
|
||||
Type: "oci",
|
||||
Name: "kube-apiserver",
|
||||
Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
|
||||
Qualifiers: packageurl.Qualifiers{
|
||||
{
|
||||
Key: "repository_url",
|
||||
Value: "k8s.gcr.io/kube-apiserver",
|
||||
},
|
||||
{
|
||||
Key: "arch",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Properties: map[string]string{
|
||||
cyc.PropertyPkgID: "k8s.gcr.io/kube-apiserver:1.21.1",
|
||||
cyc.PropertyPkgType: "oci",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: "kind-control-plane",
|
||||
Properties: map[string]string{
|
||||
"Architecture": "arm64",
|
||||
"HostName": "kind-control-plane",
|
||||
"KernelVersion": "6.2.15-300.fc38.aarch64",
|
||||
"NodeRole": "master",
|
||||
"OperatingSystem": "linux",
|
||||
},
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeOS,
|
||||
Name: "ubuntu",
|
||||
Version: "21.04",
|
||||
Properties: map[string]string{
|
||||
"Class": "os-pkgs",
|
||||
"Type": "ubuntu",
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeApplication,
|
||||
Name: "node-core-components",
|
||||
Properties: map[string]string{
|
||||
"Class": "lang-pkgs",
|
||||
"Type": "golang",
|
||||
},
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeLibrary,
|
||||
Name: "k8s.io/kubelet",
|
||||
Version: "1.21.1",
|
||||
Properties: map[string]string{
|
||||
"PkgType": "golang",
|
||||
},
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: packageurl.PackageURL{
|
||||
Type: "golang",
|
||||
Name: "k8s.io/kubelet",
|
||||
Version: "1.21.1",
|
||||
Qualifiers: packageurl.Qualifiers{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeLibrary,
|
||||
Name: "github.com/containerd/containerd",
|
||||
Version: "1.5.2",
|
||||
Properties: map[string]string{
|
||||
cyc.PropertyPkgType: "golang",
|
||||
},
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: packageurl.PackageURL{
|
||||
Type: "golang",
|
||||
Name: "github.com/containerd/containerd",
|
||||
Version: "1.5.2",
|
||||
Qualifiers: packageurl.Qualifiers{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
runner, err := cmd.NewRunner(ctx, flagOpts)
|
||||
assert.NoError(t, err)
|
||||
scanner := NewScanner(tt.clusterName, runner, flagOpts)
|
||||
got, err := scanner.Scan(ctx, tt.artifacts)
|
||||
sortNodeComponents(got.RootComponent)
|
||||
sortNodeComponents(tt.want)
|
||||
assert.Equal(t, tt.want, got.RootComponent)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func sortNodeComponents(component *core.Component) {
|
||||
nodeComp := findComponentByName(component, "node-core-components")
|
||||
sort.Slice(nodeComp.Components, func(i, j int) bool {
|
||||
return nodeComp.Components[i].Name < nodeComp.Components[j].Name
|
||||
})
|
||||
}
|
||||
|
||||
func findComponentByName(component *core.Component, compName string) *core.Component {
|
||||
if component.Name == compName {
|
||||
return component
|
||||
}
|
||||
var fComp *core.Component
|
||||
for _, comp := range component.Components {
|
||||
fComp = findComponentByName(comp, compName)
|
||||
}
|
||||
return fComp
|
||||
}
|
||||
|
||||
func TestTestOsNameVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
nameVersion string
|
||||
compName string
|
||||
compVersion string
|
||||
}{
|
||||
|
||||
{
|
||||
name: "valid version",
|
||||
nameVersion: "ubuntu 20.04",
|
||||
compName: "ubuntu",
|
||||
compVersion: "20.04",
|
||||
},
|
||||
{
|
||||
name: "valid sem version",
|
||||
nameVersion: "ubuntu 20.04.1",
|
||||
compName: "ubuntu",
|
||||
compVersion: "20.04.1",
|
||||
},
|
||||
{
|
||||
name: "non valid version",
|
||||
nameVersion: "ubuntu",
|
||||
compName: "ubuntu",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
name, version := osNameVersion(tt.nameVersion)
|
||||
assert.Equal(t, name, tt.compName)
|
||||
assert.Equal(t, version, tt.compVersion)
|
||||
})
|
||||
}
|
||||
}
|
||||
56
pkg/k8s/writer.go
Normal file
56
pkg/k8s/writer.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/report"
|
||||
|
||||
cdx "github.com/CycloneDX/cyclonedx-go"
|
||||
|
||||
rp "github.com/aquasecurity/trivy/pkg/report"
|
||||
"github.com/aquasecurity/trivy/pkg/report/table"
|
||||
)
|
||||
|
||||
type Writer interface {
|
||||
Write(report.Report) error
|
||||
}
|
||||
|
||||
// Write writes the results in the give format
|
||||
func Write(k8sreport report.Report, option report.Option) error {
|
||||
k8sreport.PrintErrors()
|
||||
|
||||
switch option.Format {
|
||||
case rp.FormatJSON:
|
||||
jwriter := report.JSONWriter{
|
||||
Output: option.Output,
|
||||
Report: option.Report,
|
||||
}
|
||||
return jwriter.Write(k8sreport)
|
||||
case rp.FormatTable:
|
||||
separatedReports := report.SeparateMisconfigReports(k8sreport, option.Scanners, option.Components)
|
||||
|
||||
if option.Report == report.SummaryReport {
|
||||
target := fmt.Sprintf("Summary Report for %s", k8sreport.ClusterName)
|
||||
table.RenderTarget(option.Output, target, table.IsOutputToTerminal(option.Output))
|
||||
}
|
||||
|
||||
for _, r := range separatedReports {
|
||||
writer := &report.TableWriter{
|
||||
Output: option.Output,
|
||||
Report: option.Report,
|
||||
Severities: option.Severities,
|
||||
ColumnHeading: report.ColumnHeading(option.Scanners, option.Components, r.Columns),
|
||||
}
|
||||
|
||||
if err := writer.Write(r.Report); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
case rp.FormatCycloneDX:
|
||||
w := report.NewCycloneDXWriter(option.Output, cdx.BOMFileFormatJSON, option.APIVersion)
|
||||
return w.Write(k8sreport.RootComponent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
409
pkg/k8s/writer_test.go
Normal file
409
pkg/k8s/writer_test.go
Normal file
@@ -0,0 +1,409 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/report"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
const (
|
||||
AllReport = "all"
|
||||
SummaryReport = "summary"
|
||||
|
||||
tableFormat = "table"
|
||||
jsonFormat = "json"
|
||||
cycloneDXFormat = "cyclonedx"
|
||||
|
||||
workloadComponent = "workload"
|
||||
infraComponent = "infra"
|
||||
)
|
||||
|
||||
var (
|
||||
roleWithMisconfig = report.Resource{
|
||||
Namespace: "default",
|
||||
Kind: "Role",
|
||||
Name: "system::leader-locking-kube-controller-manager",
|
||||
Results: types.Results{
|
||||
{
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{
|
||||
ID: "ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
apiseverPodWithMisconfigAndInfra = report.Resource{
|
||||
Namespace: "kube-system",
|
||||
Kind: "Pod",
|
||||
Name: "kube-apiserver",
|
||||
Results: types.Results{
|
||||
{
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{
|
||||
ID: "KSV-ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "KSV-ID101",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
{
|
||||
ID: "KSV-ID102",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
|
||||
{
|
||||
ID: "KCV-ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "KCV-ID101",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
deployLuaWithSecrets = report.Resource{
|
||||
Namespace: "default",
|
||||
Kind: "Deploy",
|
||||
Name: "lua",
|
||||
Results: types.Results{
|
||||
{
|
||||
Secrets: []ftypes.SecretFinding{
|
||||
{
|
||||
RuleID: "secret1",
|
||||
Severity: "CRITICAL",
|
||||
},
|
||||
{
|
||||
RuleID: "secret2",
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
deployOrionWithMisconfigs = report.Resource{
|
||||
Namespace: "default",
|
||||
Kind: "Deploy",
|
||||
Name: "orion",
|
||||
Results: types.Results{
|
||||
{
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{
|
||||
ID: "ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "ID101",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
{
|
||||
ID: "ID102",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
{
|
||||
ID: "ID103",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "CRITICAL",
|
||||
},
|
||||
{
|
||||
ID: "ID104",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "UNKNOWN",
|
||||
},
|
||||
{
|
||||
ID: "ID105",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "ID106",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
deployOrionWithVulns = report.Resource{
|
||||
Namespace: "default",
|
||||
Kind: "Deploy",
|
||||
Name: "orion",
|
||||
Results: types.Results{
|
||||
{
|
||||
Vulnerabilities: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-1111",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "LOW"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-2222",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-3333",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "HIGH"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-4444",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-5555",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "UNKNOWN"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-6666",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-7777",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func TestReportWrite_Summary(t *testing.T) {
|
||||
allSeverities := []dbTypes.Severity{
|
||||
dbTypes.SeverityUnknown,
|
||||
dbTypes.SeverityLow,
|
||||
dbTypes.SeverityMedium,
|
||||
dbTypes.SeverityHigh,
|
||||
dbTypes.SeverityCritical,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
report report.Report
|
||||
opt report.Option
|
||||
scanners types.Scanners
|
||||
components []string
|
||||
severities []dbTypes.Severity
|
||||
expectedOutput string
|
||||
}{
|
||||
{
|
||||
name: "Only config, all serverities",
|
||||
report: report.Report{
|
||||
ClusterName: "test",
|
||||
Resources: []report.Resource{deployOrionWithMisconfigs},
|
||||
},
|
||||
scanners: types.Scanners{types.MisconfigScanner},
|
||||
components: []string{workloadComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌───────────┬──────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Misconfigurations │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼──────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Deploy/orion │ 1 │ 2 │ 1 │ 2 │ 1 │
|
||||
└───────────┴──────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "Only vuln, all serverities",
|
||||
report: report.Report{
|
||||
ClusterName: "test",
|
||||
Resources: []report.Resource{deployOrionWithVulns},
|
||||
},
|
||||
scanners: types.Scanners{types.VulnerabilityScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌───────────┬──────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Vulnerabilities │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼──────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Deploy/orion │ 2 │ 1 │ 2 │ 1 │ 1 │
|
||||
└───────────┴──────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "Only rbac, all serverities",
|
||||
report: report.Report{
|
||||
ClusterName: "test",
|
||||
Resources: []report.Resource{roleWithMisconfig},
|
||||
},
|
||||
scanners: types.Scanners{types.RBACScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
RBAC Assessment
|
||||
┌───────────┬─────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ RBAC Assessment │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼─────────────────────────────────────────────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Role/system::leader-locking-kube-controller-manager │ │ │ 1 │ │ │
|
||||
└───────────┴─────────────────────────────────────────────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "Only secret, all serverities",
|
||||
report: report.Report{
|
||||
ClusterName: "test",
|
||||
Resources: []report.Resource{deployLuaWithSecrets},
|
||||
},
|
||||
scanners: types.Scanners{types.SecretScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌───────────┬────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Secrets │
|
||||
│ │ ├───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├───────────┼────────────┼───┼───┼───┼───┼───┤
|
||||
│ default │ Deploy/lua │ 1 │ │ 1 │ │ │
|
||||
└───────────┴────────────┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "apiserver, only infra and serverities",
|
||||
report: report.Report{
|
||||
ClusterName: "test",
|
||||
Resources: []report.Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
scanners: types.Scanners{types.MisconfigScanner},
|
||||
components: []string{infraComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Infra Assessment
|
||||
┌─────────────┬────────────────────┬─────────────────────────────┐
|
||||
│ Namespace │ Resource │ Kubernetes Infra Assessment │
|
||||
│ │ ├─────┬─────┬─────┬─────┬─────┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ 1 │ 1 │ │
|
||||
└─────────────┴────────────────────┴─────┴─────┴─────┴─────┴─────┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "apiserver, vuln,config,secret and serverities",
|
||||
report: report.Report{
|
||||
ClusterName: "test",
|
||||
Resources: []report.Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
scanners: types.Scanners{
|
||||
types.VulnerabilityScanner,
|
||||
types.MisconfigScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
components: []string{workloadComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌─────────────┬────────────────────┬───────────────────┬───────────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Vulnerabilities │ Misconfigurations │ Secrets │
|
||||
│ │ ├───┬───┬───┬───┬───┼───┬───┬───┬───┬───┼───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ │ │ │ │ 1 │ 1 │ 1 │ │ │ │ │ │ │
|
||||
└─────────────┴────────────────────┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "apiserver, all scanners and serverities",
|
||||
report: report.Report{
|
||||
ClusterName: "test",
|
||||
Resources: []report.Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
scanners: types.Scanners{
|
||||
types.MisconfigScanner,
|
||||
types.VulnerabilityScanner,
|
||||
types.RBACScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
|
||||
Workload Assessment
|
||||
┌─────────────┬────────────────────┬───────────────────┬───────────────────┬───────────────────┐
|
||||
│ Namespace │ Resource │ Vulnerabilities │ Misconfigurations │ Secrets │
|
||||
│ │ ├───┬───┬───┬───┬───┼───┬───┬───┬───┬───┼───┬───┬───┬───┬───┤
|
||||
│ │ │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ │ │ │ │ 1 │ 1 │ 1 │ │ │ │ │ │ │
|
||||
└─────────────┴────────────────────┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN
|
||||
|
||||
|
||||
Infra Assessment
|
||||
┌─────────────┬────────────────────┬─────────────────────────────┐
|
||||
│ Namespace │ Resource │ Kubernetes Infra Assessment │
|
||||
│ │ ├─────┬─────┬─────┬─────┬─────┤
|
||||
│ │ │ C │ H │ M │ L │ U │
|
||||
├─────────────┼────────────────────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ kube-system │ Pod/kube-apiserver │ │ │ 1 │ 1 │ │
|
||||
└─────────────┴────────────────────┴─────┴─────┴─────┴─────┴─────┘
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
output := bytes.Buffer{}
|
||||
|
||||
opt := report.Option{
|
||||
Format: "table",
|
||||
Report: "summary",
|
||||
Output: &output,
|
||||
Scanners: tc.scanners,
|
||||
Severities: tc.severities,
|
||||
Components: tc.components,
|
||||
}
|
||||
|
||||
Write(tc.report, opt)
|
||||
|
||||
assert.Equal(t, tc.expectedOutput, stripAnsi(output.String()), tc.name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
|
||||
|
||||
var ansiRegexp = regexp.MustCompile(ansi)
|
||||
|
||||
func stripAnsi(str string) string {
|
||||
return strings.TrimSpace(ansiRegexp.ReplaceAllString(str, ""))
|
||||
}
|
||||
337
pkg/sbom/cyclonedx/core/cyclonedx_test.go
Normal file
337
pkg/sbom/cyclonedx/core/cyclonedx_test.go
Normal file
@@ -0,0 +1,337 @@
|
||||
package core_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/digest"
|
||||
"github.com/aquasecurity/trivy/pkg/purl"
|
||||
"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core"
|
||||
|
||||
cdx "github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/google/uuid"
|
||||
"github.com/package-url/packageurl-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
fake "k8s.io/utils/clock/testing"
|
||||
)
|
||||
|
||||
func TestMarshaler_CoreComponent(t *testing.T) {
|
||||
noDepRefs := []string{}
|
||||
tests := []struct {
|
||||
name string
|
||||
rootComponent *core.Component
|
||||
want *cdx.BOM
|
||||
}{
|
||||
{
|
||||
name: "marshal CoreComponent",
|
||||
rootComponent: &core.Component{
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: "test-cluster",
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeApplication,
|
||||
Name: "kube-apiserver-kind-control-plane",
|
||||
Properties: map[string]string{
|
||||
"control_plane_components": "kube-apiserver",
|
||||
},
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: "k8s.gcr.io/kube-apiserver",
|
||||
Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: packageurl.PackageURL{
|
||||
Type: "oci",
|
||||
Name: "kube-apiserver",
|
||||
Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
|
||||
Qualifiers: packageurl.Qualifiers{
|
||||
{
|
||||
Key: "repository_url",
|
||||
Value: "k8s.gcr.io/kube-apiserver",
|
||||
},
|
||||
{
|
||||
Key: "arch",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Hashes: []digest.Digest{"sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f"},
|
||||
Properties: map[string]string{
|
||||
"PkgID": "k8s.gcr.io/kube-apiserver:1.21.1",
|
||||
"PkgType": "oci",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
Name: "kind-control-plane",
|
||||
Properties: map[string]string{
|
||||
"architecture": "arm64",
|
||||
"host_name": "kind-control-plane",
|
||||
"kernel_version": "6.2.13-300.fc38.aarch64",
|
||||
"node_role": "master",
|
||||
"operating_system": "linux",
|
||||
},
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeOS,
|
||||
Name: "ubuntu",
|
||||
Version: "21.04",
|
||||
Properties: map[string]string{
|
||||
"Class": "os-pkgs",
|
||||
"Type": "ubuntu",
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeApplication,
|
||||
Name: "node-core-components",
|
||||
Properties: map[string]string{
|
||||
"Class": "lang-pkgs",
|
||||
"Type": "golang",
|
||||
},
|
||||
Components: []*core.Component{
|
||||
{
|
||||
Type: cdx.ComponentTypeLibrary,
|
||||
Name: "kubelet",
|
||||
Version: "1.21.1",
|
||||
Properties: map[string]string{
|
||||
"PkgType": "golang",
|
||||
},
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: packageurl.PackageURL{
|
||||
Type: "golang",
|
||||
Name: "kubelet",
|
||||
Version: "1.21.1",
|
||||
Qualifiers: packageurl.Qualifiers{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: cdx.ComponentTypeLibrary,
|
||||
Name: "containerd",
|
||||
Version: "1.5.2",
|
||||
Properties: map[string]string{
|
||||
"PkgType": "golang",
|
||||
},
|
||||
PackageURL: &purl.PackageURL{
|
||||
PackageURL: packageurl.PackageURL{
|
||||
Type: "golang",
|
||||
Name: "containerd",
|
||||
Version: "1.5.2",
|
||||
Qualifiers: packageurl.Qualifiers{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
want: &cdx.BOM{
|
||||
XMLNS: "http://cyclonedx.org/schema/bom/1.4",
|
||||
BOMFormat: "CycloneDX",
|
||||
SerialNumber: "urn:uuid:3ff14136-e09f-4df9-80ea-000000000001",
|
||||
SpecVersion: cdx.SpecVersion1_4,
|
||||
Version: 1,
|
||||
Metadata: &cdx.Metadata{
|
||||
Timestamp: "2021-08-25T12:20:30+00:00",
|
||||
Tools: &[]cdx.Tool{
|
||||
{
|
||||
Name: "trivy",
|
||||
Vendor: "aquasecurity",
|
||||
Version: "dev",
|
||||
},
|
||||
},
|
||||
Component: &cdx.Component{
|
||||
BOMRef: "3ff14136-e09f-4df9-80ea-000000000002",
|
||||
Name: "test-cluster",
|
||||
Properties: &[]cdx.Property{},
|
||||
Type: cdx.ComponentTypeContainer,
|
||||
},
|
||||
},
|
||||
Vulnerabilities: &[]cdx.Vulnerability{},
|
||||
Components: &[]cdx.Component{
|
||||
{
|
||||
BOMRef: "3ff14136-e09f-4df9-80ea-000000000003",
|
||||
Type: "application",
|
||||
Name: "kube-apiserver-kind-control-plane",
|
||||
Properties: &[]cdx.Property{
|
||||
{
|
||||
Name: "aquasecurity:trivy:control_plane_components",
|
||||
Value: "kube-apiserver",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BOMRef: "3ff14136-e09f-4df9-80ea-000000000004",
|
||||
Type: "container",
|
||||
Name: "kind-control-plane",
|
||||
Properties: &[]cdx.Property{
|
||||
{
|
||||
Name: "aquasecurity:trivy:architecture",
|
||||
Value: "arm64",
|
||||
},
|
||||
{
|
||||
Name: "aquasecurity:trivy:host_name",
|
||||
Value: "kind-control-plane",
|
||||
},
|
||||
{
|
||||
Name: "aquasecurity:trivy:kernel_version",
|
||||
Value: "6.2.13-300.fc38.aarch64",
|
||||
},
|
||||
{
|
||||
Name: "aquasecurity:trivy:node_role",
|
||||
Value: "master",
|
||||
},
|
||||
{
|
||||
Name: "aquasecurity:trivy:operating_system",
|
||||
Value: "linux",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BOMRef: "3ff14136-e09f-4df9-80ea-000000000005",
|
||||
Type: "operating-system",
|
||||
Name: "ubuntu",
|
||||
Version: "21.04",
|
||||
Properties: &[]cdx.Property{
|
||||
{
|
||||
Name: "aquasecurity:trivy:Class",
|
||||
Value: "os-pkgs",
|
||||
},
|
||||
{
|
||||
Name: "aquasecurity:trivy:Type",
|
||||
Value: "ubuntu",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BOMRef: "3ff14136-e09f-4df9-80ea-000000000006",
|
||||
Type: "application",
|
||||
Name: "node-core-components",
|
||||
Properties: &[]cdx.Property{
|
||||
{
|
||||
Name: "aquasecurity:trivy:Class",
|
||||
Value: "lang-pkgs",
|
||||
},
|
||||
{
|
||||
Name: "aquasecurity:trivy:Type",
|
||||
Value: "golang",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BOMRef: "pkg:golang/containerd@1.5.2",
|
||||
Type: "library",
|
||||
Name: "containerd",
|
||||
Version: "1.5.2",
|
||||
PackageURL: "pkg:golang/containerd@1.5.2",
|
||||
Properties: &[]cdx.Property{
|
||||
{
|
||||
Name: "aquasecurity:trivy:PkgType",
|
||||
Value: "golang",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BOMRef: "pkg:golang/kubelet@1.21.1",
|
||||
Type: "library",
|
||||
Name: "kubelet",
|
||||
Version: "1.21.1",
|
||||
PackageURL: "pkg:golang/kubelet@1.21.1",
|
||||
Properties: &[]cdx.Property{
|
||||
{
|
||||
Name: "aquasecurity:trivy:PkgType",
|
||||
Value: "golang",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BOMRef: "pkg:oci/kube-apiserver@sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?repository_url=k8s.gcr.io%2Fkube-apiserver&arch=",
|
||||
Hashes: &[]cdx.Hash{
|
||||
{
|
||||
Algorithm: "SHA-256",
|
||||
Value: "18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
|
||||
},
|
||||
},
|
||||
Type: "container",
|
||||
Name: "k8s.gcr.io/kube-apiserver",
|
||||
Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
|
||||
PackageURL: "pkg:oci/kube-apiserver@sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?repository_url=k8s.gcr.io%2Fkube-apiserver&arch=",
|
||||
Properties: &[]cdx.Property{
|
||||
{
|
||||
Name: "aquasecurity:trivy:PkgID",
|
||||
Value: "k8s.gcr.io/kube-apiserver:1.21.1",
|
||||
},
|
||||
{
|
||||
Name: "aquasecurity:trivy:PkgType",
|
||||
Value: "oci",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: &[]cdx.Dependency{
|
||||
{
|
||||
Ref: "3ff14136-e09f-4df9-80ea-000000000002",
|
||||
Dependencies: &[]string{
|
||||
"3ff14136-e09f-4df9-80ea-000000000003",
|
||||
"3ff14136-e09f-4df9-80ea-000000000004",
|
||||
},
|
||||
},
|
||||
{
|
||||
Ref: "3ff14136-e09f-4df9-80ea-000000000003",
|
||||
Dependencies: &[]string{"pkg:oci/kube-apiserver@sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?repository_url=k8s.gcr.io%2Fkube-apiserver&arch="},
|
||||
},
|
||||
{
|
||||
Ref: "3ff14136-e09f-4df9-80ea-000000000004",
|
||||
Dependencies: &[]string{
|
||||
"3ff14136-e09f-4df9-80ea-000000000005",
|
||||
"3ff14136-e09f-4df9-80ea-000000000006",
|
||||
},
|
||||
},
|
||||
{
|
||||
Ref: "3ff14136-e09f-4df9-80ea-000000000005",
|
||||
Dependencies: &noDepRefs,
|
||||
},
|
||||
{
|
||||
Ref: "3ff14136-e09f-4df9-80ea-000000000006",
|
||||
Dependencies: &[]string{
|
||||
"pkg:golang/containerd@1.5.2",
|
||||
"pkg:golang/kubelet@1.21.1",
|
||||
},
|
||||
},
|
||||
{
|
||||
Ref: "pkg:golang/containerd@1.5.2",
|
||||
Dependencies: &noDepRefs,
|
||||
},
|
||||
{
|
||||
Ref: "pkg:golang/kubelet@1.21.1",
|
||||
Dependencies: &noDepRefs,
|
||||
},
|
||||
{
|
||||
Ref: "pkg:oci/kube-apiserver@sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?repository_url=k8s.gcr.io%2Fkube-apiserver&arch=",
|
||||
Dependencies: &noDepRefs,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
clock := fake.NewFakeClock(time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC))
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var count int
|
||||
newUUID := func() uuid.UUID {
|
||||
count++
|
||||
return uuid.Must(uuid.Parse(fmt.Sprintf("3ff14136-e09f-4df9-80ea-%012d", count)))
|
||||
}
|
||||
marshaler := core.NewCycloneDX("dev", core.WithClock(clock), core.WithNewUUID(newUUID))
|
||||
got := marshaler.Marshal(tt.rootComponent)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user