diff --git a/schema/json/schema.json b/schema/json/schema.json index d8f07eb1ab8..6bc3dfb4723 100644 --- a/schema/json/schema.json +++ b/schema/json/schema.json @@ -200,6 +200,9 @@ } ] }, + "name": { + "type": "string" + }, "originPackage": { "type": "string" }, @@ -444,9 +447,15 @@ "source": { "type": "string" }, + "sourceRpm": { + "type": "string" + }, "url": { "type": "string" }, + "vendor": { + "type": "string" + }, "version": { "type": "string" } @@ -474,61 +483,78 @@ }, "type": "array" }, - "directory": { - "type": "string" - }, - "image": { + "source": { "properties": { - "digest": { - "type": "string" - }, - "layers": { - "items": { - "properties": { - "digest": { - "type": "string" - }, - "mediaType": { - "type": "string" - }, - "size": { - "type": "integer" - } + "target": { + "anyOf": [ + { + "type": "string" }, - "required": [ - "digest", - "mediaType", - "size" - ], - "type": "object" - }, - "type": "array" + { + "properties": { + "digest": { + "type": "string" + }, + "layers": { + "items": { + "properties": { + "digest": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "size": { + "type": "integer" + } + }, + "required": [ + "digest", + "mediaType", + "size" + ], + "type": "object" + }, + "type": "array" + }, + "mediaType": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "digest", + "layers", + "mediaType", + "size", + "tags" + ], + "type": "object" + } + ] }, - "mediaType": { + "type": { "type": "string" - }, - "size": { - "type": "integer" - }, - "tags": { - "items": { - "type": "string" - }, - "type": "array" } }, "required": [ - "digest", - "layers", - "mediaType", - "size", - "tags" + "target", + "type" ], "type": "object" } }, "required": [ - "artifacts" + "artifacts", + "source" ], "type": "object" } \ No newline at end of file diff --git a/syft/lib.go b/syft/lib.go index e7ee3e34b2c..7d7a7da885f 100644 --- a/syft/lib.go +++ b/syft/lib.go @@ -3,7 +3,7 @@ A "one-stop-shop" for helper utilities for all major functionality provided by c Here is what the main execution path for syft does: - 1. Parse a user image string to get a stereoscope image.Image object + 1. Parse a user image string to get a stereoscope image.Source object 2. Invoke all catalogers to catalog the image, adding discovered packages to a single catalog object 3. Invoke a single presenter to show the contents of the catalog diff --git a/syft/presenter/json/document.go b/syft/presenter/json/document.go index b04c627b2a1..e43336df249 100644 --- a/syft/presenter/json/document.go +++ b/syft/presenter/json/document.go @@ -1,16 +1,13 @@ package json import ( - "fmt" - "github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/scope" ) type Document struct { Artifacts []Artifact `json:"artifacts"` - Image *Image `json:"image,omitempty"` - Directory *string `json:"directory,omitempty"` + Source Source `json:"source"` } func NewDocument(catalog *pkg.Catalog, s scope.Scope) (Document, error) { @@ -18,15 +15,11 @@ func NewDocument(catalog *pkg.Catalog, s scope.Scope) (Document, error) { Artifacts: make([]Artifact, 0), } - srcObj := s.Source() - switch src := srcObj.(type) { - case scope.ImageSource: - doc.Image = NewImage(src) - case scope.DirSource: - doc.Directory = &s.DirSrc.Path - default: - return Document{}, fmt.Errorf("unsupported source: %T", src) + src, err := NewSource(s) + if err != nil { + return Document{}, nil } + doc.Source = src for _, p := range catalog.Sorted() { art, err := NewArtifact(p, s) diff --git a/syft/presenter/json/source.go b/syft/presenter/json/source.go new file mode 100644 index 00000000000..a44ad86763b --- /dev/null +++ b/syft/presenter/json/source.go @@ -0,0 +1,30 @@ +package json + +import ( + "fmt" + + "github.com/anchore/syft/syft/scope" +) + +type Source struct { + Type string `json:"type"` + Target interface{} `json:"target"` +} + +func NewSource(s scope.Scope) (Source, error) { + srcObj := s.Source() + switch src := srcObj.(type) { + case scope.ImageSource: + return Source{ + Type: "image", + Target: NewImage(src), + }, nil + case scope.DirSource: + return Source{ + Type: "directory", + Target: s.DirSrc.Path, + }, nil + default: + return Source{}, fmt.Errorf("unsupported source: %T", src) + } +} diff --git a/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden b/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden index 45fb1c47dcf..e73fecc869c 100644 --- a/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden +++ b/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden @@ -23,5 +23,8 @@ ] } ], - "directory": "/some/path" + "source": { + "type": "directory", + "target": "/some/path" + } } diff --git a/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden b/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden index 41212e6224d..62d379db26a 100644 --- a/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden +++ b/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden @@ -29,29 +29,32 @@ ] } ], - "image": { - "layers": [ - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "digest": "sha256:e158b57d6f5a96ef5fd22f2fe76c70b5ba6ff5b2619f9d83125b2aad0492ac7b", - "size": 22 - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "digest": "sha256:da21056e7bf4308ecea0c0836848a7fe92f38fdcf35bc09ee6d98e7ab7beeebf", - "size": 16 - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "digest": "sha256:f0e18aa6032c24659a9c741fc36ca56f589782ea132061ccf6f52b952403da94", - "size": 27 - } - ], - "size": 65, - "digest": "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368", - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "tags": [ - "stereoscope-fixture-image-simple:04e16e44161c8888a1a963720fd0443cbf7eef8101434c431de8725cd98cc9f7" - ] + "source": { + "type": "image", + "target": { + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:e158b57d6f5a96ef5fd22f2fe76c70b5ba6ff5b2619f9d83125b2aad0492ac7b", + "size": 22 + }, + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:da21056e7bf4308ecea0c0836848a7fe92f38fdcf35bc09ee6d98e7ab7beeebf", + "size": 16 + }, + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:f0e18aa6032c24659a9c741fc36ca56f589782ea132061ccf6f52b952403da94", + "size": 27 + } + ], + "size": 65, + "digest": "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368", + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "tags": [ + "stereoscope-fixture-image-simple:04e16e44161c8888a1a963720fd0443cbf7eef8101434c431de8725cd98cc9f7" + ] + } } } diff --git a/syft/presenter/json/test-fixtures/snapshot/anchore-fixture-image-simple.golden b/syft/presenter/json/test-fixtures/snapshot/anchore-fixture-image-simple.golden index 739b614870d..3e1d2daaaed 100644 Binary files a/syft/presenter/json/test-fixtures/snapshot/anchore-fixture-image-simple.golden and b/syft/presenter/json/test-fixtures/snapshot/anchore-fixture-image-simple.golden differ