Esempio n. 1
0
    def test_persist_aws_inspection_cluster_results_image_has_errors(self):
        """Assert that inspection results with image errors are logged."""
        ami_id = util_helper.generate_dummy_image_id()
        api_helper.generate_image(
            is_encrypted=False, is_windows=False, ec2_ami_id=ami_id
        )

        error_message = _faker.sentence()
        inspection_results = {
            "cloud": "aws",
            "images": {
                ami_id: {
                    "rhel_found": False,
                    "rhel_version": None,
                    "syspurpose": None,
                    "errors": [error_message],
                }
            },
        }

        with self.assertLogs("api.clouds.aws.util", level="INFO") as logging_watcher:
            util.persist_aws_inspection_cluster_results(inspection_results)
            self.assertIn(
                "Error reported in inspection results for image",
                logging_watcher.output[0],
            )
            self.assertIn(ami_id, logging_watcher.output[0])
            self.assertIn(error_message, logging_watcher.output[0])

        aws_machine_image = AwsMachineImage.objects.get(ec2_ami_id=ami_id)
        machine_image = aws_machine_image.machine_image.get()
        self.assertFalse(machine_image.rhel_detected)
Esempio n. 2
0
    def setUp(self):
        """Set up commonly used data for each test."""
        # various images not belonging to any particular cloud account
        self.image_plain = api_helper.generate_image()
        self.image_rhel = api_helper.generate_image(rhel_detected=True)
        self.image_ocp = api_helper.generate_image(openshift_detected=True)

        # define users
        self.user_1 = util_helper.generate_test_user()
        self.user_2 = util_helper.generate_test_user()
        self.user_super = util_helper.generate_test_user(is_superuser=True)

        # define users' cloud accounts
        self.account_1 = api_helper.generate_cloud_account(user=self.user_1,
                                                           name=_faker.bs())

        # define instances that belong to user_1 account_1
        self.instance_plain = api_helper.generate_instance(
            cloud_account=self.account_1, image=self.image_plain)
        self.instance_rhel = api_helper.generate_instance(
            cloud_account=self.account_1, image=self.image_rhel)
        self.instance_ocp = api_helper.generate_instance(
            cloud_account=self.account_1, image=self.image_ocp)
        self.instance_noimage = api_helper.generate_instance(
            cloud_account=self.account_1, no_image=True)

        api_helper.generate_instance_type_definitions()
Esempio n. 3
0
    def test_attach_volumes_to_cluster_instance_not_running(
        self, mock_boto3, mock_run_inspection_cluster
    ):
        """Asserts that an exception is raised if instance exists but is not running."""
        ami_id = util_helper.generate_dummy_image_id()
        volume_id = util_helper.generate_dummy_volume_id()

        account_helper.generate_image(ec2_ami_id=ami_id, status=MachineImage.PENDING)

        instance_id = util_helper.generate_dummy_instance_id()
        mock_list_container_instances = {"containerInstanceArns": [instance_id]}
        mock_ec2 = Mock()
        mock_ec2_instance = mock_ec2.Instance.return_value
        mock_ec2_instance.state = EC2_INSTANCE_STATE_STOPPED

        mock_ecs = MagicMock()
        mock_ecs.list_container_instances.return_value = mock_list_container_instances

        mock_boto3.client.return_value = mock_ecs
        mock_boto3.resource.return_value = mock_ec2

        messages = [{"ami_id": ami_id, "volume_id": volume_id}]
        with self.assertRaises(AwsECSInstanceNotReady):
            tasks.attach_volumes_to_cluster(messages)

        mock_run_inspection_cluster.delay.assert_not_called()
Esempio n. 4
0
    def setUp(self):
        """Set up a bunch of test data."""
        self.user1 = util_helper.generate_test_user()
        self.user2 = util_helper.generate_test_user()

        self.account1 = api_helper.generate_cloud_account(user=self.user1)
        self.account2 = api_helper.generate_cloud_account(user=self.user2)

        self.image_plain = api_helper.generate_image()
        self.image_windows = api_helper.generate_image(is_windows=True)
        self.image_rhel = api_helper.generate_image(rhel_detected=True)
        self.image_ocp = api_helper.generate_image(openshift_detected=True)

        self.instance1 = api_helper.generate_instance(
            cloud_account=self.account1, image=self.image_plain
        )
        self.instance2 = api_helper.generate_instance(
            cloud_account=self.account1, image=self.image_windows
        )
        self.instance3 = api_helper.generate_instance(
            cloud_account=self.account1, image=self.image_rhel
        )
        self.instance4 = api_helper.generate_instance(
            cloud_account=self.account1, image=self.image_ocp
        )
