mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
migrate scope option to image metadata (from source)
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
91baabe5a1
commit
f46de19c6b
@ -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"
|
||||||
|
|||||||
16
syft/lib.go
16
syft/lib.go
@ -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.
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
7
syft/presenter/json/descriptor.go
Normal file
7
syft/presenter/json/descriptor.go
Normal 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"`
|
||||||
|
}
|
||||||
8
syft/presenter/json/distribution.go
Normal file
8
syft/presenter/json/distribution.go
Normal 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"`
|
||||||
|
}
|
||||||
@ -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(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
|
|||||||
@ -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": ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user