migrate scope option to image metadata (from source)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2020-11-16 08:47:24 -05:00
parent 91baabe5a1
commit f46de19c6b
No known key found for this signature in database
GPG Key ID: 5CB45AE22BAB7EA7
14 changed files with 59 additions and 60 deletions

View File

@ -339,16 +339,12 @@
"name": { "name": {
"type": "string" "type": "string"
}, },
"scope": {
"type": "string"
},
"version": { "version": {
"type": "string" "type": "string"
} }
}, },
"required": [ "required": [
"name", "name",
"scope",
"version" "version"
], ],
"type": "object" "type": "object"
@ -409,6 +405,9 @@
"mediaType": { "mediaType": {
"type": "string" "type": "string"
}, },
"scope": {
"type": "string"
},
"size": { "size": {
"type": "integer" "type": "integer"
}, },
@ -426,6 +425,7 @@
"digest", "digest",
"layers", "layers",
"mediaType", "mediaType",
"scope",
"size", "size",
"tags", "tags",
"userInput" "userInput"

View File

@ -83,11 +83,11 @@ func CatalogFromScope(s source.Source) (*pkg.Catalog, error) {
} }
// CatalogFromJSON takes an existing syft report and generates catalog primitives. // CatalogFromJSON takes an existing syft report and generates catalog primitives.
func CatalogFromJSON(reader io.Reader) (*pkg.Catalog, *distro.Distro, *source.ImageMetadata, error) { func CatalogFromJSON(reader io.Reader) (*pkg.Catalog, *distro.Distro, source.Metadata, error) {
var doc jsonPresenter.Document var doc jsonPresenter.Document
decoder := json.NewDecoder(reader) decoder := json.NewDecoder(reader)
if err := decoder.Decode(&doc); err != nil { if err := decoder.Decode(&doc); err != nil {
return nil, nil, nil, err return nil, nil, source.Metadata{}, err
} }
var pkgs = make([]pkg.Package, len(doc.Artifacts)) var pkgs = make([]pkg.Package, len(doc.Artifacts))
@ -104,18 +104,12 @@ func CatalogFromJSON(reader io.Reader) (*pkg.Catalog, *distro.Distro, *source.Im
distroType = distro.Type(doc.Distro.Name) distroType = distro.Type(doc.Distro.Name)
} }
d, err := distro.NewDistro(distroType, doc.Distro.Version, doc.Distro.IDLike) theDistro, err := distro.NewDistro(distroType, doc.Distro.Version, doc.Distro.IDLike)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, source.Metadata{}, err
} }
var imageMetadata *source.ImageMetadata return catalog, &theDistro, doc.Source.ToSourceMetadata(), nil
if doc.Source.Type == "image" {
payload := doc.Source.Target.(source.ImageMetadata)
imageMetadata = &payload
}
return catalog, &d, imageMetadata, nil
} }
// SetLogger sets the logger object used for all syft logging calls. // SetLogger sets the logger object used for all syft logging calls.

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.2" xmlns:bd="http://cyclonedx.org/schema/ext/bom-descriptor/1.0" version="1" serialNumber="urn:uuid:2bbada20-3e87-44ea-9a56-1aa0e4dd01a0"> <bom xmlns="http://cyclonedx.org/schema/bom/1.2" xmlns:bd="http://cyclonedx.org/schema/ext/bom-descriptor/1.0" version="1" serialNumber="urn:uuid:815fdd6b-917e-423d-8c91-1fe648141505">
<components> <components>
<component type="library"> <component type="library">
<name>package1</name> <name>package1</name>
@ -21,7 +21,7 @@
</component> </component>
</components> </components>
<bd:metadata> <bd:metadata>
<bd:timestamp>2020-09-23T18:26:58-04:00</bd:timestamp> <bd:timestamp>2020-11-16T08:45:54-05:00</bd:timestamp>
<bd:tool> <bd:tool>
<bd:vendor>anchore</bd:vendor> <bd:vendor>anchore</bd:vendor>
<bd:name>syft</bd:name> <bd:name>syft</bd:name>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.2" xmlns:bd="http://cyclonedx.org/schema/ext/bom-descriptor/1.0" version="1" serialNumber="urn:uuid:94dae829-4d5d-482f-afab-27f43f919e2c"> <bom xmlns="http://cyclonedx.org/schema/bom/1.2" xmlns:bd="http://cyclonedx.org/schema/ext/bom-descriptor/1.0" version="1" serialNumber="urn:uuid:3cb10332-1645-44f6-be4a-4f8be5a60cf8">
<components> <components>
<component type="library"> <component type="library">
<name>package1</name> <name>package1</name>
@ -21,15 +21,15 @@
</component> </component>
</components> </components>
<bd:metadata> <bd:metadata>
<bd:timestamp>2020-09-23T18:26:58-04:00</bd:timestamp> <bd:timestamp>2020-11-16T08:45:54-05:00</bd:timestamp>
<bd:tool> <bd:tool>
<bd:vendor>anchore</bd:vendor> <bd:vendor>anchore</bd:vendor>
<bd:name>syft</bd:name> <bd:name>syft</bd:name>
<bd:version>[not provided]</bd:version> <bd:version>[not provided]</bd:version>
</bd:tool> </bd:tool>
<bd:component type="container"> <bd:component type="container">
<name>index.docker.io/library/stereoscope-fixture-image-simple</name> <name>user-image-input</name>
<version>04e16e44161c8888a1a963720fd0443cbf7eef8101434c431de8725cd98cc9f7</version> <version>sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368</version>
</bd:component> </bd:component>
</bd:metadata> </bd:metadata>
</bom> </bom>

