mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
96 lines
3.3 KiB
Python
96 lines
3.3 KiB
Python
import os
|
|
import json
|
|
import collections
|
|
|
|
import utils.package
|
|
import utils.image
|
|
from utils.traverse import dig
|
|
|
|
|
|
class Syft:
|
|
"""
|
|
Class for parsing syft output into a set of packages and package metadata.
|
|
"""
|
|
report_tmpl = "{image}.json"
|
|
|
|
def __init__(self, image, report_dir):
|
|
self.report_path = os.path.join(
|
|
report_dir, self.report_tmpl.format(image=utils.image.clean(image))
|
|
)
|
|
|
|
def _enumerate_section(self, section):
|
|
with open(self.report_path) as json_file:
|
|
data = json.load(json_file)
|
|
for entry in data[section]:
|
|
yield entry
|
|
|
|
def packages(self):
|
|
packages = set()
|
|
metadata = collections.defaultdict(dict)
|
|
for entry in self._enumerate_section(section="artifacts"):
|
|
|
|
extra = {}
|
|
|
|
# normalize to inline
|
|
pkg_type = entry["type"].lower()
|
|
if pkg_type in ("wheel", "egg", "python"):
|
|
pkg_type = "python"
|
|
elif pkg_type in ("deb",):
|
|
pkg_type = "dpkg"
|
|
elif pkg_type in ("java-archive",):
|
|
# normalize to pseudo-inline
|
|
pkg_type = "java-?ar"
|
|
elif pkg_type in ("jenkins-plugin",):
|
|
# normalize to pseudo-inline
|
|
pkg_type = "java-?pi"
|
|
elif pkg_type in ("apk",):
|
|
pkg_type = "apkg"
|
|
|
|
pkg = utils.package.Package(
|
|
name=entry["name"],
|
|
type=pkg_type,
|
|
)
|
|
|
|
packages.add(pkg)
|
|
|
|
if "java" in pkg_type:
|
|
# lets match what inline scan expects to output
|
|
|
|
path = dig(entry, "locations", 0, "path")
|
|
specVendor = dig(entry, "metadata", "manifest", "specificationVendor")
|
|
implVendor = dig(entry, "metadata", "manifest", "implementationVendor")
|
|
|
|
specVersion = dig(entry, "metadata", "manifest", "specificationVersion") or None
|
|
implVersion = dig(entry, "metadata", "manifest", "implementationVersion") or None
|
|
|
|
extra = {
|
|
"implementation-version": implVersion,
|
|
"specification-version": specVersion,
|
|
"origin": dig(entry, "metadata", "pomProperties", "groupId"),
|
|
"location": path,
|
|
"package": dig(entry, "metadata", "pomProperties", "artifactId"),
|
|
}
|
|
|
|
if dig(entry, "metadata", "parentPackage"):
|
|
extra['origin'] = dig(entry, "metadata", "pomProperties", "groupId")
|
|
else:
|
|
# this is a nested package...
|
|
if specVendor:
|
|
extra['origin'] = specVendor
|
|
elif implVendor:
|
|
extra['origin'] = implVendor
|
|
|
|
pomPath = dig(entry, "metadata", "pomProperties", "Path")
|
|
if path and pomPath:
|
|
extra["location"] = "%s:%s" % (path, pomPath),
|
|
|
|
# temp temp temp
|
|
extra.pop("location")
|
|
|
|
elif pkg_type == "apkg":
|
|
entry["version"] = entry["version"].split("-")[0]
|
|
|
|
metadata[pkg.type][pkg] = utils.package.Metadata(version=entry["version"], extra=tuple(sorted(extra.items())))
|
|
|
|
return utils.package.Info(packages=frozenset(packages), metadata=metadata)
|