Skip to content

Commit

Permalink
Merge pull request #707 from wolfi-dev/add-export-osv
Browse files Browse the repository at this point in the history
add advisory export to OSV format
  • Loading branch information
rawlingsj committed Mar 26, 2024
2 parents 008203a + 9215851 commit e000218
Show file tree
Hide file tree
Showing 6 changed files with 425 additions and 31 deletions.
17 changes: 9 additions & 8 deletions go.mod
@@ -1,6 +1,6 @@
module github.com/wolfi-dev/wolfictl

go 1.21.7
go 1.21.8

require (
chainguard.dev/apko v0.14.1-0.20240308000904-c510767a86aa
Expand Down Expand Up @@ -29,6 +29,7 @@ require (
github.com/go-ini/ini v1.67.0
github.com/google/go-cmp v0.6.0
github.com/google/go-github/v58 v58.0.0
github.com/google/osv-scanner v1.7.1
github.com/google/uuid v1.6.0
github.com/hashicorp/go-version v1.6.0
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f
Expand All @@ -48,14 +49,14 @@ require (
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0
go.opentelemetry.io/otel/sdk v1.24.0
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f
golang.org/x/mod v0.16.0
golang.org/x/oauth2 v0.18.0
golang.org/x/sync v0.6.0
golang.org/x/term v0.18.0
golang.org/x/text v0.14.0
golang.org/x/time v0.5.0
golang.org/x/vuln v1.0.1
golang.org/x/vuln v1.0.4
gopkg.in/yaml.v3 v3.0.1
k8s.io/apimachinery v0.29.2
sigs.k8s.io/release-utils v0.7.7
Expand Down Expand Up @@ -86,7 +87,7 @@ require (
github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b // indirect
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a // indirect
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
github.com/anchore/go-struct-converter v0.0.0-20230627203149-c72ef8859ca9 // indirect
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 // indirect
github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
Expand All @@ -105,7 +106,7 @@ require (
github.com/cloudflare/circl v1.3.7 // indirect
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/containerd/console v1.0.4 // indirect
github.com/containerd/containerd v1.7.11 // indirect
github.com/containerd/continuity v0.4.3 // indirect
github.com/containerd/fifo v1.1.0 // indirect
Expand Down Expand Up @@ -155,7 +156,7 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-containerregistry v0.19.0 // indirect
github.com/google/go-containerregistry v0.19.1 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/licensecheck v0.3.1 // indirect
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a // indirect
Expand Down Expand Up @@ -213,7 +214,7 @@ require (
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/sys/signal v0.7.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
Expand Down Expand Up @@ -243,7 +244,7 @@ require (
github.com/saferwall/pe v1.5.2 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
github.com/sahilm/fuzzy v0.1.1 // indirect
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
github.com/sassoftware/go-rpmutils v0.3.0 // indirect
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect
Expand Down
25 changes: 14 additions & 11 deletions go.sum
Expand Up @@ -242,8 +242,9 @@ github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVC
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a/go.mod h1:ubLFmlsv8/DFUQrZwY5syT5/8Er3ugSr4rDFwHsE3hg=
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb h1:iDMnx6LIjtjZ46C0akqveX83WFzhpTD3eqOthawb5vU=
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb/go.mod h1:DmTY2Mfcv38hsHbG78xMiTDdxFtkHpgYNVDPsF2TgHk=
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
github.com/anchore/go-struct-converter v0.0.0-20230627203149-c72ef8859ca9 h1:6COpXWpHbhWM1wgcQN95TdsmrLTba8KQfPgImBXzkjA=
github.com/anchore/go-struct-converter v0.0.0-20230627203149-c72ef8859ca9/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0vW0nnNKJfJieyH/TZ9UYAnTZs5/gHTdAe8=
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ=
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE+o2gozGEBoUMpX27lsku+xrMwlmBZJtbg=
Expand Down Expand Up @@ -353,8 +354,8 @@ github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw=
github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE=
github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8=
Expand Down Expand Up @@ -576,8 +577,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic=
github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY=
github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
github.com/google/go-github/v58 v58.0.0 h1:Una7GGERlF/37XfkPwpzYJe0Vp4dt2k1kCjlxwjIvzw=
github.com/google/go-github/v58 v58.0.0/go.mod h1:k4hxDKEfoWpSqFlc8LTpGd9fu2KrV1YAa6Hi6FmDNY4=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
Expand All @@ -594,6 +595,8 @@ github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIG
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/osv-scanner v1.7.1 h1:xVLRp7nFNtBphuIF63++T1TW5ViO2eW5UrwyqvKauGk=
github.com/google/osv-scanner v1.7.1/go.mod h1:f1oLmNj+LnHwsJn5UYOY1FASeBL+C13JKI+O7HNahcs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
Expand Down Expand Up @@ -858,8 +861,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA=
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
Expand Down Expand Up @@ -977,8 +980,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y=
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
Expand Down Expand Up @@ -1191,8 +1194,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f h1:3CW0unweImhOzd5FmYuRsD4Y4oQFKZIjAnKbjV4WIrw=
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down
117 changes: 116 additions & 1 deletion pkg/advisory/export.go
Expand Up @@ -5,15 +5,21 @@ import (
"encoding/csv"
"fmt"
"io"
"log"
"sort"
"time"

"github.com/google/osv-scanner/pkg/models"
"github.com/samber/lo"
"gopkg.in/yaml.v3"

"github.com/wolfi-dev/wolfictl/pkg/configs"
v2 "github.com/wolfi-dev/wolfictl/pkg/configs/advisory/v2"
"gopkg.in/yaml.v3"
)

type ExportOptions struct {
AdvisoryDocIndices []*configs.Index[v2.Document]
Ecosystem models.Ecosystem
}

// ExportCSV returns a reader of advisory data encoded as CSV.
Expand Down Expand Up @@ -112,3 +118,112 @@ func ExportYAML(opts ExportOptions) (io.Reader, error) {

return buf, nil
}

func ExportOSV(opts ExportOptions) (io.Reader, error) {
buf := new(bytes.Buffer)

osvExport := make(map[string]models.Vulnerability)

for _, index := range opts.AdvisoryDocIndices {
documents := index.Select().Configurations()

for _, doc := range documents {
for _, adv := range doc.Advisories {
sortedEvents := adv.SortedEvents()
var updatedTime time.Time
tempAffected := models.Affected{}
for _, event := range sortedEvents {
switch event.Type {
case v2.EventTypeFixed:
tempAffected.Package = models.Package{
Name: doc.Package.Name,
Ecosystem: opts.Ecosystem,
Purl: fmt.Sprintf("pkg:apk/%s/%s", opts.Ecosystem, doc.Package.Name),
}
tempAffected.Ranges = []models.Range{
{
Type: v2.EventTypeFixed,
Events: []models.Event{
{
Fixed: event.Data.(v2.Fixed).FixedVersion,
},
},
},
}
updatedTime = time.Time(event.Timestamp)
case v2.EventTypeFalsePositiveDetermination:
tempAffected.Package = models.Package{
Name: doc.Package.Name,
Ecosystem: opts.Ecosystem,
Purl: fmt.Sprintf("pkg:apk/%s/%s", opts.Ecosystem, doc.Package.Name),
}
tempAffected.Ranges = []models.Range{
{
Type: v2.EventTypeFixed,
Events: []models.Event{
{
Fixed: "0",
},
},
},
}
updatedTime = time.Time(event.Timestamp)
default:
continue
}

if len(tempAffected.Ranges) == 0 {
continue
}

entry, ok := osvExport[adv.ID]
if ok {
entry.Affected = append(entry.Affected, tempAffected)

if updatedTime.After(entry.Modified) {
entry.Modified = updatedTime
}

osvExport[adv.ID] = entry
} else {
temp := models.Vulnerability{
ID: adv.ID,
Aliases: adv.Aliases,
Affected: []models.Affected{tempAffected},
}
if updatedTime.After(entry.Modified) {
temp.Modified = updatedTime
}

osvExport[adv.ID] = temp
}
}
}
}
}

keys := make([]string, 0, len(osvExport))
for k := range osvExport {
keys = append(keys, k)
}
sort.Strings(keys)

for _, k := range keys {
if len(buf.Bytes()) != 0 {
buf.WriteString("---\n")
}

e, err := osvExport[k].MarshalYAML()
if err != nil {
log.Fatal(err)
}

d, err := yaml.Marshal(e)
if err != nil {
return nil, fmt.Errorf("failed to marshal package %q: %v", osvExport[k].ID, err)
}
buf.Write(d)
}

return buf, nil
}
10 changes: 9 additions & 1 deletion pkg/advisory/export_test.go
Expand Up @@ -4,9 +4,11 @@ import (
"context"
"io"
"os"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/google/osv-scanner/pkg/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/wolfi-dev/wolfictl/pkg/configs"
Expand All @@ -32,6 +34,11 @@ func Test_ExportFuncs(t *testing.T) {
exportFuncUnderTest: ExportYAML,
pathToExpectedData: "./testdata/export/expected.yaml",
},
{
name: "osv",
exportFuncUnderTest: ExportOSV,
pathToExpectedData: "./testdata/export/expected-osv.yaml",
},
}

for _, tt := range cases {
Expand All @@ -43,6 +50,7 @@ func Test_ExportFuncs(t *testing.T) {

opts := ExportOptions{
AdvisoryDocIndices: indices,
Ecosystem: models.Ecosystem("wolfi"),
}

exported, err := tt.exportFuncUnderTest(opts)
Expand All @@ -56,7 +64,7 @@ func Test_ExportFuncs(t *testing.T) {
require.NoError(t, err)

if diff := cmp.Diff(string(expectedBytes), string(exportedBytes)); diff != "" {
t.Errorf("ExportCSV() produced unexpected data (-want +got):\n%s", diff)
t.Errorf("Export%s() produced unexpected data (-want +got):\n%s", strings.ToUpper(tt.name), diff)
}
}
})
Expand Down

0 comments on commit e000218

Please sign in to comment.