View File

@ -0,0 +1,7 @@
package json
// Descriptor describes what created the document as well as surrounding metadata
type Descriptor struct {
Name string `json:"name"`
Version string `json:"version"`
}

View File

@ -0,0 +1,8 @@
package json
// Distribution provides information about a detected Linux Distribution
type Distribution struct {
Name string `json:"name"`
Version string `json:"version"`
IDLike string `json:"idLike"`
}

View File

@ -15,20 +15,6 @@ type Document struct {
Descriptor Descriptor `json:"descriptor"` Descriptor Descriptor `json:"descriptor"`
} }
// Descriptor describes what created the document as well as surrounding metadata
type Descriptor struct {
Name string `json:"name"`
Version string `json:"version"`
Scope string `json:"scope"`
}
// Distribution provides information about a detected Linux Distribution
type Distribution struct {
Name string `json:"name"`
Version string `json:"version"`
IDLike string `json:"idLike"`
}
func NewDocument(catalog *pkg.Catalog, srcMetadata source.Metadata, d distro.Distro) (Document, error) { func NewDocument(catalog *pkg.Catalog, srcMetadata source.Metadata, d distro.Distro) (Document, error) {
src, err := NewSource(srcMetadata) src, err := NewSource(srcMetadata)
if err != nil { if err != nil {
@ -51,7 +37,6 @@ func NewDocument(catalog *pkg.Catalog, srcMetadata source.Metadata, d distro.Dis
Descriptor: Descriptor{ Descriptor: Descriptor{
Name: internal.ApplicationName, Name: internal.ApplicationName,
Version: version.FromBuild().Version, Version: version.FromBuild().Version,
Scope: srcMetadata.Scope.String(),
}, },
} }

View File

@ -56,3 +56,16 @@ func (s *Source) UnmarshalJSON(b []byte) error {
return nil return nil
} }
func (s *Source) ToSourceMetadata() source.Metadata {
var metadata source.Metadata
switch s.Type {
case "directory":
metadata.Scheme = source.DirectoryScheme
metadata.Path = s.Target.(string)
case "image":
metadata.Scheme = source.ImageScheme
metadata.ImageMetadata = s.Target.(source.ImageMetadata)
}
return metadata
}

View File

@ -4,9 +4,7 @@
"name": "package-1", "name": "package-1",
"version": "1.0.1", "version": "1.0.1",
"type": "python", "type": "python",
"foundBy": [ "foundBy": "the-cataloger-1",
"the-cataloger-1"
],
"locations": [ "locations": [
{ {
"path": "/some/path/pkg1" "path": "/some/path/pkg1"
@ -31,9 +29,7 @@
"name": "package-2", "name": "package-2",
"version": "2.0.1", "version": "2.0.1",
"type": "deb", "type": "deb",
"foundBy": [ "foundBy": "the-cataloger-2",
"the-cataloger-2"
],
"locations": [ "locations": [
{ {
"path": "/some/path/pkg1" "path": "/some/path/pkg1"
@ -64,7 +60,6 @@
}, },
"descriptor": { "descriptor": {
"name": "syft", "name": "syft",
"version": "[not provided]", "version": "[not provided]"
"scope": ""
} }
} }

View File

@ -4,9 +4,7 @@
"name": "package-1", "name": "package-1",
"version": "1.0.1", "version": "1.0.1",
"type": "python", "type": "python",
"foundBy": [ "foundBy": "the-cataloger-1",
"the-cataloger-1"
],
"locations": [ "locations": [
{ {
"path": "/somefile-1.txt", "path": "/somefile-1.txt",
@ -32,9 +30,7 @@
"name": "package-2", "name": "package-2",
"version": "2.0.1", "version": "2.0.1",
"type": "deb", "type": "deb",
"foundBy": [ "foundBy": "the-cataloger-2",
"the-cataloger-2"
],
"locations": [ "locations": [
{ {
"path": "/somefile-2.txt", "path": "/somefile-2.txt",
@ -58,6 +54,8 @@
"source": { "source": {
"type": "image", "type": "image",
"target": { "target": {
"userInput": "user-image-input",
"scope": "AllLayers",
"layers": [ "layers": [
{ {
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
@ -90,7 +88,6 @@
}, },
"descriptor": { "descriptor": {
"name": "syft", "name": "syft",
"version": "[not provided]", "version": "[not provided]"
"scope": "AllLayers"
} }
} }

View File

@ -4,6 +4,7 @@ import "github.com/anchore/stereoscope/pkg/image"
type ImageMetadata struct { type ImageMetadata struct {
UserInput string `json:"userInput"` UserInput string `json:"userInput"`
Scope Scope `json:"scope"` // specific perspective to catalog
Layers []LayerMetadata `json:"layers"` Layers []LayerMetadata `json:"layers"`
Size int64 `json:"size"` Size int64 `json:"size"`
Digest string `json:"digest"` Digest string `json:"digest"`
@ -17,7 +18,7 @@ type LayerMetadata struct {
Size int64 `json:"size"` Size int64 `json:"size"`
} }
func NewImageMetadata(img *image.Image, userInput string) ImageMetadata { func NewImageMetadata(img *image.Image, userInput string, scope Scope) ImageMetadata {
// populate artifacts... // populate artifacts...
tags := make([]string, len(img.Metadata.Tags)) tags := make([]string, len(img.Metadata.Tags))
for idx, tag := range img.Metadata.Tags { for idx, tag := range img.Metadata.Tags {
@ -25,6 +26,7 @@ func NewImageMetadata(img *image.Image, userInput string) ImageMetadata {
} }
theImg := ImageMetadata{ theImg := ImageMetadata{
UserInput: userInput, UserInput: userInput,
Scope: scope,
Digest: img.Metadata.Digest, Digest: img.Metadata.Digest,
Size: img.Metadata.Size, Size: img.Metadata.Size,
MediaType: string(img.Metadata.MediaType), MediaType: string(img.Metadata.MediaType),

View File

@ -1,7 +1,6 @@
package source package source
type Metadata struct { type Metadata struct {
Scope Scope // specific perspective to catalog
Scheme Scheme // the source data scheme type (directory or image) Scheme Scheme // the source data scheme type (directory or image)
ImageMetadata ImageMetadata // all image info (image only) ImageMetadata ImageMetadata // all image info (image only)
Path string // the root path to be cataloged (directory only) Path string // the root path to be cataloged (directory only)

View File

@ -85,12 +85,12 @@ func NewFromDirectory(path string) (Source, error) {
// NewFromImage creates a new source object tailored to catalog a given container image, relative to the // NewFromImage creates a new source object tailored to catalog a given container image, relative to the
// option given (e.g. all-layers, squashed, etc) // option given (e.g. all-layers, squashed, etc)
func NewFromImage(img *image.Image, option Scope, userImageStr string) (Source, error) { func NewFromImage(img *image.Image, scope Scope, userImageStr string) (Source, error) {
if img == nil { if img == nil {
return Source{}, fmt.Errorf("no image given") return Source{}, fmt.Errorf("no image given")
} }
resolver, err := getImageResolver(img, option) resolver, err := getImageResolver(img, scope)
if err != nil { if err != nil {
return Source{}, fmt.Errorf("could not determine file resolver: %w", err) return Source{}, fmt.Errorf("could not determine file resolver: %w", err)
} }
@ -99,9 +99,8 @@ func NewFromImage(img *image.Image, option Scope, userImageStr string) (Source,
Resolver: resolver, Resolver: resolver,
Image: img, Image: img,
Metadata: Metadata{ Metadata: Metadata{
Scope: option,
Scheme: ImageScheme, Scheme: ImageScheme,
ImageMetadata: NewImageMetadata(img, userImageStr), ImageMetadata: NewImageMetadata(img, userImageStr, scope),
}, },
}, nil }, nil
} }

View File

@ -42,12 +42,12 @@ func TestCatalogFromJSON(t *testing.T) {
t.Fatalf("failed to write to presenter: %+v", err) t.Fatalf("failed to write to presenter: %+v", err)
} }
actualCatalog, actualDistro, imageMetadata, err := syft.CatalogFromJSON(&buf) actualCatalog, actualDistro, sourceMetadata, err := syft.CatalogFromJSON(&buf)
if err != nil { if err != nil {
t.Fatalf("failed to import document: %+v", err) t.Fatalf("failed to import document: %+v", err)
} }
for _, d := range deep.Equal(*imageMetadata, expectedSource.Metadata.ImageMetadata) { for _, d := range deep.Equal(sourceMetadata, expectedSource.Metadata) {
t.Errorf(" image metadata diff: %+v", d) t.Errorf(" image metadata diff: %+v", d)
} }