def rebuild_if_not_exists(self, event, errata_id):
        """
        Initiates rebuild of artifacts based on Errata advisory with
        `errata_id` id.

        :rtype: List of ErrataAdvisoryRPMsSignedEvent instances.
        :return: List of extra events generated to initiate the rebuild.
        """

        db_event = db.session.query(Event).filter_by(
            event_type_id=EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent],
            search_key=str(errata_id)).first()
        if (db_event and db_event.state != EventState.FAILED.value and
                not event.manual):
            log.debug("Ignoring Errata advisory %d - it already exists in "
                      "Freshmaker db.", errata_id)
            return []

        # Get additional info from Errata to fill in the needed data.
        errata = Errata()
        advisories = errata.advisories_from_event(event)
        if not advisories:
            log.error("Unknown Errata advisory %d" % errata_id)
            return []

        log.info("Generating ErrataAdvisoryRPMsSignedEvent for Errata "
                 "advisory %d, because its state changed to %s.", errata_id,
                 event.advisory.state)
        advisory = advisories[0]
        new_event = ErrataAdvisoryRPMsSignedEvent(
            event.msg_id + "." + str(advisory.name), advisory)
        new_event.dry_run = event.dry_run
        new_event.manual = event.manual
        return [new_event]
Ejemplo n.º 2
0
    def handle(self, event):
        log.info("Finding out all advisories including %s", event.nvr)

        # When get a signed RPM, first step is to find out advisories
        # containing that RPM and ensure all builds are signed.
        errata = Errata()
        advisories = errata.advisories_from_event(event)

        # Filter out advisories which are not allowed by configuration.
        advisories = [
            advisory for advisory in advisories if self.allow_build(
                ArtifactType.IMAGE,
                advisory_name=advisory.name,
                advisory_security_impact=advisory.security_impact,
                advisory_highest_cve_severity=advisory.highest_cve_severity,
                advisory_state=advisory.state)
        ]

        # Filter out advisories which are already in Freshmaker DB.
        advisories = self._filter_out_existing_advisories(advisories)

        if not advisories:
            log.info("No advisories found suitable for rebuilding Docker "
                     "images")
            return []

        if not all((errata.builds_signed(advisory.errata_id)
                    for advisory in advisories)):
            log.info(
                'Not all builds in %s are signed. Do not rebuild any '
                'docker image until signed.', advisories)
            return []

        # Now we know that all advisories with this signed RPM have also other
        # RPMs signed. We can then proceed and generate
        # ErrataAdvisoryRPMsSignedEvent.
        new_events = []
        for advisory in advisories:
            new_event = ErrataAdvisoryRPMsSignedEvent(
                event.msg_id + "." + str(advisory.name), advisory)
            db_event = Event.create(db.session,
                                    new_event.msg_id,
                                    new_event.search_key,
                                    new_event.__class__,
                                    released=False)
            db.session.add(db_event)
            new_events.append(new_event)
        db.session.commit()
        return new_events