Esempio n. 5
0
    def test_copy_ami_snapshot_not_marketplace(self, mock_aws):
        """Assert that an exception is raised when there is an error."""
        mock_account_id = util_helper.generate_dummy_aws_account_id()
        mock_session = mock_aws.boto3.Session.return_value
        mock_aws.get_session_account_id.return_value = mock_account_id

        mock_region = util_helper.get_random_region()
        mock_arn = util_helper.generate_dummy_arn(mock_account_id, mock_region)

        mock_image_id = util_helper.generate_dummy_image_id()
        account_helper.generate_image(ec2_ami_id=mock_image_id)
        mock_image = util_helper.generate_mock_image(mock_image_id)
        mock_snapshot_id = util_helper.generate_dummy_snapshot_id()

        mock_aws.get_session.return_value = mock_session
        mock_aws.get_ami.return_value = mock_image
        mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id
        mock_aws.get_snapshot.side_effect = ClientError(
            error_response={
                "Error": {
                    "Code": "ItIsAMystery",
                    "Message": "Mystery Error"
                }
            },
            operation_name=Mock(),
        )

        with self.assertRaises(RuntimeError) as e:
            tasks.copy_ami_snapshot(mock_arn, mock_image_id, mock_region)

        self.assertIn("ClientError", e.exception.args[0])
        self.assertIn("ItIsAMystery", e.exception.args[0])
        self.assertIn("Mystery Error", e.exception.args[0])
Esempio n. 6
0
    def test_copy_ami_to_customer_account_not_marketplace(self, mock_aws):
        """Assert that the task fails when non-marketplace error occurs."""
        arn = util_helper.generate_dummy_arn()
        reference_ami_id = util_helper.generate_dummy_image_id()
        source_region = util_helper.get_random_region()

        api_helper.generate_image(ec2_ami_id=reference_ami_id)

        mock_aws.copy_ami.side_effect = ClientError(
            error_response={
                "Error": {
                    "Code": "ItIsAMystery",
                    "Message": "Mystery Error"
                }
            },
            operation_name=Mock(),
        )

        with self.assertRaises(RuntimeError) as e:
            tasks.copy_ami_to_customer_account(arn, reference_ami_id,
                                               source_region)

        self.assertIn("ClientError", e.exception.args[0])
        self.assertIn("ItIsAMystery", e.exception.args[0])
        self.assertIn("Mystery Error", e.exception.args[0])

        mock_aws.get_session.assert_called_with(arn)
        mock_aws.get_ami.assert_called_with(mock_aws.get_session.return_value,
                                            reference_ami_id, source_region)
Esempio n. 7
0
    def test_copy_ami_snapshot_marketplace(self, mock_aws):
        """Assert that a suspected marketplace image is checked."""
        mock_account_id = util_helper.generate_dummy_aws_account_id()
        mock_session = mock_aws.boto3.Session.return_value
        mock_aws.get_session_account_id.return_value = mock_account_id

        mock_region = util_helper.get_random_region()
        mock_arn = util_helper.generate_dummy_arn(mock_account_id, mock_region)

        mock_image_id = util_helper.generate_dummy_image_id()
        mock_image = util_helper.generate_mock_image(mock_image_id)
        mock_snapshot_id = util_helper.generate_dummy_snapshot_id()

        mock_aws.get_session.return_value = mock_session
        mock_aws.get_ami.return_value = mock_image
        mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id
        mock_aws.get_snapshot.side_effect = ClientError(
            error_response={"Error": {
                "Code": "InvalidSnapshot.NotFound"
            }},
            operation_name=Mock(),
        )

        account_helper.generate_image(ec2_ami_id=mock_image_id)

        with patch.object(tasks.imageprep,
                          "create_volume") as mock_create_volume, patch.object(
                              tasks.imageprep, "copy_ami_to_customer_account"
                          ) as mock_copy_ami_to_customer_account:
            tasks.copy_ami_snapshot(mock_arn, mock_image_id, mock_region)
            mock_create_volume.delay.assert_not_called()
            mock_copy_ami_to_customer_account.delay.assert_called_with(
                mock_arn, mock_image_id, mock_region)
