Conversation
4fef4e2 to
e80755d
Compare
There was a problem hiding this comment.
In two minds about adding local fixtures, they do test functionality and result correctness without needing external deps, but they are sort of a collection of real and fake data. I might just clean it up to a couple of examples.
|
|
||
| // Detect RHEL VEX documents by publisher namespace and use the specialised parser. | ||
| // RHEL VEX has complex product relationships and CPE-based repository matching. | ||
| if c.Document.Publisher.Namespace == "https://www.redhat.com" { |
There was a problem hiding this comment.
I think this is strong enough, but other suggestions welcome
There was a problem hiding this comment.
Feels bad that we need special Red Hat handling :/
| vulns = append(vulns, vs...) | ||
| } | ||
|
|
||
| // TODO(crozzy): Process known_not_affected products here |
There was a problem hiding this comment.
Might need to sync a little here with the not affected work
| type Auditor interface { | ||
| // Audit analyses the image at ref using the provided CSAF documents | ||
| // and returns vulnerability findings. | ||
| Audit(ctx context.Context, t testing.TB, ref string, csafDocs [][]byte) ([]Result, error) |
There was a problem hiding this comment.
I know we had some discussion around adding testing.TB to the interface method, it was to be able to use the in-built layer caching in claircore but open to other suggestions
There was a problem hiding this comment.
I think if it uses the testing package in the exported API, it should be in the test/ hierarchy. That's a simple rule that helps keep the testing package out of our "real" API surface.
e80755d to
2b9b4ea
Compare
| continue | ||
| } | ||
| switch e.Status { | ||
| case fixtures.StatusUnknown: |
There was a problem hiding this comment.
Honestly, I'm on the fence about fixtures.StatusUnknown being an actual status
There was a problem hiding this comment.
Yeah, I'm not totally clear if "Unknown" and "Extra" are different concepts. Isn't an "Unknown" status just an "Extra" package?
f9f3cb6 to
bb621ee
Compare
The acceptance testing framework allows users to hook into claircore's integration testing by calling acceptance.Run() and providing an Auditor. Signed-off-by: crozzy <joseph.crosland@gmail.com>
bb621ee to
986a408
Compare
Implement the auditor interface back by claircore. Claircore functionality is called locally. Signed-off-by: crozzy <joseph.crosland@gmail.com>
This cmd can be used to push fixtures up to a container registry. This includes a c/image, VEX files and an expected results manifest. Fixtures can then be referenced in acceptance tests. Signed-off-by: crozzy <joseph.crosland@gmail.com>
This documentation should serve as a guide for outside image maintainers (and potentially other scanning vendors) that choose to test how vulnerability ingestion, indexing and matching work. Signed-off-by: crozzy <joseph.crosland@gmail.com>
Signed-off-by: crozzy <joseph.crosland@gmail.com>
986a408 to
bb34ef3
Compare
| @@ -0,0 +1,277 @@ | |||
| //go:build integration | |||
There was a problem hiding this comment.
Why is this build-tagged instead of using integration.Skip?
There was a problem hiding this comment.
This should probably be in a test/acceptance/cmd/fixture package so that go run and/or go tool can work.
| type Auditor interface { | ||
| // Audit analyses the image at ref using the provided CSAF documents | ||
| // and returns vulnerability findings. | ||
| Audit(ctx context.Context, t testing.TB, ref string, csafDocs [][]byte) ([]Result, error) |
There was a problem hiding this comment.
I think if it uses the testing package in the exported API, it should be in the test/ hierarchy. That's a simple rule that helps keep the testing package out of our "real" API surface.
| if len(cmp.Extras) > 0 { | ||
| t.Logf("note: scanner reported %d results not in fixture", len(cmp.Extras)) | ||
| for _, e := range cmp.Extras { | ||
| t.Logf("extra: %s/%s (%s) [pkg: %s]", e.TrackingID, e.ProductID, e.Status, e.Package) |
There was a problem hiding this comment.
| t.Logf("extra: %s/%s (%s) [pkg: %s]", e.TrackingID, e.ProductID, e.Status, e.Package) | |
| t.Logf("EXTRA %s/%s: %s (package: %s)", e.TrackingID, e.ProductID, e.Status, e.Package) |
This message format should probably be similar to the other "reporting" messages.
| return nil, fmt.Errorf("indexer db connect: %w", err) | ||
| } | ||
| } | ||
| indexerStore, err := postgres.InitPostgresIndexerStore(ctx, indexerPool, true) |
There was a problem hiding this comment.
Use the migrations package directly.
| return nil, fmt.Errorf("matcher db connect: %w", err) | ||
| } | ||
| } | ||
| matcherStore, err := postgres.InitPostgresMatcherStore(ctx, matcherPool, true) |
There was a problem hiding this comment.
Use the migrations package directly.
| var errs []error | ||
| if a.indexer != nil { | ||
| a.indexer.Close(ctx) | ||
| } | ||
| if a.matcher != nil { | ||
| a.matcher.Close(ctx) | ||
| } | ||
| if a.cachedArena != nil { | ||
| if err := a.cachedArena.Close(ctx); err != nil { | ||
| errs = append(errs, err) | ||
| } | ||
| } | ||
| return errors.Join(errs...) |
There was a problem hiding this comment.
| var errs []error | |
| if a.indexer != nil { | |
| a.indexer.Close(ctx) | |
| } | |
| if a.matcher != nil { | |
| a.matcher.Close(ctx) | |
| } | |
| if a.cachedArena != nil { | |
| if err := a.cachedArena.Close(ctx); err != nil { | |
| errs = append(errs, err) | |
| } | |
| } | |
| return errors.Join(errs...) | |
| errs := make([]error, 3) | |
| if a.indexer != nil { | |
| errs[0] = a.indexer.Close(ctx) | |
| } | |
| if a.matcher != nil { | |
| errs[1] = a.matcher.Close(ctx) | |
| } | |
| if a.cachedArena != nil { | |
| errs[2] = a.cachedArena.Close(ctx) | |
| } | |
| return errors.Join(errs...) |
Errors.Join filters out nil entries, so it's simpler to just catch all the possible errors.
|
|
||
| // Detect RHEL VEX documents by publisher namespace and use the specialised parser. | ||
| // RHEL VEX has complex product relationships and CPE-based repository matching. | ||
| if c.Document.Publisher.Namespace == "https://www.redhat.com" { |
There was a problem hiding this comment.
Feels bad that we need special Red Hat handling :/
| } | ||
|
|
||
| // SeverityFromCVSSScore converts a CVSS base score to claircore.Severity. | ||
| func severityFromCVSSScore(score float64) claircore.Severity { |
There was a problem hiding this comment.
This seems like it's basically duplicating cvss.QualitativeScore?
| continue | ||
| } | ||
| switch e.Status { | ||
| case fixtures.StatusUnknown: |
There was a problem hiding this comment.
Yeah, I'm not totally clear if "Unknown" and "Extra" are different concepts. Isn't an "Unknown" status just an "Extra" package?
| want *Comparison | ||
| }{ | ||
| { | ||
| name: "all match affected", |
There was a problem hiding this comment.
The names of these subtests should be in PascalCase, so that go test's -run flag is consistent.
| // It maintains internal caches for repository and product lookups, so reusing | ||
| // the same Parser instance across multiple documents is more efficient than | ||
| // creating a new one for each document. | ||
| type Parser struct { |
There was a problem hiding this comment.
I think the docs on the Parser type needs some work to explicitly call out that's it's caching the claircore representation (e.g. Vulnerabilities and Repositories) because I was briefly confused about caching CSAF objects, which are per-document.
No description provided.