Ejemplo n.º 3
0
class TestErrata(helpers.FreshmakerTestCase):
    def setUp(self):
        super(TestErrata, self).setUp()
        self.errata = Errata("https://localhost/")

    def tearDown(self):
        super(TestErrata, self).tearDown()

    @patch.object(Errata, "_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)
        self.assertEqual(advisories[0].name, "RHSA-2017:28484")
        self.assertEqual(advisories[0].state, "QE")
        self.assertEqual(advisories[0].content_types, ["rpm"])
        self.assertEqual(advisories[0].security_impact, "important")
        self.assertEqual(advisories[0].product_short_name, "product")
        self.assertEqual(advisories[0].cve_list,
                         ["CVE-2015-3253", "CVE-2016-6814"])
        self.assertEqual(advisories[0].has_hightouch_bug, True)

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_advisories_from_event_empty_cve(self, errata_http_get,
                                             errata_rest_get):
        mocked_errata = MockedErrataAPI(errata_rest_get, errata_http_get)
        mocked_errata.advisory_rest_json["content"]["content"]["cve"] = ""
        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].cve_list, [])

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_advisories_from_event_no_bugs(self, errata_http_get,
                                           errata_rest_get):
        mocked_errata = MockedErrataAPI(errata_rest_get, errata_http_get)
        mocked_errata.bugs = []
        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].has_hightouch_bug, False)

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_advisories_from_event_empty_bug_flags(self, errata_http_get,
                                                   errata_rest_get):
        mocked_errata = MockedErrataAPI(errata_rest_get, errata_http_get)
        for bug in mocked_errata.bugs:
            bug["flags"] = ""
        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].has_hightouch_bug, False)

    @patch.object(Errata, "_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")
        advisories = self.errata.advisories_from_event(event)
        self.assertEqual(len(advisories), 0)

    def test_advisories_from_event_unsupported_event(self):
        event = GitRPMSpecChangeEvent("msgid", "libntirpc", "master", "foo")
        with self.assertRaises(ValueError):
            self.errata.advisories_from_event(event)

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_advisories_from_event_errata_state_change_event(
            self, errata_http_get, errata_rest_get):
        MockedErrataAPI(errata_rest_get, errata_http_get)
        event = ErrataAdvisoryStateChangedEvent(
            "msgid", ErrataAdvisory(28484, "name", "SHIPPED_LIVE", ['rpm']))
        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")
    @patch.object(Errata, "_errata_http_get")
    def test_builds_signed_all_signed(self, errata_http_get, errata_rest_get):
        MockedErrataAPI(errata_rest_get, errata_http_get)
        self.assertTrue(self.errata.builds_signed(28484))

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_builds_signed_some_unsigned(self, errata_http_get,
                                         errata_rest_get):
        mocked_errata = MockedErrataAPI(errata_rest_get, errata_http_get)
        mocked_errata.builds["libntirpc-1.4.3-4.el7rhgs"][
            "rpms_signed"] = False
        self.assertFalse(self.errata.builds_signed(28484))

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_builds_signed_missing_data(self, errata_http_get,
                                        errata_rest_get):
        mocked_errata = MockedErrataAPI(errata_rest_get, errata_http_get)
        mocked_errata.builds["libntirpc-1.4.3-4.el7rhgs"] = {}
        self.assertFalse(self.errata.builds_signed(28484))

    @patch('freshmaker.errata.requests.get')
    def test_get_errata_repo_ids(self, get):
        get.return_value.json.return_value = {
            'rhel-6-server-eus-source-rpms__6_DOT_7__x86_64': [],
            'rhel-6-server-eus-optional-debug-rpms__6_DOT_7__i386': [
                '/path/to/package.rpm',
                '/path/to/package1.rpm',
                '/path/to/package2.rpm',
            ],
            'rhel-6-server-eus-rpms__6_DOT_7__x86_64': [],
        }

        repo_ids = self.errata.get_pulp_repository_ids(25718)

        self.assertEqual(
            set([
                'rhel-6-server-eus-source-rpms__6_DOT_7__x86_64',
                'rhel-6-server-eus-optional-debug-rpms__6_DOT_7__i386',
                'rhel-6-server-eus-rpms__6_DOT_7__x86_64'
            ]), set(repo_ids))

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_rhel_release_from_product_version(self, errata_http_get,
                                               errata_rest_get):
        MockedErrataAPI(errata_rest_get, errata_http_get)
        ret = self.errata._rhel_release_from_product_version(
            28484, "PRODUCT1-3.2-NFS")
        self.assertEqual(ret, "RHEL-6-foobar")

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_rhel_release_from_product_version_unknown_product_ver(
            self, errata_http_get, errata_rest_get):
        MockedErrataAPI(errata_rest_get, errata_http_get)
        with self.assertRaises(ValueError):
            self.errata._rhel_release_from_product_version(
                28484, "PRODUCT1-2.9-NFS")

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_get_nvrs(self, errata_http_get, errata_rest_get):
        MockedErrataAPI(errata_rest_get, errata_http_get)
        srpms = self.errata.get_srpm_nvrs(28484, "")
        binary_rpms = self.errata.get_binary_rpm_nvrs(28484)
        self.assertEqual(
            set(srpms),
            set(['libntirpc-1.4.3-4.el7rhgs', 'libntirpc-1.4.3-4.el6rhs']))
        self.assertEqual(
            set(binary_rpms),
            set([
                'libntirpc-devel-1.4.3-4.el6rhs',
                'libntirpc-devel-1.4.3-4.el7rhgs'
            ]))

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_get_binary_rpms_rhel_7(self, errata_http_get, errata_rest_get):
        MockedErrataAPI(errata_rest_get, errata_http_get)
        ret = self.errata.get_binary_rpm_nvrs(28484, "RHEL-7")
        self.assertEqual(ret, ['libntirpc-devel-1.4.3-4.el7rhgs'])

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_get_srpm_nvrs_empty(self, errata_http_get, errata_rest_get):
        api = MockedErrataAPI(errata_rest_get, errata_http_get)
        api.builds_json = {
            "PRODUCT1": [{
                "libntirpc-1.4.3-4.el7rhgs": {
                    "PRODUCT2-3.2-NFS": {
                        "x86_64":
                        ["libntirpc-devel-1.4.3-4.el7rhgs.x86_64.rpm"]
                    }
                }
            }]
        }
        ret = self.errata.get_srpm_nvrs(28484, "")
        self.assertEqual(ret, [])

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_get_binary_nvrs_empty(self, errata_http_get, errata_rest_get):
        api = MockedErrataAPI(errata_rest_get, errata_http_get)
        api.builds_json = {
            "PRODUCT1": [{
                "libntirpc-1.4.3-4.el7rhgs": {
                    "PRODUCT2-3.2-NFS": {
                        "SRPMS":
                        ["libntirpc-devel-1.4.3-4.el7rhgs.x86_64.rpm"]
                    }
                }
            }]
        }
        ret = self.errata.get_binary_rpm_nvrs(28484, "")
        self.assertEqual(ret, [])

    @patch.object(Errata, "_errata_rest_get")
    @patch.object(Errata, "_errata_http_get")
    def test_errata_get_cve_affected_rpm_nvrs(self, errata_http_get,
                                              errata_rest_get):
        MockedErrataAPI(errata_rest_get, errata_http_get)
        ret = self.errata.get_cve_affected_rpm_nvrs(28484)
        self.assertEqual(ret, ['libntirpc-1.4.3-4.el6rhs'])

    def test_get_docker_repo_tags(self):
        with patch.object(self.errata, "xmlrpc") as xmlrpc:
            xmlrpc.get_advisory_cdn_docker_file_list.return_value = {
                'foo-container-1-1': {
                    'docker': {
                        'target': {
                            'repos': {
                                'foo-526': {
                                    'tags': ['5.26', 'latest']
                                }
                            }
                        }
                    }
                }
            }
            repo_tags = self.errata.get_docker_repo_tags(28484)

            expected = {'foo-container-1-1': {'foo-526': ['5.26', 'latest']}}
            self.assertEqual(repo_tags, expected)

    def test_get_docker_repo_tags_xmlrpc_exception(self):
        with patch.object(self.errata, "xmlrpc") as xmlrpc:
            xmlrpc.get_advisory_cdn_docker_file_list.side_effect = ValueError(
                "Expected XMLRPC test exception")
            repo_tags = self.errata.get_docker_repo_tags(28484)
            self.assertEqual(repo_tags, None)

    def test_get_docker_repo_tags_xmlrpc_non_returned(self):
        with patch.object(self.errata, "xmlrpc") as xmlrpc:
            xmlrpc.get_advisory_cdn_docker_file_list.return_value = None
            repo_tags = self.errata.get_docker_repo_tags(28484)
            self.assertEqual(repo_tags, None)