Esempio n. 8
0
    def test_copy_ami_snapshot_private_shared(self, mock_aws):
        """Assert that the task copies the image when it is private/shared."""
        mock_account_id = util_helper.generate_dummy_aws_account_id()
        mock_session = mock_aws.boto3.Session.return_value
        mock_aws.get_session_account_id.return_value = mock_account_id

        # the account id to use as the private shared image owner
        other_account_id = util_helper.generate_dummy_aws_account_id()

        mock_region = util_helper.get_random_region()
        mock_arn = util_helper.generate_dummy_arn(mock_account_id, mock_region)

        mock_image_id = util_helper.generate_dummy_image_id()
        mock_image = util_helper.generate_mock_image(mock_image_id)
        mock_snapshot_id = util_helper.generate_dummy_snapshot_id()
        mock_snapshot = util_helper.generate_mock_snapshot(
            mock_snapshot_id, encrypted=False, owner_id=other_account_id)

        mock_aws.get_session.return_value = mock_session
        mock_aws.get_ami.return_value = mock_image
        mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id
        mock_aws.get_snapshot.return_value = mock_snapshot

        account_helper.generate_image(ec2_ami_id=mock_image_id)

        with patch.object(tasks.imageprep,
                          "create_volume") as mock_create_volume, patch.object(
                              tasks.imageprep, "copy_ami_to_customer_account"
                          ) as mock_copy_ami_to_customer_account:
            tasks.copy_ami_snapshot(mock_arn, mock_image_id, mock_region)
            mock_create_volume.delay.assert_not_called()
            mock_copy_ami_to_customer_account.delay.assert_called_with(
                mock_arn, mock_image_id, mock_region)
Esempio n. 9
0
    def test_copy_ami_snapshot_retry_on_ownership_not_verified(self, mock_aws):
        """Assert that the snapshot copy task fails."""
        mock_session = mock_aws.boto3.Session.return_value
        mock_account_id = mock_aws.get_session_account_id.return_value

        mock_arn = util_helper.generate_dummy_arn()
        mock_region = util_helper.get_random_region()
        mock_image_id = util_helper.generate_dummy_image_id()
        mock_image = util_helper.generate_mock_image(mock_image_id)
        account_helper.generate_image(ec2_ami_id=mock_image_id)
        block_mapping = mock_image.block_device_mappings
        mock_snapshot_id = block_mapping[0]["Ebs"]["SnapshotId"]
        mock_snapshot = util_helper.generate_mock_snapshot(
            mock_snapshot_id, owner_id=mock_account_id)

        mock_aws.get_session.return_value = mock_session
        mock_aws.get_ami.return_value = mock_image
        mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id
        mock_aws.get_snapshot.return_value = mock_snapshot
        mock_aws.add_snapshot_ownership.side_effect = AwsSnapshotNotOwnedError(
        )

        with patch.object(tasks,
                          "create_volume") as mock_create_volume, patch.object(
                              tasks.copy_ami_snapshot, "retry") as mock_retry:
            mock_retry.side_effect = Retry()
            with self.assertRaises(Retry):
                tasks.copy_ami_snapshot(mock_arn, mock_image_id, mock_region)
            mock_create_volume.delay.assert_not_called()
Esempio n. 10
0
    def test_inspect_pending_images(self):
        """
        Test that only old "pending" images are found and reinspected.

        Note that we effectively time-travel here to points in the past to
        create the account, images, and instances. This is necessary because
        updated_at is automatically set by Django and cannot be manually set,
        but we need things with specific older updated_at times.
        """
        real_now = get_now()
        yesterday = real_now - datetime.timedelta(days=1)
        with clouditardis(yesterday):
            account = account_helper.generate_cloud_account()
            image_old_inspected = account_helper.generate_image()
            image_old_pending = account_helper.generate_image(
                status=MachineImage.PENDING)
            # an instance exists using old inspected image.
            account_helper.generate_instance(cloud_account=account,
                                             image=image_old_inspected)
            # an instance exists using old pending image.
            instance_old_pending = account_helper.generate_instance(
                cloud_account=account, image=image_old_pending)
            # another instance exists using the same old pending image, but the
            # image should still only be reinspected once regardless of how
            # many instances used it.
            account_helper.generate_instance(cloud_account=account,
                                             image=image_old_pending)

        one_hour_ago = real_now - datetime.timedelta(seconds=60 * 60)
        with clouditardis(one_hour_ago):
            image_new_inspected = account_helper.generate_image()
            image_new_pending = account_helper.generate_image(
                status=MachineImage.PENDING)
            # an instance exists using new inspected image.
            account_helper.generate_instance(cloud_account=account,
                                             image=image_new_inspected)
            # an instance exists using new pending image, but it should not
            # trigger inspection because the image is not old enough.
            account_helper.generate_instance(cloud_account=account,
                                             image=image_new_pending)

        expected_calls = [
            call(
                account.content_object.account_arn,
                image_old_pending.content_object.ec2_ami_id,
                instance_old_pending.content_object.region,
            )
        ]
        with patch.object(tasks, "start_image_inspection") as mock_start:
            tasks.inspect_pending_images()
            mock_start.assert_has_calls(expected_calls, any_order=True)
