use sbom.SBOM in ImportConfig (#621)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2021-11-08 18:39:06 -05:00 committed by GitHub
parent 9bbc9ff633
commit 9c27fa7b0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 43 deletions

View File

@ -14,10 +14,8 @@ import (
"github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/ui" "github.com/anchore/syft/internal/ui"
"github.com/anchore/syft/syft" "github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/event" "github.com/anchore/syft/syft/event"
"github.com/anchore/syft/syft/format" "github.com/anchore/syft/syft/format"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/sbom" "github.com/anchore/syft/syft/sbom"
"github.com/anchore/syft/syft/source" "github.com/anchore/syft/syft/source"
"github.com/pkg/profile" "github.com/pkg/profile"
@ -261,13 +259,6 @@ func packagesExecWorker(userInput string) <-chan error {
return return
} }
if appConfig.Anchore.Host != "" {
if err := runPackageSbomUpload(src, src.Metadata, catalog, d); err != nil {
errs <- err
return
}
}
sbomResult := sbom.SBOM{ sbomResult := sbom.SBOM{
Artifacts: sbom.Artifacts{ Artifacts: sbom.Artifacts{
PackageCatalog: catalog, PackageCatalog: catalog,
@ -276,6 +267,13 @@ func packagesExecWorker(userInput string) <-chan error {
Source: src.Metadata, Source: src.Metadata,
} }
if appConfig.Anchore.Host != "" {
if err := runPackageSbomUpload(src, sbomResult); err != nil {
errs <- err
return
}
}
bus.Publish(partybus.Event{ bus.Publish(partybus.Event{
Type: event.PresenterReady, Type: event.PresenterReady,
Value: f.Presenter(sbomResult), Value: f.Presenter(sbomResult),
@ -284,7 +282,7 @@ func packagesExecWorker(userInput string) <-chan error {
return errs return errs
} }
func runPackageSbomUpload(src *source.Source, s source.Metadata, catalog *pkg.Catalog, d *distro.Distro) error { func runPackageSbomUpload(src *source.Source, s sbom.SBOM) error {
log.Infof("uploading results to %s", appConfig.Anchore.Host) log.Infof("uploading results to %s", appConfig.Anchore.Host)
if src.Metadata.Scheme != source.ImageScheme { if src.Metadata.Scheme != source.ImageScheme {
@ -319,9 +317,7 @@ func runPackageSbomUpload(src *source.Source, s source.Metadata, catalog *pkg.Ca
importCfg := anchore.ImportConfig{ importCfg := anchore.ImportConfig{
ImageMetadata: src.Image.Metadata, ImageMetadata: src.Image.Metadata,
SourceMetadata: s, SBOM: s,
Catalog: catalog,
Distro: d,
Dockerfile: dockerfileContents, Dockerfile: dockerfileContents,
OverwriteExistingUpload: appConfig.Anchore.OverwriteExistingImage, OverwriteExistingUpload: appConfig.Anchore.OverwriteExistingImage,
Timeout: appConfig.Anchore.ImportTimeout, Timeout: appConfig.Anchore.ImportTimeout,

View File

@ -6,24 +6,19 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/antihax/optional"
"github.com/anchore/client-go/pkg/external" "github.com/anchore/client-go/pkg/external"
"github.com/anchore/stereoscope/pkg/image" "github.com/anchore/stereoscope/pkg/image"
"github.com/anchore/syft/internal/bus" "github.com/anchore/syft/internal/bus"
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/event" "github.com/anchore/syft/syft/event"
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/sbom"
"github.com/anchore/syft/syft/source" "github.com/antihax/optional"
"github.com/wagoodman/go-partybus" "github.com/wagoodman/go-partybus"
"github.com/wagoodman/go-progress" "github.com/wagoodman/go-progress"
) )
type ImportConfig struct { type ImportConfig struct {
ImageMetadata image.Metadata ImageMetadata image.Metadata
SourceMetadata source.Metadata SBOM sbom.SBOM
Catalog *pkg.Catalog
Distro *distro.Distro
Dockerfile []byte Dockerfile []byte
OverwriteExistingUpload bool OverwriteExistingUpload bool
Timeout uint Timeout uint
@ -73,19 +68,19 @@ func (c *Client) Import(ctx context.Context, cfg ImportConfig) error {
prog.N++ prog.N++
sessionID := startOperation.Uuid sessionID := startOperation.Uuid
packageDigest, err := importPackageSBOM(authedCtx, c.client.ImportsApi, sessionID, cfg.SourceMetadata, cfg.Catalog, cfg.Distro, stage) packageDigest, err := importPackageSBOM(authedCtx, c.client.ImportsApi, sessionID, cfg.SBOM, stage)
if err != nil { if err != nil {
return fmt.Errorf("failed to import Package SBOM: %w", err) return fmt.Errorf("failed to import Package SBOM: %w", err)
} }
prog.N++ prog.N++
manifestDigest, err := importManifest(authedCtx, c.client.ImportsApi, sessionID, cfg.ImageMetadata.RawManifest, stage) manifestDigest, err := importManifest(authedCtx, c.client.ImportsApi, sessionID, cfg.SBOM.Source.ImageMetadata.RawManifest, stage)
if err != nil { if err != nil {
return fmt.Errorf("failed to import Manifest: %w", err) return fmt.Errorf("failed to import Manifest: %w", err)
} }
prog.N++ prog.N++
configDigest, err := importConfig(authedCtx, c.client.ImportsApi, sessionID, cfg.ImageMetadata.RawConfig, stage) configDigest, err := importConfig(authedCtx, c.client.ImportsApi, sessionID, cfg.SBOM.Source.ImageMetadata.RawConfig, stage)
if err != nil { if err != nil {
return fmt.Errorf("failed to import Config: %w", err) return fmt.Errorf("failed to import Config: %w", err)
} }

View File

@ -14,30 +14,17 @@ import (
"github.com/wagoodman/go-progress" "github.com/wagoodman/go-progress"
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/source"
"github.com/anchore/client-go/pkg/external" "github.com/anchore/client-go/pkg/external"
"github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/pkg"
) )
type packageSBOMImportAPI interface { type packageSBOMImportAPI interface {
ImportImagePackages(context.Context, string, external.ImagePackageManifest) (external.ImageImportContentResponse, *http.Response, error) ImportImagePackages(context.Context, string, external.ImagePackageManifest) (external.ImageImportContentResponse, *http.Response, error)
} }
func packageSbomModel(srcMetadata source.Metadata, catalog *pkg.Catalog, d *distro.Distro) (*external.ImagePackageManifest, error) { func packageSbomModel(s sbom.SBOM) (*external.ImagePackageManifest, error) {
var buf bytes.Buffer var buf bytes.Buffer
// TODO: once the top-level API is refactored and SBOMs are the unit of work, then this function will be passed an SBOM and there would be no more need to create an SBOM object here.
s := sbom.SBOM{
Artifacts: sbom.Artifacts{
PackageCatalog: catalog,
Distro: d,
},
Source: srcMetadata,
}
err := syftjson.Format().Presenter(s).Present(&buf) err := syftjson.Format().Presenter(s).Present(&buf)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to serialize results: %w", err) return nil, fmt.Errorf("unable to serialize results: %w", err)
@ -52,11 +39,11 @@ func packageSbomModel(srcMetadata source.Metadata, catalog *pkg.Catalog, d *dist
return &model, nil return &model, nil
} }
func importPackageSBOM(ctx context.Context, api packageSBOMImportAPI, sessionID string, s source.Metadata, catalog *pkg.Catalog, d *distro.Distro, stage *progress.Stage) (string, error) { func importPackageSBOM(ctx context.Context, api packageSBOMImportAPI, sessionID string, s sbom.SBOM, stage *progress.Stage) (string, error) {
log.Debug("importing package SBOM") log.Debug("importing package SBOM")
stage.Current = "package SBOM" stage.Current = "package SBOM"
model, err := packageSbomModel(s, catalog, d) model, err := packageSbomModel(s)
if err != nil { if err != nil {
return "", fmt.Errorf("unable to create PackageSBOM model: %w", err) return "", fmt.Errorf("unable to create PackageSBOM model: %w", err)
} }

View File

@ -74,7 +74,15 @@ func TestPackageSbomToModel(t *testing.T) {
c := pkg.NewCatalog(p) c := pkg.NewCatalog(p)
model, err := packageSbomModel(m, c, &d) sbomResult := sbom.SBOM{
Artifacts: sbom.Artifacts{
PackageCatalog: c,
Distro: &d,
},
Source: m,
}
model, err := packageSbomModel(sbomResult)
if err != nil { if err != nil {
t.Fatalf("unable to generate model from source material: %+v", err) t.Fatalf("unable to generate model from source material: %+v", err)
} }
@ -197,7 +205,15 @@ func TestPackageSbomImport(t *testing.T) {
d, _ := distro.NewDistro(distro.CentOS, "8.0", "") d, _ := distro.NewDistro(distro.CentOS, "8.0", "")
theModel, err := packageSbomModel(m, catalog, &d) sbomResult := sbom.SBOM{
Artifacts: sbom.Artifacts{
PackageCatalog: catalog,
Distro: &d,
},
Source: m,
}
theModel, err := packageSbomModel(sbomResult)
if err != nil { if err != nil {
t.Fatalf("could not get sbom model: %+v", err) t.Fatalf("could not get sbom model: %+v", err)
} }
@ -236,7 +252,7 @@ func TestPackageSbomImport(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
digest, err := importPackageSBOM(context.TODO(), test.api, sessionID, m, catalog, &d, &progress.Stage{}) digest, err := importPackageSBOM(context.TODO(), test.api, sessionID, sbomResult, &progress.Stage{})
// validate error handling // validate error handling
if err != nil && !test.expectsError { if err != nil && !test.expectsError {