mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
condense binary cataloger config in JSON output (#2499)
This commit is contained in:
parent
3de5e98db1
commit
fb2b54a6dc
@ -4,6 +4,8 @@ Package binary provides a concrete Cataloger implementations for surfacing possi
|
|||||||
package binary
|
package binary
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/anchore/syft/internal/log"
|
"github.com/anchore/syft/internal/log"
|
||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
"github.com/anchore/syft/syft/file"
|
"github.com/anchore/syft/syft/file"
|
||||||
@ -28,6 +30,15 @@ func NewCataloger(cfg CatalogerConfig) pkg.Cataloger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg CatalogerConfig) MarshalJSON() ([]byte, error) {
|
||||||
|
// only keep the class names
|
||||||
|
var names []string
|
||||||
|
for _, cls := range cfg.Classifiers {
|
||||||
|
names = append(names, cls.Class)
|
||||||
|
}
|
||||||
|
return json.Marshal(names)
|
||||||
|
}
|
||||||
|
|
||||||
// Cataloger is the cataloger responsible for surfacing evidence of a very limited set of binary files,
|
// Cataloger is the cataloger responsible for surfacing evidence of a very limited set of binary files,
|
||||||
// which have been identified by the classifiers. The Cataloger is _NOT_ a place to catalog any and every
|
// which have been identified by the classifiers. The Cataloger is _NOT_ a place to catalog any and every
|
||||||
// binary, but rather the specific set that has been curated to be important, predominantly related to toolchain-
|
// binary, but rather the specific set that has been curated to be important, predominantly related to toolchain-
|
||||||
|
|||||||
@ -13,7 +13,9 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/anchore/packageurl-go"
|
||||||
"github.com/anchore/stereoscope/pkg/imagetest"
|
"github.com/anchore/stereoscope/pkg/imagetest"
|
||||||
|
"github.com/anchore/syft/syft/cpe"
|
||||||
"github.com/anchore/syft/syft/file"
|
"github.com/anchore/syft/syft/file"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/binary/test-fixtures/manager/testutil"
|
"github.com/anchore/syft/syft/pkg/cataloger/binary/test-fixtures/manager/testutil"
|
||||||
@ -1242,3 +1244,49 @@ func Test_Cataloger_ResilientToErrors(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, resolver.searchCalled)
|
assert.True(t, resolver.searchCalled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCatalogerConfig_MarshalJSON(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
cfg CatalogerConfig
|
||||||
|
want string
|
||||||
|
wantErr assert.ErrorAssertionFunc
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "only show names of classes",
|
||||||
|
cfg: CatalogerConfig{
|
||||||
|
Classifiers: []Classifier{
|
||||||
|
{
|
||||||
|
Class: "class",
|
||||||
|
FileGlob: "glob",
|
||||||
|
EvidenceMatcher: FileContentsVersionMatcher(".thing"),
|
||||||
|
Package: "pkg",
|
||||||
|
PURL: packageurl.PackageURL{
|
||||||
|
Type: "type",
|
||||||
|
Namespace: "namespace",
|
||||||
|
Name: "name",
|
||||||
|
Version: "version",
|
||||||
|
Qualifiers: nil,
|
||||||
|
Subpath: "subpath",
|
||||||
|
},
|
||||||
|
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: `["class"]`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.wantErr == nil {
|
||||||
|
tt.wantErr = assert.NoError
|
||||||
|
}
|
||||||
|
got, err := tt.cfg.MarshalJSON()
|
||||||
|
if !tt.wantErr(t, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.Equal(t, tt.want, string(got))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"debug/elf"
|
"debug/elf"
|
||||||
"debug/macho"
|
"debug/macho"
|
||||||
"debug/pe"
|
"debug/pe"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -44,6 +45,31 @@ type Classifier struct {
|
|||||||
CPEs []cpe.CPE `json:"cpes"`
|
CPEs []cpe.CPE `json:"cpes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg Classifier) MarshalJSON() ([]byte, error) {
|
||||||
|
type marshalled struct {
|
||||||
|
Class string `json:"class"`
|
||||||
|
FileGlob string `json:"fileGlob"`
|
||||||
|
Package string `json:"package"`
|
||||||
|
PURL string `json:"purl"`
|
||||||
|
CPEs []string `json:"cpes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var marshalledCPEs []string
|
||||||
|
for _, c := range cfg.CPEs {
|
||||||
|
marshalledCPEs = append(marshalledCPEs, c.BindToFmtString())
|
||||||
|
}
|
||||||
|
|
||||||
|
m := marshalled{
|
||||||
|
Class: cfg.Class,
|
||||||
|
FileGlob: cfg.FileGlob,
|
||||||
|
Package: cfg.Package,
|
||||||
|
PURL: cfg.PURL.String(),
|
||||||
|
CPEs: marshalledCPEs,
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(m)
|
||||||
|
}
|
||||||
|
|
||||||
// EvidenceMatcher is a function called to catalog Packages that match some sort of evidence
|
// EvidenceMatcher is a function called to catalog Packages that match some sort of evidence
|
||||||
type EvidenceMatcher func(resolver file.Resolver, classifier Classifier, location file.Location) ([]pkg.Package, error)
|
type EvidenceMatcher func(resolver file.Resolver, classifier Classifier, location file.Location) ([]pkg.Package, error)
|
||||||
|
|
||||||
|
|||||||
@ -3,8 +3,10 @@ package binary
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/anchore/packageurl-go"
|
||||||
"github.com/anchore/syft/syft/cpe"
|
"github.com/anchore/syft/syft/cpe"
|
||||||
"github.com/anchore/syft/syft/file"
|
"github.com/anchore/syft/syft/file"
|
||||||
)
|
)
|
||||||
@ -83,3 +85,46 @@ func Test_ClassifierCPEs(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClassifier_MarshalJSON(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
classifier Classifier
|
||||||
|
want string
|
||||||
|
wantErr assert.ErrorAssertionFunc
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "go case",
|
||||||
|
classifier: Classifier{
|
||||||
|
Class: "class",
|
||||||
|
FileGlob: "glob",
|
||||||
|
EvidenceMatcher: FileContentsVersionMatcher(".thing"),
|
||||||
|
Package: "pkg",
|
||||||
|
PURL: packageurl.PackageURL{
|
||||||
|
Type: "type",
|
||||||
|
Namespace: "namespace",
|
||||||
|
Name: "name",
|
||||||
|
Version: "version",
|
||||||
|
Qualifiers: nil,
|
||||||
|
Subpath: "subpath",
|
||||||
|
},
|
||||||
|
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*")},
|
||||||
|
},
|
||||||
|
want: `{"class":"class","fileGlob":"glob","package":"pkg","purl":"pkg:type/namespace/name@version#subpath","cpes":["cpe:2.3:a:some:app:*:*:*:*:*:*:*:*"]}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.wantErr == nil {
|
||||||
|
tt.wantErr = assert.NoError
|
||||||
|
}
|
||||||
|
cfg := tt.classifier
|
||||||
|
got, err := cfg.MarshalJSON()
|
||||||
|
if !tt.wantErr(t, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.Equal(t, tt.want, string(got))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user