Add file catalogers to selection configuration (#3505)

* add file catalogers to selection configuration

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix typos

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* warn when there is conflicting file cataloging configuration

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* allow for explicit removal of all package and file tasks

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address PR feedback

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2025-02-03 19:10:17 +00:00
committed by GitHub
parent 5e2ba43328
commit 684b6e3f98
25 changed files with 1206 additions and 353 deletions
+94 -64
View File
@@ -88,15 +88,15 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
wantTaskNames: [][]string{
environmentCatalogerNames(),
pkgCatalogerNamesWithTagOrName(t, "image"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
},
Used: pkgCatalogerNamesWithTagOrName(t, "image"),
Used: flatten(pkgCatalogerNamesWithTagOrName(t, "image"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -107,15 +107,15 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
wantTaskNames: [][]string{
environmentCatalogerNames(),
pkgCatalogerNamesWithTagOrName(t, "directory"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"directory"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"directory", "file"},
},
Used: pkgCatalogerNamesWithTagOrName(t, "directory"),
Used: flatten(pkgCatalogerNamesWithTagOrName(t, "directory"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -127,51 +127,53 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
wantTaskNames: [][]string{
environmentCatalogerNames(),
pkgCatalogerNamesWithTagOrName(t, "directory"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"directory"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"directory", "file"},
},
Used: pkgCatalogerNamesWithTagOrName(t, "directory"),
Used: flatten(pkgCatalogerNamesWithTagOrName(t, "directory"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
{
name: "no file digest cataloger",
src: imgSrc,
cfg: DefaultCreateSBOMConfig().WithFilesConfig(filecataloging.DefaultConfig().WithHashers()),
cfg: DefaultCreateSBOMConfig().WithCatalogerSelection(cataloging.NewSelectionRequest().WithRemovals("digest")),
wantTaskNames: [][]string{
environmentCatalogerNames(),
pkgCatalogerNamesWithTagOrName(t, "image"),
fileCatalogerNames(false, true, true), // note: the digest cataloger is not included
fileCatalogerNames("file-metadata", "content", "binary-metadata"),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
RemoveNamesOrTags: []string{"digest"},
},
Used: pkgCatalogerNamesWithTagOrName(t, "image"),
Used: flatten(pkgCatalogerNamesWithTagOrName(t, "image"), fileCatalogerNames("file-metadata", "content", "binary-metadata")),
},
wantErr: require.NoError,
},
{
name: "select no file catalogers",
src: imgSrc,
cfg: DefaultCreateSBOMConfig().WithFilesConfig(filecataloging.DefaultConfig().WithSelection(file.NoFilesSelection)),
cfg: DefaultCreateSBOMConfig().WithCatalogerSelection(cataloging.NewSelectionRequest().WithRemovals("file")),
wantTaskNames: [][]string{
environmentCatalogerNames(),
pkgCatalogerNamesWithTagOrName(t, "image"),
// note: there are no file catalogers in their own group
nil, // note: there is a file cataloging group, with no items in it
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
RemoveNamesOrTags: []string{"file"},
},
Used: pkgCatalogerNamesWithTagOrName(t, "image"),
},
@@ -186,16 +188,16 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
// note: there is a single group of catalogers for pkgs and files
append(
pkgCatalogerNamesWithTagOrName(t, "image"),
fileCatalogerNames(true, true, true)...,
fileCatalogerNames()...,
),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
},
Used: pkgCatalogerNamesWithTagOrName(t, "image"),
Used: flatten(pkgCatalogerNamesWithTagOrName(t, "image"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -208,15 +210,15 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
wantTaskNames: [][]string{
environmentCatalogerNames(),
addTo(pkgCatalogerNamesWithTagOrName(t, "image"), "persistent"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
},
Used: addTo(pkgCatalogerNamesWithTagOrName(t, "image"), "persistent"),
Used: flatten(addTo(pkgCatalogerNamesWithTagOrName(t, "image"), "persistent"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -229,15 +231,15 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
wantTaskNames: [][]string{
environmentCatalogerNames(),
addTo(pkgCatalogerNamesWithTagOrName(t, "directory"), "persistent"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"directory"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"directory", "file"},
},
Used: addTo(pkgCatalogerNamesWithTagOrName(t, "directory"), "persistent"),
Used: flatten(addTo(pkgCatalogerNamesWithTagOrName(t, "directory"), "persistent"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -246,20 +248,20 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
src: imgSrc,
cfg: DefaultCreateSBOMConfig().WithCatalogers(
pkgcataloging.NewAlwaysEnabledCatalogerReference(newDummyCataloger("persistent")),
).WithCatalogerSelection(pkgcataloging.NewSelectionRequest().WithSubSelections("javascript")),
).WithCatalogerSelection(cataloging.NewSelectionRequest().WithSubSelections("javascript")),
wantTaskNames: [][]string{
environmentCatalogerNames(),
addTo(pkgIntersect("image", "javascript"), "persistent"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
SubSelectTags: []string{"javascript"},
},
Used: addTo(pkgIntersect("image", "javascript"), "persistent"),
Used: flatten(addTo(pkgIntersect("image", "javascript"), "persistent"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -272,15 +274,15 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
wantTaskNames: [][]string{
environmentCatalogerNames(),
addTo(pkgCatalogerNamesWithTagOrName(t, "image"), "user-provided"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
},
Used: addTo(pkgCatalogerNamesWithTagOrName(t, "image"), "user-provided"),
Used: flatten(addTo(pkgCatalogerNamesWithTagOrName(t, "image"), "user-provided"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -293,15 +295,15 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
wantTaskNames: [][]string{
environmentCatalogerNames(),
pkgCatalogerNamesWithTagOrName(t, "image"),
fileCatalogerNames(true, true, true),
fileCatalogerNames(),
relationshipCatalogerNames(),
unknownsTaskNames(),
},
wantManifest: &catalogerManifest{
Requested: pkgcataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image"},
Requested: cataloging.SelectionRequest{
DefaultNamesOrTags: []string{"image", "file"},
},
Used: pkgCatalogerNamesWithTagOrName(t, "image"),
Used: flatten(pkgCatalogerNamesWithTagOrName(t, "image"), fileCatalogerNames()),
},
wantErr: require.NoError,
},
@@ -314,9 +316,6 @@ func TestCreateSBOMConfig_makeTaskGroups(t *testing.T) {
// sanity check
require.NotEmpty(t, tt.wantTaskNames)
for _, group := range tt.wantTaskNames {
require.NotEmpty(t, group)
}
// test the subject
gotTasks, gotManifest, err := tt.cfg.makeTaskGroups(tt.src)
@@ -378,20 +377,51 @@ func pkgCatalogerNamesWithTagOrName(t *testing.T, token string) []string {
return names
}
func fileCatalogerNames(digest, metadata, executable bool) []string {
func fileCatalogerNames(tokens ...string) []string {
var names []string
if digest {
names = append(names, "file-digest-cataloger")
}
if executable {
names = append(names, "file-executable-cataloger")
}
if metadata {
names = append(names, "file-metadata-cataloger")
cfg := task.DefaultCatalogingFactoryConfig()
topLoop:
for _, factory := range task.DefaultFileTaskFactories() {
cat := factory(cfg)
if cat == nil {
continue
}
name := cat.Name()
if len(tokens) == 0 {
names = append(names, name)
continue
}
for _, token := range tokens {
if selector, ok := cat.(task.Selector); ok {
if selector.HasAllSelectors(token) {
names = append(names, name)
continue topLoop
}
}
if name == token {
names = append(names, name)
}
}
}
sort.Strings(names)
return names
}
func flatten(lists ...[]string) []string {
var final []string
for _, lst := range lists {
final = append(final, lst...)
}
sort.Strings(final)
return final
}
func relationshipCatalogerNames() []string {
return []string{"relationships-cataloger"}
}
@@ -436,7 +466,7 @@ func Test_replaceDefaultTagReferences(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, replaceDefaultTagReferences("replacement", tt.lst))
assert.Equal(t, tt.want, replaceDefaultTagReferences([]string{"replacement"}, tt.lst))
})
}
}
@@ -446,7 +476,7 @@ func Test_findDefaultTag(t *testing.T) {
tests := []struct {
name string
src source.Description
want string
want []string
wantErr require.ErrorAssertionFunc
}{
{
@@ -454,21 +484,21 @@ func Test_findDefaultTag(t *testing.T) {
src: source.Description{
Metadata: source.ImageMetadata{},
},
want: pkgcataloging.ImageTag,
want: []string{pkgcataloging.ImageTag, filecataloging.FileTag},
},
{
name: "directory",
src: source.Description{
Metadata: source.DirectoryMetadata{},
},
want: pkgcataloging.DirectoryTag,
want: []string{pkgcataloging.DirectoryTag, filecataloging.FileTag},
},
{
name: "file",
src: source.Description{
Metadata: source.FileMetadata{},
},
want: pkgcataloging.DirectoryTag, // not a mistake...
want: []string{pkgcataloging.DirectoryTag, filecataloging.FileTag}, // not a mistake...
},
{
name: "unknown",
@@ -483,7 +513,7 @@ func Test_findDefaultTag(t *testing.T) {
if tt.wantErr == nil {
tt.wantErr = require.NoError
}
got, err := findDefaultTag(tt.src)
got, err := findDefaultTags(tt.src)
tt.wantErr(t, err)
if err != nil {
return