Esempio n. 11
0
    def test_persist_aws_inspection_cluster_results_no_images(self):
        """Assert that non rhel_images are not tagged rhel."""
        ami_id = util_helper.generate_dummy_image_id()
        api_helper.generate_image(
            is_encrypted=False, is_windows=False, ec2_ami_id=ami_id
        )

        inspection_results = {"cloud": "aws"}
        expected_message = "Inspection results json missing images: {}".format(
            inspection_results
        )

        with self.assertRaises(InvalidHoundigradeJsonFormat) as e:
            util.persist_aws_inspection_cluster_results(inspection_results)
        self.assertIn(expected_message, str(e.exception))
Esempio n. 12
0
    def test_save_with_concurrent_usages(self):
        """Test that save deletes the related concurrent_usages."""
        user = util_helper.generate_test_user()
        aws_account_id = util_helper.generate_dummy_aws_account_id()
        account = api_helper.generate_cloud_account(
            aws_account_id=aws_account_id,
            user=user,
        )
        image = api_helper.generate_image(
            owner_aws_account_id=aws_account_id,
            rhel_detected=True,
        )
        instance = api_helper.generate_instance(account, image=image)
        api_helper.generate_single_run(
            instance,
            (
                util_helper.utc_dt(2019, 5, 1, 1, 0, 0),
                util_helper.utc_dt(2019, 5, 1, 2, 0, 0),
            ),
            image=instance.machine_image,
        )
        request_date = datetime.date(2019, 5, 1)
        calculate_max_concurrent_usage(request_date, user_id=user.id)

        self.assertEquals(1, ConcurrentUsage.objects.count())
        image.rhel_detected_by_tag = True
        image.save()
        self.assertEquals(0, ConcurrentUsage.objects.count())
Esempio n. 13
0
 def test_is_marketplace_name_check(self):
     """Test that is_marketplace is True if image name and owner matches."""
     machine_image = helper.generate_image(
         name="marketplace-hourly2",
         owner_aws_account_id=choice(settings.RHEL_IMAGES_AWS_ACCOUNTS),
     )
     self.assertTrue(machine_image.content_object.is_marketplace)
Esempio n. 14
0
    def test_generate_aws_events_with_args_and_some_times(self):
        """Assert generation of InstanceEvents with all specified args."""
        account = helper.generate_cloud_account()
        ec2_ami_id = util_helper.generate_dummy_image_id()
        image = helper.generate_image(ec2_ami_id=ec2_ami_id)
        instance = helper.generate_instance(account, image=image)
        powered_times = (
            (None, util_helper.utc_dt(2017, 1, 1)),
            (util_helper.utc_dt(2017, 1, 2), util_helper.utc_dt(2017, 1, 3)),
            (util_helper.utc_dt(2017, 1, 4), None),
        )
        instance_type = util_helper.get_random_instance_type()
        subnet = str(uuid.uuid4())
        events = helper.generate_instance_events(
            instance,
            powered_times,
            instance_type=instance_type,
            subnet=subnet,
        )

        self.assertEqual(len(events), 4)
        # We don't care to check *everything* in the events since that should
        # already be covered by ``test_generate_events_with_some_times``.
        # Here we only care that argument values were set correctly.
        for event in events:
            if event.event_type != event.TYPE.power_off:
                self.assertEqual(
                    event.instance.machine_image.content_object.ec2_ami_id, ec2_ami_id
                )
            self.assertEqual(event.content_object.instance_type, instance_type)
            self.assertEqual(event.content_object.subnet, subnet)
Esempio n. 15
0
    def test_copy_ami_snapshot_encrypted(self, mock_aws):
        """Assert that the task marks the image as encrypted in the DB."""
        mock_account_id = util_helper.generate_dummy_aws_account_id()
        mock_region = util_helper.get_random_region()
        mock_arn = util_helper.generate_dummy_arn(mock_account_id, mock_region)

        mock_image_id = util_helper.generate_dummy_image_id()
        mock_image = util_helper.generate_mock_image(mock_image_id)
        mock_snapshot_id = util_helper.generate_dummy_snapshot_id()
        mock_snapshot = util_helper.generate_mock_snapshot(mock_snapshot_id,
                                                           encrypted=True)
        mock_session = mock_aws.boto3.Session.return_value

        mock_aws.get_session.return_value = mock_session
        mock_aws.get_ami.return_value = mock_image
        mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id
        mock_aws.get_snapshot.return_value = mock_snapshot

        ami = account_helper.generate_image(ec2_ami_id=mock_image_id)

        with patch.object(tasks, "create_volume") as mock_create_volume:
            tasks.copy_ami_snapshot(mock_arn, mock_image_id, mock_region)
            ami.refresh_from_db()
            self.assertTrue(ami.is_encrypted)
            self.assertEqual(ami.status, ami.ERROR)
            mock_create_volume.delay.assert_not_called()
