Skip to content

Commit

Permalink
feat: fix summary output (anchore#1312)
Browse files Browse the repository at this point in the history
Signed-off-by: James Neate <jamesmneate@gmail.com>
  • Loading branch information
jneate committed Jun 1, 2023
1 parent c1f6772 commit a092e12
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 123 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ func startWorker(userInput string, failOnSeverity *vulnerability.Severity) <-cha
}

bus.Publish(partybus.Event{
Type: event.VulnerabilityScanningFinished,
Type: event.PresentationStarted,
Value: presenter.GetPresenter(presenterConfig, pb),
})
}()
Expand Down
1 change: 1 addition & 0 deletions grype/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ const (
VulnerabilityScanningFinished partybus.EventType = "grype-vulnerability-scanning-finished"
NonRootCommandFinished partybus.EventType = "grype-non-root-command-finished"
DatabaseDiffingStarted partybus.EventType = "grype-database-diffing-started"
PresentationStarted partybus.EventType = "grype-presentation-started"
)
16 changes: 15 additions & 1 deletion grype/event/parsers/parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/wagoodman/go-partybus"
"github.com/wagoodman/go-progress"

"github.com/anchore/grype/grype"
diffEvents "github.com/anchore/grype/grype/differ/events"
"github.com/anchore/grype/grype/event"
"github.com/anchore/grype/grype/matcher"
Expand Down Expand Up @@ -76,11 +77,24 @@ func ParseVulnerabilityScanningStarted(e partybus.Event) (*matcher.Monitor, erro
return &monitor, nil
}

