From 6a5ca1ddfd67c68d149ee65c64cd3a0895b84163 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:28:08 -0800 Subject: [PATCH 01/11] You bet I busted some stuff, but lets start seeing what people think --- go.mod | 10 +- go.sum | 139 ++++++++++++++++++++++++ internal/audit/auditlog.go | 32 ++---- internal/audit/auditlogtextformatter.go | 57 +++++----- internal/cmd/iq.go | 22 ++-- internal/cmd/root.go | 75 ++++++++++--- packages/dep.go | 12 +- packages/mod.go | 20 +++- packages/packages.go | 14 ++- parse/parse.go | 70 +++++++----- parse/parse_test.go | 77 ++++++------- types/types.go | 13 ++- 12 files changed, 392 insertions(+), 149 deletions(-) diff --git a/go.mod b/go.mod index 5c7adee3..5e71596d 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353 // indirect github.com/shopspring/decimal v1.2.0 github.com/sirupsen/logrus v1.6.0 - github.com/sonatype-nexus-community/go-sona-types v0.0.12 + github.com/sonatype-nexus-community/go-sona-types v0.1.1 github.com/spf13/afero v1.3.4 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cobra v1.0.0 @@ -37,10 +37,10 @@ require ( gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c ) -// fix vulnerability: CVE-2020-15114 in etcd v3.3.13+incompatible -replace github.com/coreos/etcd => github.com/coreos/etcd v3.3.24+incompatible +// // fix vulnerability: CVE-2020-15114 in etcd v3.3.13+incompatible +// replace github.com/coreos/etcd => github.com/coreos/etcd v3.3.24+incompatible -// fix vulnerability: CVE-2021-3121 in github.com/gogo/protobuf v1.2.1 -replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 +// // fix vulnerability: CVE-2021-3121 in github.com/gogo/protobuf v1.2.1 +// replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 go 1.13 diff --git a/go.sum b/go.sum index 5d7f1413..b1faa3b9 100644 --- a/go.sum +++ b/go.sum @@ -4,15 +4,23 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0 h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Flaque/filet v0.0.0-20190209224823-fc4d33cfcf93 h1:NnAUCP75PRm8yWE7+MZBIAR6PA9iwsBYEc6ZNYOy+AQ= github.com/Flaque/filet v0.0.0-20190209224823-fc4d33cfcf93/go.mod h1:TK+jB3mBs+8ZMWhU5BqZKnZWJ1MrLo8etNVg51ueTBo= @@ -20,11 +28,17 @@ github.com/Masterminds/semver v0.0.0-20190925130524-317e8cce5480 h1:wMsGJ6lguH2m github.com/Masterminds/semver v0.0.0-20190925130524-317e8cce5480/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/vcs v1.13.1 h1:NL3G1X7/7xduQtA2sJLpVpfHTNBALVNSjob6KEjPXNQ= github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= @@ -32,33 +46,52 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c h1:+0HFd5KSZ/mm3JmhmrDukiId5iR6w4+BdFtfSy4yWIc= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/boltdb/bolt v1.1.0/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/common-nighthawk/go-figure v0.0.0-20200609044655-c4b36f998cf2 h1:tjT4Jp4gxECvsJcYpAMtW2I3YqzBTPuB67OejxXs86s= github.com/common-nighthawk/go-figure v0.0.0-20200609044655-c4b36f998cf2/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= +github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.24+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -66,19 +99,30 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/dep v0.5.4 h1:WfV5qbGwsBNUDhk+pfI6emWm7SdDFsnSWkqCMNG3BRs= github.com/golang/dep v0.5.4/go.mod h1:6RZ2Wai7dSWk7qL55sDYk+8UPFqcW7all2KDBraPPFA= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -94,6 +138,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -106,39 +151,64 @@ github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8= 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/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +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/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-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= 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 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= 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 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 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/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -152,22 +222,32 @@ github.com/jedib0t/go-pretty/v6 v6.0.4 h1:7WaHUeKo5yc2vABlsh30p4VWxQoXaWktBY/nR/ github.com/jedib0t/go-pretty/v6 v6.0.4/go.mod h1:MTr6FgcfNdnN5wPVBzJ6mhJeDyiF0yBvS2TMXEV/XSU= github.com/jmank88/nuts v0.4.0 h1:3rHp+7YcvtkTPohGBA++MwneB9OlX/rpORvleiRivMQ= github.com/jmank88/nuts v0.4.0/go.mod h1:TKOSbm0p73pdAzgQ7lcZheG2cinZiXqy60KM5ooL3j8= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 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 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -178,31 +258,43 @@ github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/z github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +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/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nightlyone/lockfile v1.0.0 h1:RHep2cFKK4PonZJDdEl4GmkabuhbsRMgk/k3uAmxBiA= github.com/nightlyone/lockfile v1.0.0/go.mod h1:rywoIealpdNse2r832aiD9jRk8ErCatROs6LzC841CI= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -210,6 +302,7 @@ github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/package-url/packageurl-go v0.1.0 h1:efWBc98O/dBZRg1pw2xiDzovnlMjCa9NPnfaiBduh8I= github.com/package-url/packageurl-go v0.1.0/go.mod h1:C/ApiuWpmbpni4DIOECf6WCjFUZV7O1Fx7VAzrZHgBw= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= @@ -219,35 +312,48 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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 h1:F++O52m40owAmADcojzM+9gyjmMOY/T4oYJkgFDH8RE= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/recoilme/pudge v1.0.3 h1:h/9dEv5fRqtzM4lnO69kUoN+k7ukxxrW9NGb9ug0grM= github.com/recoilme/pudge v1.0.3/go.mod h1:VMvxBLVkrSStldckzCsETBXox3pfovfrnEchafXk8qA= github.com/rhysd/go-github-selfupdate v1.2.3 h1:iaa+J202f+Nc+A8zi75uccC8Wg3omaM7HDeimXA22Ag= github.com/rhysd/go-github-selfupdate v1.2.3/go.mod h1:mp/N8zj6jFfBQy/XMYoWsmfzxazpPAODuqarmPDe2Rg= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353 h1:tnWWLf0nI2TI62Wd/ZOea4XYqE+y1sf2pdm+VItsc0c= github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353/go.mod h1:5HStXbIikwtDAgAIqiQIqVgMn7mlvZa6PTpwiAVYGYg= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= @@ -256,9 +362,15 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sonatype-nexus-community/go-sona-types v0.0.12 h1:wI4eo70vgn/9bUPT2s5xRwdTQsevwcOtlE233Vj8aEU= github.com/sonatype-nexus-community/go-sona-types v0.0.12/go.mod h1:uou8FGf9R5Nz1c6BfSM3v9K7g0R6faTYoxLh9Ybeht8= +github.com/sonatype-nexus-community/go-sona-types v0.1.0 h1:s4r0PEbBaMJwkeDJ7VLsinBej34azxzg+4CMxy7fvXY= +github.com/sonatype-nexus-community/go-sona-types v0.1.0/go.mod h1:uou8FGf9R5Nz1c6BfSM3v9K7g0R6faTYoxLh9Ybeht8= +github.com/sonatype-nexus-community/go-sona-types v0.1.1 h1:cqQLHiL6XGci7dXvO1OKpt6WtU4gazAQikYQ9u/2FPs= +github.com/sonatype-nexus-community/go-sona-types v0.1.1/go.mod h1:uou8FGf9R5Nz1c6BfSM3v9K7g0R6faTYoxLh9Ybeht8= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.3.4 h1:8q6vk3hthlpb2SouZcnBVKboxWQWMDNF38bwholZrJc= @@ -281,6 +393,7 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= @@ -294,19 +407,28 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -323,8 +445,10 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -332,10 +456,13 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0 h1:sfUMP1Gu8qASkorDVjnMuvgJzwFbTZSeXFiGBYAVdl4= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -368,6 +495,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= @@ -394,6 +522,7 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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= @@ -403,7 +532,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -435,6 +566,7 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -451,12 +583,14 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -469,6 +603,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -476,6 +611,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -485,6 +621,7 @@ gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.60.1 h1:P5y5shSkb0CFe44qEeMBgn8JLow09MP17jlJHanke5g= gopkg.in/ini.v1 v1.60.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -501,5 +638,7 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/audit/auditlog.go b/internal/audit/auditlog.go index 2865018e..8532383f 100644 --- a/internal/audit/auditlog.go +++ b/internal/audit/auditlog.go @@ -20,47 +20,35 @@ import ( "os" log "github.com/sirupsen/logrus" - "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" + ossIndexTypes "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" "github.com/sonatype-nexus-community/nancy/buildversion" + "github.com/sonatype-nexus-community/nancy/types" ) // LogResults will given a number of expected results and the results themselves, log the // results. -func LogResults(formatter log.Formatter, packageCount int, coordinates []types.Coordinate, invalidCoordinates []types.Coordinate, exclusions []string) int { +func LogResults(formatter log.Formatter, packageCount int, coordinates map[string]ossIndexTypes.Coordinate, invalidCoordinates []ossIndexTypes.Coordinate, vulnerableCoordinates map[string]types.Projects, exclusions []string) int { vulnerableCount := 0 - for _, c := range coordinates { - c.ExcludeVulnerabilities(exclusions) + if exclusions == nil { + exclusions = make([]string, 0) } - var auditedCoordinates []types.Coordinate - var vulnerableCoordinates []types.Coordinate - - for i := 0; i < len(coordinates); i++ { - coordinate := coordinates[i] - if coordinate.IsVulnerable() { - vulnerableCount++ - vulnerableCoordinates = append(vulnerableCoordinates, coordinate) - } - auditedCoordinates = append(auditedCoordinates, coordinate) + for _, c := range vulnerableCoordinates { + c.Coordinate.ExcludeVulnerabilities(exclusions) } if invalidCoordinates == nil { - invalidCoordinates = make([]types.Coordinate, 0) - } - if exclusions == nil { - exclusions = make([]string, 0) - } - if vulnerableCoordinates == nil { - vulnerableCoordinates = make([]types.Coordinate, 0) + invalidCoordinates = make([]ossIndexTypes.Coordinate, 0) } + log.SetFormatter(formatter) log.SetOutput(os.Stdout) log.WithFields(log.Fields{ "exclusions": exclusions, "num_audited": packageCount, "num_vulnerable": vulnerableCount, - "audited": auditedCoordinates, + "audited": coordinates, "vulnerable": vulnerableCoordinates, "invalid": invalidCoordinates, "version": buildversion.BuildVersion, diff --git a/internal/audit/auditlogtextformatter.go b/internal/audit/auditlogtextformatter.go index d513fca9..879a29f8 100644 --- a/internal/audit/auditlogtextformatter.go +++ b/internal/audit/auditlogtextformatter.go @@ -29,7 +29,8 @@ import ( "github.com/logrusorgru/aurora" "github.com/shopspring/decimal" . "github.com/sirupsen/logrus" - "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" + ossIndexTypes "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" + "github.com/sonatype-nexus-community/nancy/types" ) var ( @@ -47,7 +48,7 @@ type AuditLogTextFormatter struct { NoColor bool } -func logPackage(sb *strings.Builder, noColor bool, coordinate types.Coordinate) { +func logPackage(sb *strings.Builder, noColor bool, coordinate ossIndexTypes.Coordinate) { au := aurora.NewAurora(!noColor) sb.WriteString( @@ -57,7 +58,7 @@ func logPackage(sb *strings.Builder, noColor bool, coordinate types.Coordinate) ) } -func logInvalidSemVerWarning(sb *strings.Builder, noColor bool, quiet bool, invalidPurls []types.Coordinate) { +func logInvalidSemVerWarning(sb *strings.Builder, noColor bool, quiet bool, invalidPurls []ossIndexTypes.Coordinate) { if !quiet { if len(invalidPurls) > 0 { au := aurora.NewAurora(!noColor) @@ -76,19 +77,19 @@ func logInvalidSemVerWarning(sb *strings.Builder, noColor bool, quiet bool, inva } } -func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Coordinate) { +func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Projects) { au := aurora.NewAurora(!noColor) sb.WriteString(fmt.Sprintf( "%s\n%s \n", - au.Bold(au.Red(coordinate.Coordinates)).String(), - au.Red(strconv.Itoa(len(coordinate.Vulnerabilities))+" known vulnerabilities affecting installed version").String(), + au.Bold(au.Red(coordinate.Coordinate.Coordinates)).String(), + au.Red(strconv.Itoa(len(coordinate.Coordinate.Vulnerabilities))+" known vulnerabilities affecting installed version").String(), )) - sort.Slice(coordinate.Vulnerabilities, func(i, j int) bool { - return coordinate.Vulnerabilities[i].CvssScore.GreaterThan(coordinate.Vulnerabilities[j].CvssScore) + sort.Slice(coordinate.Coordinate.Vulnerabilities, func(i, j int) bool { + return coordinate.Coordinate.Vulnerabilities[i].CvssScore.GreaterThan(coordinate.Coordinate.Vulnerabilities[j].CvssScore) }) - for _, v := range coordinate.Vulnerabilities { + for _, v := range coordinate.Coordinate.Vulnerabilities { if !v.Excluded { t := table.NewWriter() t.SetStyle(table.StyleBold) @@ -102,6 +103,7 @@ func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Co t.AppendRow([]interface{}{"CVSS Vector", v.CvssVector}) t.AppendSeparator() t.AppendRow([]interface{}{"Link for more info", v.Reference}) + sb.WriteString(t.Render() + "\n") } } @@ -134,7 +136,7 @@ func scoreAssessment(score decimal.Decimal) string { return "Low" } -func groupAndPrint(vulnerable []types.Coordinate, nonVulnerable []types.Coordinate, quiet bool, noColor bool, sb *strings.Builder) { +func groupAndPrint(vulnerable map[string]types.Projects, nonVulnerable map[string]ossIndexTypes.Coordinate, quiet bool, noColor bool, sb *strings.Builder) { if !quiet { sb.WriteString("\n") for _, v := range nonVulnerable { @@ -157,8 +159,9 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { numVulnerable := entry.Data["num_vulnerable"] buildVersion := entry.Data["version"] if auditedEntries != nil && invalidEntries != nil && packageCount != nil && numVulnerable != nil && buildVersion != nil { - auditedEntries := entry.Data["audited"].([]types.Coordinate) - invalidEntries := entry.Data["invalid"].([]types.Coordinate) + auditedEntries := entry.Data["audited"].(map[string]ossIndexTypes.Coordinate) + vulnerableEntries := entry.Data["vulnerable"].(map[string]types.Projects) + invalidEntries := entry.Data["invalid"].([]ossIndexTypes.Coordinate) packageCount := entry.Data["num_audited"].(int) numVulnerable := entry.Data["num_vulnerable"].(int) @@ -168,11 +171,26 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { _ = w.Flush() logInvalidSemVerWarning(&sb, f.NoColor, f.Quiet, invalidEntries) - nonVulnerablePackages, vulnerablePackages := splitPackages(auditedEntries) - groupAndPrint(vulnerablePackages, nonVulnerablePackages, f.Quiet, f.NoColor, &sb) + groupAndPrint(vulnerableEntries, auditedEntries, f.Quiet, f.NoColor, &sb) au := aurora.NewAurora(!f.NoColor) + + var updates []string + for _, v := range vulnerableEntries { + if v.UpdateCoordinate.Coordinates != "" && v.Update != nil { + updates = append(updates, fmt.Sprintf("replace %s => %s %s\n", v.Update.Path, v.Update.Path, v.Update.Version)) + } + } + + if len(updates) > 0 { + sb.WriteString(au.Bold("I found some updated versions you can try out, that have no known vulnerabilities!\n\nTry the following in your go.mod file:\n\n").String()) + for _, v := range updates { + sb.WriteString(au.Italic(v).String()) + } + sb.WriteString("\n") + } + t := table.NewWriter() t.SetStyle(table.StyleBold) t.SetTitle("Summary") @@ -186,14 +204,3 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { } return nil, errors.New("fields passed did not match the expected values for an audit log. You should probably look at setting the formatter to something else") } - -func splitPackages(entries []types.Coordinate) (nonVulnerable []types.Coordinate, vulnerable []types.Coordinate) { - for _, v := range entries { - if v.IsVulnerable() { - vulnerable = append(vulnerable, v) - } else { - nonVulnerable = append(nonVulnerable, v) - } - } - return -} diff --git a/internal/cmd/iq.go b/internal/cmd/iq.go index 52b8c048..e694641b 100644 --- a/internal/cmd/iq.go +++ b/internal/cmd/iq.go @@ -19,20 +19,20 @@ package cmd import ( "errors" "fmt" + "io" + "os" + "github.com/mitchellh/go-homedir" "github.com/sonatype-nexus-community/go-sona-types/configuration" "github.com/sonatype-nexus-community/go-sona-types/iq" ossIndexTypes "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" "github.com/sonatype-nexus-community/nancy/internal/customerrors" "github.com/sonatype-nexus-community/nancy/internal/logger" - "github.com/sonatype-nexus-community/nancy/packages" "github.com/sonatype-nexus-community/nancy/parse" "github.com/sonatype-nexus-community/nancy/types" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" - "io" - "os" ) type iqServerFactory interface { @@ -127,9 +127,14 @@ func doIQ(cmd *cobra.Command, args []string) (err error) { func getPurls() (purls []string, err error) { if configOssi.Path != "" { var invalidPurls []string - if purls, invalidPurls, err = getPurlsFromPath(configOssi.Path); err != nil { + deps, invalidPurls, err := getPurlsFromPath(configOssi.Path) + if err != nil { panic(err) } + + for k := range deps { + purls = append(purls, k) + } invalidCoordinates := convertInvalidPurlsToCoordinates(invalidPurls) logLady.WithField("invalid", invalidCoordinates).Info("") } else { @@ -138,14 +143,15 @@ func getPurls() (purls []string, err error) { panic(err) } - mod := packages.Mod{} - - mod.ProjectList, err = parse.GoListAgnostic(os.Stdin) + deps, err := parse.GoListAgnostic(os.Stdin) if err != nil { logLady.WithError(err).Error("unexpected error in iq cmd") panic(err) } - purls = mod.ExtractPurlsFromManifest() + + for k := range deps { + purls = append(purls, k) + } } return purls, err } diff --git a/internal/cmd/root.go b/internal/cmd/root.go index d4c1555f..74a3e28e 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -19,7 +19,6 @@ package cmd import ( "bufio" "fmt" - "github.com/spf13/pflag" "os" "path/filepath" "reflect" @@ -28,6 +27,8 @@ import ( "strings" "time" + "github.com/spf13/pflag" + "github.com/common-nighthawk/go-figure" "github.com/golang/dep" "github.com/mitchellh/go-homedir" @@ -306,7 +307,7 @@ func getIsQuiet() bool { return !configOssi.Loud } -func getPurlsFromPath(path string) (purls []string, invalidPurls []string, err error) { +func getPurlsFromPath(path string) (deps map[string]types.Projects, invalidPurls []string, err error) { logLady.Info("Parsing config for file based scan") if !strings.Contains(path, GopkgLockFilename) { err = fmt.Errorf("invalid path value. must point to '%s' file. path: %s", GopkgLockFilename, path) @@ -335,20 +336,17 @@ func getPurlsFromPath(path string) (purls []string, invalidPurls []string, err e return } - purls, invalidPurls = packages.ExtractPurlsUsingDep(project) + deps, invalidPurls = packages.ExtractPurlsUsingDep(project) return } func doDepAndParse(ossIndex ossindex.IServer, path string) (err error) { - var purls, invalidPurls []string - if purls, invalidPurls, err = getPurlsFromPath(path); err != nil { - return - } - - if err = checkOSSIndex(ossIndex, purls, invalidPurls); err != nil { - return + deps, invalidPurls, err := getPurlsFromPath(path) + if err == nil { + if err = checkOSSIndex(ossIndex, deps, invalidPurls); err != nil { + return + } } - return } @@ -428,7 +426,7 @@ func doStdInAndParse(ossIndex ossindex.IServer) (err error) { mod := packages.Mod{} - mod.ProjectList, err = parse.GoListAgnostic(os.Stdin) + mods, err := parse.GoListAgnostic(os.Stdin) if err != nil { logLady.Error(err) return @@ -443,21 +441,64 @@ func doStdInAndParse(ossIndex ossindex.IServer) (err error) { }).Debug("Extracted purls") logLady.Info("Auditing purls with OSS Index") - err = checkOSSIndex(ossIndex, purls, nil) + err = checkOSSIndex(ossIndex, mods, nil) return err } -func checkOSSIndex(ossIndex ossindex.IServer, purls []string, invalidpurls []string) (err error) { - var packageCount = len(purls) - coordinates, err := ossIndex.AuditPackages(purls) +func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Projects, invalidpurls []string) (err error) { + var packageCount = len(coordinates) + purls := make([]string, 0, len(coordinates)) + for k := range coordinates { + purls = append(purls, k) + } + + ossIndexResponse, err := ossIndex.Audit(purls) if err != nil { return } + vulnerableCoordinates := make(map[string]types.Projects) + for k, v := range ossIndexResponse { + if v.IsVulnerable() { + project := coordinates[k] + fmt.Print(v) + project.Coordinate = v + vulnerableCoordinates[k] = project + } + } + + updatePurls := make([]string, 0, len(coordinates)) + updateMatrix := make(map[string]string) + + for k, v := range vulnerableCoordinates { + if v.Update != nil { + updatePurl := packages.GimmeAPurl(v.Name, v.Update.Version) + updateMatrix[updatePurl] = k + + updatePurls = append(updatePurls, updatePurl) + } + } + + var updateCoordinates map[string]ossIndexTypes.Coordinate + if len(updatePurls) > 0 { + updateCoordinates, err = ossIndex.Audit(updatePurls) + if err != nil { + return + } + + for k, v := range updateCoordinates { + originalPurl := updateMatrix[k] + project := vulnerableCoordinates[originalPurl] + + project.UpdateCoordinate = v + vulnerableCoordinates[originalPurl] = project + } + } + invalidCoordinates := convertInvalidPurlsToCoordinates(invalidpurls) - if count := audit.LogResults(configOssi.Formatter, packageCount, coordinates, invalidCoordinates, configOssi.CveList.Cves); count > 0 { + if count := audit.LogResults(configOssi.Formatter, packageCount, ossIndexResponse, invalidCoordinates, vulnerableCoordinates, configOssi.CveList.Cves); count > 0 { err = customerrors.ErrorExit{ExitCode: count} return } diff --git a/packages/dep.go b/packages/dep.go index 8d11bec3..06022d3c 100644 --- a/packages/dep.go +++ b/packages/dep.go @@ -21,12 +21,12 @@ import ( "github.com/Masterminds/semver" "github.com/golang/dep" + "github.com/sonatype-nexus-community/nancy/types" ) -func ExtractPurlsUsingDep(project *dep.Project) ([]string, []string) { +func ExtractPurlsUsingDep(project *dep.Project) (deps map[string]types.Projects, invalidPurls []string) { lockedProjects := project.Lock.P - var purls []string - var invalidPurls []string + for _, lockedProject := range lockedProjects { var version string i := lockedProject.Version().String() @@ -42,9 +42,11 @@ func ExtractPurlsUsingDep(project *dep.Project) ([]string, []string) { if err != nil { invalidPurls = append(invalidPurls, purl) } else { - purls = append(purls, purl) + dep := types.Projects{Name: packageName, Version: version} + + deps[purl] = dep } } } - return purls, invalidPurls + return } diff --git a/packages/mod.go b/packages/mod.go index 3bf0e4d6..95e6dc50 100644 --- a/packages/mod.go +++ b/packages/mod.go @@ -19,6 +19,7 @@ package packages import ( "strings" + ossIndexTypes "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" "github.com/sonatype-nexus-community/nancy/types" ) @@ -27,7 +28,11 @@ type Mod struct { GoSumPath string } -func (m Mod) ExtractPurlsFromManifest() (purls []string) { +func (m Mod) ExtractPurlsFromManifest() []string { + return removeDuplicates(m.extractPurls(m.ProjectList)) +} + +func (m Mod) extractPurls(mods types.ProjectList) (purls []string) { for _, s := range m.ProjectList.Projects { if len(s.Version) > 0 { // There must be a version we can use // OSS Index no likey v before version, IQ does though, comment left so I will never forget. @@ -39,11 +44,20 @@ func (m Mod) ExtractPurlsFromManifest() (purls []string) { } } - purls = removeDuplicates(purls) - return } +func (m Mod) ExtractUpdatePurls(vulnerable map[string]ossIndexTypes.Coordinate) (purls []string) { + projectsWithUpdate := types.ProjectList{} + for _, s := range m.ProjectList.Projects { + if s.Update != nil { + projectsWithUpdate.Projects = append(projectsWithUpdate.Projects, s) + } + } + + return removeDuplicates(m.extractPurls(projectsWithUpdate)) +} + func removeDuplicates(purls []string) (dedupedPurls []string) { encountered := map[string]bool{} diff --git a/packages/packages.go b/packages/packages.go index f8216be0..11c4db50 100644 --- a/packages/packages.go +++ b/packages/packages.go @@ -16,7 +16,11 @@ package packages -import "regexp" +import ( + "fmt" + "regexp" + "strings" +) var gopkg1Pattern = regexp.MustCompile("^gopkg.in/([^.]+).*") var gopkg2Pattern = regexp.MustCompile("^gopkg.in/([^/]+)/([^.]+).*") @@ -44,3 +48,11 @@ func convertGopkgNameToPurl(name string) (rename string) { } return } + +func GimmeAPurl(name string, version string) string { + version = strings.Replace(version, "v", "", -1) + version = strings.Replace(version, "+incompatible", "", -1) + + convertedName := convertGopkgNameToPurl(name) + return fmt.Sprintf("pkg:%s@%s", convertedName, version) +} diff --git a/parse/parse.go b/parse/parse.go index 1a435503..b25398db 100644 --- a/parse/parse.go +++ b/parse/parse.go @@ -24,6 +24,7 @@ import ( "io/ioutil" "strings" + "github.com/sonatype-nexus-community/nancy/packages" "github.com/sonatype-nexus-community/nancy/types" ) @@ -31,23 +32,17 @@ var goListDependencyCriteria = func(s []string) bool { return len(s) > 1 } -func GoList(stdIn *bufio.Scanner) (deps types.ProjectList, err error) { - for stdIn.Scan() { - parseSpaceSeparatedDependency(stdIn, &deps, goListDependencyCriteria) - } - - return deps, nil -} - // GoListAgnostic will take a io.Reader that is likely the os.StdIn, try to parse it as // if `go list -json -m all` was ran, and then try to reparse it as if `go list -m all` // was ran instead. It returns either an error, or a deps of types.ProjectList -func GoListAgnostic(stdIn io.Reader) (deps types.ProjectList, err error) { +func GoListAgnostic(stdIn io.Reader) (deps map[string]types.Projects, err error) { + deps = make(map[string]types.Projects) + // stdIn should never be massive, so taking this approach over reading from a stream // multiple times johnnyFiveNeedInput, err := ioutil.ReadAll(stdIn) if err != nil { - return + return deps, err } decoder := json.NewDecoder(strings.NewReader(string(johnnyFiveNeedInput))) @@ -63,17 +58,24 @@ func GoListAgnostic(stdIn io.Reader) (deps types.ProjectList, err error) { break } - project, err := modToProjectList(mod) + dep, err := modToProjectList(mod) if _, ok := err.(*NoVersionError); ok { continue } - deps.Projects = append(deps.Projects, project) + deps[packages.GimmeAPurl(dep.Name, dep.Version)] = dep } if err != nil { err = nil scanner := bufio.NewScanner(strings.NewReader(string(johnnyFiveNeedInput))) - deps, err = GoList(scanner) + + for scanner.Scan() { + dep := parseSpaceSeparatedDependency(scanner, goListDependencyCriteria) + if dep != nil { + deps[packages.GimmeAPurl(dep.Name, dep.Version)] = *dep + } + } + if err != nil { return } @@ -88,40 +90,58 @@ func modToProjectList(mod types.GoListModule) (dep types.Projects, err error) { err = &NoVersionError{err: fmt.Errorf("no version found for mod")} return } - dep.Name = mod.Replace.Path - dep.Version = mod.Replace.Version + + dep = populateMod(mod, mod.Replace.Path, mod.Replace.Version) + return } if mod.Version == "" { err = &NoVersionError{err: fmt.Errorf("no version found for mod")} return } - dep.Name = mod.Path - dep.Version = mod.Version + + dep = populateMod(mod, mod.Path, mod.Version) + + return +} + +func populateMod(mod types.GoListModule, name string, version string) (dep types.Projects) { + if mod.Update != nil { + dep.Update = &types.ProjectUpdate{ + Path: mod.Update.Path, + Version: mod.Update.Version, + Time: *mod.Update.Time, + } + } + dep.Name = name + dep.Version = version + return } -func parseSpaceSeparatedDependency(scanner *bufio.Scanner, deps *types.ProjectList, criteria func(s []string) bool) { +func parseSpaceSeparatedDependency(scanner *bufio.Scanner, criteria func(s []string) bool) (dep *types.Projects) { text := scanner.Text() rewrite := strings.Split(text, "=>") if len(rewrite) == 2 { v2 := strings.Split(strings.TrimSpace(rewrite[1]), " ") - addProjectDep(criteria, v2, deps) - }else{ - s := strings.Split(text, " ") - addProjectDep(criteria, s, deps) + return addProjectDep(criteria, v2) } + + s := strings.Split(text, " ") + return addProjectDep(criteria, s) } -func addProjectDep(criteria func(s []string) bool, s []string, deps *types.ProjectList) { +func addProjectDep(criteria func(s []string) bool, s []string) (dep *types.Projects) { if criteria(s) { if len(s) > 3 { - deps.Projects = append(deps.Projects, types.Projects{Name: s[0], Version: s[4]}) + return &types.Projects{Name: s[0], Version: s[4]} } else { - deps.Projects = append(deps.Projects, types.Projects{Name: s[0], Version: s[1]}) + return &types.Projects{Name: s[0], Version: s[1]} } } + + return nil } type NoVersionError struct { diff --git a/parse/parse_test.go b/parse/parse_test.go index becf2a35..deea3f43 100644 --- a/parse/parse_test.go +++ b/parse/parse_test.go @@ -17,15 +17,12 @@ package parse import ( - "bufio" - "errors" - "github.com/sonatype-nexus-community/nancy/types" "os" "strings" "testing" ) -func TestGoListJson(t *testing.T){ +func TestGoListJson(t *testing.T) { goListJSONFile, err := os.Open("testdata/golistjson.out") if err != nil { t.Error(err) @@ -35,8 +32,8 @@ func TestGoListJson(t *testing.T){ if err != nil { t.Error(err) } - if len(deps.Projects) != 48 { - t.Errorf("Unsuccessfully parsed go list -json -m all output, 48 dependencies were expected, but %d encountered", len(deps.Projects)) + if len(deps) != 48 { + t.Errorf("Unsuccessfully parsed go list -json -m all output, 48 dependencies were expected, but %d encountered", len(deps)) } } @@ -50,12 +47,12 @@ func TestGoListAgnostic(t *testing.T) { if err != nil { t.Error(err) } - if len(deps.Projects) != 48 { - t.Errorf("Unsuccessfully parsed go list -m all output, 48 dependencies were expected, but %d encountered", len(deps.Projects)) + if len(deps) != 48 { + t.Errorf("Unsuccessfully parsed go list -m all output, 48 dependencies were expected, but %d encountered", len(deps)) } } -func TestGoListJsonReplace(t *testing.T){ +func TestGoListJsonReplace(t *testing.T) { goListJSONReplaceFile, err := os.Open("testdata/golistjsonreplace.out") if err != nil { t.Error(err) @@ -65,15 +62,23 @@ func TestGoListJsonReplace(t *testing.T){ if err != nil { t.Error(err) } - if len(deps.Projects) != 134 { - t.Errorf("Unsuccessfully parsed go list -m all output, 134 dependencies were expected, but %d encountered", len(deps.Projects)) + if len(deps) != 134 { + t.Errorf("Unsuccessfully parsed go list -m all output, 134 dependencies were expected, but %d encountered", len(deps)) } - if deps.Projects[0].Version != "v1.4.2" { - t.Errorf("Version expected to be v1.4.2, but encountered %s", deps.Projects[0].Version) + + purl := "pkg:golang/github.com/gorilla/websocket@1.4.2" + + if val, ok := deps[purl]; ok { + if val.Version != "v1.4.2" { + t.Errorf("Version expected to be v1.4.2, but encountered %s", val.Version) + } + } else { + t.Error(deps) + t.Errorf("Did not find my purl, where is my purl?! %+v", val) } } -func TestGoListReplace(t *testing.T){ +func TestGoListReplace(t *testing.T) { goListReplaceFile, err := os.Open("testdata/golistreplace.out") if err != nil { t.Error(err) @@ -83,11 +88,19 @@ func TestGoListReplace(t *testing.T){ if err != nil { t.Error(err) } - if len(deps.Projects) != 1 { - t.Errorf("Unsuccessfully parsed go list -m all output, 1 dependency was expected, but %d encountered", len(deps.Projects)) + if len(deps) != 1 { + t.Errorf("Unsuccessfully parsed go list -m all output, 1 dependency was expected, but %d encountered", len(deps)) } - if deps.Projects[0].Version != "v1.4.2" { - t.Errorf("Version expected to be v1.4.2, but encountered %s", deps.Projects[0].Version) + + purl := "pkg:golang/github.com/gorilla/websocket@1.4.2" + + if val, ok := deps[purl]; ok { + if val.Version != "v1.4.2" { + t.Errorf("Version expected to be v1.4.2, but encountered %s", val.Version) + } + } else { + t.Error(deps) + t.Errorf("Did not find my purl, where is my purl?! %+v", val) } } @@ -96,24 +109,24 @@ func TestGoListAllWithSelfReference(t *testing.T) { if err != nil { t.Error(err) } - scanner := bufio.NewScanner(goListSelfReferenceOutput) - deps, err := GoList(scanner) + deps, err := GoListAgnostic(goListSelfReferenceOutput) if err != nil { t.Error(err) } - if len(deps.Projects) != 517 { + if len(deps) != 517 { t.Error(deps) } - _, err = findProject(deps, "github.com/ory/kratos-client-go") - if err == nil{ + kratosClientPurl := "pkg:golang/github.com/ory/kratos-client-go@0.5.4-alpha.1" + kratosClientCorpPurl := "pkg:golang/github.com/ory/kratos/corp@0.0.0-00010101000000-000000000000" + + if _, ok := deps[kratosClientPurl]; ok { t.Error("Project with name github.com/ory/kratos-client-go should be ignored b/c it references a submodule") } - _, err = findProject(deps, "github.com/ory/kratos/corp") - if err == nil{ + if _, ok := deps[kratosClientCorpPurl]; ok { t.Error("Project with name github.com/ory/kratos/corp should be ignored b/c it references a submodule") } } @@ -136,23 +149,13 @@ github.com/stretchr/testify v1.3.0 golang.org/x/net v0.0.0-20181220203305-927f97764cc3 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb` - scanner := bufio.NewScanner(strings.NewReader(goListMAllOutput)) - deps, err := GoList(scanner) + deps, err := GoListAgnostic(strings.NewReader(goListMAllOutput)) if err != nil { t.Error(err) } - if len(deps.Projects) != 16 { + if len(deps) != 16 { t.Error(deps) } } - -func findProject(deps types.ProjectList, name string) (types.Projects, error) { - for _, s := range deps.Projects { - if s.Name == name { - return s, nil - } - } - return types.Projects{}, errors.New("Could not find project with name : " + name) -} diff --git a/types/types.go b/types/types.go index 959138b0..e7052854 100644 --- a/types/types.go +++ b/types/types.go @@ -22,6 +22,7 @@ import ( "time" "github.com/sirupsen/logrus" + "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" ) type GoListModule struct { @@ -61,9 +62,19 @@ type Configuration struct { } type Projects struct { - Name string + Name string + Version string + Update *ProjectUpdate + Coordinate types.Coordinate + UpdateCoordinate types.Coordinate +} + +type ProjectUpdate struct { + Path string Version string + Time time.Time } + type ProjectList struct { Projects []Projects } From 26acba3fccf69fba2cd229a62236d0184f5f2bee Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:46:53 -0800 Subject: [PATCH 02/11] Add a comment on what it fixes --- internal/audit/auditlogtextformatter.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/internal/audit/auditlogtextformatter.go b/internal/audit/auditlogtextformatter.go index 879a29f8..dbed328e 100644 --- a/internal/audit/auditlogtextformatter.go +++ b/internal/audit/auditlogtextformatter.go @@ -179,7 +179,13 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { var updates []string for _, v := range vulnerableEntries { if v.UpdateCoordinate.Coordinates != "" && v.Update != nil { - updates = append(updates, fmt.Sprintf("replace %s => %s %s\n", v.Update.Path, v.Update.Path, v.Update.Version)) + var issueTitles []string + for _, v := range v.Coordinate.Vulnerabilities { + issueTitles = append(issueTitles, v.Cve) + } + comment := fmt.Sprintf("// fix issues: %s in %s %s\n", strings.Join(issueTitles, ", "), v.Name, v.Version) + replace := fmt.Sprintf("replace %s => %s %s\n\n", v.Update.Path, v.Update.Path, v.Update.Version) + updates = append(updates, comment, replace) } } @@ -188,7 +194,6 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { for _, v := range updates { sb.WriteString(au.Italic(v).String()) } - sb.WriteString("\n") } t := table.NewWriter() From 3c452f5df473c1992f08d7bdd6e9dfe684d56470 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:50:09 -0800 Subject: [PATCH 03/11] add in some color, why not --- internal/audit/auditlogtextformatter.go | 4 ++-- internal/cmd/root.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/audit/auditlogtextformatter.go b/internal/audit/auditlogtextformatter.go index dbed328e..2b3ebc54 100644 --- a/internal/audit/auditlogtextformatter.go +++ b/internal/audit/auditlogtextformatter.go @@ -183,8 +183,8 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { for _, v := range v.Coordinate.Vulnerabilities { issueTitles = append(issueTitles, v.Cve) } - comment := fmt.Sprintf("// fix issues: %s in %s %s\n", strings.Join(issueTitles, ", "), v.Name, v.Version) - replace := fmt.Sprintf("replace %s => %s %s\n\n", v.Update.Path, v.Update.Path, v.Update.Version) + comment := au.Green(fmt.Sprintf("// fix issues: %s in %s %s\n", strings.Join(issueTitles, ", "), v.Name, v.Version)).String() + replace := au.Blue(fmt.Sprintf("replace %s => %s %s\n\n", v.Update.Path, v.Update.Path, v.Update.Version)).String() updates = append(updates, comment, replace) } } diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 74a3e28e..0139263f 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -462,7 +462,6 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje for k, v := range ossIndexResponse { if v.IsVulnerable() { project := coordinates[k] - fmt.Print(v) project.Coordinate = v vulnerableCoordinates[k] = project } From 2d6749e50bc9c6f0533f179291421102704c34b2 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:55:26 -0800 Subject: [PATCH 04/11] Simplify this a bit --- internal/audit/auditlog.go | 16 +++++++--------- internal/audit/auditlogtextformatter.go | 10 +++------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/internal/audit/auditlog.go b/internal/audit/auditlog.go index 8532383f..97e0c189 100644 --- a/internal/audit/auditlog.go +++ b/internal/audit/auditlog.go @@ -28,7 +28,6 @@ import ( // LogResults will given a number of expected results and the results themselves, log the // results. func LogResults(formatter log.Formatter, packageCount int, coordinates map[string]ossIndexTypes.Coordinate, invalidCoordinates []ossIndexTypes.Coordinate, vulnerableCoordinates map[string]types.Projects, exclusions []string) int { - vulnerableCount := 0 if exclusions == nil { exclusions = make([]string, 0) @@ -45,14 +44,13 @@ func LogResults(formatter log.Formatter, packageCount int, coordinates map[strin log.SetFormatter(formatter) log.SetOutput(os.Stdout) log.WithFields(log.Fields{ - "exclusions": exclusions, - "num_audited": packageCount, - "num_vulnerable": vulnerableCount, - "audited": coordinates, - "vulnerable": vulnerableCoordinates, - "invalid": invalidCoordinates, - "version": buildversion.BuildVersion, + "exclusions": exclusions, + "num_audited": packageCount, + "audited": coordinates, + "vulnerable": vulnerableCoordinates, + "invalid": invalidCoordinates, + "version": buildversion.BuildVersion, }).Info("") - return vulnerableCount + return len(vulnerableCoordinates) } diff --git a/internal/audit/auditlogtextformatter.go b/internal/audit/auditlogtextformatter.go index 2b3ebc54..2ebeee45 100644 --- a/internal/audit/auditlogtextformatter.go +++ b/internal/audit/auditlogtextformatter.go @@ -155,15 +155,11 @@ func groupAndPrint(vulnerable map[string]types.Projects, nonVulnerable map[strin func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { auditedEntries := entry.Data["audited"] invalidEntries := entry.Data["invalid"] - packageCount := entry.Data["num_audited"] - numVulnerable := entry.Data["num_vulnerable"] buildVersion := entry.Data["version"] - if auditedEntries != nil && invalidEntries != nil && packageCount != nil && numVulnerable != nil && buildVersion != nil { + if auditedEntries != nil && invalidEntries != nil && buildVersion != nil { auditedEntries := entry.Data["audited"].(map[string]ossIndexTypes.Coordinate) vulnerableEntries := entry.Data["vulnerable"].(map[string]types.Projects) invalidEntries := entry.Data["invalid"].([]ossIndexTypes.Coordinate) - packageCount := entry.Data["num_audited"].(int) - numVulnerable := entry.Data["num_vulnerable"].(int) var sb strings.Builder @@ -199,9 +195,9 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { t := table.NewWriter() t.SetStyle(table.StyleBold) t.SetTitle("Summary") - t.AppendRow([]interface{}{"Audited Dependencies", strconv.Itoa(packageCount)}) + t.AppendRow([]interface{}{"Audited Dependencies", strconv.Itoa(len(auditedEntries))}) t.AppendSeparator() - t.AppendRow([]interface{}{"Vulnerable Dependencies", au.Bold(au.Red(strconv.Itoa(numVulnerable)))}) + t.AppendRow([]interface{}{"Vulnerable Dependencies", au.Bold(au.Red(strconv.Itoa(len(vulnerableEntries))))}) sb.WriteString(t.Render()) sb.WriteString("\n") From a514a96174cbcad7e9a3281a32f64a6f75006ba4 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:59:53 -0800 Subject: [PATCH 05/11] Fix up CSV --- internal/audit/auditlogtextformatter.go | 3 ++- internal/audit/csvformatter.go | 13 ++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/audit/auditlogtextformatter.go b/internal/audit/auditlogtextformatter.go index 2ebeee45..d018e410 100644 --- a/internal/audit/auditlogtextformatter.go +++ b/internal/audit/auditlogtextformatter.go @@ -155,8 +155,9 @@ func groupAndPrint(vulnerable map[string]types.Projects, nonVulnerable map[strin func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { auditedEntries := entry.Data["audited"] invalidEntries := entry.Data["invalid"] + vulnerableEntries := entry.Data["vulnerable"] buildVersion := entry.Data["version"] - if auditedEntries != nil && invalidEntries != nil && buildVersion != nil { + if auditedEntries != nil && invalidEntries != nil && vulnerableEntries != nil && buildVersion != nil { auditedEntries := entry.Data["audited"].(map[string]ossIndexTypes.Coordinate) vulnerableEntries := entry.Data["vulnerable"].(map[string]types.Projects) invalidEntries := entry.Data["invalid"].([]ossIndexTypes.Coordinate) diff --git a/internal/audit/csvformatter.go b/internal/audit/csvformatter.go index 53fb7974..c6f1241e 100644 --- a/internal/audit/csvformatter.go +++ b/internal/audit/csvformatter.go @@ -39,21 +39,20 @@ func (f CsvFormatter) Format(entry *Entry) ([]byte, error) { // source of the official loggers. auditedEntries := entry.Data["audited"] invalidEntries := entry.Data["invalid"] - packageCount := entry.Data["num_audited"] - numVulnerable := entry.Data["num_vulnerable"] buildVersion := entry.Data["version"] + vulnerableEntries := entry.Data["vulnerable"] - if auditedEntries != nil && invalidEntries != nil && packageCount != nil && numVulnerable != nil && buildVersion != nil { + if auditedEntries != nil && invalidEntries != nil && vulnerableEntries != nil && buildVersion != nil { auditedEntries := entry.Data["audited"].([]types.Coordinate) invalidEntries := entry.Data["invalid"].([]types.Coordinate) - packageCount := entry.Data["num_audited"].(int) - numVulnerable := entry.Data["num_vulnerable"].(int) buildVersion := entry.Data["version"].(string) + numVulnerable := len(vulnerableEntries.(map[string]interface{})) + numPackages := len(auditedEntries) var summaryHeader = []string{"Audited Count", "Vulnerable Count", "Build Version"} var invalidHeader = []string{"Count", "Package", "Reason"} var auditedHeader = []string{"Count", "Package", "Is Vulnerable", "Num Vulnerabilities", "Vulnerabilities"} - var summaryRow = []string{strconv.Itoa(packageCount), strconv.Itoa(numVulnerable), buildVersion} + var summaryRow = []string{strconv.Itoa(numPackages), strconv.Itoa(numVulnerable), buildVersion} var buf bytes.Buffer w := csv.NewWriter(&buf) @@ -105,7 +104,7 @@ func (f CsvFormatter) Format(entry *Entry) ([]byte, error) { auditEntry := auditedEntries[i-1] if auditEntry.IsVulnerable() || !f.Quiet { jsonVulns, _ := json.Marshal(auditEntry.Vulnerabilities) - if err = f.write(w, []string{"[" + strconv.Itoa(i) + "/" + strconv.Itoa(packageCount) + "]", auditEntry.Coordinates, strconv.FormatBool(auditEntry.IsVulnerable()), strconv.Itoa(len(auditEntry.Vulnerabilities)), string(jsonVulns)}); err != nil { + if err = f.write(w, []string{"[" + strconv.Itoa(i) + "/" + strconv.Itoa(numPackages) + "]", auditEntry.Coordinates, strconv.FormatBool(auditEntry.IsVulnerable()), strconv.Itoa(len(auditEntry.Vulnerabilities)), string(jsonVulns)}); err != nil { return nil, err } } From bd7f25286c449500cea77cf7e52b0951465ec318 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Mon, 12 Apr 2021 23:04:37 -0800 Subject: [PATCH 06/11] Add some comments to more rapidly explain what I did --- internal/cmd/root.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 0139263f..b7648cf0 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -458,6 +458,7 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje return } + // Wittle down list of audited to vulnerable stuff, so we can work faster vulnerableCoordinates := make(map[string]types.Projects) for k, v := range ossIndexResponse { if v.IsVulnerable() { @@ -467,9 +468,11 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje } } + // Keep a map of the original purl, and the updated one updatePurls := make([]string, 0, len(coordinates)) updateMatrix := make(map[string]string) + // Go through the vulnerable coordinates and see if there is a newer version of something, if so, let's make a new list of purls to check for k, v := range vulnerableCoordinates { if v.Update != nil { updatePurl := packages.GimmeAPurl(v.Name, v.Update.Version) @@ -479,6 +482,7 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje } } + // You guessed it, check OSS Index if we have any updated libraries to audit, and if we var updateCoordinates map[string]ossIndexTypes.Coordinate if len(updatePurls) > 0 { updateCoordinates, err = ossIndex.Audit(updatePurls) @@ -486,12 +490,15 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje return } + // If the new updated coordinates are not vulnerable, add them to the original map, so we can do something with them for k, v := range updateCoordinates { - originalPurl := updateMatrix[k] - project := vulnerableCoordinates[originalPurl] + if !v.IsVulnerable() { + originalPurl := updateMatrix[k] + project := vulnerableCoordinates[originalPurl] - project.UpdateCoordinate = v - vulnerableCoordinates[originalPurl] = project + project.UpdateCoordinate = v + vulnerableCoordinates[originalPurl] = project + } } } From 9feac53c717280d08e348523f2cbceebf1f477bc Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Mon, 12 Apr 2021 23:06:10 -0800 Subject: [PATCH 07/11] Various --- internal/cmd/root.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/root.go b/internal/cmd/root.go index b7648cf0..61f2c5fe 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -468,7 +468,7 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje } } - // Keep a map of the original purl, and the updated one + // Keep a map of the original purl, and the updated one, set max capacity to the max amount of coordinates we have to look at updatePurls := make([]string, 0, len(coordinates)) updateMatrix := make(map[string]string) @@ -482,7 +482,7 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje } } - // You guessed it, check OSS Index if we have any updated libraries to audit, and if we + // You guessed it, check OSS Index to see if the update purls are good or bad, and only check if we have some to begin with var updateCoordinates map[string]ossIndexTypes.Coordinate if len(updatePurls) > 0 { updateCoordinates, err = ossIndex.Audit(updatePurls) From b07433a16ff54921c8f0470cae26a624cebef078 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Tue, 13 Apr 2021 11:31:57 -0800 Subject: [PATCH 08/11] Update packages/packages.go Co-authored-by: gmohre <1380155+gmohre@users.noreply.github.com> --- packages/packages.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/packages.go b/packages/packages.go index 11c4db50..23fda52d 100644 --- a/packages/packages.go +++ b/packages/packages.go @@ -49,7 +49,7 @@ func convertGopkgNameToPurl(name string) (rename string) { return } -func GimmeAPurl(name string, version string) string { +func gimmeAPURL(name string, version string) string { version = strings.Replace(version, "v", "", -1) version = strings.Replace(version, "+incompatible", "", -1) From 453613bdae9fecc738d05b09bb7cf12251824cc4 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Wed, 14 Apr 2021 00:12:47 -0800 Subject: [PATCH 09/11] Rename Projects to Dependency, and do some refactoring while I am at it --- internal/audit/auditlog.go | 2 +- internal/audit/auditlogtextformatter.go | 12 ++-- internal/cmd/iq.go | 9 ++- internal/cmd/root.go | 37 ++++++----- packages/dep.go | 13 ++-- packages/dep_int_test.go | 77 +++++++++++----------- packages/mod.go | 26 +++----- packages/mod_test.go | 85 ++++++++++++++----------- parse/parse.go | 23 +++---- types/types.go | 9 ++- 10 files changed, 152 insertions(+), 141 deletions(-) diff --git a/internal/audit/auditlog.go b/internal/audit/auditlog.go index 97e0c189..534632c7 100644 --- a/internal/audit/auditlog.go +++ b/internal/audit/auditlog.go @@ -27,7 +27,7 @@ import ( // LogResults will given a number of expected results and the results themselves, log the // results. -func LogResults(formatter log.Formatter, packageCount int, coordinates map[string]ossIndexTypes.Coordinate, invalidCoordinates []ossIndexTypes.Coordinate, vulnerableCoordinates map[string]types.Projects, exclusions []string) int { +func LogResults(formatter log.Formatter, packageCount int, coordinates map[string]ossIndexTypes.Coordinate, invalidCoordinates []ossIndexTypes.Coordinate, vulnerableCoordinates map[string]types.Dependency, exclusions []string) int { if exclusions == nil { exclusions = make([]string, 0) diff --git a/internal/audit/auditlogtextformatter.go b/internal/audit/auditlogtextformatter.go index d018e410..08cbc2b0 100644 --- a/internal/audit/auditlogtextformatter.go +++ b/internal/audit/auditlogtextformatter.go @@ -77,7 +77,7 @@ func logInvalidSemVerWarning(sb *strings.Builder, noColor bool, quiet bool, inva } } -func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Projects) { +func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Dependency) { au := aurora.NewAurora(!noColor) sb.WriteString(fmt.Sprintf( "%s\n%s \n", @@ -136,7 +136,7 @@ func scoreAssessment(score decimal.Decimal) string { return "Low" } -func groupAndPrint(vulnerable map[string]types.Projects, nonVulnerable map[string]ossIndexTypes.Coordinate, quiet bool, noColor bool, sb *strings.Builder) { +func groupAndPrint(vulnerableDependencies map[string]types.Dependency, nonVulnerable map[string]ossIndexTypes.Coordinate, quiet bool, noColor bool, sb *strings.Builder) { if !quiet { sb.WriteString("\n") for _, v := range nonVulnerable { @@ -144,11 +144,11 @@ func groupAndPrint(vulnerable map[string]types.Projects, nonVulnerable map[strin } sb.WriteString(fmt.Sprintf("\n%d Non Vulnerable Packages\n\n", len(nonVulnerable))) } - if len(vulnerable) > 0 { - for _, v := range vulnerable { + if len(vulnerableDependencies) > 0 { + for _, v := range vulnerableDependencies { logVulnerablePackage(sb, noColor, v) } - sb.WriteString(fmt.Sprintf("\n%d Vulnerable Packages\n\n", len(vulnerable))) + sb.WriteString(fmt.Sprintf("\n%d Vulnerable Packages\n\n", len(vulnerableDependencies))) } } @@ -159,7 +159,7 @@ func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { buildVersion := entry.Data["version"] if auditedEntries != nil && invalidEntries != nil && vulnerableEntries != nil && buildVersion != nil { auditedEntries := entry.Data["audited"].(map[string]ossIndexTypes.Coordinate) - vulnerableEntries := entry.Data["vulnerable"].(map[string]types.Projects) + vulnerableEntries := entry.Data["vulnerable"].(map[string]types.Dependency) invalidEntries := entry.Data["invalid"].([]ossIndexTypes.Coordinate) var sb strings.Builder diff --git a/internal/cmd/iq.go b/internal/cmd/iq.go index e694641b..ba9889c2 100644 --- a/internal/cmd/iq.go +++ b/internal/cmd/iq.go @@ -127,14 +127,17 @@ func doIQ(cmd *cobra.Command, args []string) (err error) { func getPurls() (purls []string, err error) { if configOssi.Path != "" { var invalidPurls []string - deps, invalidPurls, err := getPurlsFromPath(configOssi.Path) + deps, err := getPurlsFromPath(configOssi.Path) if err != nil { panic(err) } - for k := range deps { - purls = append(purls, k) + for k, v := range deps { + if v.Valid { + purls = append(purls, k) + } } + invalidCoordinates := convertInvalidPurlsToCoordinates(invalidPurls) logLady.WithField("invalid", invalidCoordinates).Info("") } else { diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 61f2c5fe..6382c544 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -307,7 +307,7 @@ func getIsQuiet() bool { return !configOssi.Loud } -func getPurlsFromPath(path string) (deps map[string]types.Projects, invalidPurls []string, err error) { +func getPurlsFromPath(path string) (deps map[string]types.Dependency, err error) { logLady.Info("Parsing config for file based scan") if !strings.Contains(path, GopkgLockFilename) { err = fmt.Errorf("invalid path value. must point to '%s' file. path: %s", GopkgLockFilename, path) @@ -336,14 +336,15 @@ func getPurlsFromPath(path string) (deps map[string]types.Projects, invalidPurls return } - deps, invalidPurls = packages.ExtractPurlsUsingDep(project) + deps = packages.ExtractPurlsUsingDep(project) + return } func doDepAndParse(ossIndex ossindex.IServer, path string) (err error) { - deps, invalidPurls, err := getPurlsFromPath(path) + deps, err := getPurlsFromPath(path) if err == nil { - if err = checkOSSIndex(ossIndex, deps, invalidPurls); err != nil { + if err = checkOSSIndex(ossIndex, deps); err != nil { return } } @@ -424,33 +425,31 @@ func doStdInAndParse(ossIndex ossindex.IServer) (err error) { return err } - mod := packages.Mod{} - - mods, err := parse.GoListAgnostic(os.Stdin) + dependencies, err := parse.GoListAgnostic(os.Stdin) if err != nil { logLady.Error(err) return } logLady.WithFields(logrus.Fields{ - "projectList": mod.ProjectList, + "dependencies": dependencies, }).Debug("Obtained project list") - var purls = mod.ExtractPurlsFromManifest() - logLady.WithFields(logrus.Fields{ - "purls": purls, - }).Debug("Extracted purls") - logLady.Info("Auditing purls with OSS Index") - err = checkOSSIndex(ossIndex, mods, nil) + err = checkOSSIndex(ossIndex, dependencies) return err } -func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Projects, invalidpurls []string) (err error) { +func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Dependency) (err error) { var packageCount = len(coordinates) purls := make([]string, 0, len(coordinates)) - for k := range coordinates { - purls = append(purls, k) + invalidPurls := make([]string, 0, len(coordinates)) + for k, v := range coordinates { + if v.Valid { + purls = append(purls, k) + } else { + invalidPurls = append(invalidPurls, k) + } } ossIndexResponse, err := ossIndex.Audit(purls) @@ -459,7 +458,7 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje } // Wittle down list of audited to vulnerable stuff, so we can work faster - vulnerableCoordinates := make(map[string]types.Projects) + vulnerableCoordinates := make(map[string]types.Dependency) for k, v := range ossIndexResponse { if v.IsVulnerable() { project := coordinates[k] @@ -502,7 +501,7 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Proje } } - invalidCoordinates := convertInvalidPurlsToCoordinates(invalidpurls) + invalidCoordinates := convertInvalidPurlsToCoordinates(invalidPurls) if count := audit.LogResults(configOssi.Formatter, packageCount, ossIndexResponse, invalidCoordinates, vulnerableCoordinates, configOssi.CveList.Cves); count > 0 { err = customerrors.ErrorExit{ExitCode: count} diff --git a/packages/dep.go b/packages/dep.go index 06022d3c..581dc491 100644 --- a/packages/dep.go +++ b/packages/dep.go @@ -24,7 +24,8 @@ import ( "github.com/sonatype-nexus-community/nancy/types" ) -func ExtractPurlsUsingDep(project *dep.Project) (deps map[string]types.Projects, invalidPurls []string) { +func ExtractPurlsUsingDep(project *dep.Project) (deps map[string]types.Dependency) { + deps = make(map[string]types.Dependency) lockedProjects := project.Lock.P for _, lockedProject := range lockedProjects { @@ -33,20 +34,24 @@ func ExtractPurlsUsingDep(project *dep.Project) (deps map[string]types.Projects, version = strings.Replace(i, "v", "", -1) - if len(version) > 0 { // There must be a version we can use + // There must be a version we can use + if len(version) > 0 { name := lockedProject.Ident().String() packageName := convertGopkgNameToPurl(name) var purl = "pkg:" + packageName + "@" + version _, err := semver.NewVersion(version) if err != nil { - invalidPurls = append(invalidPurls, purl) + dep := types.Dependency{PackageManager: "dep", Name: packageName, Version: version, Valid: false} + + deps[purl] = dep } else { - dep := types.Projects{Name: packageName, Version: version} + dep := types.Dependency{PackageManager: "dep", Name: packageName, Version: version, Valid: true} deps[purl] = dep } } } + return } diff --git a/packages/dep_int_test.go b/packages/dep_int_test.go index e00a77d7..6fc02a2b 100644 --- a/packages/dep_int_test.go +++ b/packages/dep_int_test.go @@ -18,13 +18,15 @@ package packages import ( "fmt" - "github.com/Flaque/filet" - "github.com/golang/dep" - "github.com/stretchr/testify/require" "io/ioutil" "log" "os" "testing" + + "github.com/Flaque/filet" + "github.com/golang/dep" + "github.com/sonatype-nexus-community/nancy/types" + "github.com/stretchr/testify/require" ) func TestExtractPurlsFromManifestUsingDep(t *testing.T) { @@ -41,33 +43,45 @@ func TestExtractPurlsFromManifestUsingDep(t *testing.T) { project, err2 := ctx.LoadProject() require.NoError(t, err2) - purls, invalidPurls := ExtractPurlsUsingDep(project) - if len(invalidPurls) != 7 { - t.Errorf("Number of invalid purls not as expected. Expected : %d, Got %d", 7, len(purls)) + results := ExtractPurlsUsingDep(project) + if len(results) != 14 { + t.Errorf("Number of invalid purls not as expected. Expected : %d, Got %d", 14, len(results)) } - if len(purls) != 7 { - t.Errorf("Number of purls not as expected. Expected : %d, Got %d", 7, len(purls)) + + expectedInvalidPurls := []string{ + "pkg:golang/github.com/Masterminds/semver@2.x", + "pkg:golang/github.com/armon/go-radix@master", + "pkg:golang/github.com/nightlyone/lockfile@master", + "pkg:golang/github.com/sdboyer/constext@master", + "pkg:golang/golang.org/x/net@master", + "pkg:golang/golang.org/x/sync@master", + "pkg:golang/golang.org/x/sys@master", + } + + expectedValidPurls := []string{ + "pkg:golang/github.com/go-yaml/yaml@2", + "pkg:golang/github.com/Masterminds/vcs@1.11.1", + "pkg:golang/github.com/boltdb/bolt@1.3.1", + "pkg:golang/github.com/golang/protobuf@1.0.0", + "pkg:golang/github.com/jmank88/nuts@0.3.0", + "pkg:golang/github.com/pelletier/go-toml@1.2.0", + "pkg:golang/github.com/pkg/errors@0.8.0", } - assertPurlFound("pkg:golang/github.com/Masterminds/semver@2.x", invalidPurls, t) - assertPurlFound("pkg:golang/github.com/armon/go-radix@master", invalidPurls, t) - assertPurlFound("pkg:golang/github.com/nightlyone/lockfile@master", invalidPurls, t) - assertPurlFound("pkg:golang/github.com/sdboyer/constext@master", invalidPurls, t) - assertPurlFound("pkg:golang/golang.org/x/net@master", invalidPurls, t) - assertPurlFound("pkg:golang/golang.org/x/sync@master", invalidPurls, t) - assertPurlFound("pkg:golang/golang.org/x/sys@master", invalidPurls, t) - assertPurlFound("pkg:golang/github.com/go-yaml/yaml@2", purls, t) - assertPurlFound("pkg:golang/github.com/Masterminds/vcs@1.11.1", purls, t) - assertPurlFound("pkg:golang/github.com/boltdb/bolt@1.3.1", purls, t) - assertPurlFound("pkg:golang/github.com/golang/protobuf@1.0.0", purls, t) - assertPurlFound("pkg:golang/github.com/jmank88/nuts@0.3.0", purls, t) - assertPurlFound("pkg:golang/github.com/pelletier/go-toml@1.2.0", purls, t) - assertPurlFound("pkg:golang/github.com/pkg/errors@0.8.0", purls, t) + assertPurlsFound(expectedValidPurls, expectedInvalidPurls, results, t) } -func assertPurlFound(expectedPurl string, result []string, t *testing.T) { - if !inArray(expectedPurl, result) { - t.Errorf("Expected purl %s not found. List of purls was %s", expectedPurl, result) +func assertPurlsFound(expectedPurls []string, invalidPurls []string, results map[string]types.Dependency, t *testing.T) { + for _, v := range expectedPurls { + if val, ok := results[v]; !ok || !val.Valid { + t.Errorf("Expected purl %s not found. List of purls was %v", v, results) + } + } + + for _, v := range invalidPurls { + if val, ok := results[v]; !ok || val.Valid { + t.Errorf("Expected invalid purl %s not found. List of purls was %v", v, results) + } } } @@ -111,16 +125,3 @@ func doGoPathSimulatedSetup(t *testing.T) (string, string, error) { } return path, projectDir, e } - -func inArray(val string, array []string) (exists bool) { - exists = false - - for _, v := range array { - if val == v { - exists = true - return - } - } - - return -} diff --git a/packages/mod.go b/packages/mod.go index 95e6dc50..52533c5d 100644 --- a/packages/mod.go +++ b/packages/mod.go @@ -23,18 +23,10 @@ import ( "github.com/sonatype-nexus-community/nancy/types" ) -type Mod struct { - ProjectList types.ProjectList - GoSumPath string -} - -func (m Mod) ExtractPurlsFromManifest() []string { - return removeDuplicates(m.extractPurls(m.ProjectList)) -} - -func (m Mod) extractPurls(mods types.ProjectList) (purls []string) { - for _, s := range m.ProjectList.Projects { - if len(s.Version) > 0 { // There must be a version we can use +func ExtractGoModPurls(mods []types.Dependency) (purls []string) { + for _, s := range mods { + // There must be a version we can use + if len(s.Version) > 0 { // OSS Index no likey v before version, IQ does though, comment left so I will never forget. // go-sona-types library now takes care of querying both ossi and iq with reformatted purls as needed (to v or not to v). version := strings.Replace(s.Version, "v", "", -1) @@ -47,15 +39,15 @@ func (m Mod) extractPurls(mods types.ProjectList) (purls []string) { return } -func (m Mod) ExtractUpdatePurls(vulnerable map[string]ossIndexTypes.Coordinate) (purls []string) { - projectsWithUpdate := types.ProjectList{} - for _, s := range m.ProjectList.Projects { +func ExtractGoModUpdatePurls(vulnerable map[string]ossIndexTypes.Coordinate, deps []types.Dependency) (purls []string) { + projectsWithUpdate := []types.Dependency{} + for _, s := range deps { if s.Update != nil { - projectsWithUpdate.Projects = append(projectsWithUpdate.Projects, s) + projectsWithUpdate = append(projectsWithUpdate, s) } } - return removeDuplicates(m.extractPurls(projectsWithUpdate)) + return removeDuplicates(ExtractGoModPurls(projectsWithUpdate)) } func removeDuplicates(purls []string) (dedupedPurls []string) { diff --git a/packages/mod_test.go b/packages/mod_test.go index 50ac2ac2..52b89b82 100644 --- a/packages/mod_test.go +++ b/packages/mod_test.go @@ -22,60 +22,71 @@ import ( "github.com/sonatype-nexus-community/nancy/types" ) +type dependency struct { + name string + version string +} + // Simulate calling parse.GopkgLock() -func getProjectList() (projectList types.ProjectList) { - appendProject("github.com/AndreasBriese/bbloom", "", &projectList) - appendProject("gopkg.in/BurntSushi/toml", "v0.3.1", &projectList) - appendProject("github.com/dgraph-io/badger", "v1.5.4", &projectList) - appendProject("github.com/dgryski/go-farm", "", &projectList) - appendProject("github.com/golang/protobuf", "v1.2.0", &projectList) - appendProject("github.com/logrusorgru/aurora", "", &projectList) - appendProject("github.com/pkg/errors", "v0.8.0", &projectList) - appendProject("github.com/shopspring/decimal", "1.1.0", &projectList) - appendProject("golang.org/x/net", "", &projectList) - appendProject("golang.org/x/sys", "", &projectList) +func getDependencyList() (dependencies []types.Dependency) { + deps := []dependency{ + {name: "github.com/AndreasBriese/bbloom", version: ""}, + {name: "gopkg.in/BurntSushi/toml", version: "v0.3.1"}, + {name: "github.com/dgraph-io/badger", version: "v1.5.4"}, + {name: "github.com/dgryski/go-farm", version: ""}, + {name: "github.com/golang/protobuf", version: "v1.2.0"}, + {name: "github.com/logrusorgru/aurora", version: ""}, + {name: "github.com/pkg/errors", version: "0.8.0"}, + {name: "github.com/shopspring/decimal", version: "1.1.0"}, + {name: "golang.org/x/net", version: ""}, + {name: "golang.org/x/sys", version: ""}, + } - return projectList + return appendDependencies(deps) } -func getProjectListDuplicates() (projectList types.ProjectList) { - appendProject("github.com/AndreasBriese/bbloom", "", &projectList) - appendProject("gopkg.in/BurntSushi/toml", "v0.3.1", &projectList) - appendProject("github.com/dgraph-io/badger", "v1.5.4", &projectList) - appendProject("github.com/dgraph-io/badger", "v1.5.4", &projectList) - appendProject("gopkg.in/dgraph-io/badger", "v1.5.4", &projectList) - appendProject("github.com/dgryski/go-farm", "", &projectList) - appendProject("github.com/golang/protobuf", "v1.2.0", &projectList) - appendProject("github.com/golang/protobuf", "v1.2.0", &projectList) - appendProject("github.com/golang/protobuf", "v1.2.0", &projectList) - appendProject("github.com/logrusorgru/aurora", "", &projectList) - appendProject("github.com/pkg/errors", "v0.8.0", &projectList) - appendProject("github.com/shopspring/decimal", "1.1.0", &projectList) - appendProject("golang.org/x/net", "", &projectList) - appendProject("golang.org/x/sys", "", &projectList) +func appendDependencies(deps []dependency) (dependencies []types.Dependency) { + for _, v := range deps { + dependencies = append(dependencies, types.Dependency{Name: v.name, Version: v.version}) + } - return projectList + return } -func appendProject(name string, version string, projectList *types.ProjectList) { - projectList.Projects = append(projectList.Projects, types.Projects{Name: name, Version: version}) +func getProjectListDuplicates() (dependencies []types.Dependency) { + deps := []dependency{ + {name: "github.com/AndreasBriese/bbloom", version: ""}, + {name: "gopkg.in/BurntSushi/toml", version: "v0.3.1"}, + {name: "github.com/dgraph-io/badger", version: "v1.5.4"}, + {name: "github.com/dgraph-io/badger", version: "v1.5.4"}, + {name: "gopkg.in/dgraph-io/badger", version: "v1.5.4"}, + {name: "github.com/dgryski/go-farm", version: ""}, + {name: "github.com/golang/protobuf", version: "v1.2.0"}, + {name: "github.com/golang/protobuf", version: "v1.2.0"}, + {name: "github.com/golang/protobuf", version: "v1.2.0"}, + {name: "github.com/logrusorgru/aurora", version: ""}, + {name: "github.com/pkg/errors", version: "v0.8.0"}, + {name: "github.com/shopspring/decimal", version: "1.1.0"}, + {name: "golang.org/x/net", version: ""}, + {name: "golang.org/x/sys", version: ""}, + } + + return appendDependencies(deps) } -func TestModExtractPurlsFromManifest(t *testing.T) { - mod := Mod{} - mod.ProjectList = getProjectList() +func TestModExtractGoModPurls(t *testing.T) { + deps := getDependencyList() - result := mod.ExtractPurlsFromManifest() + result := ExtractGoModPurls(deps) if len(result) != 5 { t.Error(result) } } func TestModExtractPurlsFromManifestDuplicates(t *testing.T) { - mod := Mod{} - mod.ProjectList = getProjectListDuplicates() + deps := getProjectListDuplicates() - result := mod.ExtractPurlsFromManifest() + result := ExtractGoModPurls(deps) if len(result) != 5 { t.Error(result) } diff --git a/parse/parse.go b/parse/parse.go index b25398db..1e20686a 100644 --- a/parse/parse.go +++ b/parse/parse.go @@ -35,14 +35,14 @@ var goListDependencyCriteria = func(s []string) bool { // GoListAgnostic will take a io.Reader that is likely the os.StdIn, try to parse it as // if `go list -json -m all` was ran, and then try to reparse it as if `go list -m all` // was ran instead. It returns either an error, or a deps of types.ProjectList -func GoListAgnostic(stdIn io.Reader) (deps map[string]types.Projects, err error) { - deps = make(map[string]types.Projects) +func GoListAgnostic(stdIn io.Reader) (dependencies map[string]types.Dependency, err error) { + dependencies = make(map[string]types.Dependency) // stdIn should never be massive, so taking this approach over reading from a stream // multiple times johnnyFiveNeedInput, err := ioutil.ReadAll(stdIn) if err != nil { - return deps, err + return } decoder := json.NewDecoder(strings.NewReader(string(johnnyFiveNeedInput))) @@ -62,7 +62,7 @@ func GoListAgnostic(stdIn io.Reader) (deps map[string]types.Projects, err error) if _, ok := err.(*NoVersionError); ok { continue } - deps[packages.GimmeAPurl(dep.Name, dep.Version)] = dep + dependencies[packages.GimmeAPurl(dep.Name, dep.Version)] = dep } if err != nil { @@ -72,7 +72,7 @@ func GoListAgnostic(stdIn io.Reader) (deps map[string]types.Projects, err error) for scanner.Scan() { dep := parseSpaceSeparatedDependency(scanner, goListDependencyCriteria) if dep != nil { - deps[packages.GimmeAPurl(dep.Name, dep.Version)] = *dep + dependencies[packages.GimmeAPurl(dep.Name, dep.Version)] = *dep } } @@ -84,7 +84,7 @@ func GoListAgnostic(stdIn io.Reader) (deps map[string]types.Projects, err error) return } -func modToProjectList(mod types.GoListModule) (dep types.Projects, err error) { +func modToProjectList(mod types.GoListModule) (dep types.Dependency, err error) { if mod.Replace != nil { if mod.Replace.Version == "" { err = &NoVersionError{err: fmt.Errorf("no version found for mod")} @@ -105,7 +105,7 @@ func modToProjectList(mod types.GoListModule) (dep types.Projects, err error) { return } -func populateMod(mod types.GoListModule, name string, version string) (dep types.Projects) { +func populateMod(mod types.GoListModule, name string, version string) (dep types.Dependency) { if mod.Update != nil { dep.Update = &types.ProjectUpdate{ Path: mod.Update.Path, @@ -113,13 +113,14 @@ func populateMod(mod types.GoListModule, name string, version string) (dep types Time: *mod.Update.Time, } } + dep.Valid = true dep.Name = name dep.Version = version return } -func parseSpaceSeparatedDependency(scanner *bufio.Scanner, criteria func(s []string) bool) (dep *types.Projects) { +func parseSpaceSeparatedDependency(scanner *bufio.Scanner, criteria func(s []string) bool) (dep *types.Dependency) { text := scanner.Text() rewrite := strings.Split(text, "=>") @@ -132,12 +133,12 @@ func parseSpaceSeparatedDependency(scanner *bufio.Scanner, criteria func(s []str return addProjectDep(criteria, s) } -func addProjectDep(criteria func(s []string) bool, s []string) (dep *types.Projects) { +func addProjectDep(criteria func(s []string) bool, s []string) (dep *types.Dependency) { if criteria(s) { if len(s) > 3 { - return &types.Projects{Name: s[0], Version: s[4]} + return &types.Dependency{Valid: true, Name: s[0], Version: s[4]} } else { - return &types.Projects{Name: s[0], Version: s[1]} + return &types.Dependency{Valid: true, Name: s[0], Version: s[1]} } } diff --git a/types/types.go b/types/types.go index e7052854..cfd33d25 100644 --- a/types/types.go +++ b/types/types.go @@ -61,7 +61,10 @@ type Configuration struct { SkipUpdateCheck bool } -type Projects struct { +type Dependency struct { + PackageManager string + Purl string + Valid bool Name string Version string Update *ProjectUpdate @@ -75,10 +78,6 @@ type ProjectUpdate struct { Time time.Time } -type ProjectList struct { - Projects []Projects -} - type CveListFlag struct { Cves []string } From af2d3f2d2c23265190d8bc471858511aa1127cff Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Wed, 14 Apr 2021 00:15:32 -0800 Subject: [PATCH 10/11] Turns out this DOES need to be public, at least for now --- internal/cmd/root.go | 2 +- packages/packages.go | 2 +- parse/parse.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 6382c544..771e87b7 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -474,7 +474,7 @@ func checkOSSIndex(ossIndex ossindex.IServer, coordinates map[string]types.Depen // Go through the vulnerable coordinates and see if there is a newer version of something, if so, let's make a new list of purls to check for k, v := range vulnerableCoordinates { if v.Update != nil { - updatePurl := packages.GimmeAPurl(v.Name, v.Update.Version) + updatePurl := packages.GimmeAPURL(v.Name, v.Update.Version) updateMatrix[updatePurl] = k updatePurls = append(updatePurls, updatePurl) diff --git a/packages/packages.go b/packages/packages.go index 23fda52d..399fc567 100644 --- a/packages/packages.go +++ b/packages/packages.go @@ -49,7 +49,7 @@ func convertGopkgNameToPurl(name string) (rename string) { return } -func gimmeAPURL(name string, version string) string { +func GimmeAPURL(name string, version string) string { version = strings.Replace(version, "v", "", -1) version = strings.Replace(version, "+incompatible", "", -1) diff --git a/parse/parse.go b/parse/parse.go index 1e20686a..cb085de2 100644 --- a/parse/parse.go +++ b/parse/parse.go @@ -62,7 +62,7 @@ func GoListAgnostic(stdIn io.Reader) (dependencies map[string]types.Dependency, if _, ok := err.(*NoVersionError); ok { continue } - dependencies[packages.GimmeAPurl(dep.Name, dep.Version)] = dep + dependencies[packages.GimmeAPURL(dep.Name, dep.Version)] = dep } if err != nil { @@ -72,7 +72,7 @@ func GoListAgnostic(stdIn io.Reader) (dependencies map[string]types.Dependency, for scanner.Scan() { dep := parseSpaceSeparatedDependency(scanner, goListDependencyCriteria) if dep != nil { - dependencies[packages.GimmeAPurl(dep.Name, dep.Version)] = *dep + dependencies[packages.GimmeAPURL(dep.Name, dep.Version)] = *dep } } From e9e94b0150335ad939cbd6216c7bfc96c81afab7 Mon Sep 17 00:00:00 2001 From: Jeffry Hesse <5544326+DarthHater@users.noreply.github.com> Date: Wed, 14 Apr 2021 00:27:21 -0800 Subject: [PATCH 11/11] Fix tests, more to go --- internal/cmd/iq.go | 32 ++++++++++++++------------------ internal/cmd/iq_test.go | 8 ++++---- internal/cmd/root_test.go | 10 ++++++++++ 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/internal/cmd/iq.go b/internal/cmd/iq.go index ba9889c2..b054e930 100644 --- a/internal/cmd/iq.go +++ b/internal/cmd/iq.go @@ -108,10 +108,9 @@ func doIQ(cmd *cobra.Command, args []string) (err error) { printHeader(!configOssi.Quiet) - var purls []string - purls, err = getPurls() + dependencies, err := getDependencies() - err = auditWithIQServer(purls) + err = auditWithIQServer(dependencies) if err != nil { if errExit, ok := err.(customerrors.ErrorExit); ok { os.Exit(errExit.ExitCode) @@ -124,20 +123,14 @@ func doIQ(cmd *cobra.Command, args []string) (err error) { return } -func getPurls() (purls []string, err error) { +func getDependencies() (dependencies map[string]types.Dependency, err error) { if configOssi.Path != "" { var invalidPurls []string - deps, err := getPurlsFromPath(configOssi.Path) + dependencies, err = getPurlsFromPath(configOssi.Path) if err != nil { panic(err) } - for k, v := range deps { - if v.Valid { - purls = append(purls, k) - } - } - invalidCoordinates := convertInvalidPurlsToCoordinates(invalidPurls) logLady.WithField("invalid", invalidCoordinates).Info("") } else { @@ -146,17 +139,14 @@ func getPurls() (purls []string, err error) { panic(err) } - deps, err := parse.GoListAgnostic(os.Stdin) + dependencies, err = parse.GoListAgnostic(os.Stdin) if err != nil { logLady.WithError(err).Error("unexpected error in iq cmd") panic(err) } - - for k := range deps { - purls = append(purls, k) - } } - return purls, err + + return dependencies, err } const ( @@ -237,10 +227,16 @@ func initIQConfig() { } } -func auditWithIQServer(purls []string) error { +func auditWithIQServer(dependencies map[string]types.Dependency) error { iqServer := iqCreator.create() logLady.Debug("Sending purls to be Audited by IQ Server") + + var purls []string + for k := range dependencies { + purls = append(purls, k) + } + // go-sona-types library now takes care of querying both ossi and iq with reformatted purls as needed (to v or not to v). res, err := iqServer.AuditPackages(purls) if err != nil { diff --git a/internal/cmd/iq_test.go b/internal/cmd/iq_test.go index a84eb5b5..3be3db15 100644 --- a/internal/cmd/iq_test.go +++ b/internal/cmd/iq_test.go @@ -164,9 +164,9 @@ func TestInitIQConfigWithNoConfigFile(t *testing.T) { assert.Equal(t, "", viper.GetString(configuration.ViperKeyIQServer)) } -var testPurls = []string{ - "pkg:golang/github.com/go-yaml/yaml@v2.2.2", - "pkg:golang/golang.org/x/crypto@v0.0.0-20190308221718-c2843e01d9a2", +var testDependenciesMap = map[string]types.Dependency{ + "pkg:golang/github.com/go-yaml/yaml@v2.2.2": {Valid: true, Name: "github.com/go-yaml/yaml", Version: "v2.2.2"}, + "pkg:golang/golang.org/x/crypto@v0.0.0-20190308221718-c2843e01d9a2": {Valid: true, Name: "golang.org/x/crypto", Version: "v0.0.0-20190308221718-c2843e01d9a2"}, } type iqFactoryMock struct { @@ -205,7 +205,7 @@ func TestAuditWithIQServerAuditPackagesError(t *testing.T) { expectedErr := fmt.Errorf("forced error") iqCreator = &iqFactoryMock{mockIqServer: mockIqServer{auditPackagesErr: expectedErr}} - err := auditWithIQServer(testPurls) + err := auditWithIQServer(testDependenciesMap) assert.Error(t, err) assert.Equal(t, expectedErr, err) diff --git a/internal/cmd/root_test.go b/internal/cmd/root_test.go index d43713e1..f980a78c 100644 --- a/internal/cmd/root_test.go +++ b/internal/cmd/root_test.go @@ -403,6 +403,16 @@ type mockOssiServer struct { func (s mockOssiServer) AuditPackages(purls []string) ([]ossIndexTypes.Coordinate, error) { return s.auditPackagesResults, s.auditPackagesErr } + +func (s mockOssiServer) Audit(purls []string) (map[string]ossIndexTypes.Coordinate, error) { + deps := make(map[string]ossIndexTypes.Coordinate) + for _, v := range s.auditPackagesResults { + deps[v.Coordinates] = v + } + + return deps, s.auditPackagesErr +} + func (s mockOssiServer) NoCacheNoProblems() error { return s.auditPackagesErr }