Esempio n. 16
0
    def test_copy_ami_to_customer_account_private_no_copy_dot_error(
            self, mock_aws):
        """Assert that the task marks private (no copy) image as in error."""
        arn = util_helper.generate_dummy_arn()
        reference_ami_id = util_helper.generate_dummy_image_id()
        source_region = util_helper.get_random_region()
        image = api_helper.generate_image(ec2_ami_id=reference_ami_id,
                                          status=MachineImage.INSPECTING)
        mock_reference_ami = Mock()
        mock_reference_ami.public = False
        mock_aws.get_ami.return_value = mock_reference_ami

        mock_aws.copy_ami.side_effect = ClientError(
            error_response={
                "Error": {
                    "Code":
                    "InvalidRequest",
                    "Message":
                    "You do not have permission to access the "
                    "storage of this ami.",
                }
            },
            operation_name=Mock(),
        )

        tasks.copy_ami_to_customer_account(arn, reference_ami_id,
                                           source_region)

        mock_aws.get_session.assert_called_with(arn)
        mock_aws.get_ami.assert_called_with(mock_aws.get_session.return_value,
                                            reference_ami_id, source_region)
        image.refresh_from_db()

        self.assertEqual(image.status, MachineImage.ERROR)
Esempio n. 17
0
    def test_copy_ami_to_customer_account_marketplace_with_dot_error(
            self, mock_aws):
        """Assert that the task marks marketplace image as inspected."""
        arn = util_helper.generate_dummy_arn()
        reference_ami_id = util_helper.generate_dummy_image_id()
        source_region = util_helper.get_random_region()
        image = api_helper.generate_image(ec2_ami_id=reference_ami_id,
                                          status=MachineImage.INSPECTING)

        mock_aws.copy_ami.side_effect = ClientError(
            error_response={
                "Error": {
                    "Code":
                    "InvalidRequest",
                    "Message":
                    "Images with EC2 BillingProduct codes cannot "
                    "be copied to another AWS account.",
                }
            },
            operation_name=Mock(),
        )

        tasks.copy_ami_to_customer_account(arn, reference_ami_id,
                                           source_region)

        mock_aws.get_session.assert_called_with(arn)
        mock_aws.get_ami.assert_called_with(mock_aws.get_session.return_value,
                                            reference_ami_id, source_region)
        image.refresh_from_db()
        aws_image = image.content_object
        aws_image.refresh_from_db()

        self.assertEqual(image.status, MachineImage.INSPECTED)
        self.assertTrue(aws_image.aws_marketplace_image)
Esempio n. 18
0
 def test_start_image_inspection_cloud_access_skips(self, mock_copy):
     """Test that inspection skips for Cloud Access images."""
     image = api_helper.generate_image(is_cloud_access=True)
     util.start_image_inspection(None, image.content_object.ec2_ami_id,
                                 None)
     mock_copy.delay.assert_not_called()
     image.refresh_from_db()
     self.assertEqual(image.status, image.INSPECTED)
Esempio n. 19
0
 def setUp(self):
     """Set up basic image objects."""
     self.machine_image = helper.generate_image()
     copy_ec2_ami_id = util_helper.generate_dummy_image_id()
     api.clouds.aws.util.create_aws_machine_image_copy(
         copy_ec2_ami_id, self.machine_image.content_object.ec2_ami_id)
     self.aws_machine_image_copy = aws_models.AwsMachineImageCopy.objects.get(
         reference_awsmachineimage=self.machine_image.content_object)
Esempio n. 20
0
 def test_start_image_inspection_rhel_tagged_skips(self, mock_copy):
     """Test that inspection skips for RHEL-tagged images."""
     image = api_helper.generate_image(rhel_detected_by_tag=True)
     util.start_image_inspection(None, image.content_object.ec2_ami_id,
                                 None)
     mock_copy.delay.assert_not_called()
     image.refresh_from_db()
     self.assertEqual(image.status, image.INSPECTED)
     self.assertTrue(image.rhel_detected_by_tag)
Esempio n. 21
0
    def test_objects_exist(self):
        """Test happy path when both objects exist."""
        ec2_ami_id = util_helper.generate_dummy_image_id()
        expected_machine_image = api_helper.generate_image(ec2_ami_id=ec2_ami_id)
        expected_aws_machine_image = expected_machine_image.content_object

        result = util.get_aws_machine_image(ec2_ami_id)
        self.assertEqual(expected_aws_machine_image, result[0])
        self.assertEqual(expected_machine_image, result[1])
