def test_crawl_org_for_acts(self, mock_session): "Test that if an exception is raised the crawl continues" mock_session.client = MagicMock() account_side_effect = [] paginator_side_effect = [] ou_ids = ["r-0", "ou-0", "ou-1", "ou-2", "sou-0"] for ou_id in ou_ids: parent_acts = _generate_act_for_parent_side_effect( self.schema, ou_id) account_side_effect.extend(parent_acts) paginator = MagicMock() paginator.paginate( ParentId=ou_id ).build_full_result.return_value = self.paginator_dict[ou_id] paginator_side_effect.append(paginator) unit_crawler = AWSOrgUnitCrawler(self.account) unit_crawler._init_session() unit_crawler._client.list_roots.return_value = { "Roots": [{ "Id": "r-0", "Arn": "arn-0", "Name": "root_0" }] } unit_crawler._client.list_accounts_for_parent.side_effect = account_side_effect unit_crawler._client.get_paginator.side_effect = paginator_side_effect unit_crawler.crawl_account_hierarchy() with schema_context(self.schema): cur_count = AWSOrganizationalUnit.objects.count() total_entries = (len(ou_ids) * GEN_NUM_ACT_DEFAULT) + len(ou_ids) self.assertEqual(cur_count, total_entries)
def test_no_delete_on_exceptions(self, mock_crawl, mock_session): """Test that when things go wrong we don't delete.""" mock_crawl.side_effect = Exception() mock_session.client = MagicMock() account_side_effect = [] paginator_side_effect = [] ou_ids = ["r-0", "ou-0", "ou-1", "ou-2", "sou-0"] for ou_id in ou_ids: parent_acts = _generate_act_for_parent_side_effect( self.schema, ou_id) account_side_effect.extend(parent_acts) paginator = MagicMock() paginator.paginate( ParentId=ou_id ).build_full_result.return_value = self.paginator_dict[ou_id] paginator_side_effect.append(paginator) unit_crawler = AWSOrgUnitCrawler(self.account) unit_crawler._init_session() unit_crawler._client.list_roots.return_value = { "Roots": [{ "Id": "r-0", "Arn": "arn-0", "Name": "root_0" }] } unit_crawler._client.list_accounts_for_parent.side_effect = account_side_effect unit_crawler._client.get_paginator.side_effect = paginator_side_effect with patch( "masu.external.accounts.hierarchy.aws.aws_org_unit_crawler.AWSOrgUnitCrawler._mark_nodes_deleted" ) as mock_deleted: unit_crawler.crawl_account_hierarchy() self.assertEqual(True, unit_crawler.errors_raised) self.assertEqual(False, mock_deleted.called)
def crawl_account_hierarchy(provider_uuid=None): """Crawl top level accounts to discover hierarchy.""" if provider_uuid: _, polling_accounts = Orchestrator.get_accounts( provider_uuid=provider_uuid) else: _, polling_accounts = Orchestrator.get_accounts() LOG.info("Account hierarchy crawler found %s accounts to scan" % len(polling_accounts)) processed = 0 skipped = 0 for account in polling_accounts: crawler = None # Look for a known crawler class to handle this provider if account.get("provider_type") == Provider.PROVIDER_AWS: crawler = AWSOrgUnitCrawler(account) if crawler: LOG.info( "Starting account hierarchy crawler for type {} with provider_uuid: {}" .format(account.get("provider_type"), account.get("provider_uuid"))) crawler.crawl_account_hierarchy() processed += 1 else: LOG.info( "No known crawler for account with provider_uuid: {} of type {}" .format(account.get("provider_uuid"), account.get("provider_type"))) skipped += 1 LOG.info( f"Account hierarchy crawler finished. {processed} processed and {skipped} skipped" )
def test_general_client_error_denied(self, mock_session): """Test botocore general ClientError.""" logging.disable(logging.NOTSET) mock_session.client = MagicMock() unit_crawler = AWSOrgUnitCrawler(self.account) unit_crawler._init_session() unit_crawler._client.list_roots.side_effect = _mock_boto3_general_client_error with self.assertLogs(logger=crawler_log, level=logging.WARNING): unit_crawler.crawl_account_hierarchy()
def test_unknown_exception(self, mock_session): """Test botocore general ClientError.""" logging.disable(logging.NOTSET) mock_session.client = MagicMock() unit_crawler = AWSOrgUnitCrawler(self.account) unit_crawler._init_session() unit_crawler._client.list_roots.side_effect = Exception("unknown error") with self.assertLogs(logger=crawler_log, level=logging.raiseExceptions): unit_crawler.crawl_account_hierarchy()
def test_crawl_boto_param_exception(self, mock_session): """Test botocore parameter exception is caught properly.""" logging.disable(logging.NOTSET) mock_session.client = MagicMock() unit_crawler = AWSOrgUnitCrawler(self.account) unit_crawler._init_session() unit_crawler._client.list_roots.side_effect = ParamValidationError(report="Bad Param") with self.assertLogs(logger=crawler_log, level=logging.WARNING): unit_crawler.crawl_account_hierarchy()
def test_crawl_list_root_access_denied(self, mock_session): """Test botocore list roots access denied.""" # https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html logging.disable(logging.NOTSET) mock_session.client = MagicMock() unit_crawler = AWSOrgUnitCrawler(self.account) unit_crawler._init_session() unit_crawler._client.list_roots.side_effect = _mock_boto3_access_denied with self.assertLogs(logger=crawler_log, level=logging.WARNING): unit_crawler.crawl_account_hierarchy()