Properly report all arches and RPMs

This commit is contained in:
Mustafa Gezen 2023-02-05 02:14:58 +01:00
parent 47179f62f5
commit ba9c8c2f05
Signed by untrusted user who does not match committer: mustafa
GPG Key ID: DCDF010D946438C1

View File

@ -9,7 +9,7 @@ from slugify import slugify
from apollo.db import Advisory from apollo.db import Advisory
from apollo.db.advisory import fetch_advisories from apollo.db.advisory import fetch_advisories
from apollo.rpmworker.repomd import EPOCH_RE, NVRA_RE from apollo.rpmworker.repomd import EPOCH_RE, NEVRA_RE
from apollo.server.settings import UI_URL, get_setting from apollo.server.settings import UI_URL, get_setting
from common.fastapi import Params, to_rfc3339_date from common.fastapi import Params, to_rfc3339_date
@ -104,82 +104,59 @@ class OSVAdvisory(BaseModel):
def to_osv_advisory(ui_url: str, advisory: Advisory) -> OSVAdvisory: def to_osv_advisory(ui_url: str, advisory: Advisory) -> OSVAdvisory:
affected_pkgs = [] affected_pkgs = []
vendors = []
pkg_name_map = {} pkg_name_map = {}
for pkg in advisory.packages: for pkg in advisory.packages:
if pkg.supported_product.vendor not in vendors:
vendors.append(pkg.supported_product.vendor)
nevra = NEVRA_RE.search(pkg.nevra)
name = nevra.group(1)
arch = nevra.group(5).lower()
product_name = slugify(pkg.product_name) product_name = slugify(pkg.product_name)
if pkg.supported_products_rh_mirror: if pkg.supported_products_rh_mirror:
product_name = f"{slugify(pkg.supported_product.variant)}:{pkg.supported_products_rh_mirror.match_major_version}" product_name = f"{slugify(pkg.supported_product.variant)}:{pkg.supported_products_rh_mirror.match_major_version}"
if product_name not in pkg_name_map: if product_name not in pkg_name_map:
pkg_name_map[product_name] = {} pkg_name_map[product_name] = {}
if pkg.package_name not in pkg_name_map[product_name]: if arch not in pkg_name_map[product_name]:
pkg_name_map[product_name][pkg.package_name] = [] pkg_name_map[product_name][arch] = {}
if name not in pkg_name_map[product_name][arch]:
pkg_name_map[product_name][arch][name] = []
pkg_name_map[product_name][pkg.package_name].append(pkg) pkg_name_map[product_name][arch][name].append((pkg, nevra))
vendors = [] for product_name, arches in pkg_name_map.items():
for product_name, pkgs in pkg_name_map.items(): for arch, affected_arches in arches.items():
for pkg_name, affected_packages in pkgs.items(): if not affected_arches:
if not affected_packages:
continue continue
first_pkg = None for pkg_name, affected_packages in affected_arches.items():
noarch_pkg = None for pkg in affected_packages:
arch = None x = pkg[0]
nvra = None nevra = pkg[1]
ver_rel = None
for x in affected_packages:
if x.supported_product.vendor not in vendors:
vendors.append(x.supported_product.vendor)
nvra = NVRA_RE.search(EPOCH_RE.sub("", x.nevra))
if not nvra:
continue
ver_rel = f"{nvra.group(2)}-{nvra.group(3)}"
if x.supported_products_rh_mirror:
first_pkg = x
arch = x.supported_products_rh_mirror.match_arch
break
arch = nvra.group(4).lower()
if arch == "src": ver_rel = f"{nevra.group(3)}-{nevra.group(4)}"
continue slugified = slugify(x.supported_product.variant)
slugified_distro = slugify(x.product_name)
if arch == "noarch": for arch_, _ in arches.items():
noarch_pkg = x slugified_arch = f"-{slugify(arch_)}"
continue
first_pkg = x
break
if not first_pkg and noarch_pkg:
first_pkg = noarch_pkg
if not ver_rel:
continue
purl = None
if first_pkg:
slugified = slugify(first_pkg.supported_product.variant)
slugified_distro = slugify(first_pkg.product_name)
slugified_distro = slugified_distro.replace( slugified_distro = slugified_distro.replace(
f"-{slugify(arch)}", slugified_arch,
"", "",
) )
epoch = nevra.group(2)
purl = f"pkg:rpm/{slugified}/{pkg_name}@{ver_rel}?arch={arch}&distro={slugified_distro}&epoch={epoch}"
purl = f"pkg:rpm/{slugified}/{pkg_name}@{ver_rel}?arch={arch}&distro={slugified_distro}"
affected = OSVAffected( affected = OSVAffected(
package=OSVPackage( package=OSVPackage(
ecosystem=product_name, ecosystem=product_name,
name=pkg_name, name=pkg_name,
purl=purl, purl=purl,
), ),
ranges=[], ranges=[
versions=[],
ecosystem_specific=OSVEcosystemSpecific(),
database_specific=OSVAffectedDatabaseSpecific(),
)
for x in affected_packages:
ranges = [
OSVRange( OSVRange(
type="ECOSYSTEM", type="ECOSYSTEM",
repo=x.repo_name, repo=x.repo_name,
@ -189,8 +166,11 @@ def to_osv_advisory(ui_url: str, advisory: Advisory) -> OSVAdvisory:
], ],
database_specific=OSVRangeDatabaseSpecific(), database_specific=OSVRangeDatabaseSpecific(),
) )
] ],
affected.ranges.extend(ranges) versions=[],
ecosystem_specific=OSVEcosystemSpecific(),
database_specific=OSVAffectedDatabaseSpecific(),
)
affected_pkgs.append(affected) affected_pkgs.append(affected)