Esempio n. 22
0
    def test_persist_aws_inspection_cluster_results_our_model_is_gone(self):
        """
        Assert that we handle when the AwsMachineImage model has been deleted.

        This can happen if the customer deletes their cloud account while we
        are running or waiting on the async inspection. Deleting the cloud
        account results in the instances and potentially the images being
        deleted, and when we get the inspection results back for that deleted
        image, we should just quietly drop the results and move on to other
        results that may still need processing.
        """
        deleted_ami_id = util_helper.generate_dummy_image_id()

        ami_id = util_helper.generate_dummy_image_id()
        api_helper.generate_image(
            is_encrypted=False, is_windows=False, ec2_ami_id=ami_id
        )
        rhel_version_a = _faker.slug()
        rhel_version_b = _faker.slug()

        inspection_results = {
            "cloud": "aws",
            "images": {
                deleted_ami_id: {
                    "rhel_found": True,
                    "rhel_release_files_found": True,
                    "rhel_version": rhel_version_b,
                },
                ami_id: {
                    "rhel_found": True,
                    "rhel_release_files_found": True,
                    "rhel_version": rhel_version_a,
                },
            },
        }

        util.persist_aws_inspection_cluster_results(inspection_results)
        aws_machine_image = AwsMachineImage.objects.get(ec2_ami_id=ami_id)
        machine_image = aws_machine_image.machine_image.get()
        self.assertTrue(machine_image.rhel)
        self.assertEqual(machine_image.rhel_version, rhel_version_a)

        with self.assertRaises(AwsMachineImage.DoesNotExist):
            AwsMachineImage.objects.get(ec2_ami_id=deleted_ami_id)
Esempio n. 23
0
    def test_copy_ami_snapshot_success_with_reference(self, mock_aws):
        """Assert the snapshot copy task succeeds using a reference AMI ID."""
        mock_session = mock_aws.boto3.Session.return_value
        mock_account_id = mock_aws.get_session_account_id.return_value

        account = account_helper.generate_cloud_account()
        arn = account.content_object.account_arn

        region = util_helper.get_random_region()
        new_image_id = util_helper.generate_dummy_image_id()
        # unlike non-reference calls to copy_ami_snapshot, we do NOT want to
        # call "account_helper.generate_aws_image(ec2_ami_id=new_image_id)"
        # here because cloudigrade has only seen the reference, not the new.
        mock_image = util_helper.generate_mock_image(new_image_id)
        block_mapping = mock_image.block_device_mappings
        mock_snapshot_id = block_mapping[0]["Ebs"]["SnapshotId"]
        mock_snapshot = util_helper.generate_mock_snapshot(
            mock_snapshot_id, owner_id=mock_account_id)
        mock_new_snapshot_id = util_helper.generate_dummy_snapshot_id()

        # This is the original ID of a private/shared image.
        # It would have been saved to our DB upon initial discovery.
        reference_image = account_helper.generate_image()
        reference_image_id = reference_image.content_object.ec2_ami_id

        mock_aws.get_session.return_value = mock_session
        mock_aws.get_ami.return_value = mock_image
        mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id
        mock_aws.get_snapshot.return_value = mock_snapshot
        mock_aws.copy_snapshot.return_value = mock_new_snapshot_id

        with patch.object(tasks.imageprep,
                          "create_volume") as mock_create_volume, patch.object(
                              tasks.imageprep, "remove_snapshot_ownership"
                          ) as mock_remove_snapshot_ownership:
            tasks.copy_ami_snapshot(arn, new_image_id, region,
                                    reference_image_id)
            # arn, customer_snapshot_id, snapshot_region, snapshot_copy_id
            mock_remove_snapshot_ownership.delay.assert_called_with(
                arn, mock_snapshot_id, region, mock_new_snapshot_id)
            mock_create_volume.delay.assert_called_with(
                reference_image_id, mock_new_snapshot_id)

        mock_aws.get_session.assert_called_with(arn)
        mock_aws.get_ami.assert_called_with(mock_session, new_image_id, region)
        mock_aws.get_ami_snapshot_id.assert_called_with(mock_image)
        mock_aws.add_snapshot_ownership.assert_called_with(mock_snapshot)
        mock_aws.copy_snapshot.assert_called_with(mock_snapshot_id, region)

        # Verify that the copy object was stored correctly to reference later.
        copied_image = AwsMachineImageCopy.objects.get(ec2_ami_id=new_image_id)
        self.assertIsNotNone(copied_image)
        self.assertEqual(
            copied_image.reference_awsmachineimage.ec2_ami_id,
            reference_image_id,
        )
