Exemplo n.º 1
0
    def assert_notification_worker_offset_pages(self, indexed=False):
        layer1 = model.tag.get_tag_image(ADMIN_ACCESS_USER,
                                         SIMPLE_REPO,
                                         "latest",
                                         include_storage=True)
        layer2 = model.tag.get_tag_image(ADMIN_ACCESS_USER,
                                         COMPLEX_REPO,
                                         "prod",
                                         include_storage=True)

        # Add a repo events for the layers.
        simple_repo = model.repository.get_repository(ADMIN_ACCESS_USER,
                                                      SIMPLE_REPO)
        complex_repo = model.repository.get_repository(ADMIN_ACCESS_USER,
                                                       COMPLEX_REPO)

        model.notification.create_repo_notification(simple_repo,
                                                    "vulnerability_found",
                                                    "quay_notification", {},
                                                    {"level": 100})
        model.notification.create_repo_notification(complex_repo,
                                                    "vulnerability_found",
                                                    "quay_notification", {},
                                                    {"level": 100})

        # Ensure that there are no event queue items for the layer.
        self.assertIsNone(notification_queue.get())

        with fake_security_scanner() as security_scanner:
            # Test with an unknown notification.
            worker = SecurityNotificationWorker(None)
            self.assertFalse(
                worker.perform_notification_work(
                    {"Name": "unknownnotification"}))

            # Add some analyzed layers.
            analyzer = LayerAnalyzer(app.config, self.api)
            analyzer.analyze_recursively(layer1)
            analyzer.analyze_recursively(layer2)

            # Add a notification with pages of data.
            new_vuln_info = {
                "Name": "CVE-TEST",
                "Namespace": "debian:8",
                "Description": "Some service",
                "Link":
                "https://security-tracker.debian.org/tracker/CVE-2014-9471",
                "Severity": "Critical",
                "FixedIn": {
                    "Version": "9.23-5"
                },
            }

            security_scanner.set_vulns(security_scanner.layer_id(layer1),
                                       [new_vuln_info])
            security_scanner.set_vulns(security_scanner.layer_id(layer2),
                                       [new_vuln_info])

            # Define offsetting sets of layer IDs, to test cross-pagination support. In this test, we
            # will only serve 2 layer IDs per page: the first page will serve both of the 'New' layer IDs,
            # but since the first 2 'Old' layer IDs are "earlier" than the shared ID of
            # `devtable/simple:latest`, they won't get served in the 'New' list until the *second* page.
            # The notification handling system should correctly not notify for this layer, even though it
            # is marked 'New' on page 1 and marked 'Old' on page 2. Clair will served these
            # IDs sorted in the same manner.
            idx_old_layer_ids = [
                {
                    "LayerName": "old1",
                    "Index": 1
                },
                {
                    "LayerName": "old2",
                    "Index": 2
                },
                {
                    "LayerName": security_scanner.layer_id(layer1),
                    "Index": 3
                },
            ]

            idx_new_layer_ids = [
                {
                    "LayerName": security_scanner.layer_id(layer1),
                    "Index": 3
                },
                {
                    "LayerName": security_scanner.layer_id(layer2),
                    "Index": 4
                },
            ]

            old_layer_ids = [t["LayerName"] for t in idx_old_layer_ids]
            new_layer_ids = [t["LayerName"] for t in idx_new_layer_ids]

            if not indexed:
                idx_old_layer_ids = None
                idx_new_layer_ids = None

            notification_data = security_scanner.add_notification(
                old_layer_ids,
                new_layer_ids,
                None,
                new_vuln_info,
                max_per_page=2,
                indexed_old_layer_ids=idx_old_layer_ids,
                indexed_new_layer_ids=idx_new_layer_ids,
            )

            # Test with a known notification with pages.
            data = {
                "Name": notification_data["Name"],
            }

            worker = SecurityNotificationWorker(None)
            self.assertTrue(
                worker.perform_notification_work(data, layer_limit=2))

            # Make sure all pages were processed by ensuring we have only one notification. If the second
            # page was not processed, then the `Old` entry for layer1 will not be found, and we'd get two
            # notifications.
            time.sleep(1)
            self.assertIsNotNone(notification_queue.get())
            self.assertIsNone(notification_queue.get())
Exemplo n.º 2
0
    def test_notification_worker(self):
        layer1 = model.tag.get_tag_image(ADMIN_ACCESS_USER,
                                         SIMPLE_REPO,
                                         "latest",
                                         include_storage=True)
        layer2 = model.tag.get_tag_image(ADMIN_ACCESS_USER,
                                         COMPLEX_REPO,
                                         "prod",
                                         include_storage=True)

        # Add a repo events for the layers.
        simple_repo = model.repository.get_repository(ADMIN_ACCESS_USER,
                                                      SIMPLE_REPO)
        complex_repo = model.repository.get_repository(ADMIN_ACCESS_USER,
                                                       COMPLEX_REPO)

        model.notification.create_repo_notification(simple_repo,
                                                    "vulnerability_found",
                                                    "quay_notification", {},
                                                    {"level": 100})
        model.notification.create_repo_notification(complex_repo,
                                                    "vulnerability_found",
                                                    "quay_notification", {},
                                                    {"level": 100})

        # Ensure that there are no event queue items for the layer.
        self.assertIsNone(notification_queue.get())

        with fake_security_scanner() as security_scanner:
            # Test with an unknown notification.
            worker = SecurityNotificationWorker(None)
            self.assertFalse(
                worker.perform_notification_work(
                    {"Name": "unknownnotification"}))

            # Add some analyzed layers.
            analyzer = LayerAnalyzer(app.config, self.api)
            analyzer.analyze_recursively(layer1)
            analyzer.analyze_recursively(layer2)

            # Add a notification with pages of data.
            new_vuln_info = {
                "Name": "CVE-TEST",
                "Namespace": "debian:8",
                "Description": "Some service",
                "Link":
                "https://security-tracker.debian.org/tracker/CVE-2014-9471",
                "Severity": "Critical",
                "FixedIn": {
                    "Version": "9.23-5"
                },
            }

            security_scanner.set_vulns(security_scanner.layer_id(layer1),
                                       [new_vuln_info])
            security_scanner.set_vulns(security_scanner.layer_id(layer2),
                                       [new_vuln_info])

            layer_ids = [
                security_scanner.layer_id(layer1),
                security_scanner.layer_id(layer2)
            ]
            notification_data = security_scanner.add_notification(
                [], layer_ids, None, new_vuln_info)

            # Test with a known notification with pages.
            data = {
                "Name": notification_data["Name"],
            }

            worker = SecurityNotificationWorker(None)
            self.assertTrue(
                worker.perform_notification_work(data, layer_limit=2))

            # Make sure all pages were processed by ensuring we have two notifications.
            time.sleep(1)
            self.assertIsNotNone(notification_queue.get())
            self.assertIsNotNone(notification_queue.get())