mirror of
https://github.com/anchore/grype
synced 2024-11-10 06:34:13 +00:00
sync vulnscan db changes
This commit is contained in:
parent
0eb5faff32
commit
92cf98ab12
17 changed files with 92 additions and 632 deletions
9
Makefile
9
Makefile
|
@ -13,7 +13,7 @@ endif
|
|||
|
||||
.PHONY: all boostrap lint lint-fix unit coverage integration build-release
|
||||
|
||||
all: lint unit integration
|
||||
all: lint unit # integration
|
||||
@printf '$(SUCCESS)All checks pass!$(RESET)\n'
|
||||
|
||||
bootstrap:
|
||||
|
@ -49,9 +49,10 @@ coverage:
|
|||
|
||||
# TODO: add benchmarks
|
||||
|
||||
integration:
|
||||
@printf '$(TITLE)Running integration tests...$(RESET)\n'
|
||||
go test -tags=integration ./integration
|
||||
# TODO: add me back in when there are integration tests
|
||||
#integration:
|
||||
# @printf '$(TITLE)Running integration tests...$(RESET)\n'
|
||||
# go test -tags=integration ./integration
|
||||
|
||||
build-release:
|
||||
go build -s -w -X main.version="$(git describe --tags --dirty --always)" \
|
||||
|
|
9
go.mod
9
go.mod
|
@ -4,21 +4,24 @@ go 1.14
|
|||
|
||||
require (
|
||||
github.com/adrg/xdg v0.2.1
|
||||
github.com/anchore/go-feeds-client v0.0.0-20200624184141-4aef10511b59 // indirect
|
||||
github.com/anchore/go-testutils v0.0.0-20200520222037-edc2bf1864fe
|
||||
github.com/anchore/imgbom v0.0.0-20200616171024-2cb7dad96784
|
||||
github.com/anchore/stereoscope v0.0.0-20200616152009-189722bdb61b
|
||||
github.com/anchore/vulnscan-db v0.0.0-20200604185950-6a9f5a2c9ddf
|
||||
github.com/go-test/deep v1.0.6
|
||||
github.com/anchore/vulnscan-db v0.0.0-20200628111346-8c1d0888ed4c
|
||||
github.com/go-test/deep v1.0.6 // indirect
|
||||
github.com/hashicorp/go-getter v1.4.1
|
||||
github.com/hashicorp/go-version v1.2.0
|
||||
github.com/hashicorp/go-version v1.2.1
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
|
||||
github.com/knqyf263/go-version v1.1.1
|
||||
github.com/lib/pq v1.7.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/sergi/go-diff v1.1.0
|
||||
github.com/spf13/afero v1.3.0
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/viper v1.7.0
|
||||
go.etcd.io/bbolt v1.3.4 // indirect
|
||||
go.uber.org/zap v1.15.0
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
)
|
||||
|
|
32
go.sum
32
go.sum
|
@ -108,6 +108,10 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
|||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/anchore/go-feeds-client v0.0.0-20200608121036-d9c3f68622a7 h1:IpwJkSqsmdZHN6CmUYNKKx5J25J3g/6yzwRmpvERqhQ=
|
||||
github.com/anchore/go-feeds-client v0.0.0-20200608121036-d9c3f68622a7/go.mod h1:sugnhPPnoDCFWKzmQxSj444vF3T6UTiCdMLn8YZLyVg=
|
||||
github.com/anchore/go-feeds-client v0.0.0-20200624184141-4aef10511b59 h1:5JcA8PnPVAiXo9M71HjnHncmUfI1ZnAeb0Dq+i/K2i8=
|
||||
github.com/anchore/go-feeds-client v0.0.0-20200624184141-4aef10511b59/go.mod h1:sugnhPPnoDCFWKzmQxSj444vF3T6UTiCdMLn8YZLyVg=
|
||||
github.com/anchore/go-testutils v0.0.0-20200520222037-edc2bf1864fe h1:YMXe4RA3qy4Ri5fmGQii/Gn+Pxv3oBfiS/LqzeOVuwo=
|
||||
github.com/anchore/go-testutils v0.0.0-20200520222037-edc2bf1864fe/go.mod h1:D3rc2L/q4Hcp9eeX6AIJH4Q+kPjOtJCFhG9za90j+nU=
|
||||
github.com/anchore/imgbom v0.0.0-20200616171024-2cb7dad96784 h1:s9zoF5uqN8rvp6TBtFgwIoBsP6gwhqaCw43XfELh3C4=
|
||||
|
@ -116,8 +120,15 @@ github.com/anchore/stereoscope v0.0.0-20200520221116-025e07f1c93e h1:QBwtrM0MXi0
|
|||
github.com/anchore/stereoscope v0.0.0-20200520221116-025e07f1c93e/go.mod h1:bkyLl5VITnrmgErv4S1vDfVz/TGAZ5il6161IQo7w2g=
|
||||
github.com/anchore/stereoscope v0.0.0-20200616152009-189722bdb61b h1:LmFKsQi4oj2VJjch7JhQNzJg1A56FjwHqWZz1ZZKgIw=
|
||||
github.com/anchore/stereoscope v0.0.0-20200616152009-189722bdb61b/go.mod h1:eQ2/Al6XDA7RFk3FVfpjyGRErITRjNciUPIWixHc7kQ=
|
||||
github.com/anchore/vulnscan v0.0.0-20200624185207-0eb5faff321b/go.mod h1:q/wqDUtsNxQrES8leqrgd9Oz5+tGXiFl6W2VCUdlOmI=
|
||||
github.com/anchore/vulnscan-db v0.0.0-20200604185950-6a9f5a2c9ddf h1:U1KgI8Lk6acUjjmtBLWOCoL9U7AV8tFmHnqAtFikJ7E=
|
||||
github.com/anchore/vulnscan-db v0.0.0-20200604185950-6a9f5a2c9ddf/go.mod h1:OVROq5+BT+g+ES+heRewy7NU2f147o2QyMortckSXek=
|
||||
github.com/anchore/vulnscan-db v0.0.0-20200624185237-d8f13b221624/go.mod h1:3uEIvOc8ikZOp1ztNu9fGqmF3fmZFg04W4BYcFViXwA=
|
||||
github.com/anchore/vulnscan-db v0.0.0-20200628111346-8c1d0888ed4c h1:luiggQQg6sj5QcLbmT8XejcdYDZGXaK1eQbnWh5ydwU=
|
||||
github.com/anchore/vulnscan-db v0.0.0-20200628111346-8c1d0888ed4c/go.mod h1:dYygVCcr2YyhYCRjI85oDVnppbC5nIjA6YVTNOi473g=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ=
|
||||
github.com/apex/log v1.3.0/go.mod h1:jd8Vpsr46WAe3EZSQ/IUMs2qQD/GOycT5rPWCO1yGcs=
|
||||
github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
|
||||
|
@ -383,6 +394,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
|
|||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
|
||||
github.com/gookit/color v1.2.5 h1:s1gzb/fg3HhkSLKyWVUsZcVBUo+R1TwEYTmmxH8gGFg=
|
||||
github.com/gookit/color v1.2.5/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw=
|
||||
|
@ -432,6 +445,8 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
|||
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
|
||||
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.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=
|
||||
|
@ -475,6 +490,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
|||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
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/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg=
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
|
@ -505,6 +522,7 @@ 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/lib/pq v1.5.2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
|
@ -528,6 +546,7 @@ github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/
|
|||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
|
@ -669,6 +688,7 @@ github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOms
|
|||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
|
||||
|
@ -761,6 +781,16 @@ github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOV
|
|||
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/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||
github.com/wagoodman/go-partybus v0.0.0-20200526224238-eb215533f07d h1:KOxOL6qpmqwoPloNwi+CEgc1ayjHNOFNrvoOmeDOjDg=
|
||||
github.com/wagoodman/go-partybus v0.0.0-20200526224238-eb215533f07d/go.mod h1:JPirS5jde/CF5qIjcK4WX+eQmKXdPc6vcZkJ/P0hfPw=
|
||||
github.com/wagoodman/go-progress v0.0.0-20200526224006-dd1404d54b0b h1:UDJoympq2F2QqhIu0wF6PtI+Apq1sW3TobBoZOrUTa8=
|
||||
github.com/wagoodman/go-progress v0.0.0-20200526224006-dd1404d54b0b/go.mod h1:jLXFoL31zFaHKAAyZUh+sxiTDFe1L1ZHrcK2T1itVKA=
|
||||
github.com/wagoodman/go-progress v0.0.0-20200621153512-2778c704bf22 h1:GYaiTP0ywrCjJ4qMxxCg+YKPSDMeFJg6i1X9X55LJCA=
|
||||
github.com/wagoodman/go-progress v0.0.0-20200621153512-2778c704bf22/go.mod h1:jLXFoL31zFaHKAAyZUh+sxiTDFe1L1ZHrcK2T1itVKA=
|
||||
github.com/wagoodman/jotframe v0.0.0-20200610174534-353b72d58795 h1:x8d69ZxmiQB58l+bg7Oxy7Vc3eazx5KWgZW2pxXDsBI=
|
||||
github.com/wagoodman/jotframe v0.0.0-20200610174534-353b72d58795/go.mod h1:DzXZ1wfRedNhC3KQTick8Gf3CEPMFHsP5k4R/ldjKtw=
|
||||
github.com/wagoodman/jotframe v0.0.0-20200622123948-2995cbd43525 h1:fGlwSBQrl9/axciK2+gJ9q86SeQYJpbPx4vOrExvZXY=
|
||||
github.com/wagoodman/jotframe v0.0.0-20200622123948-2995cbd43525/go.mod h1:DzXZ1wfRedNhC3KQTick8Gf3CEPMFHsP5k4R/ldjKtw=
|
||||
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||
|
@ -797,6 +827,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
|
|||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -915,6 +946,7 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
@ -55,9 +55,10 @@ func setNonCliDefaultValues(v *viper.Viper) {
|
|||
v.SetDefault("log.structured", false)
|
||||
// e.g. ~/.cache/appname/db
|
||||
v.SetDefault("db.cache-dir", path.Join(xdg.CacheHome, internal.ApplicationName, "db"))
|
||||
// TODO: change me to the production URL at release
|
||||
// TODO: change me to the production URL before release
|
||||
v.SetDefault("db.update-url", "http://localhost:5000/listing.json")
|
||||
v.SetDefault("db.update-on-startup", true)
|
||||
// TODO: set this to true before release
|
||||
v.SetDefault("db.update-on-startup", false)
|
||||
}
|
||||
|
||||
func LoadConfigFromFile(v *viper.Viper, cliOpts *CliOnlyOptions) (*Application, error) {
|
||||
|
|
|
@ -7,7 +7,8 @@ import (
|
|||
"path"
|
||||
|
||||
"github.com/anchore/vulnscan-db/pkg/db"
|
||||
"github.com/anchore/vulnscan-db/pkg/sqlite"
|
||||
"github.com/anchore/vulnscan-db/pkg/db/curation"
|
||||
"github.com/anchore/vulnscan-db/pkg/store/sqlite"
|
||||
"github.com/anchore/vulnscan/internal/file"
|
||||
"github.com/anchore/vulnscan/internal/log"
|
||||
"github.com/hashicorp/go-version"
|
||||
|
@ -16,7 +17,7 @@ import (
|
|||
|
||||
const (
|
||||
supportedVersion = ">=1.0.0, <2.0.0"
|
||||
dbFileName = "vulnerability.db"
|
||||
FileName = db.StoreFileName
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -45,7 +46,7 @@ func NewCurator(cfg Config) (Curator, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *Curator) GetStore() (db.VulnStore, error) {
|
||||
func (c *Curator) GetStore() (db.VulnerabilityStoreReader, error) {
|
||||
// ensure the DB is ok
|
||||
err := c.Validate()
|
||||
if err != nil {
|
||||
|
@ -54,7 +55,7 @@ func (c *Curator) GetStore() (db.VulnStore, error) {
|
|||
|
||||
// provide an abstraction for the underlying store
|
||||
connectOptions := sqlite.Options{
|
||||
FilePath: path.Join(c.config.DbDir, dbFileName),
|
||||
FilePath: path.Join(c.config.DbDir, FileName),
|
||||
}
|
||||
store, _, err := sqlite.NewStore(&connectOptions)
|
||||
if err != nil {
|
||||
|
@ -67,27 +68,27 @@ func (c *Curator) Delete() error {
|
|||
return c.fs.RemoveAll(c.config.DbDir)
|
||||
}
|
||||
|
||||
func (c *Curator) IsUpdateAvailable() (bool, *ListingEntry, error) {
|
||||
func (c *Curator) IsUpdateAvailable() (bool, *curation.ListingEntry, error) {
|
||||
log.Debugf("checking for available database updates")
|
||||
|
||||
listing, err := newListingFromURL(c.fs, c.client, c.config.ListingURL)
|
||||
listing, err := curation.NewListingFromURL(c.fs, c.client, c.config.ListingURL)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("failed to get listing file: %w", err)
|
||||
}
|
||||
|
||||
updateEntry := listing.bestUpdate(c.versionConstraint)
|
||||
updateEntry := listing.BestUpdate(c.versionConstraint)
|
||||
if updateEntry == nil {
|
||||
return false, nil, fmt.Errorf("no db candidates with correct version available (maybe there is an application update available?)")
|
||||
}
|
||||
log.Debugf("found database update candidate: %s", updateEntry)
|
||||
|
||||
// compare created data to current db date
|
||||
current, err := newMetadataFromDir(c.fs, c.config.DbDir)
|
||||
current, err := curation.NewMetadataFromDir(c.fs, c.config.DbDir)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("current metadata corrupt: %w", err)
|
||||
}
|
||||
|
||||
if current.isSupercededBy(updateEntry) {
|
||||
if current.IsSupercededBy(updateEntry) {
|
||||
log.Debugf("database update available: %s", updateEntry)
|
||||
return true, updateEntry, nil
|
||||
}
|
||||
|
@ -113,7 +114,7 @@ func (c *Curator) Validate() error {
|
|||
// return nil
|
||||
// }
|
||||
|
||||
func (c *Curator) UpdateTo(listing *ListingEntry) error {
|
||||
func (c *Curator) UpdateTo(listing *curation.ListingEntry) error {
|
||||
// note: the temp directory is persisted upon download/validation/activation failure to allow for investigation
|
||||
tempDir, err := c.download(listing)
|
||||
if err != nil {
|
||||
|
@ -133,7 +134,7 @@ func (c *Curator) UpdateTo(listing *ListingEntry) error {
|
|||
return c.fs.RemoveAll(tempDir)
|
||||
}
|
||||
|
||||
func (c *Curator) download(listing *ListingEntry) (string, error) {
|
||||
func (c *Curator) download(listing *curation.ListingEntry) (string, error) {
|
||||
// get a temp dir
|
||||
tempDir, err := ioutil.TempDir("", "vulnscan-scratch")
|
||||
if err != nil {
|
||||
|
@ -160,7 +161,7 @@ func (c *Curator) download(listing *ListingEntry) (string, error) {
|
|||
|
||||
func (c *Curator) validate(dbDirPath string) error {
|
||||
// check that the disk checksum still matches the db payload
|
||||
metadata, err := newMetadataFromDir(c.fs, dbDirPath)
|
||||
metadata, err := curation.NewMetadataFromDir(c.fs, dbDirPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse database metadata (%s): %w", dbDirPath, err)
|
||||
}
|
||||
|
@ -168,7 +169,7 @@ func (c *Curator) validate(dbDirPath string) error {
|
|||
return fmt.Errorf("database metadata not found: %s", dbDirPath)
|
||||
}
|
||||
|
||||
dbPath := path.Join(dbDirPath, dbFileName)
|
||||
dbPath := path.Join(dbDirPath, FileName)
|
||||
valid, err := file.ValidateByHash(c.fs, dbPath, metadata.Checksum)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -6,12 +6,20 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/anchore/vulnscan-db/pkg/db/curation"
|
||||
"github.com/anchore/vulnscan/internal"
|
||||
"github.com/anchore/vulnscan/internal/file"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
func mustUrl(u *url.URL, err error) *url.URL {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
type testGetter struct {
|
||||
file map[string]string
|
||||
dir map[string]string
|
||||
|
@ -60,13 +68,13 @@ func newTestCurator(fs afero.Fs, getter file.Getter, dbDir, metadataUrl string)
|
|||
func TestCuratorDownload(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
entry *ListingEntry
|
||||
entry *curation.ListingEntry
|
||||
expectedURL string
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
name: "download populates returned tempdir",
|
||||
entry: &ListingEntry{
|
||||
entry: &curation.ListingEntry{
|
||||
Built: time.Date(2020, 06, 13, 17, 13, 13, 0, time.UTC),
|
||||
URL: mustUrl(url.Parse("http://a-url/payload.tar.gz")),
|
||||
Checksum: "sha256:deadbeefcafe",
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/anchore/vulnscan/internal/file"
|
||||
"github.com/anchore/vulnscan/internal/log"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
// TODO: move all of this to vulnscan-db
|
||||
|
||||
type Listing struct {
|
||||
Latest ListingEntry `json:"latest"`
|
||||
Available []ListingEntry `json:"available"`
|
||||
}
|
||||
|
||||
func newListingFromPath(fs afero.Fs, path string) (Listing, error) {
|
||||
f, err := fs.Open(path)
|
||||
if err != nil {
|
||||
return Listing{}, fmt.Errorf("unable to open DB listing path: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var l Listing
|
||||
err = json.NewDecoder(f).Decode(&l)
|
||||
if err != nil {
|
||||
return Listing{}, fmt.Errorf("unable to parse DB listing: %w", err)
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func newListingFromURL(fs afero.Fs, getter file.Getter, listingURL string) (Listing, error) {
|
||||
tempFile, err := afero.TempFile(fs, "", "vulnscan-listing")
|
||||
if err != nil {
|
||||
return Listing{}, fmt.Errorf("unable to create listing temp file: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
err := fs.RemoveAll(tempFile.Name())
|
||||
if err != nil {
|
||||
log.Errorf("failed to remove file (%s): %w", tempFile.Name(), err)
|
||||
}
|
||||
}()
|
||||
|
||||
// download the listing file
|
||||
err = getter.GetFile(tempFile.Name(), listingURL)
|
||||
if err != nil {
|
||||
return Listing{}, fmt.Errorf("unable to download listing: %w", err)
|
||||
}
|
||||
|
||||
// parse the listing file
|
||||
listing, err := newListingFromPath(fs, tempFile.Name())
|
||||
if err != nil {
|
||||
return Listing{}, err
|
||||
}
|
||||
return listing, nil
|
||||
}
|
||||
|
||||
func (l *Listing) bestUpdate(constraint version.Constraints) *ListingEntry {
|
||||
// extract the latest available db
|
||||
candidates := []ListingEntry{l.Latest}
|
||||
candidates = append(candidates, l.Available...)
|
||||
|
||||
// TODO: sort candidates by version and built date
|
||||
|
||||
for _, candidate := range candidates {
|
||||
log.Debugf("found update: %s", candidate)
|
||||
}
|
||||
|
||||
var updateEntry *ListingEntry
|
||||
for _, candidate := range candidates {
|
||||
if constraint.Check(candidate.Version) {
|
||||
copy := candidate
|
||||
updateEntry = ©
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return updateEntry
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
// TODO: move all of this to vulnscan-db
|
||||
|
||||
type ListingEntry struct {
|
||||
Built time.Time // RFC 3339
|
||||
Version *version.Version
|
||||
URL *url.URL
|
||||
Checksum string
|
||||
}
|
||||
|
||||
type ListingEntryJSON struct {
|
||||
Built string `json:"built"`
|
||||
Version string `json:"version"`
|
||||
URL string `json:"url"`
|
||||
Checksum string `json:"checksum"`
|
||||
}
|
||||
|
||||
func (l ListingEntryJSON) ToListingEntry() (ListingEntry, error) {
|
||||
build, err := time.Parse(time.RFC3339, l.Built)
|
||||
if err != nil {
|
||||
return ListingEntry{}, fmt.Errorf("cannot convert built time (%s): %+v", l.Built, err)
|
||||
}
|
||||
|
||||
ver, err := version.NewVersion(l.Version)
|
||||
if err != nil {
|
||||
return ListingEntry{}, fmt.Errorf("cannot parse version (%s): %+v", l.Version, err)
|
||||
}
|
||||
|
||||
u, err := url.Parse(l.URL)
|
||||
if err != nil {
|
||||
return ListingEntry{}, fmt.Errorf("cannot parse url (%s): %+v", l.URL, err)
|
||||
}
|
||||
|
||||
return ListingEntry{
|
||||
Built: build.UTC(),
|
||||
Version: ver,
|
||||
URL: u,
|
||||
Checksum: l.Checksum,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *ListingEntry) UnmarshalJSON(data []byte) error {
|
||||
var lej ListingEntryJSON
|
||||
if err := json.Unmarshal(data, &lej); err != nil {
|
||||
return err
|
||||
}
|
||||
le, err := lej.ToListingEntry()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*l = le
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l ListingEntry) String() string {
|
||||
return fmt.Sprintf("Listing(url=%s)", l.URL)
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-test/deep"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
func mustUrl(u *url.URL, err error) *url.URL {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func mustConst(u version.Constraints, err error) version.Constraints {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func TestNewListingFromPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expected Listing
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
fixture: "test-fixtures/listing.json",
|
||||
expected: Listing{
|
||||
Latest: ListingEntry{
|
||||
Built: time.Date(2020, 06, 13, 17, 13, 13, 0, time.UTC),
|
||||
URL: mustUrl(url.Parse("http://localhost:5000/vulnerability-db-v1.1.0+2020-6-13.tar.gz")),
|
||||
Version: version.Must(version.NewVersion("1.1.0")),
|
||||
Checksum: "sha256:dcd6a285c839a7c65939e20c251202912f64826be68609dfc6e48df7f853ddc8",
|
||||
},
|
||||
Available: []ListingEntry{
|
||||
{
|
||||
Built: time.Date(2020, 06, 12, 16, 12, 12, 0, time.UTC),
|
||||
URL: mustUrl(url.Parse("http://localhost:5000/vulnerability-db-v0.2.0+2020-6-12.tar.gz")),
|
||||
Version: version.Must(version.NewVersion("0.2.0")),
|
||||
Checksum: "sha256:e20c251202948df7f853ddc812f64826bdcd6a285c839a7c65939e68609dfc6e",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.fixture, func(t *testing.T) {
|
||||
listing, err := newListingFromPath(afero.NewOsFs(), test.fixture)
|
||||
if err != nil && !test.err {
|
||||
t.Fatalf("failed to get metadata: %+v", err)
|
||||
} else if err == nil && test.err {
|
||||
t.Fatalf("expected errer but got none")
|
||||
}
|
||||
|
||||
for _, diff := range deep.Equal(listing, test.expected) {
|
||||
t.Errorf("listing difference: %s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListingBestUpdate(t *testing.T) {
|
||||
tests := []struct {
|
||||
fixture string
|
||||
constraint version.Constraints
|
||||
expected *ListingEntry
|
||||
}{
|
||||
{
|
||||
fixture: "test-fixtures/listing.json",
|
||||
constraint: mustConst(version.NewConstraint("> 1.0.0, < 2.0.0")),
|
||||
expected: &ListingEntry{
|
||||
Built: time.Date(2020, 06, 13, 17, 13, 13, 0, time.UTC),
|
||||
URL: mustUrl(url.Parse("http://localhost:5000/vulnerability-db-v1.1.0+2020-6-13.tar.gz")),
|
||||
Version: version.Must(version.NewVersion("1.1.0")),
|
||||
Checksum: "sha256:dcd6a285c839a7c65939e20c251202912f64826be68609dfc6e48df7f853ddc8",
|
||||
},
|
||||
},
|
||||
{
|
||||
fixture: "test-fixtures/listing.json",
|
||||
constraint: mustConst(version.NewConstraint("> 0.0.0, < 1.0.0")),
|
||||
expected: &ListingEntry{
|
||||
Built: time.Date(2020, 06, 12, 16, 12, 12, 0, time.UTC),
|
||||
URL: mustUrl(url.Parse("http://localhost:5000/vulnerability-db-v0.2.0+2020-6-12.tar.gz")),
|
||||
Version: version.Must(version.NewVersion("0.2.0")),
|
||||
Checksum: "sha256:e20c251202948df7f853ddc812f64826bdcd6a285c839a7c65939e68609dfc6e",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.constraint.String(), func(t *testing.T) {
|
||||
listing, err := newListingFromPath(afero.NewOsFs(), test.fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get metadata: %+v", err)
|
||||
}
|
||||
|
||||
actual := listing.bestUpdate(test.constraint)
|
||||
if actual == nil && test.expected != nil || actual != nil && test.expected == nil {
|
||||
t.Fatalf("mismatched best candidate expectations")
|
||||
}
|
||||
|
||||
for _, diff := range deep.Equal(actual, test.expected) {
|
||||
t.Errorf("listing entry difference: %s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/anchore/vulnscan/internal/file"
|
||||
"github.com/anchore/vulnscan/internal/log"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
const metadataFileName = "metadata.json"
|
||||
|
||||
type Metadata struct {
|
||||
Built time.Time
|
||||
Version *version.Version
|
||||
Checksum string
|
||||
}
|
||||
|
||||
type MetadataJSON struct {
|
||||
Built string `json:"built"` // RFC 3339
|
||||
Version string `json:"version"`
|
||||
Checksum string `json:"checksum"`
|
||||
}
|
||||
|
||||
func (m MetadataJSON) ToMetadata() (Metadata, error) {
|
||||
build, err := time.Parse(time.RFC3339, m.Built)
|
||||
if err != nil {
|
||||
return Metadata{}, fmt.Errorf("cannot convert built time (%s): %+v", m.Built, err)
|
||||
}
|
||||
|
||||
ver, err := version.NewVersion(m.Version)
|
||||
if err != nil {
|
||||
return Metadata{}, fmt.Errorf("cannot parse version (%s): %+v", m.Version, err)
|
||||
}
|
||||
|
||||
metadata := Metadata{
|
||||
Built: build.UTC(),
|
||||
Version: ver,
|
||||
Checksum: m.Checksum,
|
||||
}
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
func metadataPath(dir string) string {
|
||||
return path.Join(dir, metadataFileName)
|
||||
}
|
||||
|
||||
func newMetadataFromDir(fs afero.Fs, dir string) (*Metadata, error) {
|
||||
metadataFilePath := metadataPath(dir)
|
||||
if !file.Exists(fs, metadataFilePath) {
|
||||
return nil, nil
|
||||
}
|
||||
f, err := fs.Open(metadataFilePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open DB metadata path (%s): %w", metadataFilePath, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var m Metadata
|
||||
err = json.NewDecoder(f).Decode(&m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse DB metadata (%s): %w", metadataFilePath, err)
|
||||
}
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (m *Metadata) UnmarshalJSON(data []byte) error {
|
||||
var mj MetadataJSON
|
||||
if err := json.Unmarshal(data, &mj); err != nil {
|
||||
return err
|
||||
}
|
||||
me, err := mj.ToMetadata()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = me
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Metadata) isSupercededBy(entry *ListingEntry) bool {
|
||||
if m == nil {
|
||||
log.Debugf("cannot find existing metadata, using update...")
|
||||
// any valid update beats no database, use it!
|
||||
return true
|
||||
}
|
||||
|
||||
if entry.Version.GreaterThan(m.Version) {
|
||||
log.Debugf("update is a newer version than the current database, using update...")
|
||||
// the listing is newer than the existing db, use it!
|
||||
return true
|
||||
}
|
||||
|
||||
if entry.Built.After(m.Built) {
|
||||
log.Debugf("existing database (%s) is older than candidate update (%s), using update...", m.Built.String(), entry.Built.String())
|
||||
// the listing is newer than the existing db, use it!
|
||||
return true
|
||||
}
|
||||
|
||||
log.Debugf("existing database is already up to date")
|
||||
return false
|
||||
}
|
||||
|
||||
func (m Metadata) String() string {
|
||||
return fmt.Sprintf("Metadata(built=%s version=%s checksum=%s)", m.Built, m.Version, m.Checksum)
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-test/deep"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
func TestMetadataParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expected Metadata
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
fixture: "test-fixtures/metadata-gocase",
|
||||
expected: Metadata{
|
||||
Built: time.Date(2020, 06, 15, 14, 02, 36, 0, time.UTC),
|
||||
Version: version.Must(version.NewVersion("0.2.0")),
|
||||
Checksum: "sha256:dcd6a285c839a7c65939e20c251202912f64826be68609dfc6e48df7f853ddc8",
|
||||
},
|
||||
},
|
||||
{
|
||||
fixture: "test-fixtures/metadata-edt-timezone",
|
||||
expected: Metadata{
|
||||
Built: time.Date(2020, 06, 15, 18, 02, 36, 0, time.UTC),
|
||||
Version: version.Must(version.NewVersion("0.2.0")),
|
||||
Checksum: "sha256:dcd6a285c839a7c65939e20c251202912f64826be68609dfc6e48df7f853ddc8",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.fixture, func(t *testing.T) {
|
||||
metadata, err := newMetadataFromDir(afero.NewOsFs(), test.fixture)
|
||||
if err != nil && !test.err {
|
||||
t.Fatalf("failed to get metadata: %+v", err)
|
||||
} else if err == nil && test.err {
|
||||
t.Fatalf("expected errer but got none")
|
||||
}
|
||||
|
||||
if metadata == nil {
|
||||
t.Fatalf("metadata not found: %+v", test.fixture)
|
||||
}
|
||||
|
||||
for _, diff := range deep.Equal(*metadata, test.expected) {
|
||||
t.Errorf("metadata difference: %s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadataIsSupercededBy(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
current *Metadata
|
||||
update *ListingEntry
|
||||
expectedToSupercede bool
|
||||
}{
|
||||
{
|
||||
name: "prefer updated versions over later dates",
|
||||
expectedToSupercede: true,
|
||||
current: &Metadata{
|
||||
Built: time.Date(2020, 06, 15, 14, 02, 36, 0, time.UTC),
|
||||
Version: version.Must(version.NewVersion("0.2.0")),
|
||||
},
|
||||
update: &ListingEntry{
|
||||
Built: time.Date(2020, 06, 13, 17, 13, 13, 0, time.UTC),
|
||||
Version: version.Must(version.NewVersion("0.3.0")),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prefer later dates when version is the same",
|
||||
expectedToSupercede: false,
|
||||
current: &Metadata{
|
||||
Built: time.Date(2020, 06, 15, 14, 02, 36, 0, time.UTC),
|
||||
Version: version.Must(version.NewVersion("1.1.0")),
|
||||
},
|
||||
update: &ListingEntry{
|
||||
Built: time.Date(2020, 06, 13, 17, 13, 13, 0, time.UTC),
|
||||
Version: version.Must(version.NewVersion("1.1.0")),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prefer something over nothing",
|
||||
expectedToSupercede: true,
|
||||
current: nil,
|
||||
update: &ListingEntry{
|
||||
Built: time.Date(2020, 06, 13, 17, 13, 13, 0, time.UTC),
|
||||
Version: version.Must(version.NewVersion("1.1.0")),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
actual := test.current.isSupercededBy(test.update)
|
||||
|
||||
if test.expectedToSupercede != actual {
|
||||
t.Errorf("failed supercede assertion: got %+v", actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"latest": {
|
||||
"built": "2020-06-13T13:13:13-04:00",
|
||||
"version": "1.1.0",
|
||||
"url": "http://localhost:5000/vulnerability-db-v1.1.0+2020-6-13.tar.gz",
|
||||
"checksum": "sha256:dcd6a285c839a7c65939e20c251202912f64826be68609dfc6e48df7f853ddc8"
|
||||
},
|
||||
"available": [
|
||||
{
|
||||
"built": "2020-06-12T12:12:12-04:00",
|
||||
"version": "0.2.0",
|
||||
"url": "http://localhost:5000/vulnerability-db-v0.2.0+2020-6-12.tar.gz",
|
||||
"checksum": "sha256:e20c251202948df7f853ddc812f64826bdcd6a285c839a7c65939e68609dfc6e"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"built": "2020-06-15T14:02:36-04:00",
|
||||
"updated": "2020-06-15T14:02:36-04:00",
|
||||
"last-check": "2020-06-15T14:02:36-04:00",
|
||||
"version": "0.2.0",
|
||||
"checksum": "sha256:dcd6a285c839a7c65939e20c251202912f64826be68609dfc6e48df7f853ddc8"
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"built": "2020-06-15T14:02:36Z",
|
||||
"version": "0.2.0",
|
||||
"checksum": "sha256:dcd6a285c839a7c65939e20c251202912f64826be68609dfc6e48df7f853ddc8"
|
||||
}
|
|
@ -2,8 +2,6 @@ package vulnerability
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/distro"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
|
@ -12,12 +10,12 @@ import (
|
|||
)
|
||||
|
||||
type StoreProvider struct {
|
||||
store db.VulnStore
|
||||
store db.VulnerabilityStoreReader
|
||||
// TODO: allows the ability to have a db cache for keeping rich objects around
|
||||
// or to have a sync.Pool of warm objects
|
||||
}
|
||||
|
||||
func NewProviderFromStore(store db.VulnStore) *StoreProvider {
|
||||
func NewProviderFromStore(store db.VulnerabilityStoreReader) *StoreProvider {
|
||||
return &StoreProvider{
|
||||
store: store,
|
||||
}
|
||||
|
@ -27,7 +25,7 @@ func (pr *StoreProvider) GetByDistro(d distro.Distro, p *pkg.Package) ([]*Vulner
|
|||
vulns := make([]*Vulnerability, 0)
|
||||
|
||||
namespace := distroNamespace(d)
|
||||
allPkgVulns, err := pr.store.Get(namespace, p.Name)
|
||||
allPkgVulns, err := pr.store.GetVulnerability(namespace, p.Name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("provider failed to fetch namespace='%s' pkg='%s': %w", namespace, p.Name, err)
|
||||
}
|
||||
|
@ -35,24 +33,14 @@ func (pr *StoreProvider) GetByDistro(d distro.Distro, p *pkg.Package) ([]*Vulner
|
|||
for _, vuln := range allPkgVulns {
|
||||
format := version.ParseFormat(vuln.VersionFormat)
|
||||
|
||||
// TODO: delete me, this should be implemented in the vulnscan-db repo
|
||||
var prefix string
|
||||
if vuln.Version == "None" {
|
||||
vuln.Version = ""
|
||||
}
|
||||
if format == version.DpkgFormat && vuln.Version != "" {
|
||||
prefix = "< "
|
||||
}
|
||||
// </TODO>
|
||||
|
||||
constraint, err := version.GetConstraint(prefix+vuln.Version, format)
|
||||
constraint, err := version.GetConstraint(vuln.VersionConstraint, format)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("provider failed to parse distro='%s' constraint='%s' format='%s': %w", d, vuln.Version, format, err)
|
||||
return nil, fmt.Errorf("provider failed to parse distro='%s' constraint='%s' format='%s': %w", d, vuln.VersionConstraint, format, err)
|
||||
}
|
||||
|
||||
vulns = append(vulns, &Vulnerability{
|
||||
Constraint: constraint,
|
||||
ID: vuln.VulnerabilityID,
|
||||
ID: vuln.ID,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -68,7 +56,7 @@ func (pr *StoreProvider) GetByLanguage(l pkg.Language, p *pkg.Package) ([]*Vulne
|
|||
}
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
allPkgVulns, err := pr.store.Get(namespace, p.Name)
|
||||
allPkgVulns, err := pr.store.GetVulnerability(namespace, p.Name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("provider failed to fetch namespace='%s' pkg='%s': %w", namespace, p.Name, err)
|
||||
}
|
||||
|
@ -76,38 +64,17 @@ func (pr *StoreProvider) GetByLanguage(l pkg.Language, p *pkg.Package) ([]*Vulne
|
|||
for _, vuln := range allPkgVulns {
|
||||
format := version.ParseFormat(vuln.VersionFormat)
|
||||
|
||||
// TODO: delete me, this should be implemented in the vulnscan-db repo
|
||||
if format == version.SemanticFormat && vuln.Version != "" {
|
||||
vuln.Version = forceSemVerConstraint(vuln.Version)
|
||||
}
|
||||
// </TODO>
|
||||
|
||||
constraint, err := version.GetConstraint(vuln.Version, format)
|
||||
constraint, err := version.GetConstraint(vuln.VersionConstraint, format)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("provider failed to parse language='%s' constraint='%s' format='%s': %w", l, vuln.Version, format, err)
|
||||
return nil, fmt.Errorf("provider failed to parse language='%s' constraint='%s' format='%s': %w", l, vuln.VersionConstraint, format, err)
|
||||
}
|
||||
|
||||
vulns = append(vulns, &Vulnerability{
|
||||
Constraint: constraint,
|
||||
ID: vuln.VulnerabilityID,
|
||||
ID: vuln.ID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return vulns, nil
|
||||
}
|
||||
|
||||
// match examples:
|
||||
// >= 5.0.0
|
||||
// <= 6.1.2.beta
|
||||
// >= 5.0.0
|
||||
// < 6.1
|
||||
// > 5.0.0
|
||||
// >=5
|
||||
// <6
|
||||
var forceSemVerPattern = regexp.MustCompile(`[><=]+\s*[^<>=]+`)
|
||||
|
||||
// TODO: delete me once implemented in vulnscan-db
|
||||
func forceSemVerConstraint(ver string) string {
|
||||
return strings.Join(forceSemVerPattern.FindAllString(ver, -1), ", ")
|
||||
}
|
||||
|
|
|
@ -18,27 +18,27 @@ func (d *mockStore) stub() {
|
|||
d.data["debian:8"] = map[string][]db.Vulnerability{
|
||||
"neutron": {
|
||||
{
|
||||
Name: "neutron",
|
||||
NamespaceName: "debian:8",
|
||||
Version: "2014.1.3-6",
|
||||
VulnerabilityID: "CVE-2014-fake-1",
|
||||
VersionFormat: "dpkg",
|
||||
PackageName: "neutron",
|
||||
Namespace: "debian:8",
|
||||
VersionConstraint: "< 2014.1.3-6",
|
||||
ID: "CVE-2014-fake-1",
|
||||
VersionFormat: "dpkg",
|
||||
},
|
||||
{
|
||||
Name: "neutron",
|
||||
NamespaceName: "debian:8",
|
||||
Version: "2013.0.2-1",
|
||||
VulnerabilityID: "CVE-2013-fake-2",
|
||||
VersionFormat: "dpkg",
|
||||
PackageName: "neutron",
|
||||
Namespace: "debian:8",
|
||||
VersionConstraint: "< 2013.0.2-1",
|
||||
ID: "CVE-2013-fake-2",
|
||||
VersionFormat: "dpkg",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *mockStore) Add(v *db.Vulnerability) error {
|
||||
func (d *mockStore) AddVulnerability(v *db.Vulnerability) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *mockStore) Get(namespace, name string) ([]db.Vulnerability, error) {
|
||||
func (d *mockStore) GetVulnerability(namespace, name string) ([]db.Vulnerability, error) {
|
||||
return d.data[namespace][name], nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package vulnerability
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/distro"
|
||||
|
@ -51,46 +50,3 @@ func TestGetByDistro(t *testing.T) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: delete me once implemented in vulnscan-db
|
||||
func TestForceSemVerConstraint(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
input: "> 5.0.0",
|
||||
expected: "> 5.0.0",
|
||||
},
|
||||
{
|
||||
input: ">= 5.0.0",
|
||||
expected: ">= 5.0.0",
|
||||
},
|
||||
{
|
||||
input: ">= 5.0.0 < 6.1",
|
||||
expected: ">= 5.0.0 , < 6.1",
|
||||
},
|
||||
{
|
||||
input: ">= 5.0.0 < 6.1.2",
|
||||
expected: ">= 5.0.0 , < 6.1.2",
|
||||
},
|
||||
{
|
||||
input: ">= 5 <= 6",
|
||||
expected: ">= 5 , <= 6",
|
||||
},
|
||||
{
|
||||
input: ">=5<6",
|
||||
expected: ">=5, <6",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
name := fmt.Sprintf("'%s'->'%s'", test.input, test.expected)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
actual := forceSemVerConstraint(test.input)
|
||||
if actual != test.expected {
|
||||
t.Errorf("failed to force semver constraint: input='%s': '%s'!='%s'", test.input, test.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue