feat: support config scanning (#931)

This commit is contained in:
Teppei Fukuda
2021-07-09 08:18:53 +03:00
committed by GitHub
parent 712f9eba35
commit a0e5c3a2e2
122 changed files with 4499 additions and 1226 deletions

View File

@@ -14,10 +14,12 @@ jobs:
scan-type: 'fs'
exit-code: '1'
severity: 'CRITICAL'
skip-dirs: integration
- name: Run Trivy vulnerability scanner to scan for Medium and High Vulnerabilities
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
exit-code: '0'
severity: 'HIGH,MEDIUM'
severity: 'HIGH,MEDIUM'
skip-dirs: integration

2
.gitignore vendored
View File

@@ -23,7 +23,7 @@ thumbs.db
# test fixtures
coverage.txt
integration/testdata/fixtures/
integration/testdata/fixtures/images
# SBOMs generated during CI
/bom.json

View File

@@ -6,12 +6,10 @@ linters-settings:
check-shadowing: false
gofmt:
simplify: false
golint:
min-confidence: 0
revive:
ignore-generated-header: true
gocyclo:
min-complexity: 10
maligned:
suggest-new: true
dupl:
threshold: 100
goconst:
@@ -32,14 +30,13 @@ linters:
- errcheck
- varcheck
- deadcode
- golint
- revive
- gosec
- unconvert
- goconst
- gocyclo
- gofmt
- goimports
- maligned
- misspell
run:

View File

@@ -33,11 +33,11 @@ $(GOBIN)/golangci-lint:
test:
go test -v -short -coverprofile=coverage.txt -covermode=atomic ./...
integration/testdata/fixtures/*.tar.gz:
git clone https://github.com/aquasecurity/trivy-test-images.git integration/testdata/fixtures
integration/testdata/fixtures/images/*.tar.gz:
git clone https://github.com/aquasecurity/trivy-test-images.git integration/testdata/fixtures/images
.PHONY: test-integration
test-integration: integration/testdata/fixtures/*.tar.gz
test-integration: integration/testdata/fixtures/images/*.tar.gz
go test -v -tags=integration ./integration/...
.PHONY: lint
@@ -62,7 +62,7 @@ install:
.PHONY: clean
clean:
rm -rf integration/testdata/fixtures/
rm -rf integration/testdata/fixtures/images
$(GOBIN)/labeler:
go install github.com/knqyf263/labeler@latest

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 622 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

8
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/fanal v0.0.0-20210628083154-9556a040f4ad
github.com/aquasecurity/fanal v0.0.0-20210707195741-f86e1e4589eb
github.com/aquasecurity/go-dep-parser v0.0.0-20210520015931-0dd56983cc62
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798
@@ -21,6 +21,7 @@ require (
github.com/docker/docker v20.10.3+incompatible
github.com/docker/go-connections v0.4.0
github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d // indirect
github.com/fatih/color v1.10.0
github.com/go-redis/redis/v8 v8.4.0
github.com/goccy/go-yaml v1.8.2 // indirect
github.com/golang/protobuf v1.4.3
@@ -36,7 +37,7 @@ require (
github.com/kylelemons/godebug v1.1.0
github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08
github.com/mitchellh/copystructure v1.1.1 // indirect
github.com/olekukonko/tablewriter v0.0.4
github.com/olekukonko/tablewriter v0.0.5
github.com/open-policy-agent/opa v0.25.2
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/smartystreets/assertions v1.2.0 // indirect
@@ -44,10 +45,9 @@ require (
github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.7.0
github.com/testcontainers/testcontainers-go v0.9.1-0.20210218153226-c8e070a2f18d
github.com/twitchtv/twirp v8.0.0+incompatible
github.com/twitchtv/twirp v8.1.0+incompatible
github.com/urfave/cli/v2 v2.3.0
go.uber.org/zap v1.16.0
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1

132
go.sum
View File

@@ -47,7 +47,6 @@ contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrL
contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw=
contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA=
cuelang.org/go v0.0.15/go.mod h1:gehQASsTv+lFZknWIG0hANGVSBiHD7HyKWmAdEZL3No=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
@@ -101,7 +100,6 @@ github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0 h1:wykTgKwhVr2t2qs+xI020s6W5dt614QqCHV+7W9dg64=
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs=
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
github.com/KeisukeYamashita/go-vcl v0.4.0/go.mod h1:af2qGlXbsHDQN5abN7hyGNKtGhcFSaDdbLl4sfud+AU=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
@@ -142,9 +140,9 @@ github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdc
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
@@ -157,7 +155,6 @@ github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZp
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis/v2 v2.14.1 h1:GjlbSeoJ24bzdLRs13HoMEeaRZx9kg5nHoRW7QV/nCs=
github.com/alicebob/miniredis/v2 v2.14.1/go.mod h1:uS970Sw5Gs9/iK3yBg0l9Uj9s25wXxSpQUE9EaJ/Blg=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@@ -167,15 +164,18 @@ github.com/apex/log v1.3.0/go.mod h1:jd8Vpsr46WAe3EZSQ/IUMs2qQD/GOycT5rPWCO1yGcs
github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE=
github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbjdL7GzRt3F8NvfJ0=
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
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/fanal v0.0.0-20210628083154-9556a040f4ad h1:YnvGxCuiIQeXVpo4XO62vaaegXIRWz1+fl7bhTi/sU8=
github.com/aquasecurity/fanal v0.0.0-20210628083154-9556a040f4ad/go.mod h1:s4rJj8D45R28N3PNz5+hpjSHzD3YhaIbYrQtuYciGdY=
github.com/aquasecurity/fanal v0.0.0-20210707195741-f86e1e4589eb h1:sgCQk8pFttzZIN0w54SxSElNkrUYWBw1Xt3vQQBk4tQ=
github.com/aquasecurity/fanal v0.0.0-20210707195741-f86e1e4589eb/go.mod h1:zl2aczB7UrczEeMgKTRH6Xp/Lf+gxf0W7kXRjaOubrU=
github.com/aquasecurity/go-dep-parser v0.0.0-20210520015931-0dd56983cc62 h1:aahEMQZXrwhpCMlDgXi2d7jJVNDTpYGJOgLyNptGQoY=
github.com/aquasecurity/go-dep-parser v0.0.0-20210520015931-0dd56983cc62/go.mod h1:Cv/FOCXy6gwvDbz/KX48+y//SmbnKroFwW5hquXn5G4=
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=
@@ -213,11 +213,11 @@ github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.31.6 h1:nKjQbpXhdImctBh1e0iLg9iQW/X297LPPuY/9f92R2k=
github.com/aws/aws-sdk-go v1.31.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk=
github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -230,6 +230,8 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U=
github.com/bombsimon/wsl/v2 v2.2.0/go.mod h1:Azh8c3XGEJl9LyX0/sFC+CKMc7Ssgua0g+6abzXN4Pg=
@@ -271,8 +273,6 @@ github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/apd/v2 v2.0.1/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
@@ -296,7 +296,6 @@ github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
github.com/containerd/containerd v1.4.4 h1:rtRG4N6Ct7GNssATwgpvMGfnjnwfjnu/Zs9W3Ikzq+M=
github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e h1:6JKvHHt396/qabvMhnhUZvWaHZzfVfldxE60TK8YLhg=
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
@@ -342,7 +341,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
@@ -355,11 +353,9 @@ github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQ
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20190925022749-754388324470/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v20.10.0-beta1.0.20201029214301-1d20b15adc38+incompatible h1:r99CiNpN5pxrSuSH36suYxrbLxFOhBvQ0sEH6624MHs=
github.com/docker/cli v20.10.0-beta1.0.20201029214301-1d20b15adc38+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v2.6.0-rc.1.0.20180327202408-83389a148052+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
@@ -368,7 +364,6 @@ github.com/docker/docker v0.0.0-20200511152416-a93e9eb0e95c/go.mod h1:eEKB0N0r5N
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20180531152204-71cd53e4a197/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v17.12.0-ce-rc1.0.20200730172259-9f28837c1d93+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.0-beta1.0.20201110211921-af34b94a78a1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.3+incompatible h1:+HS4XO73J41FpA260ztGujJ+0WibrA2TPJEnWNSyGNE=
@@ -401,7 +396,6 @@ github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/proto v1.6.15/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
@@ -431,7 +425,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-akka/configuration v0.0.0-20200606091224-a002c0330665/go.mod h1:19bUnum2ZAeftfwwLZ/wRe7idyfoW2MfmXO464Hrfbw=
github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g=
github.com/go-critic/go-critic v0.4.3/go.mod h1:j4O3D4RoIwRqlZw5jJpx0BNfXWWbpcJoKu5cYSe4YmQ=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
@@ -446,7 +439,6 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
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-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-ini/ini v1.62.0/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=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
@@ -507,7 +499,6 @@ github.com/goccy/go-yaml v1.8.2 h1:gDYrSN12XK/wQTFjxWIgcIqjNCV/Zb5V09M7cq+dbCs=
github.com/goccy/go-yaml v1.8.2/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godoctor/godoctor v0.0.0-20181123222458-69df17f3a6f6/go.mod h1:+tyhT8jBF8E0XvdlSXOSL7Iko7DlNiongHq3q+wcsPs=
github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
@@ -585,8 +576,9 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-containerregistry v0.0.0-20191010200024-a3d713f9b7f8/go.mod h1:KyKXa9ciM8+lgMXwOVsXi7UxGrsf9mM61Mzs+xKUrKE=
github.com/google/go-containerregistry v0.0.0-20200331213917-3d03ed9b1ca2/go.mod h1:pD1UFYs7MCAx+ZLShBdttcaOSbyc8F9Na/9IZLNwJeA=
github.com/google/go-containerregistry v0.1.2 h1:YjFNKqxzWUVZND8d4ItF9wuYlE75WQfECE7yKX/Nu3o=
@@ -596,7 +588,6 @@ github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+u
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
github.com/google/go-github/v33 v33.0.0 h1:qAf9yP0qc54ufQxzwv+u9H0tiVOnPJxo0lI/JXqw3ZM=
github.com/google/go-github/v33 v33.0.0/go.mod h1:GMdDnVZY/2TsWgp/lkYnpSAh6TrzhANBBwm6k6TTEXg=
github.com/google/go-jsonnet v0.17.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
@@ -680,20 +671,21 @@ github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoP
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-getter v1.5.2 h1:XDo8LiAcDisiqZdv0TKgz+HtX3WN7zA2JD1R1tjsabE=
github.com/hashicorp/go-getter v1.5.2/go.mod h1:orNH3BTYLu/fIxGIdLjLoAJHWMDQ/UKQr5O4m3iBuoo=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.15.0 h1:qMuK0wxsoW4D0ddCCYwPSTm4KQv1X1ke3WmPWZ0Mvsk=
github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
@@ -707,18 +699,22 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/hcl/v2 v2.6.0 h1:3krZOfGY6SziUXa6H9PJU6TyohHn7I+ARYnhbeNBz+o=
github.com/hashicorp/hcl/v2 v2.6.0/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
github.com/hashicorp/hcl/v2 v2.10.0 h1:1S1UnuhDGlv3gRFV4+0EdwB+znNP5HmcGbIqwnSCByg=
github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
@@ -733,6 +729,7 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
@@ -748,8 +745,11 @@ github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
@@ -769,7 +769,6 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@@ -811,13 +810,15 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/liamg/clinch v1.5.6/go.mod h1:IXM+nLBuZ5sOQAYYf9+G51nkaA0WY9cszxE5nPXexhE=
github.com/liamg/tml v0.3.0/go.mod h1:0h4EAV/zBOsqI91EWONedjRpO8O0itjGJVd+wG5eC+E=
github.com/liamg/tml v0.4.0/go.mod h1:0h4EAV/zBOsqI91EWONedjRpO8O0itjGJVd+wG5eC+E=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls=
@@ -856,9 +857,9 @@ github.com/mattn/go-jsonpointer v0.0.0-20180225143300-37667080efed/go.mod h1:SDJ
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
@@ -876,8 +877,9 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
@@ -912,7 +914,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY=
github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -938,8 +939,8 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -962,8 +963,6 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/open-policy-agent/conftest v0.23.0 h1:i/cmUjNKDz973vR1cm+x3DqTei/jBPosPvjeot6+p9M=
github.com/open-policy-agent/conftest v0.23.0/go.mod h1:NA6+vKd93pb04H9jiV3WRGJKLj/pzYdQg7XCdoPPUDI=
github.com/open-policy-agent/opa v0.25.2 h1:zTQuUMvB5xkYixKB9LFVbUd7DcUt1jfS0QKTo+/Vfyc=
github.com/open-policy-agent/opa v0.25.2/go.mod h1:iGThTRECCfKQKICueOZkXUi0opN7BR3qiAnIrNHCmlI=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -998,6 +997,7 @@ github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/owenrumney/go-sarif v1.0.11/go.mod h1:hTBFbxU7GuVRUvwMx+eStp9M/Oun4xHCS3vqpPvket8=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ=
github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
@@ -1009,7 +1009,6 @@ github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/peterh/liner v0.0.0-20170211195444-bf27d3ba8e1d/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -1019,6 +1018,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -1066,12 +1066,14 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/testscript v1.1.0/go.mod h1:lzMlnW8LS56mcdJoQYkrlzqOoTFCOemzt5LusJ93bDM=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
@@ -1100,7 +1102,6 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shteou/go-ignore v0.3.0/go.mod h1:+MO315cnlHh5qKX1xSa41OlWzOuAecXCNwcKUcbL+f0=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@@ -1139,6 +1140,7 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -1151,7 +1153,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
@@ -1163,7 +1164,6 @@ github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -1181,6 +1181,8 @@ github.com/testcontainers/testcontainers-go v0.9.1-0.20210218153226-c8e070a2f18d
github.com/testcontainers/testcontainers-go v0.9.1-0.20210218153226-c8e070a2f18d/go.mod h1:NTC1Ek1iJuUfxAM48lR8zKmXQTFIU5uMO12+ECWdIVc=
github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
github.com/tetafro/godot v0.4.2/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
github.com/tfsec/tfsec v0.40.8-0.20210702100641-956c4f18a1b8 h1:DSuEJokSK+puvRQpspuutT34k3VeXqx8XrwreJxZmKo=
github.com/tfsec/tfsec v0.40.8-0.20210702100641-956c4f18a1b8/go.mod h1:ET0ZM78u5+tR4hwnQFAOGAlynJ71fxTJ4PnQ3UvEodA=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
@@ -1195,8 +1197,8 @@ github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaoz
github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85/go.mod h1:a7cilN64dG941IOXfhJhlH0qB92hxJ9A1ewrdUmJ6xo=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
github.com/twitchtv/twirp v8.0.0+incompatible h1:uYHA8+9cit/+LUfQjL6zo/0QDKTo4U2H/WAnJ6LfhBU=
github.com/twitchtv/twirp v8.0.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
github.com/twitchtv/twirp v8.1.0+incompatible h1:KGXanpa9LXdVE/V5P/tA27rkKFmXRGCtSNT7zdeeVOY=
github.com/twitchtv/twirp v8.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
@@ -1222,7 +1224,6 @@ github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c=
github.com/vektah/gqlparser v1.2.0/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
@@ -1231,7 +1232,6 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
github.com/wasmerio/go-ext-wasm v0.3.1 h1:G95XP3fE2FszQSwIU+fHPBYzD0Csmd2ef33snQXNA5Q=
github.com/wasmerio/go-ext-wasm v0.3.1/go.mod h1:VGyarTzasuS7k5KhSIGpM3tciSZlkP31Mp9VJTHMMeI=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
@@ -1254,9 +1254,15 @@ github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBU
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.6.1 h1:wHtZ+LSSQVwUSb+XIJ5E9hgAQxyWATZsAWT+ESJ9dQ0=
github.com/zclconf/go-cty v1.6.1/go.mod h1:VDR4+I79ubFBGm1uJac1226K5yANQFHeauxPBoP54+o=
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty v1.8.4 h1:pwhhz5P+Fjxse7S7UriBrMu6AUJSZM5pKqGem1PjGAs=
github.com/zclconf/go-cty v1.8.4/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0=
github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
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 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
@@ -1304,6 +1310,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -1311,13 +1318,12 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1405,8 +1411,8 @@ golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d h1:1aflnvSoWWLI2k/dMUAl5lvU1YO4Mb4hz0gh+1rjcxU=
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1417,6 +1423,7 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5 h1:Lm4OryKCca1vehdsWogr9N4t7NfZxLbJoc/H0w4K4S4=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
@@ -1454,6 +1461,7 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1514,18 +1522,21 @@ golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1542,7 +1553,6 @@ golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -1555,6 +1565,7 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190509153222-73554e0f7805/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
@@ -1579,7 +1590,6 @@ golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191127201027-ecd32218bd7f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@@ -1843,10 +1853,8 @@ mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIa
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc=
olympos.io/encoding/edn v0.0.0-20200308123125-93e3b8dd0e24/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw=
pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
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/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=

View File

@@ -45,7 +45,7 @@ func TestClientServer(t *testing.T) {
name: "alpine 3.10 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.json.golden",
},
@@ -54,7 +54,7 @@ func TestClientServer(t *testing.T) {
testArgs: args{
Version: "dev",
IgnoreUnfixed: true,
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310-ignore-unfixed.json.golden",
},
@@ -64,7 +64,7 @@ func TestClientServer(t *testing.T) {
Version: "dev",
IgnoreUnfixed: true,
Severity: []string{"MEDIUM", "HIGH"},
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310-medium-high.json.golden",
},
@@ -74,7 +74,7 @@ func TestClientServer(t *testing.T) {
Version: "dev",
IgnoreUnfixed: false,
IgnoreIDs: []string{"CVE-2019-1549", "CVE-2019-1563"},
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310-ignore-cveids.json.golden",
},
@@ -84,7 +84,7 @@ func TestClientServer(t *testing.T) {
Format: "template",
TemplatePath: "@../contrib/gitlab.tpl",
Version: "dev",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.gitlab.golden",
},
@@ -94,7 +94,7 @@ func TestClientServer(t *testing.T) {
Format: "template",
TemplatePath: "@../contrib/gitlab-codequality.tpl",
Version: "dev",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.gitlab-codequality.golden",
},
@@ -104,7 +104,7 @@ func TestClientServer(t *testing.T) {
Format: "template",
TemplatePath: "@../contrib/sarif.tpl",
Version: "dev",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.sarif.golden",
},
@@ -112,7 +112,7 @@ func TestClientServer(t *testing.T) {
name: "alpine 3.9 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/alpine-39.tar.gz",
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39.json.golden",
},
@@ -120,7 +120,7 @@ func TestClientServer(t *testing.T) {
name: "debian buster integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/debian-buster.tar.gz",
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster.json.golden",
},
@@ -129,7 +129,7 @@ func TestClientServer(t *testing.T) {
testArgs: args{
Version: "dev",
IgnoreUnfixed: true,
Input: "testdata/fixtures/debian-buster.tar.gz",
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
},
@@ -137,7 +137,7 @@ func TestClientServer(t *testing.T) {
name: "debian stretch integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/debian-stretch.tar.gz",
Input: "testdata/fixtures/images/debian-stretch.tar.gz",
},
golden: "testdata/debian-stretch.json.golden",
},
@@ -145,7 +145,7 @@ func TestClientServer(t *testing.T) {
name: "ubuntu 18.04 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/ubuntu-1804.tar.gz",
Input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
golden: "testdata/ubuntu-1804.json.golden",
},
@@ -154,7 +154,7 @@ func TestClientServer(t *testing.T) {
testArgs: args{
Version: "dev",
IgnoreUnfixed: true,
Input: "testdata/fixtures/ubuntu-1804.tar.gz",
Input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
golden: "testdata/ubuntu-1804-ignore-unfixed.json.golden",
},
@@ -162,7 +162,7 @@ func TestClientServer(t *testing.T) {
name: "ubuntu 16.04 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/ubuntu-1604.tar.gz",
Input: "testdata/fixtures/images/ubuntu-1604.tar.gz",
},
golden: "testdata/ubuntu-1604.json.golden",
},
@@ -170,7 +170,7 @@ func TestClientServer(t *testing.T) {
name: "centos 7 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/centos-7.tar.gz",
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7.json.golden",
},
@@ -179,7 +179,7 @@ func TestClientServer(t *testing.T) {
testArgs: args{
Version: "dev",
IgnoreUnfixed: true,
Input: "testdata/fixtures/centos-7.tar.gz",
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-ignore-unfixed.json.golden",
},
@@ -189,7 +189,7 @@ func TestClientServer(t *testing.T) {
Version: "dev",
IgnoreUnfixed: true,
Severity: []string{"LOW", "HIGH"},
Input: "testdata/fixtures/centos-7.tar.gz",
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-low-high.json.golden",
},
@@ -197,7 +197,7 @@ func TestClientServer(t *testing.T) {
name: "centos 6 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/centos-6.tar.gz",
Input: "testdata/fixtures/images/centos-6.tar.gz",
},
golden: "testdata/centos-6.json.golden",
},
@@ -205,7 +205,7 @@ func TestClientServer(t *testing.T) {
name: "ubi 7 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/ubi-7.tar.gz",
Input: "testdata/fixtures/images/ubi-7.tar.gz",
},
golden: "testdata/ubi-7.json.golden",
},
@@ -213,7 +213,7 @@ func TestClientServer(t *testing.T) {
name: "distroless base integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/distroless-base.tar.gz",
Input: "testdata/fixtures/images/distroless-base.tar.gz",
},
golden: "testdata/distroless-base.json.golden",
},
@@ -222,7 +222,7 @@ func TestClientServer(t *testing.T) {
testArgs: args{
Version: "dev",
IgnoreUnfixed: true,
Input: "testdata/fixtures/distroless-base.tar.gz",
Input: "testdata/fixtures/images/distroless-base.tar.gz",
},
golden: "testdata/distroless-base-ignore-unfixed.json.golden",
},
@@ -230,7 +230,7 @@ func TestClientServer(t *testing.T) {
name: "distroless python27 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/distroless-python27.tar.gz",
Input: "testdata/fixtures/images/distroless-python27.tar.gz",
},
golden: "testdata/distroless-python27.json.golden",
},
@@ -238,7 +238,7 @@ func TestClientServer(t *testing.T) {
name: "amazon 1 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/amazon-1.tar.gz",
Input: "testdata/fixtures/images/amazon-1.tar.gz",
},
golden: "testdata/amazon-1.json.golden",
},
@@ -246,7 +246,7 @@ func TestClientServer(t *testing.T) {
name: "amazon 2 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/amazon-2.tar.gz",
Input: "testdata/fixtures/images/amazon-2.tar.gz",
},
golden: "testdata/amazon-2.json.golden",
},
@@ -254,7 +254,7 @@ func TestClientServer(t *testing.T) {
name: "oracle 6 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/oraclelinux-6-slim.tar.gz",
Input: "testdata/fixtures/images/oraclelinux-6-slim.tar.gz",
},
golden: "testdata/oraclelinux-6-slim.json.golden",
},
@@ -262,7 +262,7 @@ func TestClientServer(t *testing.T) {
name: "oracle 7 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/oraclelinux-7-slim.tar.gz",
Input: "testdata/fixtures/images/oraclelinux-7-slim.tar.gz",
},
golden: "testdata/oraclelinux-7-slim.json.golden",
},
@@ -270,7 +270,7 @@ func TestClientServer(t *testing.T) {
name: "oracle 8 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/oraclelinux-8-slim.tar.gz",
Input: "testdata/fixtures/images/oraclelinux-8-slim.tar.gz",
},
golden: "testdata/oraclelinux-8-slim.json.golden",
},
@@ -278,7 +278,7 @@ func TestClientServer(t *testing.T) {
name: "opensuse leap 15.1 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/opensuse-leap-151.tar.gz",
Input: "testdata/fixtures/images/opensuse-leap-151.tar.gz",
},
golden: "testdata/opensuse-leap-151.json.golden",
},
@@ -286,7 +286,7 @@ func TestClientServer(t *testing.T) {
name: "opensuse leap 42.3 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/opensuse-leap-423.tar.gz",
Input: "testdata/fixtures/images/opensuse-leap-423.tar.gz",
},
golden: "testdata/opensuse-leap-423.json.golden",
},
@@ -294,7 +294,7 @@ func TestClientServer(t *testing.T) {
name: "photon 1.0 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/photon-10.tar.gz",
Input: "testdata/fixtures/images/photon-10.tar.gz",
},
golden: "testdata/photon-10.json.golden",
},
@@ -302,7 +302,7 @@ func TestClientServer(t *testing.T) {
name: "photon 2.0 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/photon-20.tar.gz",
Input: "testdata/fixtures/images/photon-20.tar.gz",
},
golden: "testdata/photon-20.json.golden",
},
@@ -310,7 +310,7 @@ func TestClientServer(t *testing.T) {
name: "photon 3.0 integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/photon-30.tar.gz",
Input: "testdata/fixtures/images/photon-30.tar.gz",
},
golden: "testdata/photon-30.json.golden",
},
@@ -318,7 +318,7 @@ func TestClientServer(t *testing.T) {
name: "buxybox with Cargo.lock integration",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/busybox-with-lockfile.tar.gz",
Input: "testdata/fixtures/images/busybox-with-lockfile.tar.gz",
},
golden: "testdata/busybox-with-lockfile.json.golden",
},
@@ -328,7 +328,7 @@ func TestClientServer(t *testing.T) {
Format: "template",
TemplatePath: "@../contrib/asff.tpl",
Version: "dev",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.asff.golden",
},
@@ -338,7 +338,7 @@ func TestClientServer(t *testing.T) {
Format: "template",
TemplatePath: "@../contrib/html.tpl",
Version: "dev",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.html.golden",
},
@@ -376,7 +376,7 @@ func TestClientServerWithToken(t *testing.T) {
name: "alpine 3.10 integration with token",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
ClientToken: "token",
ClientTokenHeader: "Trivy-Token",
},
@@ -386,7 +386,7 @@ func TestClientServerWithToken(t *testing.T) {
name: "invalid token",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/distroless-base.tar.gz",
Input: "testdata/fixtures/images/distroless-base.tar.gz",
ClientToken: "invalidtoken",
ClientTokenHeader: "Trivy-Token",
},
@@ -396,7 +396,7 @@ func TestClientServerWithToken(t *testing.T) {
name: "invalid token header",
testArgs: args{
Version: "dev",
Input: "testdata/fixtures/distroless-base.tar.gz",
Input: "testdata/fixtures/images/distroless-base.tar.gz",
ClientToken: "valid-token",
ClientTokenHeader: "Trivy-Token",
},
@@ -445,7 +445,7 @@ func TestClientServerWithRedis(t *testing.T) {
// Test parameters
testArgs := args{
Version: "dev",
Input: "testdata/fixtures/centos-7.tar.gz",
Input: "testdata/fixtures/images/centos-7.tar.gz",
}
golden := "testdata/centos-7.json.golden"
@@ -484,9 +484,8 @@ func setup(t *testing.T, options setupOptions) (*cli.App, string, string) {
t.Helper()
version := "dev"
// Copy DB file
cacheDir, err := gunzipDB()
assert.NoError(t, err)
// Set up testing DB
cacheDir := gunzipDB(t)
port, err := getFreePort()
assert.NoError(t, err)

View File

@@ -38,21 +38,21 @@ func TestRun_WithDockerEngine(t *testing.T) {
name: "happy path, valid image path, alpine:3.10",
imageTag: "alpine:3.10",
expectedOutputFile: "testdata/alpine-310.json.golden",
testfile: "testdata/fixtures/alpine-310.tar.gz",
testfile: "testdata/fixtures/images/alpine-310.tar.gz",
},
{
name: "happy path, valid image path, with image subcommand, alpine:3.10",
withImageSubcommand: true,
imageTag: "alpine:3.10",
expectedOutputFile: "testdata/alpine-310.json.golden",
testfile: "testdata/fixtures/alpine-310.tar.gz",
testfile: "testdata/fixtures/images/alpine-310.tar.gz",
},
{
name: "happy path, valid image path, alpine:3.10, ignore unfixed",
ignoreUnfixed: true,
imageTag: "alpine:3.10",
expectedOutputFile: "testdata/alpine-310-ignore-unfixed.json.golden",
testfile: "testdata/fixtures/alpine-310.tar.gz",
testfile: "testdata/fixtures/images/alpine-310.tar.gz",
},
{
name: "happy path, valid image path, alpine:3.10, ignore unfixed, with medium and high severity",
@@ -60,51 +60,51 @@ func TestRun_WithDockerEngine(t *testing.T) {
severity: []string{"MEDIUM", "HIGH"},
imageTag: "alpine:3.10",
expectedOutputFile: "testdata/alpine-310-medium-high.json.golden",
testfile: "testdata/fixtures/alpine-310.tar.gz",
testfile: "testdata/fixtures/images/alpine-310.tar.gz",
},
{
name: "happy path, valid image path, alpine:3.10, with .trivyignore",
imageTag: "alpine:3.10",
ignoreIDs: []string{"CVE-2019-1549", "CVE-2019-1563"},
expectedOutputFile: "testdata/alpine-310-ignore-cveids.json.golden",
testfile: "testdata/fixtures/alpine-310.tar.gz",
testfile: "testdata/fixtures/images/alpine-310.tar.gz",
},
{
name: "happy path, valid image path, alpine:3.9",
imageTag: "alpine:3.9",
expectedOutputFile: "testdata/alpine-39.json.golden",
testfile: "testdata/fixtures/alpine-39.tar.gz",
testfile: "testdata/fixtures/images/alpine-39.tar.gz",
},
{
name: "happy path, valid image path, amazonlinux:1",
imageTag: "amazonlinux:1",
expectedOutputFile: "testdata/amazon-1.json.golden",
testfile: "testdata/fixtures/amazon-1.tar.gz",
testfile: "testdata/fixtures/images/amazon-1.tar.gz",
},
{
name: "happy path, valid image path, amazonlinux:2",
imageTag: "amazonlinux:2",
expectedOutputFile: "testdata/amazon-2.json.golden",
testfile: "testdata/fixtures/amazon-2.tar.gz",
testfile: "testdata/fixtures/images/amazon-2.tar.gz",
},
{
name: "happy path, valid image path, centos:6",
imageTag: "centos:6",
expectedOutputFile: "testdata/centos-6.json.golden",
testfile: "testdata/fixtures/centos-6.tar.gz",
testfile: "testdata/fixtures/images/centos-6.tar.gz",
},
{
name: "happy path, valid image path, centos:7",
imageTag: "centos:7",
expectedOutputFile: "testdata/centos-7.json.golden",
testfile: "testdata/fixtures/centos-7.tar.gz",
testfile: "testdata/fixtures/images/centos-7.tar.gz",
},
{
name: "happy path, valid image path, centos:7, with --ignore-unfixed option",
imageTag: "centos:7",
ignoreUnfixed: true,
expectedOutputFile: "testdata/centos-7-ignore-unfixed.json.golden",
testfile: "testdata/fixtures/centos-7.tar.gz",
testfile: "testdata/fixtures/images/centos-7.tar.gz",
},
{
name: "happy path, valid image path, centos:7, with --ignore-unfixed option, with low and high severity",
@@ -112,130 +112,130 @@ func TestRun_WithDockerEngine(t *testing.T) {
ignoreUnfixed: true,
severity: []string{"LOW", "HIGH"},
expectedOutputFile: "testdata/centos-7-low-high.json.golden",
testfile: "testdata/fixtures/centos-7.tar.gz",
testfile: "testdata/fixtures/images/centos-7.tar.gz",
},
{
name: "happy path, valid image path, debian:buster",
imageTag: "debian:buster",
expectedOutputFile: "testdata/debian-buster.json.golden",
testfile: "testdata/fixtures/debian-buster.tar.gz",
testfile: "testdata/fixtures/images/debian-buster.tar.gz",
},
{
name: "happy path, valid image path, debian:buster, with --ignore-unfixed option",
ignoreUnfixed: true,
imageTag: "debian:buster",
expectedOutputFile: "testdata/debian-buster-ignore-unfixed.json.golden",
testfile: "testdata/fixtures/debian-buster.tar.gz",
testfile: "testdata/fixtures/images/debian-buster.tar.gz",
},
{
name: "happy path, valid image path, debian:stretch",
imageTag: "debian:stretch",
expectedOutputFile: "testdata/debian-stretch.json.golden",
testfile: "testdata/fixtures/debian-stretch.tar.gz",
testfile: "testdata/fixtures/images/debian-stretch.tar.gz",
},
{
name: "happy path, valid image path, distroless:base",
imageTag: "gcr.io/distroless/base:latest",
expectedOutputFile: "testdata/distroless-base.json.golden",
testfile: "testdata/fixtures/distroless-base.tar.gz",
testfile: "testdata/fixtures/images/distroless-base.tar.gz",
},
{
name: "happy path, valid image path, distroless:base",
imageTag: "gcr.io/distroless/base:latest",
expectedOutputFile: "testdata/distroless-base.json.golden",
testfile: "testdata/fixtures/distroless-base.tar.gz",
testfile: "testdata/fixtures/images/distroless-base.tar.gz",
},
{
name: "happy path, valid image path, distroless:base, with --ignore-unfixed option",
imageTag: "gcr.io/distroless/base:latest",
ignoreUnfixed: true,
expectedOutputFile: "testdata/distroless-base-ignore-unfixed.json.golden",
testfile: "testdata/fixtures/distroless-base.tar.gz",
testfile: "testdata/fixtures/images/distroless-base.tar.gz",
},
{
name: "happy path, valid image path, distroless:python2.7",
imageTag: "gcr.io/distroless/python2.7:latest",
expectedOutputFile: "testdata/distroless-python27.json.golden",
testfile: "testdata/fixtures/distroless-python27.tar.gz",
testfile: "testdata/fixtures/images/distroless-python27.tar.gz",
},
{
name: "happy path, valid image path, oraclelinux:6-slim",
imageTag: "oraclelinux:6-slim",
expectedOutputFile: "testdata/oraclelinux-6-slim.json.golden",
testfile: "testdata/fixtures/oraclelinux-6-slim.tar.gz",
testfile: "testdata/fixtures/images/oraclelinux-6-slim.tar.gz",
},
{
name: "happy path, valid image path, oraclelinux:7-slim",
imageTag: "oraclelinux:7-slim",
expectedOutputFile: "testdata/oraclelinux-7-slim.json.golden",
testfile: "testdata/fixtures/oraclelinux-7-slim.tar.gz",
testfile: "testdata/fixtures/images/oraclelinux-7-slim.tar.gz",
},
{
name: "happy path, valid image path, oraclelinux:8-slim",
imageTag: "oraclelinux:8-slim",
expectedOutputFile: "testdata/oraclelinux-8-slim.json.golden",
testfile: "testdata/fixtures/oraclelinux-8-slim.tar.gz",
testfile: "testdata/fixtures/images/oraclelinux-8-slim.tar.gz",
},
{
name: "happy path, valid image path, ubuntu:16.04",
imageTag: "ubuntu:16.04",
expectedOutputFile: "testdata/ubuntu-1604.json.golden",
testfile: "testdata/fixtures/ubuntu-1604.tar.gz",
testfile: "testdata/fixtures/images/ubuntu-1604.tar.gz",
},
{
name: "happy path, valid image path, ubuntu:18.04",
imageTag: "ubuntu:18.04",
expectedOutputFile: "testdata/ubuntu-1804.json.golden",
testfile: "testdata/fixtures/ubuntu-1804.tar.gz",
testfile: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
{
name: "happy path, valid image path, ubuntu:18.04, with --ignore-unfixed option",
imageTag: "ubuntu:18.04",
ignoreUnfixed: true,
expectedOutputFile: "testdata/ubuntu-1804-ignore-unfixed.json.golden",
testfile: "testdata/fixtures/ubuntu-1804.tar.gz",
testfile: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
{
name: "happy path, valid image path, registry.redhat.io/ubi7",
imageTag: "registry.redhat.io/ubi7",
expectedOutputFile: "testdata/ubi-7.json.golden",
testfile: "testdata/fixtures/ubi-7.tar.gz",
testfile: "testdata/fixtures/images/ubi-7.tar.gz",
},
{
name: "happy path, valid image path, opensuse leap 15.1",
imageTag: "opensuse/leap:latest",
expectedOutputFile: "testdata/opensuse-leap-151.json.golden",
testfile: "testdata/fixtures/opensuse-leap-151.tar.gz",
testfile: "testdata/fixtures/images/opensuse-leap-151.tar.gz",
},
{
name: "happy path, valid image path, opensuse leap 42.3",
imageTag: "opensuse/leap:42.3",
expectedOutputFile: "testdata/opensuse-leap-423.json.golden",
testfile: "testdata/fixtures/opensuse-leap-423.tar.gz",
testfile: "testdata/fixtures/images/opensuse-leap-423.tar.gz",
},
{
name: "happy path, valid image path, photon 1.0",
imageTag: "photon:1.0-20190823",
expectedOutputFile: "testdata/photon-10.json.golden",
testfile: "testdata/fixtures/photon-10.tar.gz",
testfile: "testdata/fixtures/images/photon-10.tar.gz",
},
{
name: "happy path, valid image path, photon 2.0",
imageTag: "photon:2.0-20190726",
expectedOutputFile: "testdata/photon-20.json.golden",
testfile: "testdata/fixtures/photon-20.tar.gz",
testfile: "testdata/fixtures/images/photon-20.tar.gz",
},
{
name: "happy path, valid image path, photon 3.0",
imageTag: "photon:3.0-20190823",
expectedOutputFile: "testdata/photon-30.json.golden",
testfile: "testdata/fixtures/photon-30.tar.gz",
testfile: "testdata/fixtures/images/photon-30.tar.gz",
},
{
name: "buxybox with Cargo.lock integration",
imageTag: "busy-cargo:latest",
expectedOutputFile: "testdata/busybox-with-lockfile.json.golden",
testfile: "testdata/fixtures/busybox-with-lockfile.tar.gz",
testfile: "testdata/fixtures/images/busybox-with-lockfile.tar.gz",
},
{
name: "sad path, invalid image",
@@ -245,10 +245,8 @@ func TestRun_WithDockerEngine(t *testing.T) {
},
}
// Copy DB file
cacheDir, err := gunzipDB()
require.NoError(t, err)
defer os.RemoveAll(cacheDir)
// Set up testing DB
cacheDir := gunzipDB(t)
ctx := context.Background()
defer ctx.Done()

142
integration/fs_test.go Normal file
View File

@@ -0,0 +1,142 @@
// +build integration
package integration
import (
"io"
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy/pkg/commands"
)
func TestFilesystem(t *testing.T) {
type args struct {
securityChecks string
severity []string
ignoreIDs []string
policyPaths []string
namespaces []string
input string
}
tests := []struct {
name string
args args
golden string
}{
{
name: "nodejs",
args: args{
securityChecks: "vuln",
input: "testdata/fixtures/fs/nodejs",
},
golden: "testdata/nodejs.json.golden",
},
{
name: "dockerfile",
args: args{
securityChecks: "config",
policyPaths: []string{"testdata/fixtures/fs/dockerfile/policy"},
input: "testdata/fixtures/fs/dockerfile",
},
golden: "testdata/dockerfile.json.golden",
},
{
name: "dockerfile with rule exception",
args: args{
securityChecks: "config",
policyPaths: []string{"testdata/fixtures/fs/rule-exception/policy"},
input: "testdata/fixtures/fs/rule-exception",
},
golden: "testdata/dockerfile-rule-exception.json.golden",
},
{
name: "dockerfile with namespace exception",
args: args{
securityChecks: "config",
policyPaths: []string{"testdata/fixtures/fs/namespace-exception/policy"},
input: "testdata/fixtures/fs/namespace-exception",
},
golden: "testdata/dockerfile-namespace-exception.json.golden",
},
{
name: "dockerfile with custom policies",
args: args{
securityChecks: "config",
policyPaths: []string{"testdata/fixtures/fs/custom-policy/policy"},
namespaces: []string{"user"},
input: "testdata/fixtures/fs/custom-policy",
},
golden: "testdata/dockerfile-custom-policies.json.golden",
},
}
// Set up testing DB
cacheDir := gunzipDB(t)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
osArgs := []string{"trivy", "--cache-dir", cacheDir, "fs", "--skip-db-update", "--skip-policy-update",
"--format", "json", "--security-checks", tt.args.securityChecks}
if len(tt.args.policyPaths) != 0 {
for _, policyPath := range tt.args.policyPaths {
osArgs = append(osArgs, "--config-policy", policyPath)
}
}
if len(tt.args.namespaces) != 0 {
for _, namespace := range tt.args.namespaces {
osArgs = append(osArgs, "--policy-namespaces", namespace)
}
}
if len(tt.args.severity) != 0 {
osArgs = append(osArgs,
[]string{"--severity", strings.Join(tt.args.severity, ",")}...,
)
}
if len(tt.args.ignoreIDs) != 0 {
trivyIgnore := ".trivyignore"
err := os.WriteFile(trivyIgnore, []byte(strings.Join(tt.args.ignoreIDs, "\n")), 0444)
assert.NoError(t, err, "failed to write .trivyignore")
defer os.Remove(trivyIgnore)
}
// Setup the output file
var outputFile string
if *update {
outputFile = tt.golden
} else {
output, err := os.CreateTemp("", "integration")
require.NoError(t, err)
assert.Nil(t, output.Close())
defer os.Remove(output.Name())
outputFile = output.Name()
}
osArgs = append(osArgs, "--output", outputFile)
osArgs = append(osArgs, tt.args.input)
// Setup CLI App
app := commands.NewApp("dev")
app.Writer = io.Discard
// Run "trivy fs"
assert.Nil(t, app.Run(osArgs))
// Compare want and got
want, err := os.ReadFile(tt.golden)
assert.NoError(t, err)
got, err := os.ReadFile(outputFile)
assert.NoError(t, err)
assert.JSONEq(t, string(want), string(got))
})
}
}

View File

@@ -8,52 +8,39 @@ import (
"encoding/json"
"flag"
"io"
"io/ioutil"
"net"
"os"
"path/filepath"
"testing"
"time"
"github.com/spf13/afero"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db"
)
var update = flag.Bool("update", false, "update golden files")
func gunzipDB() (string, error) {
func gunzipDB(t *testing.T) string {
gz, err := os.Open("testdata/trivy.db.gz")
if err != nil {
return "", err
}
require.NoError(t, err)
zr, err := gzip.NewReader(gz)
if err != nil {
return "", err
}
tmpDir, err := ioutil.TempDir("", "integration")
if err != nil {
return "", err
}
require.NoError(t, err)
tmpDir := t.TempDir()
dbPath := db.Path(tmpDir)
dbDir := filepath.Dir(dbPath)
err = os.MkdirAll(dbDir, 0700)
if err != nil {
return "", err
}
require.NoError(t, err)
file, err := os.Create(dbPath)
if err != nil {
return "", err
}
require.NoError(t, err)
defer file.Close()
if _, err = io.Copy(file, zr); err != nil {
return "", err
}
_, err = io.Copy(file, zr)
require.NoError(t, err)
fs := afero.NewOsFs()
metadataFile := filepath.Join(dbDir, "metadata.json")
b, err := json.Marshal(db.Metadata{
Version: 1,
@@ -61,15 +48,12 @@ func gunzipDB() (string, error) {
NextUpdate: time.Time{},
UpdatedAt: time.Time{},
})
if err != nil {
return "", err
}
err = afero.WriteFile(fs, metadataFile, b, 0600)
if err != nil {
return "", err
}
require.NoError(t, err)
return tmpDir, nil
err = os.WriteFile(metadataFile, b, 0600)
require.NoError(t, err)
return tmpDir
}
func getFreePort() (int, error) {

View File

@@ -146,7 +146,7 @@ func TestRegistry(t *testing.T) {
{
name: "happy path with username/password",
imageName: "alpine:3.10",
imageFile: "testdata/fixtures/alpine-310.tar.gz",
imageFile: "testdata/fixtures/images/alpine-310.tar.gz",
option: registryOption{
AuthURL: authURL,
Username: authUsername,
@@ -157,7 +157,7 @@ func TestRegistry(t *testing.T) {
{
name: "happy path with registry token",
imageName: "alpine:3.10",
imageFile: "testdata/fixtures/alpine-310.tar.gz",
imageFile: "testdata/fixtures/images/alpine-310.tar.gz",
option: registryOption{
AuthURL: authURL,
Username: authUsername,
@@ -169,7 +169,7 @@ func TestRegistry(t *testing.T) {
{
name: "sad path",
imageName: "alpine:3.10",
imageFile: "testdata/fixtures/alpine-310.tar.gz",
imageFile: "testdata/fixtures/images/alpine-310.tar.gz",
wantErr: "unsupported status code 401; body: Auth failed",
},
}
@@ -188,7 +188,7 @@ func TestRegistry(t *testing.T) {
require.NoError(t, err)
// 2. Scan it
resultFile, cleanup, err := scan(imageRef, baseDir, tc.golden, tc.option)
resultFile, cleanup, err := scan(t, imageRef, baseDir, tc.golden, tc.option)
if tc.wantErr != "" {
require.NotNil(t, err)
@@ -220,15 +220,11 @@ func TestRegistry(t *testing.T) {
}
}
func scan(imageRef name.Reference, baseDir, goldenFile string, opt registryOption) (string, func(), error) {
func scan(t *testing.T, imageRef name.Reference, baseDir, goldenFile string, opt registryOption) (string, func(), error) {
cleanup := func() {}
// Copy DB file
cacheDir, err := gunzipDB()
if err != nil {
return "", cleanup, err
}
defer os.RemoveAll(cacheDir)
// Set up testing DB
cacheDir := gunzipDB(t)
// Setup the output file
var outputFile string
@@ -248,7 +244,7 @@ func scan(imageRef name.Reference, baseDir, goldenFile string, opt registryOptio
}
// Setup env
if err = setupEnv(imageRef, baseDir, opt); err != nil {
if err := setupEnv(imageRef, baseDir, opt); err != nil {
return "", cleanup, err
}
defer unsetEnv()
@@ -260,7 +256,7 @@ func scan(imageRef name.Reference, baseDir, goldenFile string, opt registryOptio
osArgs := []string{"trivy", "--cache-dir", cacheDir, "--format", "json", "--skip-update", "--output", outputFile, imageRef.Name()}
// Run Trivy
if err = app.Run(osArgs); err != nil {
if err := app.Run(osArgs); err != nil {
return "", cleanup, err
}
return outputFile, cleanup, nil

View File

@@ -9,7 +9,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy/pkg/commands"
)
@@ -38,7 +37,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.json.golden",
},
@@ -49,7 +48,7 @@ func TestRun_WithTar(t *testing.T) {
WithImageSubcommand: true,
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.json.golden",
},
@@ -60,7 +59,7 @@ func TestRun_WithTar(t *testing.T) {
SkipUpdate: true,
IgnoreUnfixed: true,
Format: "json",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310-ignore-unfixed.json.golden",
},
@@ -72,7 +71,7 @@ func TestRun_WithTar(t *testing.T) {
IgnoreUnfixed: true,
Severity: []string{"MEDIUM", "HIGH"},
Format: "json",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310-medium-high.json.golden",
},
@@ -84,7 +83,7 @@ func TestRun_WithTar(t *testing.T) {
IgnoreUnfixed: false,
IgnoreIDs: []string{"CVE-2019-1549", "CVE-2019-1563"},
Format: "json",
Input: "testdata/fixtures/alpine-310.tar.gz",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310-ignore-cveids.json.golden",
},
@@ -94,7 +93,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/alpine-39.tar.gz",
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39.json.golden",
},
@@ -104,7 +103,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/debian-buster.tar.gz",
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster.json.golden",
},
@@ -115,7 +114,7 @@ func TestRun_WithTar(t *testing.T) {
SkipUpdate: true,
IgnoreUnfixed: true,
Format: "json",
Input: "testdata/fixtures/debian-buster.tar.gz",
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
},
@@ -125,7 +124,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/debian-stretch.tar.gz",
Input: "testdata/fixtures/images/debian-stretch.tar.gz",
},
golden: "testdata/debian-stretch.json.golden",
},
@@ -135,7 +134,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/ubuntu-1804.tar.gz",
Input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
golden: "testdata/ubuntu-1804.json.golden",
},
@@ -146,7 +145,7 @@ func TestRun_WithTar(t *testing.T) {
SkipUpdate: true,
IgnoreUnfixed: true,
Format: "json",
Input: "testdata/fixtures/ubuntu-1804.tar.gz",
Input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
golden: "testdata/ubuntu-1804-ignore-unfixed.json.golden",
},
@@ -156,7 +155,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/ubuntu-1604.tar.gz",
Input: "testdata/fixtures/images/ubuntu-1604.tar.gz",
},
golden: "testdata/ubuntu-1604.json.golden",
},
@@ -166,7 +165,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/centos-7.tar.gz",
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7.json.golden",
},
@@ -177,7 +176,7 @@ func TestRun_WithTar(t *testing.T) {
SkipUpdate: true,
IgnoreUnfixed: true,
Format: "json",
Input: "testdata/fixtures/centos-7.tar.gz",
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-ignore-unfixed.json.golden",
},
@@ -189,7 +188,7 @@ func TestRun_WithTar(t *testing.T) {
IgnoreUnfixed: true,
Severity: []string{"LOW", "HIGH"},
Format: "json",
Input: "testdata/fixtures/centos-7.tar.gz",
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-low-high.json.golden",
},
@@ -199,7 +198,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/centos-6.tar.gz",
Input: "testdata/fixtures/images/centos-6.tar.gz",
},
golden: "testdata/centos-6.json.golden",
},
@@ -209,7 +208,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/ubi-7.tar.gz",
Input: "testdata/fixtures/images/ubi-7.tar.gz",
},
golden: "testdata/ubi-7.json.golden",
},
@@ -219,7 +218,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/distroless-base.tar.gz",
Input: "testdata/fixtures/images/distroless-base.tar.gz",
},
golden: "testdata/distroless-base.json.golden",
},
@@ -230,7 +229,7 @@ func TestRun_WithTar(t *testing.T) {
SkipUpdate: true,
IgnoreUnfixed: true,
Format: "json",
Input: "testdata/fixtures/distroless-base.tar.gz",
Input: "testdata/fixtures/images/distroless-base.tar.gz",
},
golden: "testdata/distroless-base-ignore-unfixed.json.golden",
},
@@ -240,7 +239,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/distroless-python27.tar.gz",
Input: "testdata/fixtures/images/distroless-python27.tar.gz",
},
golden: "testdata/distroless-python27.json.golden",
},
@@ -250,7 +249,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/amazon-1.tar.gz",
Input: "testdata/fixtures/images/amazon-1.tar.gz",
},
golden: "testdata/amazon-1.json.golden",
},
@@ -260,7 +259,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/amazon-2.tar.gz",
Input: "testdata/fixtures/images/amazon-2.tar.gz",
},
golden: "testdata/amazon-2.json.golden",
},
@@ -270,7 +269,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/oraclelinux-6-slim.tar.gz",
Input: "testdata/fixtures/images/oraclelinux-6-slim.tar.gz",
},
golden: "testdata/oraclelinux-6-slim.json.golden",
},
@@ -280,7 +279,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/oraclelinux-7-slim.tar.gz",
Input: "testdata/fixtures/images/oraclelinux-7-slim.tar.gz",
},
golden: "testdata/oraclelinux-7-slim.json.golden",
},
@@ -290,7 +289,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/oraclelinux-8-slim.tar.gz",
Input: "testdata/fixtures/images/oraclelinux-8-slim.tar.gz",
},
golden: "testdata/oraclelinux-8-slim.json.golden",
},
@@ -300,7 +299,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/opensuse-leap-151.tar.gz",
Input: "testdata/fixtures/images/opensuse-leap-151.tar.gz",
},
golden: "testdata/opensuse-leap-151.json.golden",
},
@@ -310,7 +309,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/opensuse-leap-423.tar.gz",
Input: "testdata/fixtures/images/opensuse-leap-423.tar.gz",
},
golden: "testdata/opensuse-leap-423.json.golden",
},
@@ -320,7 +319,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/photon-10.tar.gz",
Input: "testdata/fixtures/images/photon-10.tar.gz",
},
golden: "testdata/photon-10.json.golden",
},
@@ -330,7 +329,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/photon-20.tar.gz",
Input: "testdata/fixtures/images/photon-20.tar.gz",
},
golden: "testdata/photon-20.json.golden",
},
@@ -340,7 +339,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/photon-30.tar.gz",
Input: "testdata/fixtures/images/photon-30.tar.gz",
},
golden: "testdata/photon-30.json.golden",
},
@@ -350,7 +349,7 @@ func TestRun_WithTar(t *testing.T) {
Version: "dev",
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/busybox-with-lockfile.tar.gz",
Input: "testdata/fixtures/images/busybox-with-lockfile.tar.gz",
},
golden: "testdata/busybox-with-lockfile.json.golden",
},
@@ -361,7 +360,7 @@ func TestRun_WithTar(t *testing.T) {
SkipUpdate: true,
IgnoreUnfixed: true,
Format: "json",
Input: "testdata/fixtures/fluentd-multiple-lockfiles.tar.gz",
Input: "testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz",
SkipFiles: []string{"/Gemfile.lock"},
SkipDirs: []string{
"/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0",
@@ -372,10 +371,8 @@ func TestRun_WithTar(t *testing.T) {
},
}
// Copy DB file
cacheDir, err := gunzipDB()
require.NoError(t, err)
defer os.RemoveAll(cacheDir)
// Set up testing DB
cacheDir := gunzipDB(t)
// Setup CLI App
app := commands.NewApp("dev")

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Target": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Class": "os-pkgs",
"Type": "alpine",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Target": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Class": "os-pkgs",
"Type": "alpine",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Target": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Class": "os-pkgs",
"Type": "alpine",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,6 @@
[
{
"Target": "localhost:32799/alpine:3.10 (alpine 3.10.2)",
"Target": "localhost:55015/alpine:3.10 (alpine 3.10.2)",
"Type": "alpine",
"Vulnerabilities": [
{

View File

@@ -1,7 +1,7 @@
[
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1549",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1549",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -11,7 +11,7 @@
"Severity": {
"Label": "MEDIUM"
},
"Title": "Trivy found a vulnerability to CVE-2019-1549 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1549 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).",
"Remediation": {
"Recommendation": {
@@ -23,11 +23,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1549",
"CVE Title": "openssl: information disclosure in fork()",
@@ -46,7 +46,7 @@
},
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1551",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1551",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -56,7 +56,7 @@
"Severity": {
"Label": "MEDIUM"
},
"Title": "Trivy found a vulnerability to CVE-2019-1551 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1551 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "There is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e-dev (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u-dev (Affected 1.0.2-1.0.2t).",
"Remediation": {
"Recommendation": {
@@ -68,11 +68,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1551",
"CVE Title": "openssl: Integer overflow in RSAZ modular exponentiation on x86_64",
@@ -91,7 +91,7 @@
},
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1563",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1563",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -101,7 +101,7 @@
"Severity": {
"Label": "MEDIUM"
},
"Title": "Trivy found a vulnerability to CVE-2019-1563 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1563 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "In situations where an attacker receives automated notification of the success or failure of a decryption attempt an attacker, after sending a very large number of messages to be decrypted, can recover a CMS/PKCS7 transported encryption key or decrypt any RSA encrypted message that was encrypted with the public RSA key, using a Bleichenbacher padding oracle attack. Applications are not affected if they use a certificate together with the private RSA key to the CMS_decrypt or PKCS7_decrypt functions to select the correct recipient info to decrypt. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). Fixed in OpenSSL 1.1.0l (Affected 1.1.0-1.1.0k). Fixed in OpenSSL 1.0.2t (Affected 1.0.2-1.0.2s).",
"Remediation": {
"Recommendation": {
@@ -113,11 +113,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1563",
"CVE Title": "openssl: information disclosure in PKCS7_dataDecode and CMS_decrypt_set1_pkey",
@@ -136,7 +136,7 @@
},
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1547",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1547",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -146,7 +146,7 @@
"Severity": {
"Label": "LOW"
},
"Title": "Trivy found a vulnerability to CVE-2019-1547 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1547 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "Normally in OpenSSL EC groups always have a co-factor present and this is used in side channel resistant code paths. However, in some cases, it is possible to construct a group using explicit parameters (instead of using a named curve). In those cases it is possible that such a group does not have the cofactor present. This can occur even where all the parameters match a known named curve. If such a curve is used then OpenSSL falls back to non-side channel resistant code paths which may result in full key recovery during an ECDSA signature operation. In order to be vulnerable an attacker would have to have the ability to time the creation of a large number of signatures where explicit parameters with no co-factor present are in use by an application using libcrypto. For the avoidance of doubt libssl is not vulnerable because explicit parameters are never used. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). Fixed in OpenSSL 1.1.0l (Affected 1.1.0-1.1.0k). Fixed in OpenSSL 1.0.2t (Affected 1.0.2-1.0.2s).",
"Remediation": {
"Recommendation": {
@@ -158,11 +158,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1547",
"CVE Title": "openssl: side-channel weak encryption vulnerability",
@@ -181,7 +181,7 @@
},
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1549",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1549",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -191,7 +191,7 @@
"Severity": {
"Label": "MEDIUM"
},
"Title": "Trivy found a vulnerability to CVE-2019-1549 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1549 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).",
"Remediation": {
"Recommendation": {
@@ -203,11 +203,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1549",
"CVE Title": "openssl: information disclosure in fork()",
@@ -226,7 +226,7 @@
},
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1551",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1551",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -236,7 +236,7 @@
"Severity": {
"Label": "MEDIUM"
},
"Title": "Trivy found a vulnerability to CVE-2019-1551 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1551 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "There is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e-dev (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u-dev (Affected 1.0.2-1.0.2t).",
"Remediation": {
"Recommendation": {
@@ -248,11 +248,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1551",
"CVE Title": "openssl: Integer overflow in RSAZ modular exponentiation on x86_64",
@@ -271,7 +271,7 @@
},
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1563",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1563",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -281,7 +281,7 @@
"Severity": {
"Label": "MEDIUM"
},
"Title": "Trivy found a vulnerability to CVE-2019-1563 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1563 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "In situations where an attacker receives automated notification of the success or failure of a decryption attempt an attacker, after sending a very large number of messages to be decrypted, can recover a CMS/PKCS7 transported encryption key or decrypt any RSA encrypted message that was encrypted with the public RSA key, using a Bleichenbacher padding oracle attack. Applications are not affected if they use a certificate together with the private RSA key to the CMS_decrypt or PKCS7_decrypt functions to select the correct recipient info to decrypt. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). Fixed in OpenSSL 1.1.0l (Affected 1.1.0-1.1.0k). Fixed in OpenSSL 1.0.2t (Affected 1.0.2-1.0.2s).",
"Remediation": {
"Recommendation": {
@@ -293,11 +293,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1563",
"CVE Title": "openssl: information disclosure in PKCS7_dataDecode and CMS_decrypt_set1_pkey",
@@ -316,7 +316,7 @@
},
{
"SchemaVersion": "2018-10-08",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1547",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)/CVE-2019-1547",
"ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity",
"GeneratorId": "Trivy",
"AwsAccountId": "123456789012",
@@ -326,7 +326,7 @@
"Severity": {
"Label": "LOW"
},
"Title": "Trivy found a vulnerability to CVE-2019-1547 in container testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Title": "Trivy found a vulnerability to CVE-2019-1547 in container testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Description": "Normally in OpenSSL EC groups always have a co-factor present and this is used in side channel resistant code paths. However, in some cases, it is possible to construct a group using explicit parameters (instead of using a named curve). In those cases it is possible that such a group does not have the cofactor present. This can occur even where all the parameters match a known named curve. If such a curve is used then OpenSSL falls back to non-side channel resistant code paths which may result in full key recovery during an ECDSA signature operation. In order to be vulnerable an attacker would have to have the ability to time the creation of a large number of signatures where explicit parameters with no co-factor present are in use by an application using libcrypto. For the avoidance of doubt libssl is not vulnerable because explicit parameters are never used. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). Fixed in OpenSSL 1.1.0l (Affected 1.1.0-1.1.0k). Fixed in OpenSSL 1.0.2t (Affected 1.0.2-1.0.2s).",
"Remediation": {
"Recommendation": {
@@ -338,11 +338,11 @@
"Resources": [
{
"Type": "Container",
"Id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Partition": "aws",
"Region": "test-region",
"Details": {
"Container": { "ImageName": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)" },
"Container": { "ImageName": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)" },
"Other": {
"CVE ID": "CVE-2019-1547",
"CVE Title": "openssl: side-channel weak encryption vulnerability",

View File

@@ -22,7 +22,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{
@@ -68,7 +68,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{
@@ -124,7 +124,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{
@@ -174,7 +174,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{
@@ -226,7 +226,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{
@@ -272,7 +272,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{
@@ -328,7 +328,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{
@@ -378,7 +378,7 @@
"version": "1.1.1c-r0"
},
"operating_system": "Unknown",
"image": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)"
"image": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)"
},
"identifiers": [
{

View File

@@ -51,7 +51,7 @@
}
a.toggle-more-links { cursor: pointer; }
</style>
<title>testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2) - Trivy Report - 2020-08-10T07:28:17.000958601Z</title>
<title>testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2) - Trivy Report - 2020-08-10T07:28:17.000958601Z</title>
<script>
window.onload = function() {
document.querySelectorAll('td.links').forEach(function(linkCell) {
@@ -81,7 +81,7 @@
</script>
</head>
<body>
<h1>testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2) - Trivy Report - 2020-08-10T07:28:17.000958601Z</h1>
<h1>testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2) - Trivy Report - 2020-08-10T07:28:17.000958601Z</h1>
<table>
<tr class="group-header"><th colspan="6">alpine</th></tr>
<tr class="sub-header">

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2)",
"Target": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2)",
"Class": "os-pkgs",
"Type": "alpine",
"Vulnerabilities": [
{

View File

@@ -11,7 +11,7 @@
"version": "0.15.0",
"rules": [
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1549",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1549",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1549 Package: libcrypto1.1"
@@ -37,7 +37,7 @@
}
},
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1551",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1551",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1551 Package: libcrypto1.1"
@@ -63,7 +63,7 @@
}
},
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1563",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1563",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1563 Package: libcrypto1.1"
@@ -89,7 +89,7 @@
}
},
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1547",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1547",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1547 Package: libcrypto1.1"
@@ -115,7 +115,7 @@
}
},
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1549",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1549",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1549 Package: libssl1.1"
@@ -141,7 +141,7 @@
}
},
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1551",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1551",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1551 Package: libssl1.1"
@@ -167,7 +167,7 @@
}
},
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1563",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1563",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1563 Package: libssl1.1"
@@ -193,7 +193,7 @@
}
},
{
"id": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1547",
"id": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1547",
"name": "OS Package Vulnerability (Alpine)",
"shortDescription": {
"text": "CVE-2019-1547 Package: libssl1.1"
@@ -222,7 +222,7 @@
},
"results": [
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1549",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1549",
"ruleIndex": 0,
"level": "warning",
"message": {
@@ -231,14 +231,14 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}
}]
},
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1551",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1551",
"ruleIndex": 1,
"level": "warning",
"message": {
@@ -247,14 +247,14 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}
}]
},
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1563",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1563",
"ruleIndex": 2,
"level": "warning",
"message": {
@@ -263,14 +263,14 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}
}]
},
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1547",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libcrypto1.1-1.1.1c-r0 CVE-2019-1547",
"ruleIndex": 3,
"level": "note",
"message": {
@@ -279,14 +279,14 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}
}]
},
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1549",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1549",
"ruleIndex": 4,
"level": "warning",
"message": {
@@ -295,14 +295,14 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}
}]
},
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1551",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1551",
"ruleIndex": 5,
"level": "warning",
"message": {
@@ -311,14 +311,14 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}
}]
},
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1563",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1563",
"ruleIndex": 6,
"level": "warning",
"message": {
@@ -327,14 +327,14 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}
}]
},
{
"ruleId": "testdata/fixtures/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1547",
"ruleId": "testdata/fixtures/images/alpine-310.tar.gz (alpine 3.10.2): libssl1.1-1.1.1c-r0 CVE-2019-1547",
"ruleIndex": 7,
"level": "note",
"message": {
@@ -343,7 +343,7 @@
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "testdata/fixtures/alpine-310.tar.gz",
"uri": "testdata/fixtures/images/alpine-310.tar.gz",
"uriBaseId": "ROOTPATH"
}
}

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/alpine-39.tar.gz (alpine 3.9.4)",
"Target": "testdata/fixtures/images/alpine-39.tar.gz (alpine 3.9.4)",
"Class": "os-pkgs",
"Type": "alpine",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/amazon-1.tar.gz (amazon AMI release 2018.03)",
"Target": "testdata/fixtures/images/amazon-1.tar.gz (amazon AMI release 2018.03)",
"Class": "os-pkgs",
"Type": "amazon",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/amazon-2.tar.gz (amazon 2 (Karoo))",
"Target": "testdata/fixtures/images/amazon-2.tar.gz (amazon 2 (Karoo))",
"Class": "os-pkgs",
"Type": "amazon",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "Cargo.lock",
"Class": "lang-pkgs",
"Type": "cargo",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/centos-6.tar.gz (centos 6.10)",
"Target": "testdata/fixtures/images/centos-6.tar.gz (centos 6.10)",
"Class": "os-pkgs",
"Type": "centos",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/centos-7.tar.gz (centos 7.6.1810)",
"Target": "testdata/fixtures/images/centos-7.tar.gz (centos 7.6.1810)",
"Class": "os-pkgs",
"Type": "centos",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/centos-7.tar.gz (centos 7.6.1810)",
"Target": "testdata/fixtures/images/centos-7.tar.gz (centos 7.6.1810)",
"Class": "os-pkgs",
"Type": "centos",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/centos-7.tar.gz (centos 7.6.1810)",
"Target": "testdata/fixtures/images/centos-7.tar.gz (centos 7.6.1810)",
"Class": "os-pkgs",
"Type": "centos",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/debian-buster.tar.gz (debian 10.1)",
"Target": "testdata/fixtures/images/debian-buster.tar.gz (debian 10.1)",
"Class": "os-pkgs",
"Type": "debian",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/debian-buster.tar.gz (debian 10.1)",
"Target": "testdata/fixtures/images/debian-buster.tar.gz (debian 10.1)",
"Class": "os-pkgs",
"Type": "debian",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/debian-stretch.tar.gz (debian 9.9)",
"Target": "testdata/fixtures/images/debian-stretch.tar.gz (debian 9.9)",
"Class": "os-pkgs",
"Type": "debian",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/distroless-base.tar.gz (debian 9.9)",
"Target": "testdata/fixtures/images/distroless-base.tar.gz (debian 9.9)",
"Class": "os-pkgs",
"Type": "debian",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/distroless-base.tar.gz (debian 9.9)",
"Target": "testdata/fixtures/images/distroless-base.tar.gz (debian 9.9)",
"Class": "os-pkgs",
"Type": "debian",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/distroless-python27.tar.gz (debian 9.9)",
"Target": "testdata/fixtures/images/distroless-python27.tar.gz (debian 9.9)",
"Class": "os-pkgs",
"Type": "debian",
"Vulnerabilities": [
{

View File

@@ -0,0 +1,38 @@
[
{
"Target": "Dockerfile",
"Class": "config",
"Type": "dockerfile",
"MisconfSummary": {
"Successes": 0,
"Failures": 2,
"Exceptions": 0
},
"Misconfigurations": [
{
"Type": "N/A",
"ID": "N/A",
"Title": "N/A",
"Message": "something bad: bar",
"Namespace": "user.bar",
"Severity": "UNKNOWN",
"Status": "FAIL",
"Layer": {
"DiffID": "sha256:bbbceb3abb84c5f9deda9e8495fa8500f40995228f02ff14fae5f6db89eac69f"
}
},
{
"Type": "N/A",
"ID": "N/A",
"Title": "N/A",
"Message": "something bad: foo",
"Namespace": "user.foo",
"Severity": "UNKNOWN",
"Status": "FAIL",
"Layer": {
"DiffID": "sha256:bbbceb3abb84c5f9deda9e8495fa8500f40995228f02ff14fae5f6db89eac69f"
}
}
]
}
]

View File

@@ -0,0 +1,32 @@
[
{
"Target": "Dockerfile",
"Class": "config",
"Type": "dockerfile",
"MisconfSummary": {
"Successes": 0,
"Failures": 0,
"Exceptions": 1
},
"Misconfigurations": [
{
"Type": "Dockerfile Security Check",
"ID": "DS002",
"Title": "Image user should not be 'root'",
"Description": "It is a good practice to run the container as a non-root user.",
"Message": "data.namespace.exceptions.exception[_] == \"appshield.dockerfile.DS002\"",
"Namespace": "appshield.dockerfile.DS002",
"Resolution": "Add 'USER \u003cnon root user name\u003e' line to the Dockerfile",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/appshield/ds002",
"References": [
"https://avd.aquasec.com/appshield/ds002"
],
"Status": "EXCEPTION",
"Layer": {
"DiffID": "sha256:45a6b1614d060b576fcd52613eacb8ccf05d887c803f0b66ca7149fcd5c0c560"
}
}
]
}
]

View File

@@ -0,0 +1,32 @@
[
{
"Target": "Dockerfile",
"Class": "config",
"Type": "dockerfile",
"MisconfSummary": {
"Successes": 0,
"Failures": 0,
"Exceptions": 1
},
"Misconfigurations": [
{
"Type": "Dockerfile Security Check",
"ID": "DS002",
"Title": "Image user should not be 'root'",
"Description": "It is a good practice to run the container as a non-root user.",
"Message": "data.appshield.dockerfile.DS002.exception[_][_] == \"\"",
"Namespace": "appshield.dockerfile.DS002",
"Resolution": "Add 'USER \u003cnon root user name\u003e' line to the Dockerfile",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/appshield/ds002",
"References": [
"https://avd.aquasec.com/appshield/ds002"
],
"Status": "EXCEPTION",
"Layer": {
"DiffID": "sha256:411d7a11745832de28b907ddc3498c6975ade3053d73e9e253b629f828cc1327"
}
}
]
}
]

View File

@@ -0,0 +1,33 @@
[
{
"Target": "Dockerfile",
"Class": "config",
"Type": "dockerfile",
"MisconfSummary": {
"Successes": 0,
"Failures": 1,
"Exceptions": 0
},
"Misconfigurations": [
{
"Type": "Dockerfile Security Check",
"ID": "DS002",
"Title": "Image user should not be 'root'",
"Description": "It is a good practice to run the container as a non-root user.",
"Message": "Specify at least 1 USER command in Dockerfile",
"Namespace": "appshield.dockerfile.DS002",
"Resolution": "Add 'USER \u003cnon root user name\u003e' line to the Dockerfile",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/appshield/ds002",
"References": [
"https://docs.docker.com/develop/develop-images/dockerfile_best-practices/",
"https://avd.aquasec.com/appshield/ds002"
],
"Status": "FAIL",
"Layer": {
"DiffID": "sha256:0b78fcf040212c52c2fb86e2d5b1a63483d5ab07bd905f0009326329691f49aa"
}
}
]
}
]

View File

@@ -0,0 +1 @@
FROM alpine:3.13

View File

@@ -0,0 +1,5 @@
package user.bar
deny[res] {
res := "something bad: bar"
}

View File

@@ -0,0 +1,5 @@
package user.foo
deny[res] {
res := "something bad: foo"
}

View File

@@ -0,0 +1 @@
FROM alpine:3.13

View File

@@ -0,0 +1,49 @@
package appshield.dockerfile.DS002
import data.lib.docker
__rego_metadata__ := {
"id": "DS002",
"title": "Image user should not be 'root'",
"version": "v1.0.0",
"severity": "HIGH",
"type": "Dockerfile Security Check",
"description": "It is a good practice to run the container as a non-root user.",
"recommended_actions": "Add 'USER <non root user name>' line to the Dockerfile",
"url": "https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"
}
__rego_input__ := {
"combine": false,
"selector": [{"type": "dockerfile"}],
}
# get_user returns all the usernames from
# the USER command.
get_user[username] {
user := docker.user[_]
username := user.Value[_]
}
# fail_user_count is true if there is no USER command.
fail_user_count {
count(get_user) < 1
}
# fail_last_user_root is true if the last USER command
# value is "root"
fail_last_user_root {
user := cast_array(get_user)
len := count(get_user)
user[minus(len, 1)] == "root"
}
deny[msg] {
fail_user_count
msg = "Specify at least 1 USER command in Dockerfile"
}
deny[res] {
fail_last_user_root
res := "Last USER command in Dockerfile should not be root"
}

View File

@@ -0,0 +1,2 @@
FROM alpine:3.13
LABEL user.root="allow"

View File

@@ -0,0 +1,8 @@
package namespace.exceptions
import data.namespaces
exception[ns] {
ns := data.namespaces[_]
startswith(ns, "appshield")
}

View File

@@ -0,0 +1,48 @@
package appshield.dockerfile.DS002
import data.lib.docker
__rego_metadata__ := {
"id": "DS002",
"title": "Image user should not be 'root'",
"version": "v1.0.0",
"severity": "HIGH",
"type": "Dockerfile Security Check",
"description": "It is a good practice to run the container as a non-root user.",
"recommended_actions": "Add 'USER <non root user name>' line to the Dockerfile",
}
__rego_input__ := {
"combine": false,
"selector": [{"type": "dockerfile"}],
}
# get_user returns all the usernames from
# the USER command.
get_user[username] {
user := docker.user[_]
username := user.Value[_]
}
# fail_user_count is true if there is no USER command.
fail_user_count {
count(get_user) < 1
}
# fail_last_user_root is true if the last USER command
# value is "root"
fail_last_user_root {
user := cast_array(get_user)
len := count(get_user)
user[minus(len, 1)] == "root"
}
deny[msg] {
fail_user_count
msg = "Specify at least 1 USER command in Dockerfile"
}
deny[res] {
fail_last_user_root
res := "Last USER command in Dockerfile should not be root"
}

View File

@@ -0,0 +1,97 @@
{
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"jquery": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.0.tgz",
"integrity": "sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"requires": {
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"promise": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/promise/-/promise-8.0.3.tgz",
"integrity": "sha512-HeRDUL1RJiLhyA0/grn+PTShlBAcLuh/1BJGtrvjwbvRDCTLLMEz9rOGCV+R3vHY4MixIuoMEd9Yq/XvsTPcjw==",
"requires": {
"asap": "~2.0.6"
}
},
"prop-types": {
"version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"requires": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.8.1"
}
},
"react": {
"version": "16.8.6",
"resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz",
"integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.13.6"
}
},
"react-is": {
"version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
},
"redux": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.1.tgz",
"integrity": "sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==",
"requires": {
"loose-envify": "^1.4.0",
"symbol-observable": "^1.2.0"
}
},
"scheduler": {
"version": "0.13.6",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz",
"integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"symbol-observable": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
}
}
}

View File

@@ -0,0 +1,2 @@
FROM alpine:3.13
LABEL user.root="allow"

View File

@@ -0,0 +1,15 @@
package appshield.dockerfile.DS002
exception[rules] {
instruction := input.stages[_][_]
instruction.Cmd == "label"
key := instruction.Value[i]
i % 2 == 0
key == "user.root"
value := instruction.Value[plus(i, 1)]
value == "\"allow\""
rules = [""]
}

View File

@@ -0,0 +1,48 @@
package appshield.dockerfile.DS002
import data.lib.docker
__rego_metadata__ := {
"id": "DS002",
"title": "Image user should not be 'root'",
"version": "v1.0.0",
"severity": "HIGH",
"type": "Dockerfile Security Check",
"description": "It is a good practice to run the container as a non-root user.",
"recommended_actions": "Add 'USER <non root user name>' line to the Dockerfile",
}
__rego_input__ := {
"combine": false,
"selector": [{"type": "dockerfile"}],
}
# get_user returns all the usernames from
# the USER command.
get_user[username] {
user := docker.user[_]
username := user.Value[_]
}
# fail_user_count is true if there is no USER command.
fail_user_count {
count(get_user) < 1
}
# fail_last_user_root is true if the last USER command
# value is "root"
fail_last_user_root {
user := cast_array(get_user)
len := count(get_user)
user[minus(len, 1)] == "root"
}
deny[msg] {
fail_user_count
msg = "Specify at least 1 USER command in Dockerfile"
}
deny[res] {
fail_last_user_root
res := "Last USER command in Dockerfile should not be root"
}

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/fluentd-multiple-lockfiles.tar.gz (debian 10.2)",
"Target": "testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz (debian 10.2)",
"Class": "os-pkgs",
"Type": "debian",
"Vulnerabilities": [
{

227
integration/testdata/nodejs.json.golden vendored Normal file
View File

@@ -0,0 +1,227 @@
[
{
"Target": "package-lock.json",
"Class": "lang-pkgs",
"Type": "npm",
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2019-11358",
"PkgName": "jquery",
"InstalledVersion": "3.3.9",
"FixedVersion": "3.4.0",
"Layer": {
"DiffID": "sha256:0b7517474d221ce39e6d69d41dabef6ae965464eef0d7037ba80361160c0d63c"
},
"SeveritySource": "nodejs-security-wg",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-11358",
"Title": "js-jquery: prototype pollution in object's prototype leading to denial of service or remote code execution or property injection",
"Description": "jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.",
"Severity": "MEDIUM",
"CweIDs": [
"CWE-79"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N",
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
"V2Score": 4.3,
"V3Score": 6.1
},
"redhat": {
"V3Vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
"V3Score": 5.6
}
},
"References": [
"http://packetstormsecurity.com/files/152787/dotCMS-5.1.1-Vulnerable-Dependencies.html",
"http://packetstormsecurity.com/files/153237/RetireJS-CORS-Issue-Script-Execution.html",
"http://seclists.org/fulldisclosure/2019/May/10",
"http://seclists.org/fulldisclosure/2019/May/11",
"http://seclists.org/fulldisclosure/2019/May/13",
"http://www.openwall.com/lists/oss-security/2019/06/03/2",
"http://www.securityfocus.com/bid/108023",
"https://access.redhat.com/errata/RHSA-2019:1456",
"https://backdropcms.org/security/backdrop-sa-core-2019-009",
"https://blog.jquery.com/2019/04/10/jquery-3-4-0-released/",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11358",
"https://github.com/DanielRuf/snyk-js-jquery-174006?files=1",
"https://github.com/jquery/jquery/commit/753d591aea698e57d6db58c9f722cd0808619b1b",
"https://github.com/jquery/jquery/pull/4333",
"https://github.com/rails/jquery-rails/blob/master/CHANGELOG.md#434",
"https://hackerone.com/reports/454365",
"https://lists.apache.org/thread.html/08720ef215ee7ab3386c05a1a90a7d1c852bf0706f176a7816bf65fc@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/5928aa293e39d248266472210c50f176cac1535220f2486e6a7fa844@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/6097cdbd6f0a337bedd9bb5cc441b2d525ff002a96531de367e4259f@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/88fb0362fd40e5b605ea8149f63241537b8b6fb5bfa315391fc5cbb7@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/b736d0784cf02f5a30fbb4c5902762a15ad6d47e17e2c5a17b7d6205@%3Ccommits.airflow.apache.org%3E",
"https://lists.debian.org/debian-lts-announce/2019/05/msg00006.html",
"https://lists.debian.org/debian-lts-announce/2019/05/msg00029.html",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/4UOAZIFCSZ3ENEFOR5IXX6NFAD3HV7FA/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/5IABSKTYZ5JUGL735UKGXL5YPRYOPUYI/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KYH3OAGR2RTCHRA5NOKX2TES7SNQMWGO/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QV3PKZC3PQCO3273HAT76PAQZFBEO4KP/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RLXRX23725JL366CNZGJZ7AQQB7LHQ6F/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/WZW27UCJ5CYFL4KFFFMYMIBNMIU2ALG5/",
"https://nvd.nist.gov/vuln/detail/CVE-2019-11358",
"https://seclists.org/bugtraq/2019/Apr/32",
"https://seclists.org/bugtraq/2019/Jun/12",
"https://seclists.org/bugtraq/2019/May/18",
"https://snyk.io/vuln/SNYK-JS-JQUERY-174006",
"https://www.debian.org/security/2019/dsa-4434",
"https://www.debian.org/security/2019/dsa-4460",
"https://www.drupal.org/sa-core-2019-006"
],
"PublishedDate": "2019-04-20T00:29:00Z",
"LastModifiedDate": "2019-06-12T17:29:00Z"
},
{
"VulnerabilityID": "CVE-2019-10744",
"PkgName": "lodash",
"InstalledVersion": "4.17.4",
"FixedVersion": "4.17.12",
"Layer": {
"DiffID": "sha256:0b7517474d221ce39e6d69d41dabef6ae965464eef0d7037ba80361160c0d63c"
},
"SeveritySource": "nvd",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-10744",
"Title": "nodejs-lodash: prototype pollution in defaultsDeep function leading to modifying properties",
"Description": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.",
"Severity": "CRITICAL",
"CweIDs": [
"CWE-20"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P",
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"V2Score": 7.5,
"V3Score": 9.8
},
"redhat": {
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H",
"V3Score": 9.1
}
},
"References": [
"https://access.redhat.com/errata/RHSA-2019:3024",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10744",
"https://github.com/lodash/lodash/issues/4348",
"https://github.com/lodash/lodash/pull/4336",
"https://nvd.nist.gov/vuln/detail/CVE-2019-10744",
"https://security.netapp.com/advisory/ntap-20191004-0005/",
"https://snyk.io/vuln/SNYK-JS-LODASH-450202"
],
"PublishedDate": "2019-07-26T00:15:00Z",
"LastModifiedDate": "2019-10-04T09:15:00Z"
},
{
"VulnerabilityID": "CVE-2018-16487",
"PkgName": "lodash",
"InstalledVersion": "4.17.4",
"FixedVersion": "4.17.11",
"Layer": {
"DiffID": "sha256:0b7517474d221ce39e6d69d41dabef6ae965464eef0d7037ba80361160c0d63c"
},
"SeveritySource": "nodejs-security-wg",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2018-16487",
"Title": "lodash: Prototype pollution in utilities function",
"Description": "A prototype pollution vulnerability was found in lodash \u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.",
"Severity": "HIGH",
"CweIDs": [
"CWE-254"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P",
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"V2Score": 7.5,
"V3Score": 9.8
},
"redhat": {
"V3Vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
"V3Score": 5.6
}
},
"References": [
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487",
"https://hackerone.com/reports/380873",
"https://nvd.nist.gov/vuln/detail/CVE-2018-16487",
"https://security.netapp.com/advisory/ntap-20190919-0004/",
"https://www.npmjs.com/advisories/782"
],
"PublishedDate": "2019-02-01T18:29:00Z",
"LastModifiedDate": "2019-09-19T17:15:00Z"
},
{
"VulnerabilityID": "CVE-2019-1010266",
"PkgName": "lodash",
"InstalledVersion": "4.17.4",
"FixedVersion": "4.17.11",
"Layer": {
"DiffID": "sha256:0b7517474d221ce39e6d69d41dabef6ae965464eef0d7037ba80361160c0d63c"
},
"SeveritySource": "nvd",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-1010266",
"Title": "Moderate severity vulnerability that affects lodash",
"Description": "lodash prior to 4.17.11 is affected by: CWE-400: Uncontrolled Resource Consumption. The impact is: Denial of service. The component is: Date handler. The attack vector is: Attacker provides very long strings, which the library attempts to match using a regular expression. The fixed version is: 4.17.11.",
"Severity": "MEDIUM",
"CweIDs": [
"CWE-400"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:L/Au:S/C:N/I:N/A:P",
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"V2Score": 4,
"V3Score": 6.5
}
},
"References": [
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1010266",
"https://github.com/lodash/lodash/issues/3359",
"https://github.com/lodash/lodash/wiki/Changelog",
"https://nvd.nist.gov/vuln/detail/CVE-2019-1010266",
"https://security.netapp.com/advisory/ntap-20190919-0004/",
"https://snyk.io/vuln/SNYK-JS-LODASH-73639"
],
"PublishedDate": "2019-07-17T21:15:00Z",
"LastModifiedDate": "2019-09-19T17:15:00Z"
},
{
"VulnerabilityID": "CVE-2018-3721",
"PkgName": "lodash",
"InstalledVersion": "4.17.4",
"FixedVersion": "4.17.5",
"Layer": {
"DiffID": "sha256:0b7517474d221ce39e6d69d41dabef6ae965464eef0d7037ba80361160c0d63c"
},
"SeveritySource": "nodejs-security-wg",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2018-3721",
"Title": "lodash: Prototype pollution in utilities function",
"Description": "lodash node module before 4.17.5 suffers from a Modification of Assumed-Immutable Data (MAID) vulnerability via defaultsDeep, merge, and mergeWith functions, which allows a malicious user to modify the prototype of \"Object\" via __proto__, causing the addition or modification of an existing property that will exist on all objects.",
"Severity": "LOW",
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:L/Au:S/C:N/I:P/A:N",
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
"V2Score": 4,
"V3Score": 6.5
},
"redhat": {
"V3Vector": "CVSS:3.0/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
"V3Score": 2.9
}
},
"References": [
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3721",
"https://github.com/lodash/lodash/commit/d8e069cc3410082e44eb18fcf8e7f3d08ebe1d4a",
"https://hackerone.com/reports/310443",
"https://nvd.nist.gov/vuln/detail/CVE-2018-3721",
"https://security.netapp.com/advisory/ntap-20190919-0004/"
],
"PublishedDate": "2018-06-07T02:29:00Z",
"LastModifiedDate": "2019-10-03T00:03:00Z"
}
]
}
]

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/opensuse-leap-151.tar.gz (opensuse.leap 15.1)",
"Target": "testdata/fixtures/images/opensuse-leap-151.tar.gz (opensuse.leap 15.1)",
"Class": "os-pkgs",
"Type": "opensuse.leap",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/opensuse-leap-423.tar.gz (opensuse.leap 42.3)",
"Target": "testdata/fixtures/images/opensuse-leap-423.tar.gz (opensuse.leap 42.3)",
"Class": "os-pkgs",
"Type": "opensuse.leap"
}
]

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/oraclelinux-6-slim.tar.gz (oracle 6.10)",
"Target": "testdata/fixtures/images/oraclelinux-6-slim.tar.gz (oracle 6.10)",
"Class": "os-pkgs",
"Type": "oracle",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/oraclelinux-7-slim.tar.gz (oracle 7.6)",
"Target": "testdata/fixtures/images/oraclelinux-7-slim.tar.gz (oracle 7.6)",
"Class": "os-pkgs",
"Type": "oracle",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/oraclelinux-8-slim.tar.gz (oracle 8.0)",
"Target": "testdata/fixtures/images/oraclelinux-8-slim.tar.gz (oracle 8.0)",
"Class": "os-pkgs",
"Type": "oracle",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/photon-10.tar.gz (photon 1.0)",
"Target": "testdata/fixtures/images/photon-10.tar.gz (photon 1.0)",
"Class": "os-pkgs",
"Type": "photon",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/photon-20.tar.gz (photon 2.0)",
"Target": "testdata/fixtures/images/photon-20.tar.gz (photon 2.0)",
"Class": "os-pkgs",
"Type": "photon",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/photon-30.tar.gz (photon 3.0)",
"Target": "testdata/fixtures/images/photon-30.tar.gz (photon 3.0)",
"Class": "os-pkgs",
"Type": "photon",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/ubi-7.tar.gz (redhat 7.7)",
"Target": "testdata/fixtures/images/ubi-7.tar.gz (redhat 7.7)",
"Class": "os-pkgs",
"Type": "redhat",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/ubuntu-1604.tar.gz (ubuntu 16.04)",
"Target": "testdata/fixtures/images/ubuntu-1604.tar.gz (ubuntu 16.04)",
"Class": "os-pkgs",
"Type": "ubuntu",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/ubuntu-1804.tar.gz (ubuntu 18.04)",
"Target": "testdata/fixtures/images/ubuntu-1804.tar.gz (ubuntu 18.04)",
"Class": "os-pkgs",
"Type": "ubuntu",
"Vulnerabilities": [
{

View File

@@ -1,6 +1,7 @@
[
{
"Target": "testdata/fixtures/ubuntu-1804.tar.gz (ubuntu 18.04)",
"Target": "testdata/fixtures/images/ubuntu-1804.tar.gz (ubuntu 18.04)",
"Class": "os-pkgs",
"Type": "ubuntu",
"Vulnerabilities": [
{

View File

@@ -18,9 +18,9 @@ import (
"github.com/aquasecurity/trivy/pkg/commands/plugin"
"github.com/aquasecurity/trivy/pkg/commands/server"
tdb "github.com/aquasecurity/trivy/pkg/db"
"github.com/aquasecurity/trivy/pkg/result"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
"github.com/aquasecurity/trivy/pkg/vulnerability"
)
// VersionInfo holds the trivy DB version Info
@@ -76,10 +76,17 @@ var (
EnvVars: []string{"TRIVY_EXIT_CODE"},
}
skipUpdateFlag = cli.BoolFlag{
Name: "skip-update",
Usage: "skip db update",
EnvVars: []string{"TRIVY_SKIP_UPDATE"},
skipDBUpdateFlag = cli.BoolFlag{
Name: "skip-db-update",
Aliases: []string{"skip-update"},
Usage: "skip updating vulnerability database",
EnvVars: []string{"TRIVY_SKIP_UPDATE", "TRIVY_SKIP_DB_UPDATE"},
}
skipPolicyUpdateFlag = cli.BoolFlag{
Name: "skip-policy-update",
Usage: "skip updating builtin policies",
EnvVars: []string{"TRIVY_SKIP_POLICY_UPDATE"},
}
downloadDBOnlyFlag = cli.BoolFlag{
@@ -145,7 +152,6 @@ var (
Value: types.SecurityCheckVulnerability,
Usage: "comma-separated list of what security issues to detect (vuln,config)",
EnvVars: []string{"TRIVY_SECURITY_CHECKS"},
Hidden: true,
}
cacheDirFlag = cli.StringFlag{
@@ -164,7 +170,7 @@ var (
ignoreFileFlag = cli.StringFlag{
Name: "ignorefile",
Value: vulnerability.DefaultIgnoreFile,
Value: result.DefaultIgnoreFile,
Usage: "specify .trivyignore file",
EnvVars: []string{"TRIVY_IGNOREFILE"},
}
@@ -219,6 +225,40 @@ var (
EnvVars: []string{"TRIVY_SKIP_DIRS"},
}
configPolicy = cli.StringSliceFlag{
Name: "config-policy",
Usage: "specify paths to the Rego policy files directory, applying config files",
EnvVars: []string{"TRIVY_CONFIG_POLICY"},
}
configPolicyAlias = cli.StringSliceFlag{
Name: "policy",
Aliases: []string{"config-policy"},
Usage: "specify paths to the Rego policy files directory, applying config files",
EnvVars: []string{"TRIVY_POLICY"},
}
filePatterns = cli.StringSliceFlag{
Name: "file-patterns",
Usage: "specify file patterns",
EnvVars: []string{"TRIVY_FILE_PATTERNS"},
}
policyNamespaces = cli.StringSliceFlag{
Name: "policy-namespaces",
Aliases: []string{"namespaces"},
Usage: "Rego namespaces",
Value: cli.NewStringSlice("users"),
EnvVars: []string{"TRIVY_POLICY_NAMESPACES"},
}
includeSuccesses = cli.BoolFlag{
Name: "include-successes",
Usage: "include successes of misconfigurations",
Value: false,
EnvVars: []string{"TRIVY_INCLUDE_SUCCESSES"},
}
globalFlags = []cli.Flag{
&quietFlag,
&debugFlag,
@@ -232,7 +272,7 @@ var (
&severityFlag,
&outputFlag,
&exitCodeFlag,
&skipUpdateFlag,
&skipDBUpdateFlag,
&downloadDBOnlyFlag,
&resetFlag,
&clearCacheFlag,
@@ -246,9 +286,11 @@ var (
&lightFlag,
&ignorePolicy,
&listAllPackages,
&skipFiles,
&skipDirs,
&cacheBackendFlag,
stringSliceFlag(skipFiles),
stringSliceFlag(skipDirs),
stringSliceFlag(configPolicy),
stringSliceFlag(policyNamespaces),
}
// deprecated options
@@ -294,6 +336,7 @@ func NewApp(version string) *cli.App {
NewRepositoryCommand(),
NewClientCommand(),
NewServerCommand(),
NewConfigCommand(),
NewPluginCommand(),
}
app.Commands = append(app.Commands, plugin.LoadCommands()...)
@@ -410,7 +453,8 @@ func NewFilesystemCommand() *cli.Command {
&severityFlag,
&outputFlag,
&exitCodeFlag,
&skipUpdateFlag,
&skipDBUpdateFlag,
&skipPolicyUpdateFlag,
&clearCacheFlag,
&ignoreUnfixedFlag,
&removedPkgsFlag,
@@ -422,8 +466,10 @@ func NewFilesystemCommand() *cli.Command {
&noProgressFlag,
&ignorePolicy,
&listAllPackages,
&skipFiles,
&skipDirs,
stringSliceFlag(skipFiles),
stringSliceFlag(skipDirs),
stringSliceFlag(configPolicy),
&policyNamespaces,
},
}
}
@@ -443,7 +489,8 @@ func NewRepositoryCommand() *cli.Command {
&severityFlag,
&outputFlag,
&exitCodeFlag,
&skipUpdateFlag,
&skipDBUpdateFlag,
&skipPolicyUpdateFlag,
&clearCacheFlag,
&ignoreUnfixedFlag,
&removedPkgsFlag,
@@ -455,8 +502,8 @@ func NewRepositoryCommand() *cli.Command {
&noProgressFlag,
&ignorePolicy,
&listAllPackages,
&skipFiles,
&skipDirs,
stringSliceFlag(skipFiles),
stringSliceFlag(skipDirs),
},
}
}
@@ -484,7 +531,9 @@ func NewClientCommand() *cli.Command {
&ignoreFileFlag,
&timeoutFlag,
&ignorePolicy,
stringSliceFlag(configPolicy),
&listAllPackages,
// original flags
&token,
&tokenHeader,
@@ -511,7 +560,7 @@ func NewServerCommand() *cli.Command {
Usage: "server mode",
Action: server.Run,
Flags: []cli.Flag{
&skipUpdateFlag,
&skipDBUpdateFlag,
&downloadDBOnlyFlag,
&resetFlag,
&cacheBackendFlag,
@@ -529,6 +578,38 @@ func NewServerCommand() *cli.Command {
}
}
// NewConfigCommand adds config command
func NewConfigCommand() *cli.Command {
return &cli.Command{
Name: "config",
Aliases: []string{"conf"},
ArgsUsage: "dir",
Usage: "scan config files",
Action: artifact.ConfigRun,
Flags: []cli.Flag{
&templateFlag,
&formatFlag,
&severityFlag,
&outputFlag,
&exitCodeFlag,
&skipPolicyUpdateFlag,
&clearCacheFlag,
&ignoreUnfixedFlag,
&ignoreFileFlag,
&cacheBackendFlag,
&timeoutFlag,
&noProgressFlag,
&ignorePolicy,
stringSliceFlag(skipFiles),
stringSliceFlag(skipDirs),
stringSliceFlag(configPolicyAlias),
stringSliceFlag(filePatterns),
stringSliceFlag(policyNamespaces),
&includeSuccesses,
},
}
}
// NewPluginCommand is the factory method to add plugin command
func NewPluginCommand() *cli.Command {
return &cli.Command{
@@ -561,3 +642,10 @@ func NewPluginCommand() *cli.Command {
},
}
}
// StringSliceFlag is defined globally. When the app runs multiple times,
// the previous value will be retained and it causes unexpected results.
// The flag value is copied through this function to prevent the issue.
func stringSliceFlag(f cli.StringSliceFlag) *cli.StringSliceFlag {
return &f
}

View File

@@ -0,0 +1,31 @@
package artifact
import (
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/types"
)
// ConfigRun runs scan on config files
func ConfigRun(ctx *cli.Context) error {
opt, err := NewOption(ctx)
if err != nil {
return xerrors.Errorf("option error: %w", err)
}
// initialize options
if err = opt.Init(); err != nil {
return xerrors.Errorf("failed to initialize options: %w", err)
}
// Scan only config files
opt.VulnType = nil
opt.SecurityChecks = []string{types.SecurityCheckConfig}
// Skip downloading vulnerability DB
opt.SkipDBUpdate = true
// Run filesystem command internally
return Run(ctx.Context, opt, filesystemScanner, initFSCache)
}

View File

@@ -11,8 +11,8 @@ import (
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/fanal/analyzer/config"
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/trivy/pkg/result"
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/vulnerability"
)
func initializeDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache,
@@ -43,7 +43,7 @@ func initializeRepositoryScanner(ctx context.Context, url string, artifactCache
return scanner.Scanner{}, nil, nil
}
func initializeResultClient() vulnerability.Client {
wire.Build(vulnerability.SuperSet)
return vulnerability.Client{}
func initializeResultClient() result.Client {
wire.Build(result.SuperSet)
return result.Client{}
}

View File

@@ -15,6 +15,7 @@ type Option struct {
option.ImageOption
option.ReportOption
option.CacheOption
option.ConfigOption
// deprecated
onlyUpdate string
@@ -38,6 +39,7 @@ func NewOption(c *cli.Context) (Option, error) {
ImageOption: option.NewImageOption(c),
ReportOption: option.NewReportOption(c),
CacheOption: option.NewCacheOption(c),
ConfigOption: option.NewConfigOption(c),
onlyUpdate: c.String("only-update"),
refresh: c.Bool("refresh"),

View File

@@ -42,6 +42,24 @@ func TestOption_Init(t *testing.T) {
},
},
},
{
name: "config scanning",
args: []string{"--severity", "CRITICAL", "--security-checks", "config", "--quiet", "alpine:3.10"},
want: Option{
GlobalOption: option.GlobalOption{
Quiet: true,
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.10",
},
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckConfig},
Output: os.Stdout,
},
},
},
{
name: "happy path: reset",
args: []string{"--reset"},
@@ -154,8 +172,8 @@ func TestOption_Init(t *testing.T) {
},
{
name: "sad: skip and download db",
args: []string{"--skip-update", "--download-db-only", "alpine:3.10"},
wantErr: "--skip-update and --download-db-only options can not be specified both",
args: []string{"--skip-db-update", "--download-db-only", "alpine:3.10"},
wantErr: "--skip-db-update and --download-db-only options can not be specified both",
},
{
name: "sad: multiple image names",
@@ -176,7 +194,7 @@ func TestOption_Init(t *testing.T) {
set.Bool("quiet", false, "")
set.Bool("no-progress", false, "")
set.Bool("reset", false, "")
set.Bool("skip-update", false, "")
set.Bool("skip-db-update", false, "")
set.Bool("download-db-only", false, "")
set.Bool("auto-refresh", false, "")
set.String("severity", "CRITICAL", "")

View File

@@ -20,6 +20,8 @@ import (
"github.com/aquasecurity/trivy/pkg/utils"
)
const defaultPolicyNamespace = "appshield"
var errSkipScan = errors.New("skip subsequent processes")
// InitializeScanner type to define initialize function signature
@@ -72,7 +74,7 @@ func runWithTimeout(ctx context.Context, opt Option, initializeScanner Initializ
return xerrors.Errorf("filter error: %w", err)
}
if err = pkgReport.Write(opt.Format, opt.Output, opt.Severities, report, opt.Template, opt.Light); err != nil {
if err = pkgReport.Write(opt.Format, opt.Output, opt.Severities, report, opt.Template, opt.Light, opt.IncludeSuccesses); err != nil {
return xerrors.Errorf("unable to write results: %w", err)
}
@@ -109,7 +111,7 @@ func initFSCache(c Option) (cache.Cache, error) {
func initDB(c Option) error {
// download the database file
noProgress := c.Quiet || c.NoProgress
if err := operation.DownloadDB(c.AppVersion, c.CacheDir, noProgress, c.Light, c.SkipUpdate); err != nil {
if err := operation.DownloadDB(c.AppVersion, c.CacheDir, noProgress, c.Light, c.SkipDBUpdate); err != nil {
return err
}
@@ -146,10 +148,21 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner,
disabledAnalyzers = []analyzer.Type{}
}
// TODO: fix the scanner option and enable config analyzers once we finalize the specification of config scanning.
configScannerOptions := config.ScannerOption{}
disabledAnalyzers = append(disabledAnalyzers, analyzer.TypeYaml, analyzer.TypeTOML, analyzer.TypeJSON,
analyzer.TypeDockerfile, analyzer.TypeHCL)
// ScannerOptions is filled only when config scanning is enabled.
var configScannerOptions config.ScannerOption
if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) {
builtinPolicyPaths, err := operation.InitBuiltinPolicies(ctx, opt.SkipPolicyUpdate)
if err != nil {
return pkgReport.Report{}, xerrors.Errorf("failed to initialize builtin policies: %w", err)
}
configScannerOptions = config.ScannerOption{
Namespaces: append(opt.PolicyNamespaces, defaultPolicyNamespace),
PolicyPaths: append(opt.PolicyPaths, builtinPolicyPaths...),
DataPaths: opt.DataPaths,
FilePatterns: opt.FilePatterns,
}
}
s, cleanup, err := initializeScanner(ctx, target, cacheClient, cacheClient, opt.Timeout,
disabledAnalyzers, configScannerOptions)
@@ -169,13 +182,14 @@ func filter(ctx context.Context, opt Option, report pkgReport.Report) (pkgReport
resultClient := initializeResultClient()
results := report.Results
for i := range results {
resultClient.FillInfo(results[i].Vulnerabilities, results[i].Type)
vulns, err := resultClient.Filter(ctx, results[i].Vulnerabilities,
opt.Severities, opt.IgnoreUnfixed, opt.IgnoreFile, opt.IgnorePolicy)
resultClient.FillVulnerabilityInfo(results[i].Vulnerabilities, results[i].Type)
vulns, misconfs, err := resultClient.Filter(ctx, results[i].Vulnerabilities, results[i].Misconfigurations,
opt.Severities, opt.IgnoreUnfixed, opt.IncludeSuccesses, opt.IgnoreFile, opt.IgnorePolicy)
if err != nil {
return pkgReport.Report{}, xerrors.Errorf("unable to filter vulnerabilities: %w", err)
}
results[i].Vulnerabilities = vulns
results[i].Misconfigurations = misconfs
}
return report, nil
}

View File

@@ -17,10 +17,10 @@ import (
"github.com/aquasecurity/fanal/image"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/detector/ospkg"
"github.com/aquasecurity/trivy/pkg/result"
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/scanner/local"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/vulnerability"
"time"
)
@@ -92,8 +92,8 @@ func initializeRepositoryScanner(ctx context.Context, url string, artifactCache
}, nil
}
func initializeResultClient() vulnerability.Client {
func initializeResultClient() result.Client {
dbConfig := db.Config{}
client := vulnerability.NewClient(dbConfig)
client := result.NewClient(dbConfig)
return client
}

View File

@@ -11,9 +11,9 @@ import (
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/fanal/analyzer/config"
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/trivy/pkg/result"
"github.com/aquasecurity/trivy/pkg/rpc/client"
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/vulnerability"
)
func initializeDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, customHeaders client.CustomHeaders,
@@ -30,7 +30,7 @@ func initializeArchiveScanner(ctx context.Context, filePath string, artifactCach
return scanner.Scanner{}, nil
}
func initializeResultClient() vulnerability.Client {
wire.Build(vulnerability.SuperSet)
return vulnerability.Client{}
func initializeResultClient() result.Client {
wire.Build(result.SuperSet)
return result.Client{}
}

View File

@@ -14,9 +14,11 @@ import (
type Option struct {
option.GlobalOption
option.ArtifactOption
ListAllPkgs bool
option.ImageOption
option.ReportOption
option.ConfigOption
ListAllPkgs bool
RemoteAddr string
token string
tokenHeader string
@@ -37,11 +39,12 @@ func NewOption(c *cli.Context) (Option, error) {
ArtifactOption: option.NewArtifactOption(c),
ImageOption: option.NewImageOption(c),
ReportOption: option.NewReportOption(c),
ConfigOption: option.NewConfigOption(c),
ListAllPkgs: c.Bool("list-all-pkgs"),
RemoteAddr: c.String("remote"),
token: c.String("token"),
tokenHeader: c.String("token-header"),
customHeaders: c.StringSlice("custom-headers"),
ListAllPkgs: c.Bool("list-all-pkgs"),
}, nil
}

View File

@@ -44,6 +44,25 @@ func TestConfig_Init(t *testing.T) {
CustomHeaders: http.Header{},
},
},
{
name: "config scanning",
args: []string{"--severity", "CRITICAL", "--security-checks", "config", "--quiet", "alpine:3.10"},
want: Option{
GlobalOption: option.GlobalOption{
Quiet: true,
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.10",
},
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckConfig},
Output: os.Stdout,
},
CustomHeaders: http.Header{},
},
},
{
name: "happy path with token and token header",
args: []string{"--token", "secret", "--token-header", "X-Trivy-Token", "alpine:3.11"},

View File

@@ -10,6 +10,7 @@ import (
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/cache"
"github.com/aquasecurity/trivy/pkg/commands/operation"
"github.com/aquasecurity/trivy/pkg/log"
pkgReport "github.com/aquasecurity/trivy/pkg/report"
"github.com/aquasecurity/trivy/pkg/rpc/client"
@@ -18,6 +19,8 @@ import (
"github.com/aquasecurity/trivy/pkg/utils"
)
const defaultPolicyNamespace = "appshield"
// Run runs the scan
func Run(cliCtx *cli.Context) error {
opt, err := NewOption(cliCtx)
@@ -67,15 +70,16 @@ func runWithTimeout(ctx context.Context, opt Option) error {
resultClient := initializeResultClient()
results := report.Results
for i := range results {
vulns, err := resultClient.Filter(ctx, results[i].Vulnerabilities,
opt.Severities, opt.IgnoreUnfixed, opt.IgnoreFile, opt.IgnorePolicy)
vulns, misconfs, err := resultClient.Filter(ctx, results[i].Vulnerabilities, results[i].Misconfigurations,
opt.Severities, opt.IgnoreUnfixed, opt.IncludeSuccesses, opt.IgnoreFile, opt.IgnorePolicy)
if err != nil {
return xerrors.Errorf("filter error: %w", err)
}
results[i].Vulnerabilities = vulns
results[i].Misconfigurations = misconfs
}
if err = pkgReport.Write(opt.Format, opt.Output, opt.Severities, report, opt.Template, false); err != nil {
if err = pkgReport.Write(opt.Format, opt.Output, opt.Severities, report, opt.Template, false, opt.IncludeSuccesses); err != nil {
return xerrors.Errorf("unable to write results: %w", err)
}
@@ -111,10 +115,21 @@ func initializeScanner(ctx context.Context, opt Option) (scanner.Scanner, func()
disabledAnalyzers = []analyzer.Type{}
}
// TODO: fix the scanner option and enable config analyzers once we finalize the specification of config scanning.
configScannerOptions := config.ScannerOption{}
disabledAnalyzers = append(disabledAnalyzers, analyzer.TypeYaml, analyzer.TypeTOML, analyzer.TypeJSON,
analyzer.TypeDockerfile, analyzer.TypeHCL)
// ScannerOptions is filled only when config scanning is enabled.
var configScannerOptions config.ScannerOption
if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) {
builtinPolicyPaths, err := operation.InitBuiltinPolicies(ctx, false)
if err != nil {
return scanner.Scanner{}, nil, xerrors.Errorf("failed to initialize default policies: %w", err)
}
configScannerOptions = config.ScannerOption{
Namespaces: append(opt.PolicyNamespaces, defaultPolicyNamespace),
PolicyPaths: append(opt.PolicyPaths, builtinPolicyPaths...),
DataPaths: opt.DataPaths,
FilePatterns: opt.FilePatterns,
}
}
if opt.Input != "" {
// Scan tar file

View File

@@ -13,10 +13,10 @@ import (
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/fanal/image"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/result"
"github.com/aquasecurity/trivy/pkg/rpc/client"
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/vulnerability"
"time"
)
@@ -59,8 +59,8 @@ func initializeArchiveScanner(ctx context.Context, filePath string, artifactCach
return scanner2, nil
}
func initializeResultClient() vulnerability.Client {
func initializeResultClient() result.Client {
dbConfig := db.Config{}
vulnerabilityClient := vulnerability.NewClient(dbConfig)
return vulnerabilityClient
resultClient := result.NewClient(dbConfig)
return resultClient
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/trivy/pkg/db"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/policy"
"github.com/aquasecurity/trivy/pkg/utils"
)
@@ -102,6 +103,40 @@ func DownloadDB(appVersion, cacheDir string, quiet, light, skipUpdate bool) erro
return nil
}
// InitBuiltinPolicies downloads the builtin policies and loads them
func InitBuiltinPolicies(ctx context.Context, skipUpdate bool) ([]string, error) {
client, err := policy.NewClient()
if err != nil {
return nil, xerrors.Errorf("policy client error: %w", err)
}
needsUpdate := false
if !skipUpdate {
needsUpdate, err = client.NeedsUpdate()
if err != nil {
return nil, xerrors.Errorf("unable to check if builtin policies need to be updated: %w", err)
}
}
if needsUpdate {
log.Logger.Info("Need to update the builtin policies")
log.Logger.Info("Downloading the builtin policies...")
if err = client.DownloadBuiltinPolicies(ctx); err != nil {
return nil, xerrors.Errorf("failed to download builtin policies: %w", err)
}
}
policyPaths, err := client.LoadBuiltinPolicies()
if err != nil {
if skipUpdate {
log.Logger.Info("No builtin policies were loaded")
return nil, nil
}
return nil, xerrors.Errorf("policy load error: %w", err)
}
return policyPaths, nil
}
func showDBInfo(cacheDir string) error {
m := db.NewMetadata(afero.NewOsFs(), cacheDir)
metadata, err := m.Get()

View File

@@ -0,0 +1,29 @@
package option
import (
"github.com/urfave/cli/v2"
)
// ConfigOption holds the options for config scanning
type ConfigOption struct {
FilePatterns []string
IncludeSuccesses bool
SkipPolicyUpdate bool
// Rego
PolicyPaths []string
DataPaths []string
PolicyNamespaces []string
}
// NewConfigOption is the factory method to return config scanning options
func NewConfigOption(c *cli.Context) ConfigOption {
return ConfigOption{
IncludeSuccesses: c.Bool("include-successes"),
SkipPolicyUpdate: c.Bool("skip-policy-update"),
FilePatterns: c.StringSlice("file-patterns"),
PolicyPaths: c.StringSlice("config-policy"),
DataPaths: c.StringSlice("config-data"),
PolicyNamespaces: c.StringSlice("policy-namespaces"),
}
}

View File

@@ -9,7 +9,7 @@ import (
type DBOption struct {
Reset bool
DownloadDBOnly bool
SkipUpdate bool
SkipDBUpdate bool
Light bool
NoProgress bool
}
@@ -19,7 +19,7 @@ func NewDBOption(c *cli.Context) DBOption {
return DBOption{
Reset: c.Bool("reset"),
DownloadDBOnly: c.Bool("download-db-only"),
SkipUpdate: c.Bool("skip-update"),
SkipDBUpdate: c.Bool("skip-db-update"),
Light: c.Bool("light"),
NoProgress: c.Bool("no-progress"),
}
@@ -27,8 +27,8 @@ func NewDBOption(c *cli.Context) DBOption {
// Init initialize the DBOption
func (c *DBOption) Init() (err error) {
if c.SkipUpdate && c.DownloadDBOnly {
return xerrors.New("--skip-update and --download-db-only options can not be specified both")
if c.SkipDBUpdate && c.DownloadDBOnly {
return xerrors.New("--skip-db-update and --download-db-only options can not be specified both")
}
return nil
}

View File

@@ -17,10 +17,10 @@ func TestNewDBOption(t *testing.T) {
}{
{
name: "happy path",
args: []string{"--reset", "--skip-update"},
args: []string{"--reset", "--skip-db-update"},
want: option.DBOption{
Reset: true,
SkipUpdate: true,
Reset: true,
SkipDBUpdate: true,
},
},
}
@@ -29,7 +29,7 @@ func TestNewDBOption(t *testing.T) {
app := &cli.App{}
set := flag.NewFlagSet("test", 0)
set.Bool("reset", false, "")
set.Bool("skip-update", false, "")
set.Bool("skip-db-update", false, "")
c := cli.NewContext(app, set, nil)
_ = set.Parse(tt.args)
@@ -64,7 +64,7 @@ func TestDBOption_Init(t *testing.T) {
DownloadDBOnly: true,
SkipUpdate: true,
},
wantErr: "--skip-update and --download-db-only options can not be specified both",
wantErr: "--skip-db-update and --download-db-only options can not be specified both",
},
}
for _, tt := range tests {
@@ -72,7 +72,7 @@ func TestDBOption_Init(t *testing.T) {
c := &option.DBOption{
Reset: tt.fields.Reset,
DownloadDBOnly: tt.fields.DownloadDBOnly,
SkipUpdate: tt.fields.SkipUpdate,
SkipDBUpdate: tt.fields.SkipUpdate,
Light: tt.fields.Light,
}

View File

@@ -57,7 +57,7 @@ func TestReportReportConfig_Init(t *testing.T) {
fields: fields{
severities: "CRITICAL,INVALID",
vulnType: "os,library",
securityChecks: "vuln",
securityChecks: "config",
},
args: []string{"centos:7"},
logs: []string{
@@ -66,7 +66,7 @@ func TestReportReportConfig_Init(t *testing.T) {
want: ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical, dbTypes.SeverityUnknown},
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
SecurityChecks: []string{types.SecurityCheckConfig},
Output: os.Stdout,
},
},
@@ -97,7 +97,7 @@ func TestReportReportConfig_Init(t *testing.T) {
Template: "@contrib/gitlab.tpl",
severities: "LOW",
vulnType: "os",
securityChecks: "vuln",
securityChecks: "config",
},
args: []string{"gitlab/gitlab-ce:12.7.2-ce.0"},
logs: []string{
@@ -109,7 +109,7 @@ func TestReportReportConfig_Init(t *testing.T) {
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
Template: "@contrib/gitlab.tpl",
VulnType: []string{types.VulnTypeOS},
SecurityChecks: []string{types.SecurityCheckVulnerability},
SecurityChecks: []string{types.SecurityCheckConfig},
},
},
{

View File

@@ -20,15 +20,15 @@ func TestNew(t *testing.T) {
}{
{
name: "happy path",
args: []string{"-quiet", "--no-progress", "--reset", "--skip-update", "--listen", "localhost:8080"},
args: []string{"-quiet", "--no-progress", "--reset", "--skip-db-update", "--listen", "localhost:8080"},
want: server.Config{
GlobalOption: option.GlobalOption{
Quiet: true,
},
DBOption: option.DBOption{
Reset: true,
SkipUpdate: true,
NoProgress: true,
Reset: true,
SkipDBUpdate: true,
NoProgress: true,
},
Listen: "localhost:8080",
},
@@ -41,7 +41,7 @@ func TestNew(t *testing.T) {
set.Bool("quiet", false, "")
set.Bool("no-progress", false, "")
set.Bool("reset", false, "")
set.Bool("skip-update", false, "")
set.Bool("skip-db-update", false, "")
set.String("listen", "", "")
ctx := cli.NewContext(app, set, nil)
@@ -79,11 +79,11 @@ func TestConfig_Init(t *testing.T) {
{
name: "sad: skip and download db",
dbConfig: option.DBOption{
SkipUpdate: true,
SkipDBUpdate: true,
DownloadDBOnly: true,
},
args: []string{"alpine:3.10"},
wantErr: "--skip-update and --download-db-only options can not be specified both",
wantErr: "--skip-db-update and --download-db-only options can not be specified both",
},
}
for _, tt := range tests {

View File

@@ -40,7 +40,7 @@ func run(c Config) (err error) {
}
// download the database file
if err = operation.DownloadDB(c.AppVersion, c.CacheDir, true, false, c.SkipUpdate); err != nil {
if err = operation.DownloadDB(c.AppVersion, c.CacheDir, true, false, c.SkipDBUpdate); err != nil {
return err
}

254
pkg/policy/policy.go Normal file
View File

@@ -0,0 +1,254 @@
package policy
import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"time"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/open-policy-agent/opa/bundle"
"golang.org/x/xerrors"
"k8s.io/utils/clock"
"github.com/aquasecurity/trivy/pkg/downloader"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/utils"
)
const (
bundleVersion = 1
bundleRepository = "ghcr.io/aquasecurity/appshield"
layerMediaType = "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip"
)
type options struct {
img v1.Image
clock clock.Clock
}
// Option is a functional option
type Option func(*options)
// WithImage takes an OCI v1 Image
func WithImage(img v1.Image) Option {
return func(opts *options) {
opts.img = img
}
}
// WithClock takes a clock
func WithClock(clock clock.Clock) Option {
return func(opts *options) {
opts.clock = clock
}
}
// Metadata holds default policy metadata
type Metadata struct {
Digest string
LastDownloadedAt time.Time
}
// Client implements policy operations
type Client struct {
img v1.Image
clock clock.Clock
}
// NewClient is the factory method for policy client
func NewClient(opts ...Option) (Client, error) {
o := &options{
clock: clock.RealClock{},
}
for _, opt := range opts {
opt(o)
}
if o.img == nil {
repo := fmt.Sprintf("%s:%d", bundleRepository, bundleVersion)
ref, err := name.ParseReference(repo)
if err != nil {
return Client{}, xerrors.Errorf("repository name error (%s): %w", repo, err)
}
o.img, err = remote.Image(ref)
if err != nil {
return Client{}, xerrors.Errorf("OCI repository error: %w", err)
}
}
return Client{
img: o.img,
clock: o.clock,
}, nil
}
// LoadBuiltinPolicies loads default policies
func (c Client) LoadBuiltinPolicies() ([]string, error) {
f, err := os.Open(manifestPath())
if err != nil {
return nil, xerrors.Errorf("manifest file open error (%s): %w", manifestPath(), err)
}
var manifest bundle.Manifest
if err = json.NewDecoder(f).Decode(&manifest); err != nil {
return nil, xerrors.Errorf("json decode error (%s): %w", manifestPath(), err)
}
// If the "roots" field is not included in the manifest it defaults to [""]
// which means that ALL data and policy must come from the bundle.
if manifest.Roots == nil || len(*manifest.Roots) == 0 {
return []string{contentDir()}, nil
}
var policyPaths []string
for _, root := range *manifest.Roots {
policyPaths = append(policyPaths, filepath.Join(contentDir(), root))
}
return policyPaths, nil
}
// NeedsUpdate returns if the default policy should be updated
func (c Client) NeedsUpdate() (bool, error) {
f, err := os.Open(metadataPath())
if err != nil {
log.Logger.Debugf("Failed to open the policy metadata: %s", err)
return true, nil
}
var meta Metadata
if err = json.NewDecoder(f).Decode(&meta); err != nil {
log.Logger.Warnf("Policy metadata decode error: %s", err)
return true, nil
}
// No need to update if it's been within a day since the last update.
if c.clock.Now().Before(meta.LastDownloadedAt.Add(24 * time.Hour)) {
return false, nil
}
digest, err := c.img.Digest()
if err != nil {
return false, xerrors.Errorf("digest error: %w", err)
}
if meta.Digest != digest.String() {
return true, nil
}
return false, nil
}
// DownloadBuiltinPolicies download default policies from GitHub Pages
func (c Client) DownloadBuiltinPolicies(ctx context.Context) error {
layers, err := c.img.Layers()
if err != nil {
return xerrors.Errorf("OCI layer error: %w", err)
}
if len(layers) != 1 {
return xerrors.Errorf("OPA bundle must be a single layer: %w", err)
}
bundleLayer := layers[0]
mediaType, err := bundleLayer.MediaType()
if err != nil {
return xerrors.Errorf("media type error: %w", err)
}
if mediaType != layerMediaType {
return xerrors.Errorf("unacceptable media type: %s", mediaType)
}
if err = c.downloadBuiltinPolicies(ctx, bundleLayer); err != nil {
return xerrors.Errorf("download error: %w", err)
}
digest, err := c.img.Digest()
if err != nil {
return xerrors.Errorf("digest error: %w", err)
}
log.Logger.Debugf("Digest of the builtin policies: %s", digest)
// Update metadata.json with the new digest and the current date
if err = c.updateMetadata(digest.String(), c.clock.Now()); err != nil {
return xerrors.Errorf("unable to update the policy metadata: %w", err)
}
return nil
}
func (c Client) downloadBuiltinPolicies(ctx context.Context, bundleLayer v1.Layer) error {
// Take the first layer as OPA bundle
rc, err := bundleLayer.Compressed()
if err != nil {
return xerrors.Errorf("failed to fetch a layer: %w", err)
}
defer rc.Close()
// https://github.com/hashicorp/go-getter/issues/326
f, err := os.CreateTemp("", "bundle-*.tar.gz")
if err != nil {
return xerrors.Errorf("failed to create a temp dir: %w", err)
}
defer func() {
_ = f.Close()
_ = os.Remove(f.Name())
}()
// Download bundle.tar.gz into a temporal file
if _, err = io.Copy(f, rc); err != nil {
return xerrors.Errorf("copy error: %w", err)
}
// Decompress bundle.tar.gz and copy into the cache dir
dst := contentDir()
if err = downloader.Download(ctx, f.Name(), dst, dst); err != nil {
return xerrors.Errorf("policy download error: %w", err)
}
return nil
}
func (c Client) updateMetadata(digest string, now time.Time) error {
meta := Metadata{
Digest: digest,
LastDownloadedAt: now,
}
f, err := os.Create(metadataPath())
if err != nil {
return xerrors.Errorf("failed to open a policy manifest: %w", err)
}
defer f.Close()
if err = json.NewEncoder(f).Encode(meta); err != nil {
return xerrors.Errorf("json encode error: %w", err)
}
return nil
}
func policyDir() string {
return filepath.Join(utils.CacheDir(), "policy")
}
func contentDir() string {
return filepath.Join(policyDir(), "content")
}
func metadataPath() string {
return filepath.Join(policyDir(), "metadata.json")
}
func manifestPath() string {
return filepath.Join(contentDir(), bundle.ManifestExt)
}

315
pkg/policy/policy_test.go Normal file
View File

@@ -0,0 +1,315 @@
package policy_test
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"testing"
"time"
v1 "github.com/google/go-containerregistry/pkg/v1"
fakei "github.com/google/go-containerregistry/pkg/v1/fake"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/utils/clock"
fake "k8s.io/utils/clock/testing"
"github.com/aquasecurity/trivy/pkg/policy"
"github.com/aquasecurity/trivy/pkg/utils"
)
type fakeLayer struct {
v1.Layer
}
func (f fakeLayer) MediaType() (types.MediaType, error) {
return "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip", nil
}
func newFakeLayer(t *testing.T) v1.Layer {
layer, err := tarball.LayerFromFile("testdata/bundle.tar.gz")
require.NoError(t, err)
return fakeLayer{layer}
}
func TestClient_LoadBuiltinPolicies(t *testing.T) {
tests := []struct {
name string
cacheDir string
want []string
wantErr string
}{
{
name: "happy path",
cacheDir: "testdata/happy",
want: []string{
"testdata/happy/policy/content/kubernetes",
"testdata/happy/policy/content/docker",
},
},
{
name: "empty roots",
cacheDir: "testdata/empty",
want: []string{
"testdata/empty/policy/content",
},
},
{
name: "broken manifest",
cacheDir: "testdata/broken",
want: []string{},
wantErr: "json decode error",
},
{
name: "no such file",
cacheDir: "testdata/unknown",
want: []string{},
wantErr: "manifest file open error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
utils.SetCacheDir(tt.cacheDir)
img := new(fakei.FakeImage)
c, err := policy.NewClient(policy.WithImage(img))
require.NoError(t, err)
got, err := c.LoadBuiltinPolicies()
if tt.wantErr != "" {
require.NotNil(t, err)
assert.Contains(t, err.Error(), tt.wantErr)
return
}
assert.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
}
func TestClient_NeedsUpdate(t *testing.T) {
type digestReturns struct {
h v1.Hash
err error
}
tests := []struct {
name string
clock clock.Clock
digestReturns digestReturns
metadata interface{}
want bool
wantErr bool
}{
{
name: "recent download",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
digestReturns: digestReturns{
h: v1.Hash{Algorithm: "sha256", Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d"},
},
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
LastDownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
},
want: false,
},
{
name: "same digest",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: digestReturns{
h: v1.Hash{Algorithm: "sha256", Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d"},
},
metadata: policy.Metadata{
Digest: `sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d`,
LastDownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
},
want: false,
},
{
name: "different digest",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: digestReturns{
h: v1.Hash{Algorithm: "sha256", Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d"},
},
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
LastDownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
},
want: true,
},
{
name: "sad: Digest returns an error",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: digestReturns{
err: fmt.Errorf("error"),
},
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
LastDownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
},
want: false,
wantErr: true,
},
{
name: "sad: non-existent metadata",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
want: true,
},
{
name: "sad: broken metadata",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
metadata: `"foo"`,
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set up a temporary directory
tmpDir := t.TempDir()
utils.SetCacheDir(tmpDir)
// Mock image
img := new(fakei.FakeImage)
img.DigestReturns(tt.digestReturns.h, tt.digestReturns.err)
// Create a policy directory
err := os.MkdirAll(filepath.Join(tmpDir, "policy"), os.ModePerm)
require.NoError(t, err)
if tt.metadata != nil {
b, err := json.Marshal(tt.metadata)
require.NoError(t, err)
// Write a metadata file
metadataPath := filepath.Join(tmpDir, "policy", "metadata.json")
err = os.WriteFile(metadataPath, b, os.ModePerm)
require.NoError(t, err)
}
// Assert results
c, err := policy.NewClient(policy.WithImage(img), policy.WithClock(tt.clock))
require.NoError(t, err)
got, err := c.NeedsUpdate()
assert.Equal(t, tt.wantErr, err != nil)
assert.Equal(t, tt.want, got)
})
}
}
func TestClient_DownloadBuiltinPolicies(t *testing.T) {
layer := newFakeLayer(t)
type digestReturns struct {
h v1.Hash
err error
}
type layersReturns struct {
layers []v1.Layer
err error
}
tests := []struct {
name string
clock clock.Clock
layersReturns layersReturns
digestReturns digestReturns
want *policy.Metadata
wantErr string
}{
{
name: "happy path",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
layersReturns: layersReturns{
layers: []v1.Layer{layer},
},
digestReturns: digestReturns{
h: v1.Hash{Algorithm: "sha256", Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d"},
},
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
LastDownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
},
},
{
name: "sad: two layers",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
layersReturns: layersReturns{
layers: []v1.Layer{layer, layer},
},
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
LastDownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
},
wantErr: "OPA bundle must be a single layer",
},
{
name: "sad: Layers returns an error",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
layersReturns: layersReturns{
err: fmt.Errorf("error"),
},
digestReturns: digestReturns{
h: v1.Hash{Algorithm: "sha256", Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d"},
},
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
LastDownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
},
wantErr: "OCI layer error",
},
{
name: "sad: Digest returns an error",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
layersReturns: layersReturns{
layers: []v1.Layer{layer},
},
digestReturns: digestReturns{
err: fmt.Errorf("error"),
},
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
LastDownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
},
wantErr: "digest error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tempDir := t.TempDir()
utils.SetCacheDir(tempDir)
// Mock image
img := new(fakei.FakeImage)
img.DigestReturns(tt.digestReturns.h, tt.digestReturns.err)
img.LayersReturns(tt.layersReturns.layers, tt.layersReturns.err)
c, err := policy.NewClient(policy.WithClock(tt.clock), policy.WithImage(img))
require.NoError(t, err)
err = c.DownloadBuiltinPolicies(context.Background())
if tt.wantErr != "" {
require.NotNil(t, err)
assert.Contains(t, err.Error(), tt.wantErr)
return
}
assert.NoError(t, err)
// Assert metadata.json
metadata := filepath.Join(tempDir, "policy", "metadata.json")
b, err := os.ReadFile(metadata)
require.NoError(t, err)
got := new(policy.Metadata)
err = json.Unmarshal(b, got)
require.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
}

View File

@@ -0,0 +1,3 @@
{
"revision": 1
}

BIN
pkg/policy/testdata/bundle.tar.gz vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,3 @@
{
"revision": "1"
}

View File

@@ -0,0 +1,4 @@
{
"revision": "1",
"roots": ["kubernetes", "docker"]
}

View File

@@ -71,7 +71,7 @@ func TestReportWriter_JSON(t *testing.T) {
},
}
err := report.Write("json", &jsonWritten, nil, inputResults, "", false)
err := report.Write("json", &jsonWritten, nil, inputResults, "", false, false)
assert.NoError(t, err)
writtenResults := report.Results{}

View File

@@ -6,6 +6,7 @@ import (
"os"
"strings"
"github.com/fatih/color"
"github.com/olekukonko/tablewriter"
ftypes "github.com/aquasecurity/fanal/types"
@@ -16,9 +17,10 @@ import (
// TableWriter implements Writer and output in tabular form
type TableWriter struct {
Severities []dbTypes.Severity
Output io.Writer
Light bool
Severities []dbTypes.Severity
Output io.Writer
Light bool
IncludeSuccesses bool
}
// Write writes the result on standard output
@@ -36,7 +38,13 @@ func (tw TableWriter) Write(report Report) error {
func (tw TableWriter) write(result Result) {
table := tablewriter.NewWriter(tw.Output)
total, severityCount := tw.writeVulnerabilities(table, result.Vulnerabilities)
var total int
var severityCount map[string]int
if len(result.Vulnerabilities) != 0 {
total, severityCount = tw.writeVulnerabilities(table, result.Vulnerabilities)
} else if len(result.Misconfigurations) != 0 {
severityCount = tw.writeMisconfigurations(table, result.Misconfigurations)
}
var severities []string
for _, sev := range tw.Severities {
@@ -52,11 +60,25 @@ func (tw TableWriter) write(result Result) {
results = append(results, r)
}
fmt.Printf("\n%s\n", result.Target)
fmt.Println(strings.Repeat("=", len(result.Target)))
fmt.Printf("Total: %d (%s)\n\n", total, strings.Join(results, ", "))
target := result.Target
if result.Class != ClassOSPkg {
target += fmt.Sprintf(" (%s)", result.Type)
}
if len(result.Vulnerabilities) == 0 {
fmt.Printf("\n%s\n", target)
fmt.Println(strings.Repeat("=", len(target)))
if result.MisconfSummary != nil {
// for misconfigurations
summary := result.MisconfSummary
fmt.Printf("Tests: %d (SUCCESSES: %d, FAILURES: %d, EXCEPTIONS: %d)\n",
summary.Successes+summary.Failures+summary.Exceptions, summary.Successes, summary.Failures, summary.Exceptions)
fmt.Printf("Failures: %d (%s)\n\n", summary.Failures, strings.Join(results, ", "))
} else {
// for vulnerabilities
fmt.Printf("Total: %d (%s)\n\n", total, strings.Join(results, ", "))
}
if len(result.Vulnerabilities) == 0 && len(result.Misconfigurations) == 0 {
return
}
@@ -77,6 +99,27 @@ func (tw TableWriter) writeVulnerabilities(table *tablewriter.Table, vulns []typ
return len(vulns), severityCount
}
func (tw TableWriter) writeMisconfigurations(table *tablewriter.Table, misconfs []types.DetectedMisconfiguration) map[string]int {
table.SetColWidth(40)
alignment := []int{tablewriter.ALIGN_CENTER, tablewriter.ALIGN_CENTER, tablewriter.ALIGN_LEFT,
tablewriter.ALIGN_CENTER, tablewriter.ALIGN_CENTER, tablewriter.ALIGN_LEFT}
header := []string{"Type", "Misconf ID", "Check", "Severity", "Status", "Message"}
if !tw.IncludeSuccesses {
// Remove status
statusPos := 4
alignment = append(alignment[:statusPos], alignment[statusPos+1:]...)
header = append(header[:statusPos], header[statusPos+1:]...)
}
table.SetColumnAlignment(alignment)
table.SetHeader(header)
severityCount := tw.setMisconfRows(table, misconfs)
return severityCount
}
func (tw TableWriter) setVulnerabilityRows(table *tablewriter.Table, vulns []types.DetectedVulnerability) map[string]int {
severityCount := map[string]int{}
for _, v := range vulns {
@@ -111,3 +154,37 @@ func (tw TableWriter) setVulnerabilityRows(table *tablewriter.Table, vulns []typ
}
return severityCount
}
func (tw TableWriter) setMisconfRows(table *tablewriter.Table, misconfs []types.DetectedMisconfiguration) map[string]int {
severityCount := map[string]int{}
for _, misconf := range misconfs {
if misconf.Status == types.StatusFailure {
severityCount[misconf.Severity]++
if misconf.PrimaryURL != "" {
primaryURL := strings.TrimPrefix(misconf.PrimaryURL, "https://")
misconf.Message = fmt.Sprintf("%s -->%s", misconf.Message, primaryURL)
}
}
var row []string
if tw.Output == os.Stdout {
if misconf.Status == types.StatusPassed {
row = []string{misconf.Type, misconf.ID, misconf.Title, color.New(color.FgGreen).Sprint(misconf.Severity),
color.New(color.FgGreen).Sprint(misconf.Status), misconf.Message}
} else {
row = []string{misconf.Type, misconf.ID, misconf.Title, dbTypes.ColorizeSeverity(misconf.Severity),
color.New(color.FgRed).Sprint(misconf.Status), misconf.Message}
}
} else {
row = []string{misconf.Type, misconf.ID, misconf.Title, misconf.Severity, string(misconf.Status), misconf.Message}
}
if !tw.IncludeSuccesses {
// Remove status
row = append(row[:4], row[5:]...)
}
table.Append(row)
}
return severityCount
}

View File

@@ -13,10 +13,11 @@ import (
func TestReportWriter_Table(t *testing.T) {
testCases := []struct {
name string
results report.Results
expectedOutput string
light bool
name string
results report.Results
expectedOutput string
light bool
includeSuccesses bool
}{
{
name: "happy path full",
@@ -127,6 +128,82 @@ func TestReportWriter_Table(t *testing.T) {
| foo | CVE-2020-1234 | HIGH | 1.2.3 | 3.4.5 | a b c d e f g h i j k l... |
| | | | | | -->avd.aquasec.com/nvd/cve-2020-1234 |
+---------+------------------+----------+-------------------+---------------+--------------------------------------+
`,
},
{
name: "happy path misconfigurations",
results: report.Results{
{
Target: "test",
Misconfigurations: []types.DetectedMisconfiguration{
{
Type: "Kubernetes Security Check",
ID: "KSV001",
Title: "Image tag ':latest' used",
Message: "Message",
Severity: "HIGH",
PrimaryURL: "https://avd.aquasec.com/appshield/ksv001",
Status: types.StatusFailure,
},
{
Type: "Kubernetes Security Check",
ID: "KSV002",
Title: "SYS_ADMIN capability added",
Message: "Message",
Severity: "CRITICAL",
PrimaryURL: "https://avd.aquasec.com/appshield/ksv002",
Status: types.StatusFailure,
},
},
},
},
expectedOutput: `+---------------------------+------------+----------------------------+----------+------------------------------------------+
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
+---------------------------+------------+----------------------------+----------+------------------------------------------+
| Kubernetes Security Check | KSV001 | Image tag ':latest' used | HIGH | Message |
| | | | | -->avd.aquasec.com/appshield/ksv001 |
+ +------------+----------------------------+----------+------------------------------------------+
| | KSV002 | SYS_ADMIN capability added | CRITICAL | Message |
| | | | | -->avd.aquasec.com/appshield/ksv002 |
+---------------------------+------------+----------------------------+----------+------------------------------------------+
`,
},
{
name: "happy path misconfigurations with successes",
includeSuccesses: true,
results: report.Results{
{
Target: "test",
Misconfigurations: []types.DetectedMisconfiguration{
{
Type: "Kubernetes Security Check",
ID: "KSV001",
Title: "Image tag ':latest' used",
Message: "Message",
Severity: "HIGH",
PrimaryURL: "https://avd.aquasec.com/appshield/ksv001",
Status: types.StatusFailure,
},
{
Type: "Kubernetes Security Check",
ID: "KSV002",
Title: "SYS_ADMIN capability added",
Message: "Message",
Severity: "CRITICAL",
PrimaryURL: "https://avd.aquasec.com/appshield/ksv002",
Status: types.StatusPassed,
},
},
},
},
expectedOutput: `+---------------------------+------------+----------------------------+----------+--------+------------------------------------------+
| TYPE | MISCONF ID | CHECK | SEVERITY | STATUS | MESSAGE |
+---------------------------+------------+----------------------------+----------+--------+------------------------------------------+
| Kubernetes Security Check | KSV001 | Image tag ':latest' used | HIGH | FAIL | Message |
| | | | | | -->avd.aquasec.com/appshield/ksv001 |
+ +------------+----------------------------+----------+--------+------------------------------------------+
| | KSV002 | SYS_ADMIN capability added | CRITICAL | PASS | Message |
+---------------------------+------------+----------------------------+----------+--------+------------------------------------------+
`,
},
{
@@ -138,7 +215,9 @@ func TestReportWriter_Table(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tableWritten := bytes.Buffer{}
assert.NoError(t, report.Write("table", &tableWritten, nil, report.Report{Results: tc.results}, "", tc.light), tc.name)
err := report.Write("table", &tableWritten, nil, report.Report{Results: tc.results},
"", tc.light, tc.includeSuccesses)
assert.NoError(t, err)
assert.Equal(t, tc.expectedOutput, tableWritten.String(), tc.name)
})
}

View File

@@ -176,7 +176,7 @@ func TestReportWriter_Template(t *testing.T) {
},
}
assert.NoError(t, report.Write("template", &tmplWritten, nil, inputReport, tc.template, false))
assert.NoError(t, report.Write("template", &tmplWritten, nil, inputReport, tc.template, false, false))
assert.Equal(t, tc.expected, tmplWritten.String())
})
}
@@ -208,7 +208,7 @@ func TestReportWriter_Template_SARIF(t *testing.T) {
},
},
}
assert.NoError(t, report.Write("template", &got, nil, inputReport, string(template), false), tc.name)
assert.NoError(t, report.Write("template", &got, nil, inputReport, string(template), false, false), tc.name)
assert.JSONEq(t, tc.want, got.String(), tc.name)
})
}

View File

@@ -36,31 +36,58 @@ type Metadata struct {
// Results to hold list of Result
type Results []Result
type ResultClass string
const (
ClassOSPkg = "os-pkgs"
ClassLangPkg = "lang-pkgs"
ClassConfig = "config"
)
// Result holds a target and detected vulnerabilities
type Result struct {
Target string `json:"Target"`
Type string `json:"Type,omitempty"`
Packages []ftypes.Package `json:"Packages,omitempty"`
Vulnerabilities []types.DetectedVulnerability `json:"Vulnerabilities,omitempty"`
Target string `json:"Target"`
Class ResultClass `json:"Class,omitempty"`
Type string `json:"Type,omitempty"`
Packages []ftypes.Package `json:"Packages,omitempty"`
Vulnerabilities []types.DetectedVulnerability `json:"Vulnerabilities,omitempty"`
MisconfSummary *MisconfSummary `json:"MisconfSummary,omitempty"`
Misconfigurations []types.DetectedMisconfiguration `json:"Misconfigurations,omitempty"`
}
// Failed returns whether the result includes any vulnerabilities
type MisconfSummary struct {
Successes int
Failures int
Exceptions int
}
// Failed returns whether the result includes any vulnerabilities or misconfigurations
func (results Results) Failed() bool {
for _, r := range results {
if len(r.Vulnerabilities) > 0 {
return true
}
for _, m := range r.Misconfigurations {
if m.Status == types.StatusFailure {
return true
}
}
}
return false
}
// Write writes the result to output, format as passed in argument
func Write(format string, output io.Writer, severities []dbTypes.Severity, report Report,
outputTemplate string, light bool) error {
outputTemplate string, light, includeSuccesses bool) error {
var writer Writer
switch format {
case "table":
writer = &TableWriter{Output: output, Light: light, Severities: severities}
writer = &TableWriter{
Output: output,
Severities: severities,
Light: light,
IncludeSuccesses: includeSuccesses,
}
case "json":
writer = &JSONWriter{Output: output}
case "template":

View File

@@ -41,6 +41,40 @@ func TestResults_Failed(t *testing.T) {
},
want: true,
},
{
name: "failed misconfigurations",
results: report.Results{
{
Target: "test",
Type: "test",
Misconfigurations: []types.DetectedMisconfiguration{
{
Type: "Docker Security Check",
ID: "ID-001",
Status: types.StatusFailure,
},
},
},
},
want: true,
},
{
name: "passed misconfigurations",
results: report.Results{
{
Target: "test",
Type: "test",
Misconfigurations: []types.DetectedMisconfiguration{
{
Type: "Docker Security Check",
ID: "ID-001",
Status: types.StatusPassed,
},
},
},
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@@ -1,4 +1,4 @@
package vulnerability
package result
const (
module = `

View File

@@ -1,4 +1,4 @@
package vulnerability
package result
import (
"bufio"
@@ -22,7 +22,7 @@ import (
)
const (
// DefaultIgnoreFile is the file name to be ignored
// DefaultIgnoreFile is the file name to be evaluated
DefaultIgnoreFile = ".trivyignore"
)
@@ -43,16 +43,8 @@ var (
var SuperSet = wire.NewSet(
wire.Struct(new(db.Config)),
NewClient,
wire.Bind(new(Operation), new(Client)),
)
// Operation defines the vulnerability operations
type Operation interface {
FillInfo(vulns []types.DetectedVulnerability, reportType string)
Filter(ctx context.Context, vulns []types.DetectedVulnerability, severities []dbTypes.Severity,
ignoreUnfixed bool, ignoreFile string, policy string) ([]types.DetectedVulnerability, error)
}
// Client implements db operations
type Client struct {
dbc db.Operation
@@ -63,8 +55,8 @@ func NewClient(dbc db.Config) Client {
return Client{dbc: dbc}
}
// FillInfo fills extra info in vulnerability objects
func (c Client) FillInfo(vulns []types.DetectedVulnerability, reportType string) {
// FillVulnerabilityInfo fills extra info in vulnerability objects
func (c Client) FillVulnerabilityInfo(vulns []types.DetectedVulnerability, reportType string) {
var err error
for i := range vulns {
@@ -146,25 +138,28 @@ func (c Client) getPrimaryURL(vulnID string, refs []string, source string) strin
}
// Filter filter out the vulnerabilities
func (c Client) Filter(ctx context.Context, vulns []types.DetectedVulnerability, severities []dbTypes.Severity,
ignoreUnfixed bool, ignoreFile string, policyFile string) ([]types.DetectedVulnerability, error) {
func (c Client) Filter(ctx context.Context, vulns []types.DetectedVulnerability, misconfs []types.DetectedMisconfiguration,
severities []dbTypes.Severity, ignoreUnfixed, includeSuccesses bool, ignoreFile, policyFile string) (
[]types.DetectedVulnerability, []types.DetectedMisconfiguration, error) {
ignoredIDs := getIgnoredIDs(ignoreFile)
vulnerabilities := filterVulnerabilities(vulns, severities, ignoredIDs, ignoreUnfixed)
filteredVulns := filterVulnerabilities(vulns, severities, ignoreUnfixed, ignoredIDs)
filteredMisconfs := filterMisconfigurations(misconfs, severities, includeSuccesses, ignoredIDs)
if policyFile != "" {
var err error
vulnerabilities, err = applyPolicy(ctx, vulnerabilities, policyFile)
filteredVulns, filteredMisconfs, err = applyPolicy(ctx, filteredVulns, filteredMisconfs, policyFile)
if err != nil {
return nil, xerrors.Errorf("failed to apply the policy: %w", err)
return nil, nil, xerrors.Errorf("failed to apply the policy: %w", err)
}
}
sort.Sort(types.BySeverity(vulnerabilities))
return vulnerabilities, nil
sort.Sort(types.BySeverity(filteredVulns))
return filteredVulns, filteredMisconfs, nil
}
func filterVulnerabilities(vulns []types.DetectedVulnerability, severities []dbTypes.Severity, ignoredIDs []string,
ignoreUnfixed bool) []types.DetectedVulnerability {
func filterVulnerabilities(vulns []types.DetectedVulnerability, severities []dbTypes.Severity,
ignoreUnfixed bool, ignoredIDs []string) []types.DetectedVulnerability {
uniqVulns := make(map[string]types.DetectedVulnerability)
for _, vuln := range vulns {
if vuln.Severity == "" {
@@ -192,10 +187,29 @@ func filterVulnerabilities(vulns []types.DetectedVulnerability, severities []dbT
break
}
}
return toSlice(uniqVulns)
}
func filterMisconfigurations(misconfs []types.DetectedMisconfiguration, severities []dbTypes.Severity,
includeSuccesses bool, ignoredIDs []string) []types.DetectedMisconfiguration {
var filtered []types.DetectedMisconfiguration
for _, misconf := range misconfs {
// Filter misconfigurations by severity
for _, s := range severities {
if s.String() == misconf.Severity {
if utils.StringInSlice(misconf.ID, ignoredIDs) {
continue
} else if misconf.Status == types.StatusPassed && !includeSuccesses {
continue
}
filtered = append(filtered, misconf)
break
}
}
}
return filtered
}
func toSlice(uniqVulns map[string]types.DetectedVulnerability) []types.DetectedVulnerability {
// Convert map to slice
var vulnerabilities []types.DetectedVulnerability
@@ -206,10 +220,11 @@ func toSlice(uniqVulns map[string]types.DetectedVulnerability) []types.DetectedV
return vulnerabilities
}
func applyPolicy(ctx context.Context, vulns []types.DetectedVulnerability, policyFile string) ([]types.DetectedVulnerability, error) {
func applyPolicy(ctx context.Context, vulns []types.DetectedVulnerability, misconfs []types.DetectedMisconfiguration,
policyFile string) ([]types.DetectedVulnerability, []types.DetectedMisconfiguration, error) {
policy, err := ioutil.ReadFile(policyFile)
if err != nil {
return nil, xerrors.Errorf("unable to read the policy file: %w", err)
return nil, nil, xerrors.Errorf("unable to read the policy file: %w", err)
}
query, err := rego.New(
@@ -218,30 +233,50 @@ func applyPolicy(ctx context.Context, vulns []types.DetectedVulnerability, polic
rego.Module("trivy.rego", string(policy)),
).PrepareForEval(ctx)
if err != nil {
return nil, xerrors.Errorf("unable to prepare for eval: %w", err)
return nil, nil, xerrors.Errorf("unable to prepare for eval: %w", err)
}
var filtered []types.DetectedVulnerability
// Vulnerabilities
var filteredVulns []types.DetectedVulnerability
for _, vuln := range vulns {
results, err := query.Eval(ctx, rego.EvalInput(vuln))
ignored, err := evaluate(ctx, query, vuln)
if err != nil {
return nil, xerrors.Errorf("unable to evaluate the policy: %w", err)
} else if len(results) == 0 {
// Handle undefined result.
filtered = append(filtered, vuln)
return nil, nil, err
}
if ignored {
continue
}
ignore, ok := results[0].Expressions[0].Value.(bool)
if !ok {
// Handle unexpected result type.
return nil, xerrors.New("the policy must return boolean")
}
if ignore {
continue
}
filtered = append(filtered, vuln)
filteredVulns = append(filteredVulns, vuln)
}
return filtered, nil
// Misconfigurations
var filteredMisconfs []types.DetectedMisconfiguration
for _, misconf := range misconfs {
ignored, err := evaluate(ctx, query, misconf)
if err != nil {
return nil, nil, err
}
if ignored {
continue
}
filteredMisconfs = append(filteredMisconfs, misconf)
}
return filteredVulns, filteredMisconfs, nil
}
func evaluate(ctx context.Context, query rego.PreparedEvalQuery, input interface{}) (bool, error) {
results, err := query.Eval(ctx, rego.EvalInput(input))
if err != nil {
return false, xerrors.Errorf("unable to evaluate the policy: %w", err)
} else if len(results) == 0 {
// Handle undefined result.
return false, nil
}
ignore, ok := results[0].Expressions[0].Value.(bool)
if !ok {
// Handle unexpected result type.
return false, xerrors.New("the policy must return boolean")
}
return ignore, nil
}
func getIgnoredIDs(ignoreFile string) []string {

Some files were not shown because too many files have changed in this diff Show More