def get_running_instances(session): """ Find all running EC2 instances visible to the given ARN. Args: session (boto3.Session): A temporary session tied to a customer account Returns: dict: Lists of instance IDs keyed by region where they were found. """ running_instances = {} for region_name in get_regions(session): ec2 = session.client('ec2', region_name=region_name) logger.debug(_('Describing instances in {0}').format(region_name)) instances = ec2.describe_instances() running_instances[region_name] = list() for reservation in instances.get('Reservations', []): running_instances[region_name].extend([ instance for instance in reservation.get('Instances', []) if InstanceState.is_running(instance['State']['Code']) ]) return running_instances
def test_get_regions_with_custom_service(self): """Assert get_regions with service name returns expected regions.""" mock_regions = [ f'region-{uuid.uuid4()}', f'region-{uuid.uuid4()}', ] mock_session = Mock() mock_session.get_available_regions.return_value = mock_regions actual_regions = helper.get_regions(mock_session, 'tng') self.assertTrue(mock_session.get_available_regions.called) mock_session.get_available_regions.assert_called_with('tng') self.assertListEqual(mock_regions, actual_regions)
def test_get_regions_with_no_args(self): """Assert get_regions with no args returns expected regions.""" mock_regions = [ f'region-{uuid.uuid4()}', f'region-{uuid.uuid4()}', ] mock_session = Mock() mock_session.get_available_regions.return_value = mock_regions actual_regions = helper.get_regions(mock_session) self.assertTrue(mock_session.get_available_regions.called) mock_session.get_available_regions.assert_called_with('ec2') self.assertListEqual(mock_regions, actual_regions)
def test_get_regions_with_no_args(self): """Assert get_regions with no args returns expected regions.""" mock_region_names = [ f"region-{uuid.uuid4()}", f"region-{uuid.uuid4()}", ] mock_regions = { "Regions": [ {"RegionName": mock_region_names[0]}, {"RegionName": mock_region_names[1]}, ] } mock_client = Mock() mock_client.describe_regions.return_value = mock_regions mock_session = Mock() mock_session.client.return_value = mock_client actual_regions = helper.get_regions(mock_session) self.assertTrue(mock_client.describe_regions.called) mock_session.client.assert_called_with("ec2") self.assertListEqual(mock_region_names, actual_regions)
def describe_instances_everywhere(session): """ Describe all EC2 instances visible to the given ARN in every known region. Note: When we collect and return the results of the AWS describe calls, we now specifically exclude instances that have the terminated state. Although we should be able to extract useful data from them, in our integration tests when we are rapidly creating and terminating EC2 instances, it has been confusing to see data from terminated instances from a previous test affect later tests. There does not appear to be a convenient way to handle this in those tests since AWS also takes an unknown length of time to actually remove terminated instances. So, we are "solving" this problem here by unilaterally ignoring them. Args: session (boto3.Session): A temporary session tied to a customer account Returns: dict: Lists of instance IDs keyed by region where they were found. """ running_instances = {} for region_name in get_regions(session): ec2 = session.client("ec2", region_name=region_name) logger.debug(_("Describing instances in %s"), region_name) instances = ec2.describe_instances() running_instances[region_name] = list() for reservation in instances.get("Reservations", []): running_instances[region_name].extend([ instance for instance in reservation.get("Instances", []) if instance.get("State", {}).get("Code", None) != InstanceState.terminated.value ]) return running_instances