Remove MetadataType from core package object and normalize JSON metadataType values (#1983)

* [wip]

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

* distinct the package metadata functions

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

* remove metadata type from package core model

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

* incorporate review feedback for names

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

* add RPM archive metadata and split parser helpers

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

* clarify the python package metadata type

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

* rename the KB metadata type

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

* break hackage and composer types by use case

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

* linting fix

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

* fix encoding and decoding for syft-json and cyclonedx

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

* bump json schema to 11

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

* update cyclonedx-json snapshots

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

* update cyclonedx-xml snapshots

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

* update spdx-json snapshots

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

* update spdx-tv snapshots

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

* update syft-json snapshots

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

* correct metadata type in stack yaml parser test

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

* fix bom-ref redactor for cyclonedx-xml

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

* add tests for legacy package metadata names

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

* regenerate json schema v11

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

* fix legacy HackageMetadataType reflect type value check

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

* fix linting

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

* packagemetadata discovery should account for type shadowing

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

* fix linting

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

* fix cli tests

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

* bump json schema version to v12

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

* update json schema to incorporate changes from main

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

* add syft-json legacy config option

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

* add tests around v11-v12 json decoding

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

* add docs for SYFT_JSON_LEGACY

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

* rename structs to be compliant with new naming scheme

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
2023-10-30 12:12:04 -04:00
committed by GitHub
parent f442586ec9
commit 1aaa644007
261 changed files with 7010 additions and 4040 deletions
+4 -3
View File
@@ -59,13 +59,14 @@ func Attest(app clio.Application) *cobra.Command {
OutputFile: options.OutputFile{ // nolint:staticcheck
Enabled: false, // explicitly not allowed
},
OutputTemplate: options.OutputTemplate{
Enabled: false, // explicitly not allowed
},
Format: options.DefaultFormat(),
},
Catalog: options.DefaultCatalog(),
}
// template format explicitly not allowed
opts.Format.Template.Enabled = false
return app.SetupCommand(&cobra.Command{
Use: "attest --output [FORMAT] <IMAGE>",
Short: "Generate an SBOM as an attestation for the given [SOURCE] container image",
+45
View File
@@ -0,0 +1,45 @@
package options
import (
"github.com/anchore/syft/syft/format/cyclonedxjson"
"github.com/anchore/syft/syft/format/cyclonedxxml"
"github.com/anchore/syft/syft/format/github"
"github.com/anchore/syft/syft/format/spdxjson"
"github.com/anchore/syft/syft/format/spdxtagvalue"
"github.com/anchore/syft/syft/format/syftjson"
"github.com/anchore/syft/syft/format/table"
"github.com/anchore/syft/syft/format/template"
"github.com/anchore/syft/syft/format/text"
"github.com/anchore/syft/syft/sbom"
)
// Format contains all user configuration for output formatting.
type Format struct {
Template FormatTemplate `yaml:"template" json:"template" mapstructure:"template"`
JSON FormatJSON `yaml:"json" json:"json" mapstructure:"json"`
}
func DefaultFormat() Format {
return Format{
Template: DefaultFormatTemplate(),
JSON: DefaultFormatJSON(),
}
}
func (o *Format) Encoders() ([]sbom.FormatEncoder, error) {
// setup all encoders based on the configuration
var list encoderList
// in the future there will be application configuration options that can be used to set the default output format
list.addWithErr(template.ID)(o.Template.formatEncoders())
list.addWithErr(syftjson.ID)(o.JSON.formatEncoders())
list.add(table.ID)(table.NewFormatEncoder())
list.add(text.ID)(text.NewFormatEncoder())
list.add(github.ID)(github.NewFormatEncoder())
list.addWithErr(cyclonedxxml.ID)(cycloneDxXMLEncoders())
list.addWithErr(cyclonedxjson.ID)(cycloneDxJSONEncoders())
list.addWithErr(spdxjson.ID)(spdxJSONEncoders())
list.addWithErr(spdxtagvalue.ID)(spdxTagValueEncoders())
return list.encoders, list.err
}
+25
View File
@@ -0,0 +1,25 @@
package options
import (
"github.com/anchore/syft/syft/format/syftjson"
"github.com/anchore/syft/syft/sbom"
)
type FormatJSON struct {
Legacy bool `yaml:"legacy" json:"legacy" mapstructure:"legacy"`
}
func DefaultFormatJSON() FormatJSON {
return FormatJSON{
Legacy: false,
}
}
func (o FormatJSON) formatEncoders() ([]sbom.FormatEncoder, error) {
enc, err := syftjson.NewFormatEncoderWithConfig(
syftjson.EncoderConfig{
Legacy: o.Legacy,
},
)
return []sbom.FormatEncoder{enc}, err
}
@@ -6,21 +6,27 @@ import (
"github.com/anchore/syft/syft/sbom"
)
var _ clio.FlagAdder = (*OutputTemplate)(nil)
var _ clio.FlagAdder = (*FormatTemplate)(nil)
type OutputTemplate struct {
type FormatTemplate struct {
Enabled bool `yaml:"-" json:"-" mapstructure:"-"`
Path string `yaml:"path" json:"path" mapstructure:"path"` // -t template file to use for output
}
func (o *OutputTemplate) AddFlags(flags clio.FlagSet) {
func DefaultFormatTemplate() FormatTemplate {
return FormatTemplate{
Enabled: true,
}
}
func (o *FormatTemplate) AddFlags(flags clio.FlagSet) {
if o.Enabled {
flags.StringVarP(&o.Path, "template", "t",
"specify the path to a Go template file")
}
}
func (o OutputTemplate) formatEncoders() ([]sbom.FormatEncoder, error) {
func (o FormatTemplate) formatEncoders() ([]sbom.FormatEncoder, error) {
if !o.Enabled {
return nil, nil
}
+3 -23
View File
@@ -32,7 +32,7 @@ type Output struct {
AllowMultipleOutputs bool `yaml:"-" json:"-" mapstructure:"-"`
Outputs []string `yaml:"output" json:"output" mapstructure:"output"` // -o, the format to use for output
OutputFile `yaml:",inline" json:"" mapstructure:",squash"`
OutputTemplate `yaml:"template" json:"template" mapstructure:"template"`
Format `yaml:"format" json:"format" mapstructure:"format"`
}
func DefaultOutput() Output {
@@ -42,9 +42,7 @@ func DefaultOutput() Output {
OutputFile: OutputFile{
Enabled: true,
},
OutputTemplate: OutputTemplate{
Enabled: true,
},
Format: DefaultFormat(),
}
}
@@ -68,7 +66,7 @@ func (o Output) SBOMWriter() (sbom.Writer, error) {
usesTemplateOutput := names.Has(string(template.ID))
if usesTemplateOutput && o.OutputTemplate.Path == "" {
if usesTemplateOutput && o.Format.Template.Path == "" {
return nil, fmt.Errorf(`must specify path to template file when using "template" output format`)
}
@@ -80,24 +78,6 @@ func (o Output) SBOMWriter() (sbom.Writer, error) {
return makeSBOMWriter(o.Outputs, o.File, encoders)
}
func (o *Output) Encoders() ([]sbom.FormatEncoder, error) {
// setup all encoders based on the configuration
var list encoderList
// in the future there will be application configuration options that can be used to set the default output format
list.addWithErr(template.ID)(o.OutputTemplate.formatEncoders())
list.add(syftjson.ID)(syftjson.NewFormatEncoder())
list.add(table.ID)(table.NewFormatEncoder())
list.add(text.ID)(text.NewFormatEncoder())
list.add(github.ID)(github.NewFormatEncoder())
list.addWithErr(cyclonedxxml.ID)(cycloneDxXMLEncoders())
list.addWithErr(cyclonedxjson.ID)(cycloneDxJSONEncoders())
list.addWithErr(spdxjson.ID)(spdxJSONEncoders())
list.addWithErr(spdxtagvalue.ID)(spdxTagValueEncoders())
return list.encoders, list.err
}
func (o Output) OutputNameSet() *strset.Set {
names := strset.New()
for _, output := range o.Outputs {
+2 -2
View File
@@ -27,7 +27,7 @@ func Test_getEncoders(t *testing.T) {
}
opts := DefaultOutput()
opts.OutputTemplate.Path = "somewhere"
opts.Format.Template.Path = "somewhere"
encoders, err := opts.Encoders()
require.NoError(t, err)
@@ -158,7 +158,7 @@ func Test_EncoderCollection_ByString_IDOnly_Defaults(t *testing.T) {
}
opts := DefaultOutput()
opts.OutputTemplate.Path = "somewhere"
opts.Format.Template.Path = "somewhere"
defaultEncoders, err := opts.Encoders()
require.NoError(t, err)