@@ -13,6 +13,9 @@ import (
13
13
"github.com/quay/zlog"
14
14
15
15
"github.com/quay/claircore"
16
+ "github.com/quay/claircore/libvuln/driver"
17
+ _ "github.com/quay/claircore/matchers/defaults"
18
+ "github.com/quay/claircore/matchers/registry"
16
19
)
17
20
18
21
var (
@@ -39,71 +42,71 @@ var (
39
42
)
40
43
)
41
44
42
- func queryBuilder (v * claircore.Vulnerability , vp claircore. CheckVulnerablePipeline ) (string , error ) {
45
+ func queryBuilder (v * claircore.Vulnerability , m driver. Matcher ) (string , error ) {
43
46
psql := goqu .Dialect ("postgres" )
44
47
exps := []goqu.Expression {}
45
48
packageQuery := goqu.Ex {"package.name" : v .Package .Name }
46
49
exps = append (exps , packageQuery )
47
- seen := make (map [claircore .MatchConstraint ]struct {})
48
- for _ , m := range vp .Query () {
50
+ seen := make (map [driver .MatchConstraint ]struct {})
51
+ for _ , m := range m .Query () {
49
52
if _ , ok := seen [m ]; ok {
50
53
continue
51
54
}
52
55
var ex goqu.Ex
53
56
switch m {
54
- case claircore .PackageModule :
57
+ case driver .PackageModule :
55
58
ex = goqu.Ex {"package.module" : v .Package .Module }
56
- case claircore .DistributionDID :
59
+ case driver .DistributionDID :
57
60
if v .Dist .DID == "" {
58
61
return "" , ErrVulnNotApplicable
59
62
}
60
63
ex = goqu.Ex {"dist.did" : v .Dist .DID }
61
- case claircore .DistributionName :
64
+ case driver .DistributionName :
62
65
if v .Dist .Name == "" {
63
66
return "" , ErrVulnNotApplicable
64
67
}
65
68
ex = goqu.Ex {"dist.name" : v .Dist .Name }
66
- case claircore .DistributionVersionID :
69
+ case driver .DistributionVersionID :
67
70
if v .Dist .VersionID == "" {
68
71
return "" , ErrVulnNotApplicable
69
72
}
70
73
ex = goqu.Ex {"dist.version_id" : v .Dist .VersionID }
71
- case claircore .DistributionVersion :
74
+ case driver .DistributionVersion :
72
75
if v .Dist .Version == "" {
73
76
return "" , ErrVulnNotApplicable
74
77
}
75
78
ex = goqu.Ex {"dist.version" : v .Dist .Version }
76
- case claircore .DistributionVersionCodeName :
79
+ case driver .DistributionVersionCodeName :
77
80
if v .Dist .VersionCodeName == "" {
78
81
return "" , ErrVulnNotApplicable
79
82
}
80
83
ex = goqu.Ex {"dist.version_code_name" : v .Dist .VersionCodeName }
81
- case claircore .DistributionPrettyName :
84
+ case driver .DistributionPrettyName :
82
85
if v .Dist .PrettyName == "" {
83
86
return "" , ErrVulnNotApplicable
84
87
}
85
88
ex = goqu.Ex {"dist.pretty_name" : v .Dist .PrettyName }
86
- case claircore .DistributionCPE :
89
+ case driver .DistributionCPE :
87
90
if v .Dist .CPE .String () == "" {
88
91
return "" , ErrVulnNotApplicable
89
92
}
90
93
ex = goqu.Ex {"dist.cpe" : v .Dist .CPE }
91
- case claircore .DistributionArch :
94
+ case driver .DistributionArch :
92
95
if v .Dist .Arch == "" {
93
96
return "" , ErrVulnNotApplicable
94
97
}
95
98
ex = goqu.Ex {"dist.arch" : v .Dist .Arch }
96
- case claircore .RepositoryName :
99
+ case driver .RepositoryName :
97
100
if v .Repo .Name == "" {
98
101
return "" , ErrVulnNotApplicable
99
102
}
100
103
ex = goqu.Ex {"repo.name" : v .Repo .Name }
101
- case claircore .RepositoryKey :
104
+ case driver .RepositoryKey :
102
105
if v .Repo .Key == "" {
103
106
return "" , ErrVulnNotApplicable
104
107
}
105
108
ex = goqu.Ex {"repo.key" : v .Repo .Key }
106
- case claircore .HasFixedInVersion :
109
+ case driver .HasFixedInVersion :
107
110
if v .FixedInVersion == "" {
108
111
// No unpatched vulnerabilities wanted
109
112
return "" , ErrVulnNotApplicable
@@ -114,7 +117,8 @@ func queryBuilder(v *claircore.Vulnerability, vp claircore.CheckVulnerablePipeli
114
117
exps = append (exps , ex )
115
118
seen [m ] = struct {}{}
116
119
}
117
- if vp .VersionAuthoritative != nil {
120
+ f , ok := m .(driver.VersionFilter )
121
+ if ok && f .VersionAuthoritative () {
118
122
kind , lower , upper := rangefmt (v .Range )
119
123
if kind != nil {
120
124
exps = append (exps , goqu .And (
@@ -156,100 +160,108 @@ func queryBuilder(v *claircore.Vulnerability, vp claircore.CheckVulnerablePipeli
156
160
return sql , nil
157
161
}
158
162
159
- func (s * IndexerStore ) AffectedManifests (ctx context.Context , v claircore.Vulnerability , vps []claircore.CheckVulnerablePipeline ) ([]claircore.Digest , error ) {
163
+ func (s * IndexerStore ) AffectedManifests (ctx context.Context , v claircore.Vulnerability ) ([]claircore.Digest , error ) {
164
+ matcherFactories := registry .Registered ()
160
165
ctx = zlog .ContextWithValues (ctx , "component" , "datastore/postgres/AffectedManifests" )
161
166
mrs := map [string ]struct {}{}
162
167
out := []claircore.Digest {}
163
- for _ , vp := range vps {
164
- miQuery , err := queryBuilder (& v , vp )
165
- switch {
166
- case errors .Is (err , nil ):
167
- case errors .Is (err , ErrVulnNotApplicable ):
168
- continue
169
- default :
170
- return nil , fmt .Errorf ("error building query %w" , err )
168
+ for n , mf := range matcherFactories {
169
+ ms , err := mf .Matcher (ctx )
170
+ if err != nil {
171
+ return nil , fmt .Errorf ("failed to create matchers from factory %s: %w" , n , err )
171
172
}
172
- err = func () error {
173
- start := time .Now ()
174
- rows , err := s .pool .Query (ctx , miQuery )
173
+ for _ , m := range ms {
174
+ miQuery , err := queryBuilder (& v , m )
175
175
switch {
176
176
case errors .Is (err , nil ):
177
+ case errors .Is (err , ErrVulnNotApplicable ):
178
+ continue
177
179
default :
178
- return fmt .Errorf ("failed to query packages associated with vulnerability %q: %w" , v . ID , err )
180
+ return nil , fmt .Errorf ("error building query %w" , err )
179
181
}
180
-
181
- defer rows . Close ()
182
- for rows . Next () {
183
- ir := & claircore. IndexRecord {
184
- Package : & claircore. Package {},
185
- Repository : & claircore. Repository {},
186
- Distribution : & claircore. Distribution {},
182
+ err = func () error {
183
+ start := time . Now ()
184
+ rows , err := s . pool . Query ( ctx , miQuery )
185
+ switch {
186
+ case errors . Is ( err , nil ):
187
+ default :
188
+ return fmt . Errorf ( "failed to query packages associated with vulnerability %q: %w" , v . ID , err )
187
189
}
188
- var (
189
- manifestDigest * claircore.Digest
190
- nVer pgtype.Int4Array
191
- nKind * string
192
- )
193
- err := rows .Scan (
194
- & manifestDigest ,
195
- & ir .Package .Name ,
196
- & ir .Package .Version ,
197
- & ir .Package .Kind ,
198
- & nKind ,
199
- & nVer ,
200
- & ir .Package .Arch ,
201
- & ir .Distribution .Name ,
202
- & ir .Distribution .DID ,
203
- & ir .Distribution .Version ,
204
- & ir .Distribution .VersionCodeName ,
205
- & ir .Distribution .VersionID ,
206
- & ir .Distribution .Arch ,
207
- & ir .Distribution .CPE ,
208
- & ir .Distribution .PrettyName ,
209
- & ir .Repository .Name ,
210
- & ir .Repository .Key ,
211
- & ir .Repository .URI ,
212
- & ir .Repository .CPE ,
213
- )
214
- if err != nil {
215
- return fmt .Errorf ("failed to scan index record: %w" , err )
216
- }
217
- if nKind != nil {
218
- ir .Package .NormalizedVersion .Kind = * nKind
219
- for i , n := range nVer .Elements {
220
- ir .Package .NormalizedVersion .V [i ] = n .Int
190
+
191
+ defer rows .Close ()
192
+ for rows .Next () {
193
+ ir := & claircore.IndexRecord {
194
+ Package : & claircore.Package {},
195
+ Repository : & claircore.Repository {},
196
+ Distribution : & claircore.Distribution {},
221
197
}
222
- }
223
- if _ , ok := mrs [manifestDigest .String ()]; ok {
224
- // We've already seen the manifest we don't need to
225
- // redo the work.
226
- continue
227
- }
228
- if ! vp .Filter (ir ) {
229
- continue
230
- }
231
- var match bool
232
- if vp .VersionAuthoritative != nil && vp .VersionAuthoritative () {
233
- // We've already done the vulnerable checking so don't need
234
- // to call the Vulnerable() function.
235
- match = true
236
- } else {
237
- match , err = vp .Vulnernable (ctx , ir , & v )
198
+ var (
199
+ manifestDigest * claircore.Digest
200
+ nVer pgtype.Int4Array
201
+ nKind * string
202
+ )
203
+ err := rows .Scan (
204
+ & manifestDigest ,
205
+ & ir .Package .Name ,
206
+ & ir .Package .Version ,
207
+ & ir .Package .Kind ,
208
+ & nKind ,
209
+ & nVer ,
210
+ & ir .Package .Arch ,
211
+ & ir .Distribution .Name ,
212
+ & ir .Distribution .DID ,
213
+ & ir .Distribution .Version ,
214
+ & ir .Distribution .VersionCodeName ,
215
+ & ir .Distribution .VersionID ,
216
+ & ir .Distribution .Arch ,
217
+ & ir .Distribution .CPE ,
218
+ & ir .Distribution .PrettyName ,
219
+ & ir .Repository .Name ,
220
+ & ir .Repository .Key ,
221
+ & ir .Repository .URI ,
222
+ & ir .Repository .CPE ,
223
+ )
238
224
if err != nil {
239
- return fmt .Errorf ("error checking for if IndexRecord is vulnerable %w" , err )
225
+ return fmt .Errorf ("failed to scan index record: %w" , err )
226
+ }
227
+ if nKind != nil {
228
+ ir .Package .NormalizedVersion .Kind = * nKind
229
+ for i , n := range nVer .Elements {
230
+ ir .Package .NormalizedVersion .V [i ] = n .Int
231
+ }
232
+ }
233
+ if _ , ok := mrs [manifestDigest .String ()]; ok {
234
+ // We've already seen the manifest we don't need to
235
+ // redo the work.
236
+ continue
237
+ }
238
+ if ! m .Filter (ir ) {
239
+ continue
240
+ }
241
+ var match bool
242
+ f , ok := m .(driver.VersionFilter )
243
+ if ok && f .VersionAuthoritative () {
244
+ // We've already done the vulnerable checking so don't need
245
+ // to call the Vulnerable() function.
246
+ match = true
247
+ } else {
248
+ match , err = m .Vulnerable (ctx , ir , & v )
249
+ if err != nil {
250
+ return fmt .Errorf ("error checking for if IndexRecord is vulnerable %w" , err )
251
+ }
252
+ }
253
+ if match {
254
+ mrs [manifestDigest .String ()] = struct {}{}
255
+ out = append (out , * manifestDigest )
240
256
}
241
257
}
242
- if match {
243
- mrs [manifestDigest .String ()] = struct {}{}
244
- out = append (out , * manifestDigest )
245
- }
258
+ getAffectedManifestsCounter .WithLabelValues ("query_batch" ).Add (1 )
259
+ getAffectedManifestsDuration .WithLabelValues ("query_batch" ).Observe (time .Since (start ).Seconds ())
260
+ return nil
261
+ }()
262
+ if err != nil {
263
+ return nil , err
246
264
}
247
- getAffectedManifestsCounter .WithLabelValues ("query_batch" ).Add (1 )
248
- getAffectedManifestsDuration .WithLabelValues ("query_batch" ).Observe (time .Since (start ).Seconds ())
249
- return nil
250
- }()
251
- if err != nil {
252
- return nil , err
253
265
}
254
266
}
255
267
return out , nil
0 commit comments