func ParseVulnerabilityScanningFinished(e partybus.Event) (presenter.Presenter, error) {
func ParseVulnerabilityScanningFinished(e partybus.Event) (*grype.MatcherResults, error) {
if err := checkEventType(e.Type, event.VulnerabilityScanningFinished); err != nil {
return nil, err
}

matcherResults, ok := e.Value.(grype.MatcherResults)
if !ok {
return nil, newPayloadErr(e.Type, "Value", e.Value)
}

return &matcherResults, nil
}

func ParsePresentationStarted(e partybus.Event) (presenter.Presenter, error) {
if err := checkEventType(e.Type, event.PresentationStarted); err != nil {
return nil, err
}

pres, ok := e.Value.(presenter.Presenter)
if !ok {
return nil, newPayloadErr(e.Type, "Value", e.Value)
Expand Down
68 changes: 0 additions & 68 deletions grype/matcher/matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/wagoodman/go-partybus"
"github.com/wagoodman/go-progress"

grypeDb "github.com/anchore/grype/grype/db/v5"
"github.com/anchore/grype/grype/distro"
"github.com/anchore/grype/grype/event"
"github.com/anchore/grype/grype/match"
Expand All @@ -31,51 +30,29 @@ import (
type Monitor struct {
PackagesProcessed progress.Monitorable
VulnerabilitiesDiscovered progress.Monitorable
Fixed progress.Monitorable
BySeverity map[vulnerability.Severity]progress.Monitorable
}

type monitor struct {
PackagesProcessed *progress.Manual
VulnerabilitiesDiscovered *progress.Manual
Fixed *progress.Manual
BySeverity map[vulnerability.Severity]*progress.Manual
}

func newMonitor() (monitor, Monitor) {
manualBySev := make(map[vulnerability.Severity]*progress.Manual)
for _, severity := range vulnerability.AllSeverities() {
manualBySev[severity] = progress.NewManual(-1)
}
manualBySev[vulnerability.UnknownSeverity] = progress.NewManual(-1)

m := monitor{
PackagesProcessed: progress.NewManual(-1),
VulnerabilitiesDiscovered: progress.NewManual(-1),
Fixed: progress.NewManual(-1),
BySeverity: manualBySev,
}

monitorableBySev := make(map[vulnerability.Severity]progress.Monitorable)
for sev, manual := range manualBySev {
monitorableBySev[sev] = manual
}

return m, Monitor{
PackagesProcessed: m.PackagesProcessed,
VulnerabilitiesDiscovered: m.VulnerabilitiesDiscovered,
Fixed: m.Fixed,
BySeverity: monitorableBySev,
}
}

func (m *monitor) SetCompleted() {
m.PackagesProcessed.SetCompleted()
m.VulnerabilitiesDiscovered.SetCompleted()
m.Fixed.SetCompleted()
for _, v := range m.BySeverity {
v.SetCompleted()
}
}

// Config contains values used by individual matcher structs for advanced configuration
Expand Down Expand Up @@ -180,63 +157,18 @@ func FindMatches(store interface {
logMatches(p, matches)
res.Add(matches...)
progressMonitor.VulnerabilitiesDiscovered.Add(int64(len(matches)))
updateVulnerabilityList(progressMonitor, matches, store)
}
}
}

progressMonitor.SetCompleted()

logListSummary(progressMonitor)

// Filter out matches based off of the records in the exclusion table in the database or from the old hard-coded rules
res = match.ApplyExplicitIgnoreRules(store, res)

return res
}

func logListSummary(vl *monitor) {
log.Infof("found %d vulnerabilities for %d packages", vl.VulnerabilitiesDiscovered.Current(), vl.PackagesProcessed.Current())
log.Debugf(" ├── fixed: %d", vl.Fixed.Current())
log.Debugf(" └── matched: %d", vl.VulnerabilitiesDiscovered.Current())

var unknownCount int64
if count, ok := vl.BySeverity[vulnerability.UnknownSeverity]; ok {
unknownCount = count.Current()
}
log.Debugf(" ├── %s: %d", vulnerability.UnknownSeverity.String(), unknownCount)

allSeverities := vulnerability.AllSeverities()
for idx, sev := range allSeverities {
branch := "├"
if idx == len(allSeverities)-1 {
branch = "└"
}
log.Debugf(" %s── %s: %d", branch, sev.String(), vl.BySeverity[sev].Current())
}
}

func updateVulnerabilityList(list *monitor, matches []match.Match, metadataProvider vulnerability.MetadataProvider) {
for _, m := range matches {
metadata, err := metadataProvider.GetMetadata(m.Vulnerability.ID, m.Vulnerability.Namespace)
if err != nil || metadata == nil {
list.BySeverity[vulnerability.UnknownSeverity].Increment()
continue
}

sevManualProgress, ok := list.BySeverity[vulnerability.ParseSeverity(metadata.Severity)]
if !ok {
list.BySeverity[vulnerability.UnknownSeverity].Increment()
continue
}
sevManualProgress.Increment()

if m.Vulnerability.Fix.State == grypeDb.FixedState {
list.Fixed.Increment()
}
}
}

func logMatches(p pkg.Package, matches []match.Match) {
if len(matches) > 0 {
log.Debugf("found %d vulnerabilities for pkg=%s", len(matches), p)
Expand Down
18 changes: 18 additions & 0 deletions grype/vulnerability_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package grype
import (
"strings"

"github.com/anchore/grype/grype/event"
"github.com/anchore/grype/grype/grypeerr"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/matcher"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/store"
"github.com/anchore/grype/grype/vulnerability"
"github.com/anchore/grype/internal/bus"
"github.com/anchore/grype/internal/log"
"github.com/wagoodman/go-partybus"
)

type VulnerabilityMatcher struct {
Expand All @@ -20,6 +23,12 @@ type VulnerabilityMatcher struct {
NormalizeByCVE bool
}

type MatcherResults struct {
Matches *match.Matches
IgnoredMatches []match.IgnoredMatch
Store store.Store
}

func DefaultVulnerabilityMatcher(store store.Store) *VulnerabilityMatcher {
return &VulnerabilityMatcher{
Store: store,
Expand Down Expand Up @@ -61,6 +70,15 @@ func (m *VulnerabilityMatcher) FindMatches(pkgs []pkg.Package, context pkg.Conte
matches, ignoredMatches = m.applyIgnoreRules(normalizedMatches)
}

bus.Publish(partybus.Event{
Type: event.VulnerabilityScanningFinished,
Value: MatcherResults{
Matches: &matches,
IgnoredMatches: ignoredMatches,
Store: m.Store,
},
})

var err error
if m.FailSeverity != nil && HasSeverityAtOrAbove(m.Store, *m.FailSeverity, matches) {
err = grypeerr.ErrAboveSeverityThreshold
Expand Down
6 changes: 3 additions & 3 deletions internal/ui/common_event_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
grypeEventParsers "github.com/anchore/grype/grype/event/parsers"
)

func handleVulnerabilityScanningFinished(event partybus.Event, reportOutput io.Writer) error {
func handlePresentationStarted(event partybus.Event, reportOutput io.Writer) error {
// show the report to stdout
pres, err := grypeEventParsers.ParseVulnerabilityScanningFinished(event)
pres, err := grypeEventParsers.ParsePresentationStarted(event)
if err != nil {
return fmt.Errorf("bad CatalogerFinished event: %w", err)
return fmt.Errorf("bad PresentationStarted event: %w", err)
}

if err := pres.Present(reportOutput); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/ui/ephemeral_terminal_ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ func (h *ephemeralTerminalUI) Handle(event partybus.Event) error {
log.Errorf("unable to show %s event: %+v", event.Type, err)
}

case event.Type == grypeEvent.VulnerabilityScanningFinished:
case event.Type == grypeEvent.PresentationStarted:
// we need to close the screen now since signaling the the presenter is ready means that we
// are about to write bytes to stdout, so we should reset the terminal state first
h.closeScreen(false)

if err := handleVulnerabilityScanningFinished(event, h.reportOutput); err != nil {
if err := handlePresentationStarted(event, h.reportOutput); err != nil {
log.Errorf("unable to show %s event: %+v", event.Type, err)
}

Expand Down
6 changes: 3 additions & 3 deletions internal/ui/logger_ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ func (l *loggerUI) Setup(unsubscribe func() error) error {

func (l loggerUI) Handle(event partybus.Event) error {
switch event.Type {
case grypeEvent.VulnerabilityScanningFinished:
if err := handleVulnerabilityScanningFinished(event, l.reportOutput); err != nil {
log.Warnf("unable to show catalog image finished event: %+v", err)
case grypeEvent.PresentationStarted:
if err := handlePresentationStarted(event, l.reportOutput); err != nil {
log.Warnf("unable to show presentation started event: %+v", err)
}
case grypeEvent.NonRootCommandFinished:
if err := handleNonRootCommandFinished(event, l.reportOutput); err != nil {
Expand Down
Loading

0 comments on commit a092e12

Please sign in to comment.