chore: add grype version to db network operations (#2062)

Signed-off-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
Keith Zantow 2024-08-20 10:54:16 -04:00 committed by GitHub
parent e7a3c011bc
commit 41cfd42de6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 73 additions and 16 deletions

View file

@ -0,0 +1,41 @@
package commands
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/anchore/clio"
)
func Test_ListingUserAgent(t *testing.T) {
listingFile := "/listing.json"
got := ""
// setup mock
handler := http.NewServeMux()
handler.HandleFunc(listingFile, func(w http.ResponseWriter, r *http.Request) {
got = r.Header.Get("User-Agent")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("1.0.0"))
})
mockSrv := httptest.NewServer(handler)
defer mockSrv.Close()
dbOptions := *dbOptionsDefault(clio.Identification{
Name: "the-app",
Version: "v3.2.1",
})
dbOptions.DB.RequireUpdateCheck = true
dbOptions.DB.UpdateURL = mockSrv.URL + listingFile
_ = runDBList(&dbListOptions{
Output: "",
DBOptions: dbOptions,
})
if got != "the-app v3.2.1" {
t.Errorf("expected User-Agent header to match, got: %v", got)
}
}

View file

@ -12,16 +12,17 @@ import (
) )
type Database struct { type Database struct {
Dir string `yaml:"cache-dir" json:"cache-dir" mapstructure:"cache-dir"` ID clio.Identification `yaml:"-" json:"-" mapstructure:"-"`
UpdateURL string `yaml:"update-url" json:"update-url" mapstructure:"update-url"` Dir string `yaml:"cache-dir" json:"cache-dir" mapstructure:"cache-dir"`
CACert string `yaml:"ca-cert" json:"ca-cert" mapstructure:"ca-cert"` UpdateURL string `yaml:"update-url" json:"update-url" mapstructure:"update-url"`
AutoUpdate bool `yaml:"auto-update" json:"auto-update" mapstructure:"auto-update"` CACert string `yaml:"ca-cert" json:"ca-cert" mapstructure:"ca-cert"`
ValidateByHashOnStart bool `yaml:"validate-by-hash-on-start" json:"validate-by-hash-on-start" mapstructure:"validate-by-hash-on-start"` AutoUpdate bool `yaml:"auto-update" json:"auto-update" mapstructure:"auto-update"`
ValidateAge bool `yaml:"validate-age" json:"validate-age" mapstructure:"validate-age"` ValidateByHashOnStart bool `yaml:"validate-by-hash-on-start" json:"validate-by-hash-on-start" mapstructure:"validate-by-hash-on-start"`
MaxAllowedBuiltAge time.Duration `yaml:"max-allowed-built-age" json:"max-allowed-built-age" mapstructure:"max-allowed-built-age"` ValidateAge bool `yaml:"validate-age" json:"validate-age" mapstructure:"validate-age"`
RequireUpdateCheck bool `yaml:"require-update-check" json:"require-update-check" mapstructure:"require-update-check"` MaxAllowedBuiltAge time.Duration `yaml:"max-allowed-built-age" json:"max-allowed-built-age" mapstructure:"max-allowed-built-age"`
UpdateAvailableTimeout time.Duration `yaml:"update-available-timeout" json:"update-available-timeout" mapstructure:"update-available-timeout"` RequireUpdateCheck bool `yaml:"require-update-check" json:"require-update-check" mapstructure:"require-update-check"`
UpdateDownloadTimeout time.Duration `yaml:"update-download-timeout" json:"update-download-timeout" mapstructure:"update-download-timeout"` UpdateAvailableTimeout time.Duration `yaml:"update-available-timeout" json:"update-available-timeout" mapstructure:"update-available-timeout"`
UpdateDownloadTimeout time.Duration `yaml:"update-download-timeout" json:"update-download-timeout" mapstructure:"update-download-timeout"`
} }
var _ interface { var _ interface {
@ -36,6 +37,7 @@ const (
func DefaultDatabase(id clio.Identification) Database { func DefaultDatabase(id clio.Identification) Database {
return Database{ return Database{
ID: id,
Dir: path.Join(xdg.CacheHome, id.Name, "db"), Dir: path.Join(xdg.CacheHome, id.Name, "db"),
UpdateURL: internal.DBUpdateURL, UpdateURL: internal.DBUpdateURL,
AutoUpdate: true, AutoUpdate: true,
@ -50,6 +52,7 @@ func DefaultDatabase(id clio.Identification) Database {
func (cfg Database) ToCuratorConfig() db.Config { func (cfg Database) ToCuratorConfig() db.Config {
return db.Config{ return db.Config{
ID: cfg.ID,
DBRootDir: cfg.Dir, DBRootDir: cfg.Dir,
ListingURL: cfg.UpdateURL, ListingURL: cfg.UpdateURL,
CACert: cfg.CACert, CACert: cfg.CACert,

View file

@ -17,6 +17,7 @@ import (
partybus "github.com/wagoodman/go-partybus" partybus "github.com/wagoodman/go-partybus"
progress "github.com/wagoodman/go-progress" progress "github.com/wagoodman/go-progress"
"github.com/anchore/clio"
grypeDB "github.com/anchore/grype/grype/db/v5" grypeDB "github.com/anchore/grype/grype/db/v5"
"github.com/anchore/grype/grype/db/v5/store" "github.com/anchore/grype/grype/db/v5/store"
"github.com/anchore/grype/grype/event" "github.com/anchore/grype/grype/event"
@ -31,6 +32,7 @@ const (
) )
type Config struct { type Config struct {
ID clio.Identification
DBRootDir string DBRootDir string
ListingURL string ListingURL string
CACert string CACert string
@ -75,8 +77,8 @@ func NewCurator(cfg Config) (Curator, error) {
return Curator{ return Curator{
fs: fs, fs: fs,
targetSchema: vulnerability.SchemaVersion, targetSchema: vulnerability.SchemaVersion,
listingDownloader: file.NewGetter(listingClient), listingDownloader: file.NewGetter(cfg.ID, listingClient),
updateDownloader: file.NewGetter(dbClient), updateDownloader: file.NewGetter(cfg.ID, dbClient),
dbDir: dbDir, dbDir: dbDir,
dbPath: path.Join(dbDir, FileName), dbPath: path.Join(dbDir, FileName),
listingURL: cfg.ListingURL, listingURL: cfg.ListingURL,

View file

@ -9,6 +9,7 @@ import (
"github.com/hashicorp/go-getter/helper/url" "github.com/hashicorp/go-getter/helper/url"
"github.com/wagoodman/go-progress" "github.com/wagoodman/go-progress"
"github.com/anchore/clio"
"github.com/anchore/grype/internal/stringutil" "github.com/anchore/grype/internal/stringutil"
) )
@ -32,10 +33,13 @@ type HashiGoGetter struct {
// NewGetter creates and returns a new Getter. Providing an http.Client is optional. If one is provided, // NewGetter creates and returns a new Getter. Providing an http.Client is optional. If one is provided,
// it will be used for all HTTP(S) getting; otherwise, go-getter's default getters will be used. // it will be used for all HTTP(S) getting; otherwise, go-getter's default getters will be used.
func NewGetter(httpClient *http.Client) *HashiGoGetter { func NewGetter(id clio.Identification, httpClient *http.Client) *HashiGoGetter {
return &HashiGoGetter{ return &HashiGoGetter{
httpGetter: getter.HttpGetter{ httpGetter: getter.HttpGetter{
Client: httpClient, Client: httpClient,
Header: http.Header{
"User-Agent": []string{fmt.Sprintf("%v %v", id.Name, id.Version)},
},
}, },
} }
} }

View file

@ -14,6 +14,8 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/anchore/clio"
) )
func TestGetter_GetFile(t *testing.T) { func TestGetter_GetFile(t *testing.T) {
@ -45,7 +47,7 @@ func TestGetter_GetFile(t *testing.T) {
tc.prepareClient(httpClient) tc.prepareClient(httpClient)
} }
getter := NewGetter(httpClient) getter := NewGetter(testID, httpClient)
requestURL := createRequestURL(t, server, requestPath) requestURL := createRequestURL(t, server, requestPath)
tempDir := t.TempDir() tempDir := t.TempDir()
@ -72,7 +74,7 @@ func TestGetter_GetToDir_FilterNonArchivesWired(t *testing.T) {
for _, test := range testCases { for _, test := range testCases {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
test.assert(t, NewGetter(nil).GetToDir(t.TempDir(), test.source)) test.assert(t, NewGetter(testID, nil).GetToDir(t.TempDir(), test.source))
}) })
} }
} }
@ -138,7 +140,7 @@ func TestGetter_GetToDir_CertConcerns(t *testing.T) {
tc.prepareClient(httpClient) tc.prepareClient(httpClient)
} }
getter := NewGetter(httpClient) getter := NewGetter(testID, httpClient)
requestURL := createRequestURL(t, server, requestPath) requestURL := createRequestURL(t, server, requestPath)
tempDir := t.TempDir() tempDir := t.TempDir()
@ -193,6 +195,11 @@ func withResponseForPath(t *testing.T, path string, response []byte) muxOption {
} }
} }
var testID = clio.Identification{
Name: "test-app",
Version: "v0.5.3",
}
func newTestServer(t *testing.T, muxOptions ...muxOption) *httptest.Server { func newTestServer(t *testing.T, muxOptions ...muxOption) *httptest.Server {
t.Helper() t.Helper()