def test_check_cluster_instances_under_limit(self, mock_aws, mock_boto3): """Assert logs info and debug if launch times are under the configured limit.""" instance_id_1 = helper.generate_dummy_instance_id() instance_id_2 = helper.generate_dummy_instance_id() instance_ids = [instance_id_1, instance_id_2] launch_time = TEST_TIME - timedelta( seconds=10) # less than 600 seconds older mock_aws.describe_instances.return_value = dict(( instance_id, helper.generate_dummy_describe_instance(instance_id, launch_time=launch_time), ) for instance_id in instance_ids) with self.assertLogs("api.clouds.aws.tasks.inspection", level="DEBUG") as logging_watcher: inspection.check_cluster_instances_age(instance_ids) self.assertEqual(len(logging_watcher.output), 4) self.assertInLog(instance_id_1, logging_watcher.output[0]) self.assertInLog(instance_id_2, logging_watcher.output[1]) self.assertInLog(instance_id_1, logging_watcher.output[2], "DEBUG") self.assertInLog(instance_id_2, logging_watcher.output[3], "DEBUG") self.assertInLog("fits within", logging_watcher.output[2], "DEBUG") self.assertInLog("10.0 seconds", logging_watcher.output[2], "DEBUG") self.assertInLog("fits within", logging_watcher.output[3], "DEBUG") self.assertInLog("10.0 seconds", logging_watcher.output[3], "DEBUG") mock_boto3.Session.assert_called_once() mock_aws.describe_instances.assert_called_once_with( mock_boto3.Session.return_value, instance_ids, mock_aws.ECS_CLUSTER_REGION, )
def test_scale_up_inspection_cluster_aborts_when_not_scaled_down( self, mock_aws, mock_check, mock_attach_cluster_volumes): """Assert scale up aborts when not scaled down.""" instance_ids = [ helper.generate_dummy_instance_id(), helper.generate_dummy_instance_id(), ] mock_aws.is_scaled_down.return_value = ( False, { "Instances": [{ "InstanceId": instance_id } for instance_id in instance_ids] }, ) tasks.scale_up_inspection_cluster() mock_check.assert_called_once_with(instance_ids) mock_aws.is_scaled_down.assert_called_once_with( settings.HOUNDIGRADE_AWS_AUTOSCALING_GROUP_NAME) mock_aws.scale_up.assert_not_called() mock_aws.read_messages_from_queue.assert_not_called() mock_attach_cluster_volumes.delay.assert_not_called() mock_aws.add_messages_to_queue.assert_not_called()
def test_check_cluster_instances_age_no_launch_time( self, mock_aws, mock_boto3): """Assert logs info and errors if no launch times from AWS.""" instance_id_1 = helper.generate_dummy_instance_id() instance_id_2 = helper.generate_dummy_instance_id() instance_ids = [instance_id_1, instance_id_2] mock_aws.describe_instances.return_value = dict(( instance_id, helper.generate_dummy_describe_instance(instance_id, launch_time=None), ) for instance_id in instance_ids) with self.assertLogs("api.clouds.aws.tasks.inspection", level="INFO") as logging_watcher: inspection.check_cluster_instances_age(instance_ids) self.assertEqual(len(logging_watcher.output), 4) self.assertInLog(instance_id_1, logging_watcher.output[0]) self.assertInLog(instance_id_2, logging_watcher.output[1]) self.assertInLog(instance_id_1, logging_watcher.output[2], "ERROR") self.assertInLog(instance_id_2, logging_watcher.output[3], "ERROR") self.assertInLog("no launch time", logging_watcher.output[2], "ERROR") self.assertInLog("no launch time", logging_watcher.output[3], "ERROR") mock_boto3.Session.assert_called_once() mock_aws.describe_instances.assert_called_once_with( mock_boto3.Session.return_value, instance_ids, mock_aws.ECS_CLUSTER_REGION, )
def test_describe_instances(self): """Assert that describe_instances returns a dict of instances data.""" instance_ids = [ helper.generate_dummy_instance_id(), helper.generate_dummy_instance_id(), helper.generate_dummy_instance_id(), helper.generate_dummy_instance_id(), ] individual_described_instances = [ helper.generate_dummy_describe_instance(instance_id) for instance_id in instance_ids ] response = { "Reservations": [ { "Instances": individual_described_instances[:2], }, { "Instances": individual_described_instances[2:], }, ], } mock_session = Mock() mock_client = mock_session.client.return_value mock_client.describe_instances.return_value = response region = helper.get_random_region() described_instances = ec2.describe_instances(mock_session, instance_ids, region) self.assertEqual(set(described_instances.keys()), set(instance_ids)) for described_instance in individual_described_instances: self.assertIn(described_instance, described_instances.values())
def test_run_inspection_cluster_success(self, mock_boto3): """Asserts successful starting of the houndigrade task.""" mock_list_container_instances = { 'containerInstanceArns': [util_helper.generate_dummy_instance_id()] } mock_ec2 = 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': util_helper.generate_dummy_image_id(), 'volume_id': util_helper.generate_dummy_volume_id() }] tasks.run_inspection_cluster(messages) mock_ecs.list_container_instances.assert_called_once_with( cluster=settings.HOUNDIGRADE_ECS_CLUSTER_NAME) mock_ecs.describe_container_instances.assert_called_once_with( containerInstances=[ mock_list_container_instances['containerInstanceArns'][0] ], cluster=settings.HOUNDIGRADE_ECS_CLUSTER_NAME) mock_ecs.register_task_definition.assert_called_once() mock_ecs.run_task.assert_called_once() mock_ec2.Volume.assert_called_once_with(messages[0]['volume_id']) mock_ec2.Volume.return_value.attach_to_instance.assert_called_once()
def generate_aws_instance(account, ec2_instance_id=None, region=None): """ Generate an AwsInstance for the AwsAccount for testing. Any optional arguments not provided will be randomly generated. Args: account (AwsAccount): Account that owns the instance. ec2_instance_id (str): Optional EC2 instance id. region (str): Optional AWS region where the instance runs. Returns: AwsInstance: The created AwsInstance. """ if ec2_instance_id is None: ec2_instance_id = helper.generate_dummy_instance_id() if region is None: region = random.choice(helper.SOME_AWS_REGIONS) return AwsInstance.objects.create( account=account, ec2_instance_id=ec2_instance_id, region=region, )
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()
def test_run_inspection_cluster_with_too_many_instances(self, mock_boto3): """Assert that an exception is raised with too many instances.""" mock_list_container_instances = { 'containerInstanceArns': [ util_helper.generate_dummy_instance_id(), util_helper.generate_dummy_instance_id() ] } mock_ecs = MagicMock() mock_ecs.list_container_instances.return_value = \ mock_list_container_instances mock_boto3.client.return_value = mock_ecs with self.assertRaises(AwsTooManyECSInstances): tasks.run_inspection_cluster([Mock()])
def setUp(self): """Set up fixtures.""" self.ec2_instance_id = util_helper.generate_dummy_instance_id() self.ami_id_a = util_helper.generate_dummy_image_id() self.ami_id_b = util_helper.generate_dummy_image_id() self.ami_id_c = util_helper.generate_dummy_image_id() self.ami_mountpoints = [ (self.ami_id_a, "/dev/sdba"), (self.ami_id_b, "/dev/sdbb"), (self.ami_id_c, "/dev/sdbc"), ]
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()
def test_attach_volumes_to_cluster_success( self, mock_boto3, mock_run_inspection_cluster ): """Asserts successful starting of the houndigrade task.""" ami_id = util_helper.generate_dummy_image_id() volume_id = util_helper.generate_dummy_volume_id() device_name = misc.generate_device_name(0) expected_ami_mountpoints = [(ami_id, device_name)] 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_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 mock_ecs.describe_container_instances.return_value = { "containerInstances": [{"ec2InstanceId": instance_id}] } messages = [{"ami_id": ami_id, "volume_id": volume_id}] tasks.attach_volumes_to_cluster(messages) image.refresh_from_db() self.assertEqual(image.status, MachineImage.INSPECTING) 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_ec2.Volume.assert_called_once_with(volume_id) mock_ec2.Volume.return_value.attach_to_instance.assert_called_once_with( Device=device_name, InstanceId=instance_id ) mock_run_inspection_cluster.delay.assert_called_once_with( instance_id, expected_ami_mountpoints )
def test_run_inspection_cluster_success(self, mock_aws, mock_boto3, mock_machine_image_objects): """Asserts successful starting of the houndigrade task.""" mock_machine_image_objects.get.return_value = \ mock_machine_image_objects mock_machine_image_objects.INSPECTING.return_value = 'inspecting' mock_list_container_instances = { 'containerInstanceArns': [util_helper.generate_dummy_instance_id()] } mock_ec2 = 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 mock_session = mock_aws.boto3.Session.return_value mock_aws.get_session.return_value = mock_session mock_ami_id = util_helper.generate_dummy_image_id() messages = [{ 'ami_id': mock_ami_id, 'volume_id': util_helper.generate_dummy_volume_id() }] tasks.run_inspection_cluster(messages) mock_machine_image_objects.get.assert_called_once_with( ec2_ami_id=mock_ami_id) self.assertEqual(mock_machine_image_objects.status.return_value, mock_machine_image_objects.INSPECTING.return_value) mock_ecs.list_container_instances.assert_called_once_with( cluster=settings.HOUNDIGRADE_ECS_CLUSTER_NAME) mock_ecs.describe_container_instances.assert_called_once_with( containerInstances=[ mock_list_container_instances['containerInstanceArns'][0] ], cluster=settings.HOUNDIGRADE_ECS_CLUSTER_NAME) mock_ecs.register_task_definition.assert_called_once() mock_ecs.run_task.assert_called_once() mock_ec2.Volume.assert_called_once_with(messages[0]['volume_id']) mock_ec2.Volume.return_value.attach_to_instance.assert_called_once()
def test_run_inspection_cluster_with_too_many_instances( self, mock_boto3, mock_machine_image_objects): """Assert that an exception is raised with too many instances.""" messages = [{ 'ami_id': util_helper.generate_dummy_image_id(), 'volume_id': util_helper.generate_dummy_volume_id() }] mock_machine_image_objects.get.return_value = \ mock_machine_image_objects mock_list_container_instances = { 'containerInstanceArns': [ util_helper.generate_dummy_instance_id(), util_helper.generate_dummy_instance_id() ] } mock_ecs = MagicMock() mock_ecs.list_container_instances.return_value = \ mock_list_container_instances mock_boto3.client.return_value = mock_ecs with self.assertRaises(AwsTooManyECSInstances): tasks.run_inspection_cluster(messages)
def test_generate_aws_instance_with_args(self): """Assert generation of an AwsInstance with all specified args.""" account = helper.generate_aws_account() ec2_instance_id = util_helper.generate_dummy_instance_id() region = random.choice(util_helper.SOME_AWS_REGIONS) instance = helper.generate_aws_instance( account, ec2_instance_id=ec2_instance_id, region=region, ) self.assertIsInstance(instance, AwsInstance) self.assertEqual(instance.account, account) self.assertEqual(instance.ec2_instance_id, ec2_instance_id) self.assertEqual(instance.region, region)
def test_get_ec2_instance(self): """Assert that get_ec2_instance returns an Instance.""" mock_instance_id = helper.generate_dummy_instance_id() mock_instance = helper.generate_mock_ec2_instance(mock_instance_id) mock_session = Mock() mock_resource = mock_session.resource.return_value mock_resource.Instance.return_value = mock_instance actual_instance = ec2.get_ec2_instance(mock_session, mock_instance_id) self.assertEqual(actual_instance, mock_instance) mock_session.resource.assert_called_once_with('ec2') mock_resource.Instance.assert_called_once_with(mock_instance_id)
def test_generate_aws_instance_with_args(self): """Assert generation of an AwsInstance with all specified args.""" account = helper.generate_cloud_account() ec2_instance_id = util_helper.generate_dummy_instance_id() region = util_helper.get_random_region() instance = helper.generate_instance( account, ec2_instance_id=ec2_instance_id, region=region, ) self.assertIsInstance(instance, Instance) self.assertEqual(instance.cloud_account, account) self.assertEqual(instance.content_object.ec2_instance_id, ec2_instance_id) self.assertEqual(instance.content_object.region, region)
def test_attach_volumes_to_cluster_with_too_many_instances( self, mock_boto3, mock_machine_image_objects, mock_run_inspection_cluster ): """Assert that an exception is raised with too many instances.""" ami_id = util_helper.generate_dummy_image_id() volume_id = util_helper.generate_dummy_volume_id() instance_ids = [ util_helper.generate_dummy_instance_id(), util_helper.generate_dummy_instance_id(), ] mock_machine_image_objects.get.return_value = mock_machine_image_objects mock_list_container_instances = {"containerInstanceArns": instance_ids} mock_ecs = MagicMock() mock_ecs.list_container_instances.return_value = mock_list_container_instances mock_boto3.client.return_value = mock_ecs messages = [{"ami_id": ami_id, "volume_id": volume_id}] with self.assertRaises(AwsTooManyECSInstances): tasks.attach_volumes_to_cluster(messages) mock_run_inspection_cluster.delay.assert_not_called()
def test_generate_dummy_describe_instance_with_values(self): """Assert generated instance contains given values.""" image_id = helper.generate_dummy_image_id() instance_id = helper.generate_dummy_instance_id() subnet_id = helper.generate_dummy_subnet_id() state = aws.InstanceState.shutting_down instance_type = random.choice(helper.SOME_EC2_INSTANCE_TYPES) instance = helper.generate_dummy_describe_instance( instance_id, image_id, subnet_id, state, instance_type) self.assertEqual(instance['ImageId'], image_id) self.assertEqual(instance['InstanceId'], instance_id) self.assertEqual(instance['InstanceType'], instance_type) self.assertEqual(instance['SubnetId'], subnet_id) self.assertEqual(instance['State']['Code'], state.value) self.assertEqual(instance['State']['Name'], state.name)
def test_command_output_non_on_off_events(self, mock_receive, mock_s3, mock_del): """Test that non on/off events are not processed.""" mock_instance_id = util_helper.generate_dummy_instance_id() mock_queue_url = 'https://sqs.queue.url' mock_receipt_handle = str(uuid.uuid4()) mock_sqs_message_body = { 'Records': [{ 's3': { 'bucket': { 'name': 'test-bucket', }, 'object': { 'key': 'path/to/log', }, }, }] } mock_message = util_helper.generate_mock_sqs_message( mock_queue_url, json.dumps(mock_sqs_message_body), mock_receipt_handle) mock_cloudtrail_log = { 'Records': [{ 'eventSource': 'null.amazonaws.com', }, { 'errorCode': 123, }, { 'eventName': 'InvalidEvent' }] } mock_receive.return_value = [mock_message] mock_s3.return_value = json.dumps(mock_cloudtrail_log) mock_del.return_value = 'Success' tasks.analyze_log() instances = list( AwsInstance.objects.filter(ec2_instance_id=mock_instance_id).all()) instance_events = list( AwsInstanceEvent.objects.filter( instance=instances[0]).all()) if instances else [] self.assertListEqual(instances, []) self.assertListEqual(instance_events, [])
def test_generate_dummy_describe_instance_with_values(self): """Assert generated instance contains given values.""" image_id = helper.generate_dummy_image_id() instance_id = helper.generate_dummy_instance_id() subnet_id = helper.generate_dummy_subnet_id() state = aws.InstanceState.shutting_down instance_type = helper.get_random_instance_type() device_mapping = helper.generate_dummy_block_device_mapping() instance = helper.generate_dummy_describe_instance( instance_id=instance_id, image_id=image_id, subnet_id=subnet_id, state=state, instance_type=instance_type, device_mappings=[device_mapping], ) self.assertEqual(instance["ImageId"], image_id) self.assertEqual(instance["InstanceId"], instance_id) self.assertEqual(instance["InstanceType"], instance_type) self.assertEqual(instance["SubnetId"], subnet_id) self.assertEqual(instance["State"]["Code"], state.value) self.assertEqual(instance["State"]["Name"], state.name) self.assertEqual(instance["State"]["Name"], state.name) self.assertEqual(instance["BlockDeviceMappings"], [device_mapping])
def generate_instance( # noqa: C901 cloud_account, ec2_instance_id=None, region=None, image=None, no_image=False, cloud_type=AWS_PROVIDER_STRING, azure_instance_resource_id=None, ): """ Generate an AwsInstance for the AwsAccount for testing. Any optional arguments not provided will be randomly generated. Args: cloud_account (CloudAccount): Account that owns the instance. ec2_instance_id (str): Optional EC2 instance id. region (str): Optional AWS region where the instance runs. image (MachineImage): Optional image to add instead of creating one. no_image (bool): Whether an image should be attached to this instance. cloud_type (str): Str denoting cloud type, defaults to "aws" azure_instance_resource_id (str): optional str for azure instance resource id Returns: Instance: The created Instance. """ if region is None: region = helper.get_random_region(cloud_type=cloud_type) if cloud_type == AZURE_PROVIDER_STRING: if azure_instance_resource_id is None: azure_instance_resource_id = helper.generate_dummy_azure_instance_id( ) if image is None: if not no_image: image_resource_id = helper.generate_dummy_azure_image_id() try: azure_image = AzureMachineImage.objects.get( resource_id=image_resource_id) image = azure_image.machine_image.get() except AzureMachineImage.DoesNotExist: image = generate_image( azure_image_resource_id=image_resource_id, status=MachineImage.PENDING, cloud_type=cloud_type, ) provider_instance = AzureInstance.objects.create( resource_id=azure_instance_resource_id, region=region, ) else: if ec2_instance_id is None: ec2_instance_id = helper.generate_dummy_instance_id() if image is None: if not no_image: ec2_ami_id = helper.generate_dummy_image_id() try: aws_image = AwsMachineImage.objects.get( ec2_ami_id=ec2_ami_id) image = aws_image.machine_image.get() except AwsMachineImage.DoesNotExist: aws_account_id = cloud_account.content_object.aws_account_id image = generate_image( ec2_ami_id=ec2_ami_id, owner_aws_account_id=aws_account_id, status=MachineImage.PENDING, ) provider_instance = AwsInstance.objects.create( ec2_instance_id=ec2_instance_id, region=region, ) instance = Instance.objects.create( cloud_account=cloud_account, content_object=provider_instance, machine_image=image, ) return instance
def test_command_output_success_ec2_attributes_included( self, mock_receive, mock_s3, mock_del, mock_session, mock_ec2, mock_inspection): """Test processing a CloudTrail log with all data included.""" mock_queue_url = 'https://sqs.queue.url' mock_receipt_handle = str(uuid.uuid4()) mock_instance_id = util_helper.generate_dummy_instance_id() mock_instance_id2 = util_helper.generate_dummy_instance_id() mock_region = random.choice(util_helper.SOME_AWS_REGIONS) mock_event_type = 'RunInstances' now = datetime.datetime.utcnow() # Work around for sqlite handling of microseconds mock_occurred_at = datetime.datetime(year=now.year, month=now.month, day=now.day, hour=now.hour, minute=now.minute, second=now.second, tzinfo=tz.tzutc()) mock_subnet = 'subnet-9000' mock_ec2_ami_id = util_helper.generate_dummy_image_id() mock_instance_type = 't2.nano' mock_instance = util_helper.generate_mock_ec2_instance( mock_instance_id, mock_ec2_ami_id, mock_subnet, None, mock_instance_type, 'windows') mock_inspection.delay.return_value = True mock_sqs_message_body = { 'Records': [{ 's3': { 'bucket': { 'name': 'test-bucket', }, 'object': { 'key': 'path/to/log/log.json.gz', }, }, }] } mock_message = util_helper.generate_mock_sqs_message( mock_queue_url, json.dumps(mock_sqs_message_body), mock_receipt_handle) mock_cloudtrail_log = { 'Records': [{ 'awsRegion': mock_region, 'eventName': mock_event_type, 'eventSource': 'ec2.amazonaws.com', 'eventTime': mock_occurred_at.strftime('%Y-%m-%dT%H:%M:%SZ'), 'eventType': 'AwsApiCall', 'responseElements': { 'instancesSet': { 'items': [{ 'imageId': mock_ec2_ami_id, 'instanceId': mock_instance_id, 'instanceType': mock_instance_type, 'subnetId': mock_subnet }] }, }, 'userIdentity': { 'accountId': self.mock_account_id } }, { 'awsRegion': mock_region, 'eventName': mock_event_type, 'eventSource': 'ec2.amazonaws.com', 'eventTime': mock_occurred_at.strftime('%Y-%m-%dT%H:%M:%SZ'), 'eventType': 'AwsApiCall', 'responseElements': { 'instancesSet': { 'items': [{ 'imageId': mock_ec2_ami_id, 'instanceId': mock_instance_id, 'instanceType': mock_instance_type, 'subnetId': mock_subnet }] }, }, 'userIdentity': { 'accountId': self.mock_account_id } }, { 'awsRegion': mock_region, 'eventName': mock_event_type, 'eventSource': 'ec2.amazonaws.com', 'eventTime': mock_occurred_at.strftime('%Y-%m-%dT%H:%M:%SZ'), 'eventType': 'DifferentAwsApiCall', 'responseElements': { 'instancesSet': { 'items': [{ 'imageId': mock_ec2_ami_id, 'instanceId': mock_instance_id2, 'instanceType': mock_instance_type, 'subnetId': mock_subnet }] }, }, 'userIdentity': { 'accountId': self.mock_account_id } }] } mock_receive.return_value = [mock_message] mock_s3.return_value = json.dumps(mock_cloudtrail_log) mock_del.return_value = 'Success' mock_session.return_value = 'Session' mock_ec2.return_value = mock_instance tasks.analyze_log() instances = list( AwsInstance.objects.filter(ec2_instance_id=mock_instance_id).all()) instance_events = list( AwsInstanceEvent.objects.filter( instance=instances[0]).all()) if instances else [] for instance in instances: self.assertEqual(instance.account, self.mock_account) self.assertEqual(instance.ec2_instance_id, mock_instance_id) self.assertEqual(instance.region, mock_region) for event in instance_events: self.assertEqual(event.instance, instances[0]) self.assertEqual(event.event_type, InstanceEvent.TYPE.power_on) self.assertEqual(event.occurred_at, mock_occurred_at) self.assertEqual(event.subnet, mock_subnet) self.assertEqual(event.machineimage.ec2_ami_id, mock_ec2_ami_id) self.assertEqual(event.instance_type, mock_instance_type)
def test_other_tags_ignored(self, mock_receive, mock_s3, mock_del): """Test processing a CloudTrail log for other tags ignored.""" mock_instance_id = util_helper.generate_dummy_instance_id() mock_sqs_message_body = { 'Records': [{ 's3': { 'bucket': { 'name': 'test-bucket', }, 'object': { 'key': 'path/to/log/log.json.gz', }, }, }] } mock_queue_url = 'https://sqs.queue.url' mock_receipt_handle = str(uuid.uuid4()) mock_region = random.choice(util_helper.SOME_AWS_REGIONS) now = datetime.datetime.utcnow() mock_occurred_at = datetime.datetime(year=now.year, month=now.month, day=now.day, hour=now.hour, minute=now.minute, second=now.second, tzinfo=tz.tzutc()) mock_message = util_helper.generate_mock_sqs_message( mock_queue_url, json.dumps(mock_sqs_message_body), mock_receipt_handle) mock_cloudtrail_log = { 'Records': [{ 'eventTime': mock_occurred_at.strftime('%Y-%m-%dT%H:%M:%SZ'), 'eventSource': 'ec2.amazonaws.com', 'awsRegion': mock_region, 'eventName': tasks.DELETE_TAG, 'requestParameters': { 'resourcesSet': { 'items': [{ 'resourceId': mock_instance_id }] }, 'tagSet': { 'items': [{ 'key': tasks.AWS_OPENSHIFT_TAG, 'value': tasks.AWS_OPENSHIFT_TAG }] } } }] } mock_receive.return_value = [mock_message] mock_s3.return_value = json.dumps(mock_cloudtrail_log) try: tasks.analyze_log() except Exception: self.fail('Should not raise exceptions for ignored tag events.')
def test_generate_dummy_instance_id(self): """Assert generation of an appropriate EC2 instance ID.""" volume_id = helper.generate_dummy_instance_id() self.assertTrue(volume_id.startswith('i-')) self.assertEqual(len(volume_id), 19)