diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 888faea8..c7957cae 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,16 +21,5 @@ jobs: - name: Build run: go build -v ./cmd/... - - name: vet - run: go vet ./... - - - name: gofmt - uses: Jerome1337/gofmt-action@v1.0.5 - with: - gofmt-flags: "-l -d" - - - name: Revive Action - uses: morphy2k/revive-action@v2.5.7 - - name: Tests run: go test -v ./... diff --git a/cmd/csaf_downloader/downloader.go b/cmd/csaf_downloader/downloader.go index be7ea42f..fef90be6 100644 --- a/cmd/csaf_downloader/downloader.go +++ b/cmd/csaf_downloader/downloader.go @@ -434,7 +434,7 @@ nextAdvisory: filename := filepath.Base(u.Path) if !util.ConformingFileName(filename) { stats.filenameFailed++ - errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprint("CSAF has non conforming filename ", filename)} + errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprintf("CSAF has non conforming filename %s", filename)} slog.Warn("Ignoring none conforming filename", "filename", filename) continue @@ -443,7 +443,7 @@ nextAdvisory: resp, err := client.Get(file.URL()) if err != nil { stats.downloadFailed++ - errorCh <- csafErrs.ErrNetwork{Message: fmt.Sprint("can't retrieve CSAF document ", filename, " from URL", file.URL(), ":", err)} + errorCh <- csafErrs.ErrNetwork{Message: fmt.Sprintf("can't retrieve CSAF document %s from URL %s: %v", filename, file.URL(), err)} slog.Warn("Cannot GET", "url", file.URL(), "error", err) @@ -453,9 +453,9 @@ nextAdvisory: if resp.StatusCode != http.StatusOK { switch { case resp.StatusCode == http.StatusUnauthorized: - errorCh <- csafErrs.ErrInvalidCredentials{Message: fmt.Sprint("invalid credentials to retrieve CSAF document ", filename, " at URL ", file.URL(), ": ", resp.Status)} + errorCh <- csafErrs.ErrInvalidCredentials{Message: fmt.Sprintf("invalid credentials to retrieve CSAF document %s at URL %s: %s", filename, file.URL(), resp.Status)} case resp.StatusCode == http.StatusNotFound: - errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprint("could not find CSAF document '", filename, "' listed in table of content at URL ", file.URL(), ": ", resp.Status)} + errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprintf("could not find CSAF document %s listed in table of content at URL %s: %s ", filename, file.URL(), resp.Status)} case resp.StatusCode >= 500: errorCh <- fmt.Errorf("could not retrieve CSAF document %s at URL %s: %s %w", filename, file.URL(), resp.Status, csafErrs.ErrRetryable) // mark as retryable error default: @@ -518,7 +518,7 @@ nextAdvisory: return json.NewDecoder(tee).Decode(&doc) }(); err != nil { stats.downloadFailed++ - errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprint("CSAF document ", filename, " at URL ", file.URL(), " is not valid json:", err)} + errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprintf("CSAF document %s at URL %s is not valid json: %v", filename, file.URL(), err)} slog.Warn("Downloading failed", "url", file.URL(), "error", err) @@ -529,7 +529,7 @@ nextAdvisory: s256Check := func() error { if s256 != nil && !bytes.Equal(s256.Sum(nil), remoteSHA256) { stats.sha256Failed++ - errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprint("SHA256 checksum of CSAF document ", filename, " at URL ", file.URL(), " does not match")} + errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprintf("SHA256 checksum of CSAF document %s at URL %s does not match", filename, file.URL())} return fmt.Errorf("SHA256 checksum of %s does not match", file.URL()) } return nil @@ -538,7 +538,7 @@ nextAdvisory: s512Check := func() error { if s512 != nil && !bytes.Equal(s512.Sum(nil), remoteSHA512) { stats.sha512Failed++ - errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprint("SHA512 checksum of CSAF document ", filename, " at URL ", file.URL(), " does not match")} + errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprintf("SHA512 checksum of CSAF document %s at URL %s does not match", filename, file.URL())} return fmt.Errorf("SHA512 checksum of %s does not match", file.URL()) } return nil @@ -561,7 +561,7 @@ nextAdvisory: if err := d.checkSignature(data.Bytes(), sign); err != nil { if !d.cfg.IgnoreSignatureCheck { stats.signatureFailed++ - errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprint("cannot verify signature for CSAF document ", filename, " at URL ", file.URL(), ": ", err)} + errorCh <- csafErrs.ErrCsafProviderIssue{Message: fmt.Sprintf("cannot verify signature for CSAF document %s at URL %s: %v", filename, file.URL(), err)} return fmt.Errorf("cannot verify signature for %s: %v", file.URL(), err) } } @@ -576,7 +576,7 @@ nextAdvisory: if err != nil { errorCh <- fmt.Errorf("schema validation for CSAF document %s failed: %w", filename, err) } else { - errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprint("CSAF document ", filename, " at URL ", file.URL(), " does not conform to JSON schema:", errors)} + errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprintf("CSAF document %s at URL %s does not conform to JSON schema: %v", filename, file.URL(), errors)} } d.logValidationIssues(file.URL(), errors, err) return fmt.Errorf("schema validation for %q failed", file.URL()) @@ -588,7 +588,7 @@ nextAdvisory: filenameCheck := func() error { if err := util.IDMatchesFilename(d.eval, doc, filename); err != nil { stats.filenameFailed++ - errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprint("invalid CSAF document ", filename, " at URL ", file.URL(), ":", err)} + errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprintf("invalid CSAF document %s at URL %s: %v", filename, file.URL(), err)} return fmt.Errorf("filename not conforming %s: %s", file.URL(), err) } return nil @@ -608,7 +608,7 @@ nextAdvisory: } if !rvr.Valid { stats.remoteFailed++ - errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprint("remote validation of CSAF document ", filename, " at URL ", file.URL(), " failed")} + errorCh <- csafErrs.ErrInvalidCsaf{Message: fmt.Sprintf("remote validation of CSAF document %s at URL %s failed", filename, file.URL())} return fmt.Errorf("remote validation of %q failed", file.URL()) } return nil diff --git a/csaf/advisories.go b/csaf/advisories.go index 173bf80f..30e723c6 100644 --- a/csaf/advisories.go +++ b/csaf/advisories.go @@ -262,10 +262,18 @@ func (afp *AdvisoryFileProcessor) processROLIE( if feed.URL == nil { continue } + + var label TLPLabel + if feed.TLPLabel != nil { + label = *feed.TLPLabel + } else { + label = "unknown" + } + up, err := url.Parse(string(*feed.URL)) if err != nil { log.Printf("Invalid URL %s in feed: %v.", *feed.URL, err) - feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprint("invalid feed URL", *feed.URL, ":", err)}) + feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprintf("invalid TLP:%s feed URL %s: %v", label, *feed.URL, err)}) continue } feedURL := afp.base.ResolveReference(up) @@ -274,20 +282,20 @@ func (afp *AdvisoryFileProcessor) processROLIE( fb, err := util.BaseURL(feedURL) if err != nil { log.Printf("error: Invalid feed base URL '%s': %v\n", fb, err) - feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprint("invalid feed base URL ", fb, ":", err)}) + feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprintf("invalid TLP:%s feed base URL %s: %v", label, fb, err)}) continue } feedBaseURL, err := url.Parse(fb) if err != nil { log.Printf("error: Cannot parse feed base URL '%s': %v\n", fb, err) - feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprint("cannot parse feed base URL ", fb, ":", err)}) + feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprintf("cannot parse TLP:%s feed base URL %s: %v", label, fb, err)}) continue } res, err := afp.client.Get(feedURL.String()) if err != nil { log.Printf("error: Cannot get feed '%s'\n", err) - feedErrs = append(feedErrs, errs.ErrNetwork{Message: fmt.Sprint("cannot get feed ", feedURL.String(), ":", err)}) + feedErrs = append(feedErrs, errs.ErrNetwork{Message: fmt.Sprintf("failed get for TLP:%s feed url %s: %v", label, feedURL.String(), err)}) continue } if res.StatusCode != http.StatusOK { @@ -295,15 +303,15 @@ func (afp *AdvisoryFileProcessor) processROLIE( feedURL, res.StatusCode, res.Status) switch { case res.StatusCode == http.StatusUnauthorized: - feedErrs = append(feedErrs, errs.ErrInvalidCredentials{Message: fmt.Sprint("invalid credentials to retrieve ROLIE feed ", feedURL.String(), ": ", res.Status)}) + feedErrs = append(feedErrs, errs.ErrInvalidCredentials{Message: fmt.Sprintf("invalid credentials for TLP:%s ROLIE feed at %s: %s", label, feedURL.String(), res.Status)}) case res.StatusCode == http.StatusNotFound: - feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprint("could not find ROLIE feed ", feedURL.String(), ": ", res.Status)}) + feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprintf("could not find TLP:%s ROLIE feed at %s: %s", label, feedURL.String(), res.Status)}) case res.StatusCode == http.StatusForbidden: // user has insufficient permissions to access feed, no error case res.StatusCode > 500: - feedErrs = append(feedErrs, fmt.Errorf("could not retrieve ROLIE feed %s: %s %w", feedURL.String(), res.Status, errs.ErrRetryable)) // mark error as retryable + feedErrs = append(feedErrs, fmt.Errorf("could not retrieve TLP:%s ROLIE feed at %s: %s %w", label, feedURL.String(), res.Status, errs.ErrRetryable)) // mark error as retryable default: - feedErrs = append(feedErrs, fmt.Errorf("could not retrieve ROLIE feed %s: %s", feedURL.String(), res.Status)) + feedErrs = append(feedErrs, fmt.Errorf("could not retrieve TLP:%s ROLIE feed at %s: %s", label, feedURL.String(), res.Status)) } continue } @@ -313,7 +321,7 @@ func (afp *AdvisoryFileProcessor) processROLIE( }() if err != nil { log.Printf("Loading ROLIE feed failed: %v.", err) - feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprint("ROLIE feed ", feedURL.String(), " is not valid JSON:", err)}) + feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprintf("TLP:%s ROLIE feed at %s is not valid JSON: %v", label, feedURL.String(), err)}) continue } @@ -321,12 +329,12 @@ func (afp *AdvisoryFileProcessor) processROLIE( resolve := func(u string) (string, error) { if u == "" { - return "", errs.ErrCsafProviderIssue{Message: "empty url in ROLIE feed to file"} + return "", errs.ErrCsafProviderIssue{Message: fmt.Sprintf("empty url in TLP:%s ROLIE feed at %s to file", label, feedURL.String())} } p, err := url.Parse(u) if err != nil { log.Printf("error: Invalid URL '%s': %v", u, err) - return "", errs.ErrCsafProviderIssue{Message: fmt.Sprint("invalid url in ROLIE feed to file", u, ":", err)} + return "", errs.ErrCsafProviderIssue{Message: fmt.Sprintf("invalid url in TLP:%s ROLIE feed at %s to file %s: %v", label, feedURL.String(), u, err)} } return feedBaseURL.ResolveReference(p).String(), nil } @@ -376,7 +384,7 @@ func (afp *AdvisoryFileProcessor) processROLIE( } if !csafLinkExists { - feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprint("ROLIE feed ", feedURL.String(), " contains entry (ID '", entry.ID, "') without link to csaf document")}) + feedErrs = append(feedErrs, errs.ErrCsafProviderIssue{Message: fmt.Sprintf("TLP:%s ROLIE feed at %s contains entry (ID '%s') without link to csaf document", label, feedURL.String(), entry.ID)}) } var file AdvisoryFile @@ -390,13 +398,6 @@ func (afp *AdvisoryFileProcessor) processROLIE( files = append(files, file) }) - var label TLPLabel - if feed.TLPLabel != nil { - label = *feed.TLPLabel - } else { - label = "unknown" - } - if err := fn(label, files); err != nil { feedErrs = append(feedErrs, err) } diff --git a/version.go b/version.go index be190e0e..ccdfb6dc 100644 --- a/version.go +++ b/version.go @@ -2,5 +2,5 @@ package main // THIS IS AN AUTOGENERATED FILE. DO NOT TOUCH! -var version = "3.1.1-dev1" +var version = "3.2.1-dev1"