From 49800b6747b3006efc9460ec2ecbb135fdb86d84 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Fri, 25 Sep 2020 14:07:38 -0400 Subject: [PATCH] Normalize the json image/dir source (#180) * normalize the json image/dir source Signed-off-by: Alex Goodman * update json image presenter golden file Signed-off-by: Alex Goodman --- schema/json/schema.json | 112 +++++++++++------- syft/lib.go | 2 +- syft/presenter/json/document.go | 17 +-- syft/presenter/json/source.go | 30 +++++ .../snapshot/TestJsonDirsPresenter.golden | 5 +- .../snapshot/TestJsonImgsPresenter.golden | 51 ++++---- .../anchore-fixture-image-simple.golden | Bin 23552 -> 23552 bytes 7 files changed, 136 insertions(+), 81 deletions(-) create mode 100644 syft/presenter/json/source.go diff --git a/schema/json/schema.json b/schema/json/schema.json index d8f07eb1a..6bc3dfb47 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 e7ee3e34b..7d7a7da88 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 b04c627b2..e43336df2 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 000000000..a44ad8676 --- /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 45fb1c47d..e73fecc86 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 41212e622..62d379db2 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 739b614870d13721615fb355e03552da1525bc68..3e1d2daaaed20003cb49b3a526de3f0e8cc9713f 100644 GIT binary patch literal 23552 zcmeHPTW{M&7WQ+0h01-|1#J1ueMZ1OWSamjP;3^h+X5Q|!CWJ5WztL1Z4ATzeGesB zz9g|^Qxcrb2(rb?%y9UfbI5ZY(AIDxJXo$lO94&>WuwqaCT$4=p;PdWP*+u)Rjj&%R# zhK{$V{xFpOzrOnE=O14G^P%Yi0g#;Er~CCjBFFC1pMv6WFd9sghbDD>?klH18Se$< zYqaz4Gecmo{Qsw|t2OtuPW}}W_vK&W13An88eF$=`m!iPF)4p z04DSAzxxJt)!DL&%{$ym<@;iCS$to&U1d)r_QDn~>r-rSv;RvQo5h(IU1$CD=Ps00 zF-dmT#=~NDtUkwExPLG<*mZgEq`O#czdnoA-Ero7uPcv}Shjyv{ZUM+^V#gM`0f<% zXtDXjseQkk=&$wc{4}=LXMU@j-^=R#%W^r}S5?L2IjY&F!6*2USf z`_*Al<7P1{tMd=V)dmbQl<>zhdl8#)uS0$Ivqt{;NBSQnf`}~tp9OS_C))Znrg9dK z=(zjPZE@gRL#?4d0A1++geobhME##A!884DLAbNc1?@-u^Aw-n?YBF-P#!oVkP*lT zWCWfS0#q?V1qq&^7m#>}0+RO$yqZ0#E>4AH60s4SPnAGFp_89)&LL)WOUJkqgsUT?dn`-8qluB_Hg%Zl9 z=oEuMxJaC83(EIEZrQ&3!YtoyQs_-_j08Jwr-;h%TXwsi8oAn zX{`W_E`~_80OQc{Yza*|NH0}jJQ`^dQjT!+P#6|1Q9(%qNU%{^jgCh>LtLBZ&zB2U z4ibvi(-D{>%1#KG2s+_xOemL9>fTWjYX3WWN&bjUTh{3BK!?g0`WAR@TDD!?pgZHu zlP#{<%_M!qIg&OI-SE5CEt@0uQ?BR{%Di{7S~SkLgyL0J$aY9I+{GL#d_Vqjnl zM8^`O=!r8i@B|K|r#x!yjAzn_IWbn&De0}#QE_#+Zl(rfSVo)2%rqqC6z55BYaEfz zpbrYC1d&CfgYlL+Zj!J{1(Phwea|jIIh%ymn!??g&h6;+GrdEkrMv4POt;A2SIFSE zyhMjZQ`cQWx6x(MU7YprfVoen?YXB+>0KG{+?!%43z4AXPN*Oe5hG&~DNvedib{F~ zPB<%55{^n@k_o!kE*!Ns0ICw!D~F>lM?&r(AY@c7aRxg2Xu*RWrWq zSitya@%CyHU)et1$NRp92Fm-FnQ$av{M8_Sl%e-lVK6vK8F?T&c&(70!6UxWGD3`| z7Mv#5#2v+dB}4yzj{okS8wS&VH}PM5eP#WB_tZZ)$noEOp!|HVFRxcj6Oy$jJR7@&mTX z7k3j3o~;MtGj7LQhUwR8lI>Ml82aGfLjH&PME(coS^wV)AD}mHHoMrwihufaHqHOO z$^QV+=YM4T|LK@-+H*<&@t@Q2{I5Ry@1|WhZr7*Augm}M+blnr|3i7s|JfMcK@FGm zuVRb&mOFY3JYN1OFns=J`5#2ujXK|@|2!LvZ95ZiZT=ry)PLMO|C!`D{=X6ZhBmTQ z-A!XN>M8&2H-DDhbcD&nu^o@cLx;}&GXfcbj6g=<86z;XSZ5QJaZ~+oRsV}lUyk)3 zS^wKT;|!+%PU62`R&*Lx$*xI zB}sn%4+4F|&K(v3%$#a3#;(GvVAp4BJz{k&?-R(@JH@hFua`U2yl zvS0Y%hD>N%f_gKlbYn%`de*QwHy0XcF^{U4(;eFUbxo)!u&dI0`@9x@Er`IjQ+|2-Y>NA$${{|6+ruL&J2q?5t?UtC>nmFXXWPi~qK$OvQv I{$COJAK@Xtvj6}9 literal 23552 zcmeHPZExc?63*xT3Rm~#3d9bF?=)~9_PPtSK+!GQTo34Cv7q>}*437BlG1Jv3CWH|VzcPsCC;1H*4U(> zlJ39UP;2{&kz?!nr$kaX8V%OTV~x7G_ZQbc zOb&wb4ch7d3qxRV|Nl=@l^fn^Q~y_--tYfhsMP;Az`B#$ms#PnX*Sdhvg7Q`)}d@s zmXN}EXPAw|G7=!?M)3efIp;vq7L0PU2whdjwz(_L& zI%aSRW=aVDjETU%U8$;UZBd5$10KcVV>Z3azNwnFw2OdMvBc|Yfdy{Q|J8*0`p&Di zwQlxP>x(j*Mmul9akjcvo#T7lzZhz)y1aPWUaXGao`rHL z&yTaO7x-G&hu<#j$7Mr*uIA^9(A?blcUAvdlpkLg%htXr+xp_HDmr|x>%J}jd0xy{ zqQ0|vm@lhe9cL9DX7i#v|CC)lZYDz&e=@fhp`LVes0TkA`al1_`5y(QWa|G90=mN+ zO|=NIn1?Z)w4d4?3ce$%*S~yZ{zv=yzfc4u>&gK-03zxC4upFV4o=X~ubuPON3d#Sn<#j0l-C ziQR?>5@Ynr<&J`IO6QItd2YRS0vrOlW7qC8b9#5Fp?BE{D(s}0A*$mJ+Q0q1tj@j~ zy?Xt6KFo(H9XgLK++X?X|{3pwDP2pzn4qoN$0 zj5>q3@yuVY6|4vnN@&N3j43&#WD0T$W+J&kB#0KjAV|J)zamBQTd13&Lb3xXl?h>! zj%Jw^O(v+k>)r*@jogo+qH6dv!r%a&aN z$3I7uHqjdEB{et|2+|XThsB&Q5j6)8HZsSp)|NACC5gatCp7}gQ0h`rj%MJv29TnQ zMJZyXjKO1+QRKu(NiAxC29P>ehG`cWC>y!bigq+(ek+NPToaUy1GFRHEgCHWA%S?R zwF?Zih}IE26%eTPme8CFtE_S&3T?9YR~y)}gM1|)^dUpZ+P%boaRkCJaEkvPz!C=Q ze=qT0pfbgO51{>{qZI!=2+S|`A%pw>aQ`0{d&qn7UjU>8()y1BSj{s2JJbwry@KAs zNHN>vY=1G^U7E#E#qTHnO9@Ny-(9NtL0RkW^@GI*-Pj!e?Z^MM_^+gC{2v7RmX%xN zfJPl#Gn(0E6$ak2aw?V(NC+eZ5(1ws0$r>`=O)sectHA905g!|pMW7)2+|-!Pr9%d zF6HErMr2|Q#)^@k!BxB5hQ08Apt!*KU&{a3zgZ2||6ce%B7mp)-~P3q_`gG7{F0wB zxc?95|1j1g?(u&ZKurAqLCj{!{|z+**Cr(Q zBuxzjGXuH9>_AK&RG6~qF?-ONsJc|m@4Eem`bX_+SwFNVT)N3vmx+WRk_ zq~HyOYt&U!U>0Z*nhiyteS1^?$8@|qdqMX7A2UtU{Qud2KcOP#|3A`0yJXP8opd_b Z{