Skip to content

Commit 2ad0f01

Browse files
committed
Migrate Rockylinux Importer to Importer_Pipeline
Signed-off-by: ambuj <kulshreshthaak.12@gmail.com>
1 parent b0ca192 commit 2ad0f01

File tree

5 files changed

+78
-134
lines changed

5 files changed

+78
-134
lines changed

vulnerabilities/importers/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
from vulnerabilities.importers import pysec
3030
from vulnerabilities.importers import redhat
3131
from vulnerabilities.importers import retiredotnet
32-
from vulnerabilities.importers import rockylinux
3332
from vulnerabilities.importers import ruby
3433
from vulnerabilities.importers import suse_scores
3534
from vulnerabilities.importers import ubuntu
@@ -43,6 +42,7 @@
4342
from vulnerabilities.pipelines import npm_importer
4443
from vulnerabilities.pipelines import nvd_importer
4544
from vulnerabilities.pipelines import pypa_importer
45+
from vulnerabilities.pipelines import rockylinux_importer
4646

4747
IMPORTERS_REGISTRY = [
4848
pysec.PyPIImporter,
@@ -70,7 +70,6 @@
7070
oss_fuzz.OSSFuzzImporter,
7171
ruby.RubyImporter,
7272
github_osv.GithubOSVImporter,
73-
rockylinux.RockyLinuxImporter,
7473
curl.CurlImporter,
7574
epss.EPSSImporter,
7675
vulnrichment.VulnrichImporter,
@@ -80,6 +79,7 @@
8079
gitlab_importer.GitLabImporterPipeline,
8180
github_importer.GitHubAPIImporterPipeline,
8281
nvd_importer.NVDImporterPipeline,
82+
rockylinux_importer.RockylinuxImporterPipeline,
8383
]
8484

