From a572545b4645119e7a0673379b320f91dbe538a5 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Aug 14 2017 07:55:26 +0000 Subject: Allow whitelisting/blacklisting based on the advisory security_impact. --- diff --git a/freshmaker/errata.py b/freshmaker/errata.py index c77d22c..fe694de 100644 --- a/freshmaker/errata.py +++ b/freshmaker/errata.py @@ -32,13 +32,14 @@ class ErrataAdvisory(object): Represents Errata advisory. """ - def __init__(self, errata_id, name, state): + def __init__(self, errata_id, name, state, security_impact=None): """ Initializes the ErrataAdvisory instance. """ self.errata_id = errata_id self.name = name self.state = state + self.security_impact = security_impact or "" class Errata(object): @@ -91,9 +92,17 @@ class Errata(object): build = self._errata_rest_get("/build/%s" % str(event.nvr)) if "all_errata" not in build: return [] - return [ - ErrataAdvisory(errata["id"], errata["name"], errata["status"]) - for errata in build["all_errata"]] + + advisories = [] + for errata in build["all_errata"]: + extra_data = self._errata_http_get( + "advisory/%s.json" % str(errata["id"])) + advisory = ErrataAdvisory( + errata["id"], errata["name"], errata["status"], + extra_data["security_impact"]) + advisories.append(advisory) + + return advisories else: raise ValueError("Unsupported event type") diff --git a/freshmaker/handlers/__init__.py b/freshmaker/handlers/__init__.py index 0199e5e..bdbbcda 100644 --- a/freshmaker/handlers/__init__.py +++ b/freshmaker/handlers/__init__.py @@ -145,7 +145,13 @@ class BaseHandler(object): def match_rule(kwargs, rule): for key, value in kwargs.items(): value_rule = rule.get(key, None) - if value_rule and not re.compile(value_rule).match(value): + if not value_rule: + continue + + if not isinstance(value_rule, list): + value_rule = [value_rule] + + if not any((re.compile(r).match(value) for r in value_rule)): return False return True diff --git a/freshmaker/handlers/brew/sign_rpm.py b/freshmaker/handlers/brew/sign_rpm.py index e3968d9..eac8070 100644 --- a/freshmaker/handlers/brew/sign_rpm.py +++ b/freshmaker/handlers/brew/sign_rpm.py @@ -202,8 +202,9 @@ class BrewSignRPMHandler(BaseHandler): # Filter out advisories which are not allow by configuration advisories = [advisory for advisory in advisories - if self.allow_build(ArtifactType.IMAGE, - advisory_name=advisory.name)] + if self.allow_build( + ArtifactType.IMAGE, advisory_name=advisory.name, + advisory_security_impact=advisory.security_impact)] if not advisories: log.info("No advisories found suitable for rebuilding Docker " "images") diff --git a/tests/test_brew_sign_rpm_handler.py b/tests/test_brew_sign_rpm_handler.py index 01cfbb0..be441dc 100644 --- a/tests/test_brew_sign_rpm_handler.py +++ b/tests/test_brew_sign_rpm_handler.py @@ -130,6 +130,68 @@ class TestAllowBuild(unittest.TestCase): builds_signed.assert_called_once() + @patch('freshmaker.errata.Errata.advisories_from_event') + @patch('freshmaker.errata.Errata.builds_signed') + @patch( + "freshmaker.config.Config.handler_build_whitelist", + new_callable=PropertyMock, + return_value={ + "BrewSignRPMHandler": { + "image": [{ + "advisory_security_impact": [ + "Normal", "Important" + ] + }] + } + }) + def test_allow_security_impact_important_true( + self, handler_build_whitelist, builds_signed, + advisories_from_event): + """ + Tests that allow_build does not filter out advisories based on + advisory_security_impact. + """ + advisories_from_event.return_value = [ + ErrataAdvisory(123, "RHSA-2017", "REL_PREP", "Important")] + builds_signed.return_value = False + + event = MagicMock() + handler = BrewSignRPMHandler() + handler.handle(event) + + builds_signed.assert_called_once() + + @patch('freshmaker.errata.Errata.advisories_from_event') + @patch('freshmaker.errata.Errata.builds_signed') + @patch( + "freshmaker.config.Config.handler_build_whitelist", + new_callable=PropertyMock, + return_value={ + "BrewSignRPMHandler": { + "image": [{ + "advisory_security_impact": [ + "Normal", "Important" + ] + }] + } + }) + def test_allow_security_impact_important_false( + self, handler_build_whitelist, builds_signed, + advisories_from_event): + """ + Tests that allow_build dost filter out advisories based on + advisory_security_impact. + """ + advisories_from_event.return_value = [ + ErrataAdvisory(123, "RHSA-2017", "REL_PREP", "None")] + builds_signed.return_value = False + + event = MagicMock() + handler = BrewSignRPMHandler() + handler.handle(event) + + builds_signed.assert_not_called() + class TestBatches(unittest.TestCase): """Test handling of batches""" diff --git a/tests/test_errata.py b/tests/test_errata.py index e261d8b..0f75b35 100644 --- a/tests/test_errata.py +++ b/tests/test_errata.py @@ -68,6 +68,8 @@ class MockedErrataAPI(object): "all_errata": [{"id": 28484, "name": "RHSA-2017:28484", "status": "QE"}], "rpms_signed": True} + self.advisory_json = {"security_impact": "Important"} + def errata_rest_get(self, endpoint): if endpoint.find("build/") != -1: nvr = endpoint.split("/")[-1] @@ -76,6 +78,8 @@ class MockedErrataAPI(object): def errata_http_get(self, endpoint): if endpoint.endswith("builds.json"): return self.builds_json + elif endpoint.startswith("advisory/"): + return self.advisory_json class TestErrata(unittest.TestCase): @@ -83,16 +87,18 @@ class TestErrata(unittest.TestCase): self.errata = Errata("https://localhost/") @patch.object(Errata, "_errata_rest_get") - def test_advisories_from_event(self, errata_rest_get): - MockedErrataAPI(errata_rest_get) + @patch.object(Errata, "_errata_http_get") + def test_advisories_from_event(self, errata_http_get, errata_rest_get): + MockedErrataAPI(errata_rest_get, errata_http_get) event = BrewSignRPMEvent("msgid", "libntirpc-1.4.3-4.el7rhgs") advisories = self.errata.advisories_from_event(event) self.assertEqual(len(advisories), 1) self.assertEqual(advisories[0].errata_id, 28484) @patch.object(Errata, "_errata_rest_get") - def test_advisories_from_event_missing_all_errata(self, errata_rest_get): - mocked_errata = MockedErrataAPI(errata_rest_get) + @patch.object(Errata, "_errata_http_get") + def test_advisories_from_event_missing_all_errata(self, errata_http_get, errata_rest_get): + mocked_errata = MockedErrataAPI(errata_rest_get, errata_http_get) del mocked_errata.builds["libntirpc-1.4.3-4.el7rhgs"]["all_errata"] event = BrewSignRPMEvent("msgid", "libntirpc-1.4.3-4.el7rhgs")