From 873eb4879bec4c8f63ea52787a8600324e693684 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Wed, 2 Aug 2023 20:01:04 +0200 Subject: [PATCH] Add time range to checker report. --- cmd/csaf_checker/config.go | 16 ++++------------ cmd/csaf_checker/processor.go | 13 +++++++------ cmd/csaf_checker/report.go | 8 +++++--- cmd/csaf_checker/tmpl/report.html | 22 ++++++++++++++++++++-- internal/models/models.go | 19 ++++++++++++++++++- 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/cmd/csaf_checker/config.go b/cmd/csaf_checker/config.go index aa456cc..396df81 100644 --- a/cmd/csaf_checker/config.go +++ b/cmd/csaf_checker/config.go @@ -13,7 +13,6 @@ import ( "errors" "fmt" "net/http" - "time" "github.com/csaf-poc/csaf_distribution/v2/internal/filter" "github.com/csaf-poc/csaf_distribution/v2/internal/models" @@ -49,7 +48,7 @@ type config struct { Config string `short:"c" long:"config" description:"Path to config TOML file" value-name:"TOML-FILE" toml:"-"` clientCerts []tls.Certificate - ageAccept func(time.Time) bool + ageAccept *models.TimeRange ignorePattern filter.PatternMatcher } @@ -156,14 +155,6 @@ func (cfg *config) prepareCertificates() error { return nil } -// acceptYears returns a filter that accepts advisories from the last years. -func acceptYears(years uint) func(time.Time) bool { - good := time.Now().AddDate(-int(years), 0, 0) - return func(t time.Time) bool { - return !t.Before(good) - } -} - // prepareTimeRangeFilter sets up the filter in which time range // advisory should be considered for checking. func (cfg *config) prepareTimeRangeFilter() error { @@ -172,10 +163,11 @@ func (cfg *config) prepareTimeRangeFilter() error { return errors.New(`"timerange" and "years" are both configured: only one allowed`) case cfg.Years != nil: - cfg.ageAccept = acceptYears(*cfg.Years) + years := models.NYears(*cfg.Years) + cfg.ageAccept = &years case cfg.Range != nil: - cfg.ageAccept = cfg.Range.Contains + cfg.ageAccept = cfg.Range } return nil } diff --git a/cmd/csaf_checker/processor.go b/cmd/csaf_checker/processor.go index 4da23ad..e6fecd8 100644 --- a/cmd/csaf_checker/processor.go +++ b/cmd/csaf_checker/processor.go @@ -241,8 +241,9 @@ func (p *processor) clean() { func (p *processor) run(domains []string) (*Report, error) { report := Report{ - Date: ReportTime{Time: time.Now().UTC()}, - Version: util.SemVersion, + Date: ReportTime{Time: time.Now().UTC()}, + Version: util.SemVersion, + TimeRange: p.cfg.ageAccept, } for _, d := range domains { @@ -545,8 +546,8 @@ func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) { rfeed.Entries(func(entry *csaf.Entry) { // Filter if we have date checking. - if p.cfg.ageAccept != nil { - if pub := time.Time(entry.Published); !pub.IsZero() && !p.cfg.ageAccept(pub) { + if accept := p.cfg.ageAccept; accept != nil { + if pub := time.Time(entry.Published); !pub.IsZero() && !accept.Contains(pub) { return } } @@ -666,7 +667,7 @@ func (p *processor) integrity( if m := yearFromURL.FindStringSubmatch(u); m != nil { year, _ := strconv.Atoi(m[1]) // Check if we are in checking time interval. - if p.cfg.ageAccept != nil && !p.cfg.ageAccept( + if accept := p.cfg.ageAccept; accept != nil && !accept.Contains( time.Date( year, 12, 31, // Assume last day of year. 23, 59, 59, 0, // 23:59:59 @@ -972,7 +973,7 @@ func (p *processor) checkChanges(base string, mask whereType) error { return nil, nil, err } // Apply date range filtering. - if p.cfg.ageAccept != nil && !p.cfg.ageAccept(t) { + if accept := p.cfg.ageAccept; accept != nil && !accept.Contains(t) { continue } path := r[pathColumn] diff --git a/cmd/csaf_checker/report.go b/cmd/csaf_checker/report.go index a50c61b..d8c46fc 100644 --- a/cmd/csaf_checker/report.go +++ b/cmd/csaf_checker/report.go @@ -19,6 +19,7 @@ import ( "time" "github.com/csaf-poc/csaf_distribution/v2/csaf" + "github.com/csaf-poc/csaf_distribution/v2/internal/models" ) // MessageType is the kind of the message. @@ -60,9 +61,10 @@ type ReportTime struct{ time.Time } // Report is the overall report. type Report struct { - Domains []*Domain `json:"domains,omitempty"` - Version string `json:"version,omitempty"` - Date ReportTime `json:"date,omitempty"` + Domains []*Domain `json:"domains,omitempty"` + Version string `json:"version,omitempty"` + Date ReportTime `json:"date,omitempty"` + TimeRange *models.TimeRange `json:"timerange,omitempty"` } // MarshalText implements the encoding.TextMarshaller interface. diff --git a/cmd/csaf_checker/tmpl/report.html b/cmd/csaf_checker/tmpl/report.html index 29e83ef..36c3bfa 100644 --- a/cmd/csaf_checker/tmpl/report.html +++ b/cmd/csaf_checker/tmpl/report.html @@ -62,8 +62,26 @@ {{ end }} diff --git a/internal/models/models.go b/internal/models/models.go index a7f6b02..caacd0f 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -10,6 +10,7 @@ package models import ( + "encoding/json" "fmt" "strings" "time" @@ -27,10 +28,17 @@ func NewTimeInterval(a, b time.Time) TimeRange { return TimeRange{a, b} } +// NYears returns a time interval spanning the last years. +func NYears(years uint) TimeRange { + now := time.Now() + start := now.AddDate(-int(years), 0, 0) + return NewTimeInterval(start, now) +} + // guessDate tries to guess an RFC 3339 date time from a given string. func guessDate(s string) (time.Time, bool) { for _, layout := range []string{ - "2006-01-02T15:04:05Z07:00", + time.RFC3339, "2006-01-02T15:04:05", "2006-01-02T15:04", "2006-01-02T15", @@ -50,6 +58,15 @@ func (tr *TimeRange) UnmarshalText(text []byte) error { return tr.UnmarshalFlag(string(text)) } +// MarshalJSON implements [encoding/json.Marshaler]. +func (tr TimeRange) MarshalJSON() ([]byte, error) { + s := []string{ + tr[0].Format(time.RFC3339), + tr[1].Format(time.RFC3339), + } + return json.Marshal(s) +} + // UnmarshalFlag implements [go-flags/Unmarshaler]. func (tr *TimeRange) UnmarshalFlag(s string) error { s = strings.TrimSpace(s)