8585
IMPORTERS_REGISTRY = {

vulnerabilities/improvers/valid_versions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
from vulnerabilities.importers.github_osv import GithubOSVImporter
3535
from vulnerabilities.importers.istio import IstioImporter
3636
from vulnerabilities.importers.oss_fuzz import OSSFuzzImporter
37-
from vulnerabilities.importers.rockylinux import RockyLinuxImporter
3837
from vulnerabilities.importers.ruby import RubyImporter
3938
from vulnerabilities.importers.ubuntu import UbuntuImporter
4039
from vulnerabilities.improver import MAX_CONFIDENCE
@@ -46,6 +45,7 @@
4645
from vulnerabilities.pipelines.gitlab_importer import GitLabImporterPipeline
4746
from vulnerabilities.pipelines.nginx_importer import NginxImporterPipeline
4847
from vulnerabilities.pipelines.npm_importer import NpmImporterPipeline
48+
from vulnerabilities.pipelines.rockylinux_importer import RockylinuxImporterPipeline
4949
from vulnerabilities.utils import AffectedPackage as LegacyAffectedPackage
5050
from vulnerabilities.utils import clean_nginx_git_tag
5151
from vulnerabilities.utils import get_affected_packages_by_patched_package
@@ -480,7 +480,7 @@ class GithubOSVImprover(ValidVersionImprover):
480480

481481

482482
class RockyLinuxImprover(ValidVersionImprover):
483-
importer = RockyLinuxImporter
483+
importer = RockylinuxImporterPipeline
484484
ignorable_versions = []
485485

486486

vulnerabilities/importers/rockylinux.py renamed to vulnerabilities/pipelines/rockylinux_importer.py

Lines changed: 64 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,62 +13,70 @@
1313
from typing import Iterable
1414
from typing import List
1515

16-
import dateparser
1716
import requests
1817
from cwe2.database import Database
18+
from dateutil import parser as dateparser
1919
from packageurl import PackageURL
2020
from univers.version_range import RpmVersionRange
2121

2222
from vulnerabilities import severity_systems
2323
from vulnerabilities.importer import AdvisoryData
2424
from vulnerabilities.importer import AffectedPackage
25-
from vulnerabilities.importer import Importer
2625
from vulnerabilities.importer import Reference
2726
from vulnerabilities.importer import VulnerabilitySeverity
27+
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipeline
2828
from vulnerabilities.rpm_utils import rpm_to_purl
2929
from vulnerabilities.utils import get_cwe_id
30-
from vulnerabilities.utils import get_item
3130
from vulnerabilities.utils import requests_with_5xx_retry
3231

3332
logger = logging.getLogger(__name__)
34-
35-
# FIXME: we should use a centralized retry
3633
requests_session = requests_with_5xx_retry(max_retries=5, backoff_factor=1)
3734

3835

39-
def fetch_cves() -> Iterable[List[Dict]]:
40-
page_no = 0
41-
cve_data_list = []
42-
while True:
43-
current_url = f"https://errata.rockylinux.org/api/v2/advisories?filters.product=&filters.fetchRelated=true&page={page_no}&limit=100"
44-
try:
45-
response = requests_session.get(current_url)
46-
if response.status_code != requests.codes.ok:
47-
logger.error(f"Failed to fetch RedHat CVE results from {current_url}")
48-
break
49-
cve_data = response.json().get("advisories") or []
50-
cve_data_list.extend(cve_data)
51-
except Exception as e:
52-
logger.error(f"Failed to fetch rockylinux CVE results from {current_url} {e}")
53-
break
54-
if not cve_data:
55-
break
56-
page_no += 1
57-
return cve_data_list
58-
59-
60-
class RockyLinuxImporter(Importer):
36+
class RockylinuxImporterPipeline(VulnerableCodeBaseImporterPipeline):
37+
pipeline_id = "rockylinux_importer"
38+
6139
spdx_license_expression = "CC-BY-4.0"
6240
license_url = "https://access.redhat.com/security/data"
63-
importer_name = "Rocky Importer"
41+
importer_name = "Rockylinux Importer"
42+
43+
@classmethod
44+
def steps(cls):
45+
return (cls.fetch, cls.collect_and_store_advisories, cls.import_new_advisories)
46+
47+
def fetch(self) -> Iterable[List[Dict]]:
48+
page_no = 0
49+
self.advisory_data = []
50+
51+
while True:
52+
current_url = f"https://errata.rockylinux.org/api/v2/advisories?filters.product=&filters.fetchRelated=true&page={page_no}&limit=100"
53+
try:
54+
response = requests_session.get(current_url)
55+
if response.status_code != requests.codes.ok:
56+
logger.error(f"Failed to fetch RedHat CVE results from {current_url}")
57+
break
58+
cve_data = response.json().get("advisories") or []
59+
self.advisory_data.extend(cve_data)
60+
except Exception as e:
61+
logger.error(f"Failed to fetch rockylinux CVE results from {current_url} {e}")
62+
break
63+
if not cve_data:
64+
break
65+
page_no += 1
66+
67+
def advisories_count(self):
68+
return len(self.advisory_data)
69+
70+
def collect_advisories(self) -> Iterable[AdvisoryData]:
71+
for rl_advisory in self.advisory_data:
72+
yield to_advisory(rl_advisory)
6473

65-
def advisory_data(self) -> Iterable[AdvisoryData]:
6674

67-
for rockylinux_cve in fetch_cves():
68-
yield to_advisory(rockylinux_cve)
75+
class VersionParsingError(Exception):
76+
pass
6977

7078

71-
def to_advisory(advisory_data):
79+
def to_advisory(advisory_data) -> AdvisoryData:
7280

7381
"""
7482
Convert Rockylinux advisory data into an AdvisoryData object.
@@ -169,24 +177,36 @@ def to_advisory(advisory_data):
169177
for fix in advisory_data["fixes"]
170178
]
171179

172-
for ref in advisory_data.get("cves") or []:
180+
for ref in advisory_data.get("cves", []):
173181

174182
name = ref.get("name", "")
175183
if not isinstance(name, str):
176184
logger.error(f"Invalid advisory type {name}")
177185
continue
178186

179-
if "CVE" in name.upper():
180-
severities = VulnerabilitySeverity(
181-
system=severity_systems.CVSSV31,
182-
value=ref.get("cvss3BaseScore", ""),
183-
scoring_elements=ref.get("cvss3ScoringVector", "")
184-
if ref.get("cvss3ScoringVector", "") != "UNKNOWN"
185-
else "",
186-
)
187-
references.append(
188-
Reference(severities=[severities], url=ref.get("sourceLink", ""), reference_id=name)
189-
)
187+
if ref.get("sourceLink", ""):
188+
name_upper = name.upper()
189+
cvss_vector = ref.get("cvss3ScoringVector", "")
190+
191+
if "CVE" in name_upper and cvss_vector != "UNKNOWN":
192+
base_score = ref.get("cvss3BaseScore", "")
193+
194+
if base_score and cvss_vector:
195+
severities = [
196+
VulnerabilitySeverity(
197+
system=severity_systems.CVSSV31,
198+
value=base_score,
199+
scoring_elements=cvss_vector,
200+
)
201+
]
202+
else:
203+
severities = []
204+
205+
references.append(
206+
Reference(
207+
severities=severities, url=ref.get("sourceLink", ""), reference_id=name
208+
)
209+
)
190210

191211
return AdvisoryData(
192212
aliases=aliases,
@@ -199,10 +219,6 @@ def to_advisory(advisory_data):
199219
)
200220

201221

202-
class VersionParsingError(Exception):
203-
pass
204-
205-
206222
def get_cwes_from_rockylinux_advisory(advisory_data) -> [int]:
207223
"""
208224
Extract CWE IDs from advisory data and validate them against a database.

vulnerabilities/tests/test_rockylinux.py renamed to vulnerabilities/tests/pipelines/test_rockylinux_importer_pipeline.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,40 @@
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
99

10-
import json
1110
import os
11+
from pathlib import Path
1212
from unittest import TestCase
1313
from unittest.mock import patch
1414

1515
from packageurl import PackageURL
1616

17-
from vulnerabilities.importers import rockylinux
18-
from vulnerabilities.importers.rockylinux import get_cwes_from_rockylinux_advisory
19-
from vulnerabilities.importers.rockylinux import to_advisory
17+
from vulnerabilities.pipelines.rockylinux_importer import get_cwes_from_rockylinux_advisory
18+
from vulnerabilities.pipelines.rockylinux_importer import to_advisory
2019
from vulnerabilities.rpm_utils import rpm_to_purl
2120
from vulnerabilities.utils import load_json
2221

23-
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
24-
TEST_DATA = os.path.join(BASE_DIR, "test_data", "rockylinux")
22+
TEST_DATA = Path(__file__).parent.parent / "test_data" / "rockylinux"
2523

2624

27-
class TestRockyLinuxImporter(TestCase):
25+
class TestRockylinuxImporterPipeline(TestCase):
2826
def test_to_advisory1(self):
2927
test1 = os.path.join(TEST_DATA, "rockylinux_test1.json")
3028
mock_response = load_json(test1)
3129
expected_result = load_json(os.path.join(TEST_DATA, "rockylinux_expected1.json"))
30+
# print(f"1st is {to_advisory(mock_response).to_dict()}")
3231
assert to_advisory(mock_response).to_dict() == expected_result
3332

3433
def test_to_advisory2(self):
3534
test2 = os.path.join(TEST_DATA, "rockylinux_test2.json")
3635
mock_response2 = load_json(test2)
3736
expected_result2 = load_json(os.path.join(TEST_DATA, "rockylinux_expected2.json"))
3837
assert to_advisory(mock_response2).to_dict() == expected_result2
38+
# print(f"2nd is {to_advisory(mock_response2).to_dict()}")
3939

4040
def test_rpm_to_purl(self):
41-
assert rockylinux.rpm_to_purl("foobar", "rocky-linux") is None
42-
assert rockylinux.rpm_to_purl("foo-bar-devel-0:sys76", "rocky-linux") is None
43-
assert rockylinux.rpm_to_purl("cockpit-0:264.1-1.el8.aarch64", "rocky-linux") == PackageURL(
41+
assert rpm_to_purl("foobar", "rocky-linux") is None
42+
assert rpm_to_purl("foo-bar-devel-0:sys76", "rocky-linux") is None
43+
assert rpm_to_purl("cockpit-0:264.1-1.el8.aarch64", "rocky-linux") == PackageURL(
4444
type="rpm",
4545
namespace="rocky-linux",
4646
name="cockpit",

vulnerabilities/tests/test_data/rockylinux/rockylinux_expected2.json

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -141,78 +141,6 @@
141141
"reference_type": "",
142142
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2270666",
143143
"severities": []
144-
},
145-
{
146-
"reference_id": "CVE-2023-5388",
147-
"reference_type": "",
148-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-5388",
149-
"severities": [
150-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
151-
]
152-
},
153-
{
154-
"reference_id": "CVE-2024-0743",
155-
"reference_type": "",
156-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-0743",
157-
"severities": [
158-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
159-
]
160-
},
161-
{
162-
"reference_id": "CVE-2024-1936",
163-
"reference_type": "",
164-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-1936",
165-
"severities": [
166-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
167-
]
168-
},
169-
{
170-
"reference_id": "CVE-2024-2607",
171-
"reference_type": "",
172-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-2607",
173-
"severities": [
174-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
175-
]
176-
},
177-
{
178-
"reference_id": "CVE-2024-2608",
179-
"reference_type": "",
180-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-2608",
181-
"severities": [
182-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
183-
]
184-
},
185-
{
186-
"reference_id": "CVE-2024-2610",
187-
"reference_type": "",
188-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-2610",
189-
"severities": [
190-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
191-
]
192-
},
193-
{
194-
"reference_id": "CVE-2024-2611",
195-
"reference_type": "",
196-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-2611",
197-
"severities": [
198-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
199-
]
200-
},
201-
{
202-
"reference_id": "CVE-2024-2612",
203-
"reference_type": "",
204-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-2612",
205-
"severities": [
206-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
207-
]
208-
},
209-
{
210-
"reference_id": "CVE-2024-2614",
211-
"reference_type": "",
212-
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-2614",
213-
"severities": [
214-
{ "system": "cvssv3.1", "value": "UNKNOWN", "scoring_elements": "" }
215-
]
216144
}
217145
],
218146
"date_published": "2024-03-27T04:34:32.999941+00:00",

0 commit comments

Comments
 (0)