Esempio n. 24
0
    def test_persist_aws_inspection_cluster_results(self):
        """Assert that non rhel_images are not tagged rhel."""
        ami_id = util_helper.generate_dummy_image_id()
        api_helper.generate_image(
            is_encrypted=False, is_windows=False, ec2_ami_id=ami_id
        )

        inspection_results = {
            "cloud": "aws",
            "images": {
                ami_id: {
                    "rhel_found": False,
                    "rhel_version": None,
                    "syspurpose": None,
                    "drive": {
                        "partition": {
                            "facts": [
                                {
                                    "release_file": "/centos-release",
                                    "release_file_contents": "CentOS\n",
                                    "rhel_found": False,
                                }
                            ]
                        }
                    },
                    "errors": [],
                }
            },
        }

        util.persist_aws_inspection_cluster_results(inspection_results)
        aws_machine_image = AwsMachineImage.objects.get(ec2_ami_id=ami_id)
        machine_image = aws_machine_image.machine_image.get()
        self.assertFalse(machine_image.rhel_detected)
        self.assertFalse(machine_image.openshift_detected)
        self.assertEqual(
            json.loads(machine_image.inspection_json),
            inspection_results["images"][ami_id],
        )
        self.assertFalse(machine_image.rhel)
        self.assertIsNone(machine_image.rhel_version)
        self.assertIsNone(machine_image.syspurpose)
        self.assertFalse(machine_image.openshift)
Esempio n. 25
0
    def test_persist_aws_inspection_cluster_results_mark_rhel(self):
        """Assert that rhel_images are tagged rhel."""
        ami_id = util_helper.generate_dummy_image_id()
        api_helper.generate_image(
            is_encrypted=False, is_windows=False, ec2_ami_id=ami_id
        )
        rhel_version = _faker.slug()
        syspurpose = {_faker.slug(): _faker.text()}
        inspection_results = {
            "cloud": "aws",
            "images": {
                ami_id: {
                    "rhel_found": True,
                    "rhel_release_files_found": True,
                    "rhel_version": rhel_version,
                    "syspurpose": syspurpose,
                    "drive": {
                        "partition": {
                            "facts": [
                                {
                                    "release_file": "/redhat-release",
                                    "release_file_contents": "RHEL\n",
                                    "rhel_found": True,
                                }
                            ]
                        }
                    },
                    "errors": [],
                }
            },
        }

        util.persist_aws_inspection_cluster_results(inspection_results)
        aws_machine_image = AwsMachineImage.objects.get(ec2_ami_id=ami_id)
        machine_image = aws_machine_image.machine_image.get()
        self.assertTrue(machine_image.rhel_detected)
        self.assertEqual(
            json.loads(machine_image.inspection_json),
            inspection_results["images"][ami_id],
        )
        self.assertTrue(machine_image.rhel)
        self.assertEqual(machine_image.rhel_version, rhel_version)
        self.assertFalse(machine_image.openshift)
Esempio n. 26
0
 def test_start_image_inspection_exceed_max_allowed(self, mock_copy):
     """Test that inspection stops when max allowed attempts is exceeded."""
     image = api_helper.generate_image()
     for _ in range(0, settings.MAX_ALLOWED_INSPECTION_ATTEMPTS + 1):
         MachineImageInspectionStart.objects.create(machineimage=image)
     util.start_image_inspection(None, image.content_object.ec2_ami_id,
                                 None)
     mock_copy.delay.assert_not_called()
     image.refresh_from_db()
     self.assertEqual(image.status, image.ERROR)
Esempio n. 27
0
    def test_copy_ami_snapshot_success(self, mock_aws):
        """Assert that the snapshot copy task succeeds."""
        mock_session = mock_aws.boto3.Session.return_value
        mock_account_id = mock_aws.get_session_account_id.return_value

        mock_arn = util_helper.generate_dummy_arn()
        mock_region = util_helper.get_random_region()
        mock_image_id = util_helper.generate_dummy_image_id()
        mock_image = util_helper.generate_mock_image(mock_image_id)
        account_helper.generate_image(ec2_ami_id=mock_image_id)
        block_mapping = mock_image.block_device_mappings
        mock_snapshot_id = block_mapping[0]["Ebs"]["SnapshotId"]
        mock_snapshot = util_helper.generate_mock_snapshot(
            mock_snapshot_id, owner_id=mock_account_id)
        mock_new_snapshot_id = util_helper.generate_dummy_snapshot_id()

        mock_aws.get_session.return_value = mock_session
        mock_aws.get_ami.return_value = mock_image
        mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id
        mock_aws.get_snapshot.return_value = mock_snapshot
        mock_aws.copy_snapshot.return_value = mock_new_snapshot_id

        with patch.object(tasks.imageprep,
                          "create_volume") as mock_create_volume:
            with patch.object(tasks.imageprep, "remove_snapshot_ownership"
                              ) as mock_remove_snapshot_ownership:
                tasks.copy_ami_snapshot(mock_arn, mock_image_id, mock_region)
                mock_create_volume.delay.assert_called_with(
                    mock_image_id, mock_new_snapshot_id)
                mock_remove_snapshot_ownership.delay.assert_called_with(
                    mock_arn,
                    mock_snapshot_id,
                    mock_region,
                    mock_new_snapshot_id,
                )

        mock_aws.get_session.assert_called_with(mock_arn)
        mock_aws.get_ami.assert_called_with(mock_session, mock_image_id,
                                            mock_region)
        mock_aws.get_ami_snapshot_id.assert_called_with(mock_image)
        mock_aws.add_snapshot_ownership.assert_called_with(mock_snapshot)
        mock_aws.copy_snapshot.assert_called_with(mock_snapshot_id,
                                                  mock_region)
