예제 #1
0
    def test_generate_aws_ami_messages_deduplicate(self):
        """Test that messages are also deduplicated."""
        region = util_helper.get_random_region()
        image_id_1 = util_helper.generate_dummy_image_id()
        image_id_2 = util_helper.generate_dummy_image_id()
        instance_1 = util_helper.generate_dummy_describe_instance(
            image_id=image_id_1)
        instance_2 = util_helper.generate_dummy_describe_instance(
            image_id=image_id_1)
        instance_3 = util_helper.generate_dummy_describe_instance(
            image_id=image_id_1)
        instance_4 = util_helper.generate_dummy_describe_instance(
            image_id=image_id_2)
        instances_data = {
            region: [instance_1, instance_2, instance_3, instance_4]
        }
        ami_list = [image_id_1, image_id_2]

        expected = [
            {
                "cloud_provider": AWS_PROVIDER_STRING,
                "region": region,
                "image_id": image_id_1,
            },
            {
                "cloud_provider": AWS_PROVIDER_STRING,
                "region": region,
                "image_id": image_id_2,
            },
        ]

        result = generate_aws_ami_messages(instances_data, ami_list)
        self.assertEqual(len(result), len(expected))
        for message in expected:
            self.assertIn(message, result)
예제 #2
0
    def test_generate_aws_ami_messages(self):
        """Test that messages are formatted correctly."""
        region = util_helper.get_random_region()
        instance = util_helper.generate_dummy_describe_instance()
        instances_data = {region: [instance]}
        ami_list = [instance["ImageId"]]

        expected = [{
            "cloud_provider": AWS_PROVIDER_STRING,
            "region": region,
            "image_id": instance["ImageId"],
        }]

        result = generate_aws_ami_messages(instances_data, ami_list)

        self.assertEqual(result, expected)
예제 #3
0
def initial_aws_describe_instances(account_id):
    """
    Fetch and save instances data found upon AWS cloud account creation.

    Args:
        account_id (int): the AwsAccount id
    """
    try:
        aws_account = AwsCloudAccount.objects.get(pk=account_id)
    except AwsCloudAccount.DoesNotExist:
        logger.warning(
            _("AwsCloudAccount id %s could not be found for initial describe"),
            account_id,
        )
        # This can happen if a customer creates and then quickly deletes their
        # cloud account before this async task has started to run. Early exit!
        return

    account = aws_account.cloud_account.get()
    if not account.is_enabled:
        logger.warning(
            _("AwsCloudAccount id %s is not enabled; skipping initial describe"
              ),
            account_id,
        )
        # This can happen if a customer creates and then quickly disabled their
        # cloud account before this async task has started to run. Early exit!
        return
    arn = aws_account.account_arn

    session = aws.get_session(arn)
    instances_data = aws.describe_instances_everywhere(session)

    try:
        user_id = account.user.id
    except User.DoesNotExist:
        logger.info(
            _("User for account id %s has already been deleted; "
              "skipping initial describe."),
            account_id,
        )
        # This can happen if a customer creates and then quickly deletes their
        # cloud account before this async task has started to run. If the user has
        # no other cloud accounts the user will also be deleted. Early exit!
        return

    # Lock the task at a user level. A user can only run one task at a time.
    with lock_task_for_user_ids([user_id]):
        try:
            # Explicitly "get" the related AwsCloudAccount before proceeding.
            # We do this at the start of this transaction in case the account has been
            # deleted during the potentially slow describe_instances_everywhere above.
            # If this fails, we'll jump to the except block to log an important warning.
            AwsCloudAccount.objects.get(pk=account_id)

            create_missing_power_off_aws_instance_events(
                account, instances_data)
            new_ami_ids = create_new_machine_images(session, instances_data)
            logger.info(
                _("Created new machine images include: %(new_ami_ids)s"),
                {"new_ami_ids": new_ami_ids},
            )
            create_initial_aws_instance_events(account, instances_data)
        except AwsCloudAccount.DoesNotExist:
            logger.warning(
                _("AwsCloudAccount id %s could not be found to save newly "
                  "discovered images and instances"),
                account_id,
            )
            # This can happen if a customer deleted their cloud account between
            # the start of this function and here. The AWS calls for
            # describe_instances_everywhere may be slow and are not within this
            # transaction. That's why we have to check again after it.
            return

    messages = generate_aws_ami_messages(instances_data, new_ami_ids)
    for message in messages:
        start_image_inspection(str(arn), message["image_id"],
                               message["region"])