fix(server): exclude JavaDB and CheckBundle from /version endpoint (#10100)

This commit is contained in:
Teppei Fukuda
2026-01-30 14:48:49 +04:00
committed by GitHub
parent 8fb9191a07
commit b9a8d2d80a
4 changed files with 109 additions and 60 deletions

View File

@@ -146,7 +146,7 @@ func (s Server) NewServeMux(ctx context.Context, serverCache cache.Cache, dbUpda
mux.HandleFunc("/version", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Add("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(version.NewVersionInfo(s.cacheDir)); err != nil {
if err := json.NewEncoder(w).Encode(version.NewVersionInfo(s.cacheDir, version.Server())); err != nil {
log.Error("Version error", log.Err(err))
}
})

View File

@@ -19,7 +19,6 @@ import (
"github.com/aquasecurity/trivy/pkg/clock"
"github.com/aquasecurity/trivy/pkg/db"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/policy"
"github.com/aquasecurity/trivy/pkg/version"
rpcCache "github.com/aquasecurity/trivy/rpc/cache"
)
@@ -218,7 +217,8 @@ func Test_VersionEndpoint(t *testing.T) {
var versionInfo version.VersionInfo
require.NoError(t, json.NewDecoder(resp.Body).Decode(&versionInfo))
expected := version.VersionInfo{
// Server mode excludes JavaDB and CheckBundle as they are managed on the client side
want := version.VersionInfo{
Version: "dev",
VulnerabilityDB: &metadata.Metadata{
Version: 2,
@@ -226,10 +226,6 @@ func Test_VersionEndpoint(t *testing.T) {
UpdatedAt: time.Date(2023, 7, 20, 12, 11, 37, 696263932, time.UTC),
DownloadedAt: time.Date(2023, 7, 25, 7, 1, 41, 239158000, time.UTC),
},
CheckBundle: &policy.Metadata{
Digest: "sha256:829832357626da2677955e3b427191212978ba20012b6eaa03229ca28569ae43",
DownloadedAt: time.Date(2023, 7, 23, 16, 40, 33, 122462000, time.UTC),
},
}
assert.Equal(t, expected, versionInfo)
assert.Equal(t, want, versionInfo)
}

View File

@@ -20,6 +20,21 @@ type VersionInfo struct {
CheckBundle *policy.Metadata `json:",omitempty"`
}
// VersionOption is a functional option for NewVersionInfo
type VersionOption func(*versionOptions)
type versionOptions struct {
forServer bool
}
// Server returns a VersionOption that excludes JavaDB and CheckBundle
// from version info, as these are managed on the client side in client/server mode.
func Server() VersionOption {
return func(o *versionOptions) {
o.forServer = true
}
}
func formatDBMetadata(title string, meta metadata.Metadata) string {
return fmt.Sprintf(`%s:
Version: %d
@@ -43,9 +58,15 @@ func (v *VersionInfo) String() string {
return output
}
func NewVersionInfo(cacheDir string) VersionInfo {
func NewVersionInfo(cacheDir string, opts ...VersionOption) VersionInfo {
var options versionOptions
for _, opt := range opts {
opt(&options)
}
var dbMeta *metadata.Metadata
var javadbMeta *metadata.Metadata
var pbMeta *policy.Metadata
mc := metadata.NewClient(db.Dir(cacheDir))
meta, err := mc.Get()
@@ -61,35 +82,37 @@ func NewVersionInfo(cacheDir string) VersionInfo {
}
}
mcJava := javadb.NewMetadata(filepath.Join(cacheDir, "java-db"))
metaJava, err := mcJava.Get()
if err != nil {
log.Debug("Failed to get Java DB metadata", log.Err(err))
}
if !metaJava.UpdatedAt.IsZero() && !metaJava.NextUpdate.IsZero() && metaJava.Version != 0 {
javadbMeta = &metadata.Metadata{
Version: metaJava.Version,
NextUpdate: metaJava.NextUpdate.UTC(),
UpdatedAt: metaJava.UpdatedAt.UTC(),
DownloadedAt: metaJava.DownloadedAt.UTC(),
}
}
var pbMeta *policy.Metadata
pc, err := policy.NewClient(cacheDir, false, "")
if err != nil {
log.Debug("Failed to instantiate policy client", log.Err(err))
}
if pc != nil && err == nil {
ctx := log.WithContextPrefix(context.TODO(), log.PrefixMisconfiguration)
pbMetaRaw, err := pc.GetMetadata(ctx)
// Skip JavaDB and CheckBundle for server mode as they are managed on the client side
if !options.forServer {
mcJava := javadb.NewMetadata(filepath.Join(cacheDir, "java-db"))
metaJava, err := mcJava.Get()
if err != nil {
log.Debug("Failed to get policy metadata", log.Err(err))
} else {
pbMeta = &policy.Metadata{
Digest: pbMetaRaw.Digest,
DownloadedAt: pbMetaRaw.DownloadedAt.UTC(),
log.Debug("Failed to get Java DB metadata", log.Err(err))
}
if !metaJava.UpdatedAt.IsZero() && !metaJava.NextUpdate.IsZero() && metaJava.Version != 0 {
javadbMeta = &metadata.Metadata{
Version: metaJava.Version,
NextUpdate: metaJava.NextUpdate.UTC(),
UpdatedAt: metaJava.UpdatedAt.UTC(),
DownloadedAt: metaJava.DownloadedAt.UTC(),
}
}
pc, err := policy.NewClient(cacheDir, false, "")
if err != nil {
log.Debug("Failed to instantiate policy client", log.Err(err))
}
if pc != nil && err == nil {
ctx := log.WithContextPrefix(context.TODO(), log.PrefixMisconfiguration)
pbMetaRaw, err := pc.GetMetadata(ctx)
if err != nil {
log.Debug("Failed to get policy metadata", log.Err(err))
} else {
pbMeta = &policy.Metadata{
Digest: pbMetaRaw.Digest,
DownloadedAt: pbMetaRaw.DownloadedAt.UTC(),
}
}
}
}

View File

@@ -10,32 +10,62 @@ import (
"github.com/aquasecurity/trivy/pkg/policy"
)
func Test_BuildVersionInfo(t *testing.T) {
expected := VersionInfo{
Version: "dev",
VulnerabilityDB: &metadata.Metadata{
Version: 2,
NextUpdate: time.Date(2023, 7, 20, 18, 11, 37, 696263532, time.UTC),
UpdatedAt: time.Date(2023, 7, 20, 12, 11, 37, 696263932, time.UTC),
DownloadedAt: time.Date(2023, 7, 25, 7, 1, 41, 239158000, time.UTC),
func TestNewVersionInfo(t *testing.T) {
tests := []struct {
name string
opts []VersionOption
want VersionInfo
}{
{
name: "default",
opts: nil,
want: VersionInfo{
Version: "dev",
VulnerabilityDB: &metadata.Metadata{
Version: 2,
NextUpdate: time.Date(2023, 7, 20, 18, 11, 37, 696263532, time.UTC),
UpdatedAt: time.Date(2023, 7, 20, 12, 11, 37, 696263932, time.UTC),
DownloadedAt: time.Date(2023, 7, 25, 7, 1, 41, 239158000, time.UTC),
},
JavaDB: &metadata.Metadata{
Version: 1,
NextUpdate: time.Date(2023, 7, 28, 1, 3, 52, 169192565, time.UTC),
UpdatedAt: time.Date(2023, 7, 25, 1, 3, 52, 169192765, time.UTC),
DownloadedAt: time.Date(2023, 7, 25, 9, 37, 48, 906152000, time.UTC),
},
CheckBundle: &policy.Metadata{
Digest: "sha256:829832357626da2677955e3b427191212978ba20012b6eaa03229ca28569ae43",
DownloadedAt: time.Date(2023, 7, 23, 16, 40, 33, 122462000, time.UTC),
},
},
},
JavaDB: &metadata.Metadata{
Version: 1,
NextUpdate: time.Date(2023, 7, 28, 1, 3, 52, 169192565, time.UTC),
UpdatedAt: time.Date(2023, 7, 25, 1, 3, 52, 169192765, time.UTC),
DownloadedAt: time.Date(2023, 7, 25, 9, 37, 48, 906152000, time.UTC),
},
CheckBundle: &policy.Metadata{
Digest: "sha256:829832357626da2677955e3b427191212978ba20012b6eaa03229ca28569ae43",
DownloadedAt: time.Date(2023, 7, 23, 16, 40, 33, 122462000, time.UTC),
{
name: "server mode excludes JavaDB and CheckBundle",
opts: []VersionOption{Server()},
want: VersionInfo{
Version: "dev",
VulnerabilityDB: &metadata.Metadata{
Version: 2,
NextUpdate: time.Date(2023, 7, 20, 18, 11, 37, 696263532, time.UTC),
UpdatedAt: time.Date(2023, 7, 20, 12, 11, 37, 696263932, time.UTC),
DownloadedAt: time.Date(2023, 7, 25, 7, 1, 41, 239158000, time.UTC),
},
JavaDB: nil,
CheckBundle: nil,
},
},
}
assert.Equal(t, expected, NewVersionInfo("testdata/testcache"))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := NewVersionInfo("testdata/testcache", tt.opts...)
assert.Equal(t, tt.want, got)
})
}
}
func Test_VersionInfoString(t *testing.T) {
expected := `Version: dev
func TestVersionInfo_String(t *testing.T) {
want := `Version: dev
Vulnerability DB:
Version: 2
UpdatedAt: 2023-07-20 12:11:37.696263932 +0000 UTC
@@ -50,6 +80,6 @@ Check Bundle:
Digest: sha256:829832357626da2677955e3b427191212978ba20012b6eaa03229ca28569ae43
DownloadedAt: 2023-07-23 16:40:33.122462 +0000 UTC
`
versionInfo := NewVersionInfo("testdata/testcache")
assert.Equal(t, expected, versionInfo.String())
got := NewVersionInfo("testdata/testcache")
assert.Equal(t, want, got.String())
}