Esempio n. 28
0
    def test_attach_volumes_to_cluster_with_marketplace_volume(
        self, mock_boto3, mock_run_inspection_cluster
    ):
        """Assert that ami is marked as inspected if marketplace volume."""
        ami_id = util_helper.generate_dummy_image_id()
        volume_id = util_helper.generate_dummy_volume_id()

        image = account_helper.generate_image(
            ec2_ami_id=ami_id, status=MachineImage.PENDING
        )

        instance_id = util_helper.generate_dummy_instance_id()
        mock_list_container_instances = {"containerInstanceArns": [instance_id]}
        mock_ec2 = Mock()
        mock_ec2_instance = mock_ec2.Instance.return_value
        mock_ec2_instance.state = EC2_INSTANCE_STATE_RUNNING

        mock_volume = mock_ec2.Volume.return_value
        mock_volume.attach_to_instance.side_effect = ClientError(
            error_response={
                "Error": {
                    "Code": "OptInRequired",
                    "Message": "Marketplace Error",
                }
            },
            operation_name=Mock(),
        )

        mock_ecs = MagicMock()
        mock_ecs.list_container_instances.return_value = mock_list_container_instances

        mock_boto3.client.return_value = mock_ecs
        mock_boto3.resource.return_value = mock_ec2

        messages = [{"ami_id": ami_id, "volume_id": volume_id}]
        tasks.attach_volumes_to_cluster(messages)
        image.refresh_from_db()

        self.assertEqual(image.status, MachineImage.INSPECTED)

        mock_ecs.list_container_instances.assert_called_once_with(
            cluster=settings.HOUNDIGRADE_ECS_CLUSTER_NAME, status="ACTIVE"
        )
        mock_ecs.describe_container_instances.assert_called_once_with(
            containerInstances=[instance_id],
            cluster=settings.HOUNDIGRADE_ECS_CLUSTER_NAME,
        )
        mock_ecs.register_task_definition.assert_not_called()
        mock_ecs.run_task.assert_not_called()

        mock_ec2.Volume.assert_called_once_with(volume_id)
        mock_ec2.Volume.return_value.attach_to_instance.assert_called_once()

        mock_run_inspection_cluster.delay.assert_not_called()
Esempio n. 29
0
 def setUp(self):
     """Set up a bunch of test data."""
     self.user1 = util_helper.generate_test_user()
     self.user1.date_joined = util_helper.utc_dt(2019, 1, 1, 0, 0, 0)
     self.user1.save()
     self.account1 = api_helper.generate_cloud_account(user=self.user1)
     self.account2 = api_helper.generate_cloud_account(user=self.user1)
     self.image1_rhel = api_helper.generate_image(
         rhel_detected=True,
         rhel_version="7.7",
         syspurpose={"role": "potato"},
     )
     self.image2_rhel = api_helper.generate_image(rhel_detected=True)
     self.instance1 = api_helper.generate_instance(self.account1,
                                                   image=self.image1_rhel)
     self.instance2 = api_helper.generate_instance(self.account1,
                                                   image=self.image2_rhel)
     self.instance_type1 = "c5.xlarge"  # 4 vcpu and 8.0 memory
     self.factory = APIRequestFactory()
     self.faker = faker.Faker()
Esempio n. 30
0
    def setUp(self):
        """Set up basic aws account."""
        self.account = helper.generate_cloud_account()

        self.image = helper.generate_image()
        self.instance = helper.generate_instance(cloud_account=self.account,
                                                 image=self.image)
        self.instance_without_image = helper.generate_instance(
            cloud_account=self.account,
            no_image=True,
        )