mirror of
https://github.com/anchore/syft.git
synced 2026-11-05 00:46:38 +01:00
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:
@@ -0,0 +1,6 @@
|
||||
package filecataloging
|
||||
|
||||
const (
|
||||
// FileTag should be used to identify catalogers that primarily discover information about files (as opposed to packages).
|
||||
FileTag = "file"
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
package pkgcataloging
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/cataloging"
|
||||
)
|
||||
|
||||
// SelectionRequest is deprecated: use cataloging.SelectionRequest instead
|
||||
type SelectionRequest = cataloging.SelectionRequest
|
||||
|
||||
// NewSelectionRequest is deprecated: use cataloging.NewSelectionRequest instead
|
||||
var NewSelectionRequest = cataloging.NewSelectionRequest
|
||||
@@ -1,8 +1,6 @@
|
||||
package pkgcataloging
|
||||
package cataloging
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
import "strings"
|
||||
|
||||
type SelectionRequest struct {
|
||||
DefaultNamesOrTags []string `json:"default,omitempty"`
|
||||
@@ -50,6 +48,10 @@ func (s SelectionRequest) WithRemovals(nameOrTags ...string) SelectionRequest {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s SelectionRequest) IsEmpty() bool {
|
||||
return len(s.AddNames) == 0 && len(s.RemoveNamesOrTags) == 0 && len(s.SubSelectTags) == 0 && len(s.DefaultNamesOrTags) == 0
|
||||
}
|
||||
|
||||
func cleanSelection(tags []string) []string {
|
||||
var cleaned []string
|
||||
for _, tag := range tags {
|
||||
@@ -21,8 +21,8 @@ type configurationAuditTrail struct {
|
||||
}
|
||||
|
||||
type catalogerManifest struct {
|
||||
Requested pkgcataloging.SelectionRequest `json:"requested" yaml:"requested" mapstructure:"requested"`
|
||||
Used []string `json:"used" yaml:"used" mapstructure:"used"`
|
||||
Requested cataloging.SelectionRequest `json:"requested" yaml:"requested" mapstructure:"requested"`
|
||||
Used []string `json:"used" yaml:"used" mapstructure:"used"`
|
||||
}
|
||||
|
||||
type marshalAPIConfiguration configurationAuditTrail
|
||||
|
||||
@@ -125,6 +125,9 @@ func monitorCatalogingTask(srcID artifact.ID, tasks [][]task.Task) *monitor.Cata
|
||||
func formatTaskNames(tasks []task.Task) []string {
|
||||
set := strset.New()
|
||||
for _, td := range tasks {
|
||||
if td == nil {
|
||||
continue
|
||||
}
|
||||
set.Add(td.Name())
|
||||
}
|
||||
list := set.List()
|
||||
|
||||
+97
-48
@@ -28,14 +28,14 @@ type CreateSBOMConfig struct {
|
||||
Packages pkgcataloging.Config
|
||||
Files filecataloging.Config
|
||||
Parallelism int
|
||||
CatalogerSelection pkgcataloging.SelectionRequest
|
||||
CatalogerSelection cataloging.SelectionRequest
|
||||
|
||||
// audit what tool is being used to generate the SBOM
|
||||
ToolName string
|
||||
ToolVersion string
|
||||
ToolConfiguration interface{}
|
||||
|
||||
packageTaskFactories task.PackageTaskFactories
|
||||
packageTaskFactories task.Factories
|
||||
packageCatalogerReferences []pkgcataloging.CatalogerReference
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ func (c *CreateSBOMConfig) WithoutFiles() *CreateSBOMConfig {
|
||||
}
|
||||
|
||||
// WithCatalogerSelection allows for adding to, removing from, or sub-selecting the final set of catalogers by name or tag.
|
||||
func (c *CreateSBOMConfig) WithCatalogerSelection(selection pkgcataloging.SelectionRequest) *CreateSBOMConfig {
|
||||
func (c *CreateSBOMConfig) WithCatalogerSelection(selection cataloging.SelectionRequest) *CreateSBOMConfig {
|
||||
c.CatalogerSelection = selection
|
||||
return c
|
||||
}
|
||||
@@ -166,6 +166,10 @@ func (c *CreateSBOMConfig) WithoutCatalogers() *CreateSBOMConfig {
|
||||
// WithCatalogers allows for adding user-provided catalogers to the final set of catalogers that will always be run
|
||||
// regardless of the source type or any cataloger selections provided.
|
||||
func (c *CreateSBOMConfig) WithCatalogers(catalogerRefs ...pkgcataloging.CatalogerReference) *CreateSBOMConfig {
|
||||
for i := range catalogerRefs {
|
||||
// ensure that all package catalogers have the package tag
|
||||
catalogerRefs[i].Tags = append(catalogerRefs[i].Tags, pkgcataloging.PackageTag)
|
||||
}
|
||||
c.packageCatalogerReferences = append(c.packageCatalogerReferences, catalogerRefs...)
|
||||
|
||||
return c
|
||||
@@ -182,8 +186,8 @@ func (c *CreateSBOMConfig) makeTaskGroups(src source.Description) ([][]task.Task
|
||||
environmentTasks := c.environmentTasks()
|
||||
relationshipsTasks := c.relationshipTasks(src)
|
||||
unknownTasks := c.unknownsTasks()
|
||||
fileTasks := c.fileTasks()
|
||||
pkgTasks, selectionEvidence, err := c.packageTasks(src)
|
||||
|
||||
pkgTasks, fileTasks, selectionEvidence, err := c.selectTasks(src)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -214,80 +218,117 @@ func (c *CreateSBOMConfig) makeTaskGroups(src source.Description) ([][]task.Task
|
||||
taskGroups...,
|
||||
)
|
||||
|
||||
var allTasks []task.Task
|
||||
allTasks = append(allTasks, pkgTasks...)
|
||||
allTasks = append(allTasks, fileTasks...)
|
||||
|
||||
return taskGroups, &catalogerManifest{
|
||||
Requested: selectionEvidence.Request,
|
||||
Used: formatTaskNames(pkgTasks),
|
||||
Used: formatTaskNames(allTasks),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// fileTasks returns the set of tasks that should be run to catalog files.
|
||||
func (c *CreateSBOMConfig) fileTasks() []task.Task {
|
||||
var tsks []task.Task
|
||||
|
||||
if t := task.NewFileDigestCatalogerTask(c.Files.Selection, c.Files.Hashers...); t != nil {
|
||||
tsks = append(tsks, t)
|
||||
}
|
||||
if t := task.NewFileMetadataCatalogerTask(c.Files.Selection); t != nil {
|
||||
tsks = append(tsks, t)
|
||||
}
|
||||
if t := task.NewFileContentCatalogerTask(c.Files.Content); t != nil {
|
||||
tsks = append(tsks, t)
|
||||
}
|
||||
if t := task.NewExecutableCatalogerTask(c.Files.Selection, c.Files.Executable); t != nil {
|
||||
tsks = append(tsks, t)
|
||||
func (c *CreateSBOMConfig) fileTasks(cfg task.CatalogingFactoryConfig) ([]task.Task, error) {
|
||||
tsks, err := task.DefaultFileTaskFactories().Tasks(cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create file cataloger tasks: %w", err)
|
||||
}
|
||||
|
||||
return tsks
|
||||
return tsks, nil
|
||||
}
|
||||
|
||||
// packageTasks returns the set of tasks that should be run to catalog packages.
|
||||
func (c *CreateSBOMConfig) packageTasks(src source.Description) ([]task.Task, *task.Selection, error) {
|
||||
// selectTasks returns the set of tasks that should be run to catalog packages and files.
|
||||
func (c *CreateSBOMConfig) selectTasks(src source.Description) ([]task.Task, []task.Task, *task.Selection, error) {
|
||||
cfg := task.CatalogingFactoryConfig{
|
||||
SearchConfig: c.Search,
|
||||
RelationshipsConfig: c.Relationships,
|
||||
DataGenerationConfig: c.DataGeneration,
|
||||
PackagesConfig: c.Packages,
|
||||
ComplianceConfig: c.Compliance,
|
||||
FilesConfig: c.Files,
|
||||
}
|
||||
|
||||
persistentTasks, selectableTasks, err := c.allPackageTasks(cfg)
|
||||
persistentPkgTasks, selectablePkgTasks, err := c.allPackageTasks(cfg)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to create package cataloger tasks: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("unable to create package cataloger tasks: %w", err)
|
||||
}
|
||||
|
||||
req, err := finalSelectionRequest(c.CatalogerSelection, src)
|
||||
req, err := finalTaskSelectionRequest(c.CatalogerSelection, src)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
finalTasks, selection, err := task.Select(selectableTasks, *req)
|
||||
selectableFileTasks, err := c.fileTasks(cfg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
finalTasks = append(finalTasks, persistentTasks...)
|
||||
|
||||
if len(finalTasks) == 0 {
|
||||
log.Warn("no catalogers selected")
|
||||
return finalTasks, &selection, nil
|
||||
taskGroups := [][]task.Task{
|
||||
selectablePkgTasks,
|
||||
selectableFileTasks,
|
||||
}
|
||||
|
||||
return finalTasks, &selection, nil
|
||||
finalTaskGroups, selection, err := task.SelectInGroups(taskGroups, *req)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
finalPkgTasks := finalTaskGroups[0]
|
||||
finalFileTasks := finalTaskGroups[1]
|
||||
|
||||
finalPkgTasks = append(finalPkgTasks, persistentPkgTasks...)
|
||||
|
||||
if len(finalPkgTasks) == 0 && len(finalFileTasks) == 0 {
|
||||
return nil, nil, nil, fmt.Errorf("no catalogers selected")
|
||||
}
|
||||
|
||||
logTaskNames(finalPkgTasks, "package cataloger")
|
||||
logTaskNames(finalFileTasks, "file cataloger")
|
||||
|
||||
if len(finalPkgTasks) == 0 && len(finalFileTasks) == 0 {
|
||||
return nil, nil, nil, fmt.Errorf("no catalogers selected")
|
||||
}
|
||||
|
||||
if len(finalPkgTasks) == 0 {
|
||||
log.Debug("no package catalogers selected")
|
||||
}
|
||||
|
||||
if len(finalFileTasks) == 0 {
|
||||
if c.Files.Selection != file.NoFilesSelection {
|
||||
log.Warnf("no file catalogers selected but file selection is configured as %q (this may be unintentional)", c.Files.Selection)
|
||||
} else {
|
||||
log.Debug("no file catalogers selected")
|
||||
}
|
||||
}
|
||||
|
||||
return finalPkgTasks, finalFileTasks, &selection, nil
|
||||
}
|
||||
|
||||
func finalSelectionRequest(req pkgcataloging.SelectionRequest, src source.Description) (*pkgcataloging.SelectionRequest, error) {
|
||||
func logTaskNames(tasks []task.Task, kind string) {
|
||||
// log as tree output (like tree command)
|
||||
log.Debugf("selected %d %s tasks", len(tasks), kind)
|
||||
names := formatTaskNames(tasks)
|
||||
for idx, t := range names {
|
||||
if idx == len(tasks)-1 {
|
||||
log.Tracef("└── %s", t)
|
||||
} else {
|
||||
log.Tracef("├── %s", t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func finalTaskSelectionRequest(req cataloging.SelectionRequest, src source.Description) (*cataloging.SelectionRequest, error) {
|
||||
if len(req.DefaultNamesOrTags) == 0 {
|
||||
defaultTag, err := findDefaultTag(src)
|
||||
defaultTags, err := findDefaultTags(src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to determine default cataloger tag: %w", err)
|
||||
}
|
||||
|
||||
if defaultTag != "" {
|
||||
req.DefaultNamesOrTags = append(req.DefaultNamesOrTags, defaultTag)
|
||||
}
|
||||
req.DefaultNamesOrTags = append(req.DefaultNamesOrTags, defaultTags...)
|
||||
|
||||
req.RemoveNamesOrTags = replaceDefaultTagReferences(defaultTag, req.RemoveNamesOrTags)
|
||||
req.SubSelectTags = replaceDefaultTagReferences(defaultTag, req.SubSelectTags)
|
||||
req.RemoveNamesOrTags = replaceDefaultTagReferences(defaultTags, req.RemoveNamesOrTags)
|
||||
req.SubSelectTags = replaceDefaultTagReferences(defaultTags, req.SubSelectTags)
|
||||
}
|
||||
|
||||
return &req, nil
|
||||
@@ -379,21 +420,29 @@ func (c *CreateSBOMConfig) Create(ctx context.Context, src source.Source) (*sbom
|
||||
return CreateSBOM(ctx, src, c)
|
||||
}
|
||||
|
||||
func findDefaultTag(src source.Description) (string, error) {
|
||||
func findDefaultTags(src source.Description) ([]string, error) {
|
||||
switch m := src.Metadata.(type) {
|
||||
case source.ImageMetadata:
|
||||
return pkgcataloging.ImageTag, nil
|
||||
return []string{pkgcataloging.ImageTag, filecataloging.FileTag}, nil
|
||||
case source.FileMetadata, source.DirectoryMetadata:
|
||||
return pkgcataloging.DirectoryTag, nil
|
||||
return []string{pkgcataloging.DirectoryTag, filecataloging.FileTag}, nil
|
||||
default:
|
||||
return "", fmt.Errorf("unable to determine default cataloger tag for source type=%T", m)
|
||||
return nil, fmt.Errorf("unable to determine default cataloger tag for source type=%T", m)
|
||||
}
|
||||
}
|
||||
|
||||
func replaceDefaultTagReferences(defaultTag string, lst []string) []string {
|
||||
func replaceDefaultTagReferences(defaultTags []string, lst []string) []string {
|
||||
for i, tag := range lst {
|
||||
if strings.ToLower(tag) == "default" {
|
||||
lst[i] = defaultTag
|
||||
switch len(defaultTags) {
|
||||
case 0:
|
||||
lst[i] = ""
|
||||
case 1:
|
||||
lst[i] = defaultTags[0]
|
||||
default:
|
||||
// remove the default tag and add the individual tags
|
||||
lst = append(lst[:i], append(defaultTags, lst[i+1:]...)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return lst
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user