def setUp(self): """Set up GCP resources for tests.""" self.alre = alre self.alre.LOGGER = mock.MagicMock() self.org_234 = Organization('234', display_name='Organization 234', full_name='organization/234/', data='fake_org_data_234') self.folder_56 = Folder('56', display_name='Folder 56', full_name='folder/56', data='fake_folder_data456456') self.proj_1 = Project('proj-1', project_number=11223344, display_name='My project 1', parent=self.org_234, full_name='organization/234/project/proj-1/', data='fake_project_data_2341') self.proj_2 = Project( 'proj-2', project_number=223344, display_name='My project 2', parent=self.folder_56, full_name='organization/234/folder/56/project/proj-2/', data='fake_project_data_4562') self.proj_3 = Project('project-3', project_number=33445566, display_name='My project 3', parent=self.org_234, full_name='organization/234/project/proj-3/', data='fake_project_data_1233')
def setUp(self): """Set up.""" self.maxDiff = None self.fake_timestamp = '12345' self.org789 = Organization('778899', display_name='My org') self.project1 = Project( 'my-project-1', 12345, display_name='My project 1', parent=self.org789) self.project2 = Project('my-project-2', 12346, display_name='My project 2')
def setUp(self): """Set up GCP resources for tests.""" self.lsre = lsre self.lsre.LOGGER = mock.MagicMock() # Set up resources in the following hierarchy: # +-----> billing_acct_abcd # | # | # +-----------------------> proj-1 # | # | # org_234 +-----> folder_56 +-----> proj-2 # | # | # +-----------------------> proj-3 self.org_234 = Organization('234', display_name='Organization 234', full_name='organization/234/', data='fake_org_data_234') self.billing_acct_abcd = BillingAccount( 'ABCD-1234', display_name='Billing Account ABCD', full_name='organization/234/billingAccount/ABCD-1234/', data='fake_billing_account_data_abcd') self.folder_56 = Folder('56', display_name='Folder 56', full_name='organization/234/folder/56/', data='fake_folder_data456456') self.proj_1 = Project('proj-1', project_number=11223344, display_name='My project 1', parent=self.org_234, full_name='organization/234/project/proj-1/', data='fake_project_data_2341') self.proj_2 = Project( 'proj-2', project_number=223344, display_name='My project 2', parent=self.folder_56, full_name='organization/234/folder/56/project/proj-2/', data='fake_project_data_4562') self.proj_3 = Project('proj-3', project_number=33445566, display_name='My project 3', parent=self.org_234, full_name='organization/234/project/proj-3/', data='fake_project_data_1233')
def test_project_notequals_other_project_is_true(self): """Test that a Project does not equal a Project of different id.""" id_1 = 'my-project-1' number_1 = 1234567890 name_1 = 'My project 1' project1 = Project(id_1, number_1, display_name=name_1) id_2 = 'my-project-2' number_2 = 1234567891 name_2 = 'My project 2' project2 = Project(id_2, number_2, display_name=name_2) self.assertTrue(project1 != project2)
def test_project_equals_other_project_is_true(self): """Test that Project == another Project.""" id_1 = 'my-project-1' number_1 = 1234567890 name_1 = 'My project 1' project1 = Project(id_1, number_1, display_name=name_1) id_2 = 'my-project-1' number_2 = 1234567890 name_2 = 'My project 1' project2 = Project(id_2, number_2, display_name=name_2) self.assertTrue(project1 == project2)
def setUp(self): self.org = Organization('1234567890', display_name='My org name') self.folder = Folder('55555', display_name='My folder', parent=self.org) self.project1 = Project('project-1', 11111, display_name='Project 1') self.project2 = Project('project-2', 22222, display_name='Project 2', parent=self.org) self.project3 = Project('project-3', 33333, display_name='Project 3', parent=self.folder)
def _retrieve(self): """Retrieves the data for scanner. Returns: list: List of projects' enabled API data. Raises: NoDataError: If no enabled APIs are found. """ model_manager = self.service_config.model_manager scoped_session, data_access = model_manager.get(self.model_name) with scoped_session as session: enabled_apis_data = [] for apis in data_access.scanner_iter(session, 'enabled_apis'): enabled_apis = [] for enabled_api in json.loads(apis.data): if 'serviceName' in enabled_api: enabled_apis.append(enabled_api['serviceName']) if enabled_apis: enabled_apis_data.append( (Project(apis.parent.name, apis.parent.full_name, apis.data), enabled_apis)) if not enabled_apis_data: LOGGER.warn('No Enabled APIs found.') return [] return enabled_apis_data
def test_find_violations(self): """Test finding violations""" epas.get_user_emails = mock.MagicMock(return_value=TEST_EMAILS) scanner = epas.ExternalProjectAccessScanner( self.global_configs, self.scanner_configs, self.service_config, self.model_name, self.snapshot_timestamp, self.rules) scanner.rules_engine.build_rule_book( self.service_config.get_inventory_config()) user_ancestries = { '*****@*****.**': [[Project('1234'), Organization('1234567')], [Project('12345'), Folder('ABCDEFG'), Organization('HIJKLMNOP')]] } violations = scanner._find_violations(user_ancestries) self.assertEqual(len(violations), 2)
def test_create_resource_is_ok(self): """Test the resource_util.create_resource() creates the types.""" expect_org = Organization(12345) actual_org = resource_util.create_resource( 12345, ResourceType.ORGANIZATION) self.assertEqual(expect_org, actual_org) expect_proj = Project('abcd', project_number=54321) actual_proj = resource_util.create_resource( 'abcd', ResourceType.PROJECT, project_number=54321) self.assertEqual(expect_proj, actual_proj) self.assertEqual(expect_proj.project_number, actual_proj.project_number)
def test_project_notequals_org_is_true(self): """Test that a Project != Organization.""" id_1 = 'my-project-1' number_1 = 1234567890 name_1 = 'My project 1' project = Project(id_1, number_1, display_name=name_1) id_2 = '1234567890' name_2 = 'My org 1' org = Organization(id_2, display_name=name_2) self.assertTrue(project != org)
def setUp(self): """Set up parent GCP resources for tests.""" self.org_234 = Organization('234', display_name='Organization 234', full_name='organization/234/', data='fake_org_data_234') self.proj_1 = Project('proj-1', project_number=11223344, display_name='My project 1', parent=self.org_234, full_name='organization/234/project/proj-1/', data='fake_project_data_2341')
def test_org_notequals_project(self): """Test that an Organization != Project.""" proj_id = 'my-project-1' proj_num = 1234567890 proj_name = 'My project 1' project1 = Project(proj_id, proj_num, display_name=proj_name) folder_id = '88888' folder_name = 'My folder' folder1 = folder.Folder(folder_id, display_name=folder_name) org_id = '1234567890' org_name = 'My org 1' org1 = Organization(org_id, display_name=org_name) self.assertTrue(org1 != project1) self.assertTrue(org1 != folder1)
def test_create_project_getters_are_correct(self): """Test Project getters returns correct values.""" my_project_id = 'my-projectid-1' my_project_number = 1234567890 my_project_name = 'My project name' project = Project(my_project_id, project_number=my_project_number, display_name=my_project_name, lifecycle_state=ProjectLifecycleState.ACTIVE) self.assertEqual(my_project_id, project.id) self.assertEqual(my_project_number, project.project_number) self.assertEqual(Project.RESOURCE_NAME_FMT % my_project_id, project.name) self.assertEqual(my_project_name, project.display_name) self.assertEqual(ResourceType.PROJECT, project.type) self.assertEqual(None, project.parent) self.assertEqual(ProjectLifecycleState.ACTIVE, project.lifecycle_state)
def _retrieve(self): """Retrieves the data for scanner. Returns: list: List of projects' audit logging config data. """ model_manager = self.service_config.model_manager scoped_session, data_access = model_manager.get(self.model_name) with scoped_session as session: project_configs = [] ancestor_configs = {} # Types that can contain AuditConfigs in the IamPolicy. audit_policy_types = frozenset([ 'organization', 'folder', 'project']) for policy in data_access.scanner_iter(session, 'iam_policy'): if policy.parent.type not in audit_policy_types: continue audit_config = iam_policy.IamAuditConfig.create_from( json.loads(policy.data).get('auditConfigs', [])) if policy.parent.type == 'project': project_configs.append( (Project(policy.parent.name, policy.parent.full_name, policy.data), audit_config)) elif audit_config.service_configs: ancestor_configs[policy.parent.type, policy.parent.name] = ( audit_config) # Merge ancestor configs into project level configs. for project, audit_config in project_configs: ancestors = utils.get_resources_from_full_name(project.full_name) next(ancestors) for res_type, res_name in ancestors: ancestor_config = ancestor_configs.get((res_type, res_name)) if ancestor_config: audit_config.merge_configs(ancestor_config) return project_configs
class ExternalProjectAccessRulesEngineTest(ForsetiTestCase): """Tests for the ExternalProjectAccessRulesEngine.""" TEST_ANCESTRIES = { '*****@*****.**': [Project('13579'), Folder('24680'), Organization('1234567')], '*****@*****.**': [Project('13579'), Folder('0987654321'), Organization('1234567')]} TEST_ANCESTRIES_SIMPLE = { '*****@*****.**': [Project('13579'), Organization('567890')]} TEST_ANCESTRIES_VIOLATIONS = { '*****@*****.**': [Project('13579'), Folder('24680'), Organization('1357924680')]} def setUp(self): self.rules_engine = engine_module self.rules_engine.LOGGER = mock.MagicMock() self.inventory_config = mock.MagicMock() self.inventory_config.get_root_resource_id = ( mock.MagicMock(return_value='organizations/567890')) def test_no_rule_added(self): """Test that a RuleBook is built correctly with an empty yaml file.""" rules_local_path = get_datafile_path( __file__, 'external_project_access_test_rules_0.yaml') rules_engine = engine_module.ExternalProjectAccessRulesEngine( rules_file_path=rules_local_path) rules_engine.build_rule_book(self.inventory_config) self.assertEqual(0, len(rules_engine.rule_book.resource_rules_map)) def test_good_yaml_file(self): """Test that a RuleBook is built correctly with a yaml file.""" rules_local_path = get_datafile_path( __file__, 'external_project_access_test_rules_1.yaml') rules_engine = engine_module.ExternalProjectAccessRulesEngine( rules_file_path=rules_local_path) rules_engine.build_rule_book(self.inventory_config) self.assertEqual(2, len(rules_engine.rule_book.resource_rules_map)) def test_yaml_file_bad_ancestor(self): """Test that a RuleBook is built correctly with a yaml file.""" rules_local_path = get_datafile_path( __file__, 'external_project_access_test_rules_2.yaml') rules_engine = engine_module.ExternalProjectAccessRulesEngine( rules_file_path=rules_local_path) with self.assertRaises(audit_errors.InvalidRulesSchemaError): rules_engine.build_rule_book(self.inventory_config) def test_no_violations(self): """Test that no violations are found""" all_violations = [] rules_local_path = get_datafile_path( __file__, 'external_project_access_test_rules_1.yaml') rules_engine = engine_module.ExternalProjectAccessRulesEngine( rules_file_path=rules_local_path) rules_engine.build_rule_book(self.inventory_config) for user, ancestry in self.TEST_ANCESTRIES.items(): violations = rules_engine.find_violations( user, ancestry, True) all_violations.extend(violations) self.assertEqual(len(all_violations), 0) def test_no_violations_no_rules(self): """Test that no violations are found when no rules in the file.""" all_violations = [] rules_local_path = get_datafile_path( __file__, 'external_project_access_test_rules_0.yaml') rules_engine = engine_module.ExternalProjectAccessRulesEngine( rules_file_path=rules_local_path) rules_engine.build_rule_book(self.inventory_config) for user, ancestry in self.TEST_ANCESTRIES_SIMPLE.items(): violations = rules_engine.find_violations( user, ancestry, True) all_violations.extend(violations) self.assertEqual(len(all_violations), 0) def test_violations_are_found(self): """Test that violations are found""" all_violations = [] rules_local_path = get_datafile_path( __file__, 'external_project_access_test_rules_1.yaml') rules_engine = engine_module.ExternalProjectAccessRulesEngine( rules_file_path=rules_local_path) rules_engine.build_rule_book(self.inventory_config) for user, ancestry in self.TEST_ANCESTRIES_VIOLATIONS.items(): violations = rules_engine.find_violations(user, ancestry, True) all_violations.extend(violations) self.assertEqual(len(all_violations), 2)
class ExternalProjectAccessRuleTest(ForsetiTestCase): """Tests for the ExternalProjectAccessRuleBook.""" TEST_ANCESTORS = [Project('123'), Folder('456'), Organization('7890')] def test_single_item_in_rule_match(self): """Test no violations are found with single item in rule""" processed_rule = { 'ancestor_resources': [Organization('7890')], } rule = engine_module.Rule(rule_name='test_single_item_in_rule_match', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertIsNone(violation) def test_single_item_in_rule_match_with_user(self): """Test no violations are found with single item in rule with a user""" processed_rule = { 'ancestor_resources': [Organization('7890')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_single_item_in_rule_match_with_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertIsNone(violation) def test_single_item_in_rule_match_with_wrong_user(self): """Test no violations are found with single item in rule with a user that doesn't match the rule""" processed_rule = { 'ancestor_resources': [Organization('7890')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_single_item_in_rule_match_with_wrong_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertIsNotNone(violation) def test_multi_items_in_rule_match(self): """Test no violations are found with multiple items in rule""" processed_rule = { 'ancestor_resources': [Folder('456'), Organization('7890')] } rule = engine_module.Rule(rule_name='test_multi_items_in_rule_match', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertIsNone(violation) def test_multi_items_in_rule_match_with_user(self): """Test no violations are found with multiple items in rule with a user""" processed_rule = { 'ancestor_resources': [Folder('456'), Organization('7890')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_multi_items_in_rule_match_with_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertIsNone(violation) def test_multi_items_in_rule_match_with_wrong_user(self): """Test no violations are found with multiple items in rule with user that doesn't match the rule""" processed_rule = { 'ancestor_resources': [Folder('456'), Organization('7890')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_multi_items_in_rule_match_with_wrong_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertIsNotNone(violation) def test_single_item_no_match(self): """Test violations are found with single item in rule""" processed_rule = { 'ancestor_resources': [Organization('789')] } rule = engine_module.Rule(rule_name='test_single_item_no_match', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertEqual(0, violation.rule_index) self.assertEqual('test_single_item_no_match', violation.rule_name) self.assertEqual('projects/123', violation.full_name) self.assertEqual('projects/123,folders/456,organizations/7890', violation.resource_data) def test_single_item_no_match_with_user(self): """Test violations are found with single item in rule with a user""" processed_rule = { 'ancestor_resources': [Organization('789')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_single_item_no_match_with_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertEqual(0, violation.rule_index) self.assertEqual('test_single_item_no_match_with_user', violation.rule_name) self.assertEqual('projects/123', violation.full_name) self.assertEqual('projects/123,folders/456,organizations/7890', violation.resource_data) def test_single_item_no_match_with_wrong_user(self): """Test violations are found with single item in rule with user that doesn't match the rule""" processed_rule = { 'ancestor_resources': [Organization('789')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_single_item_no_match_with_wrong_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertEqual(0, violation.rule_index) self.assertEqual('test_single_item_no_match_with_wrong_user', violation.rule_name) self.assertEqual('projects/123', violation.full_name) self.assertEqual('projects/123,folders/456,organizations/7890', violation.resource_data) def test_multi_items_no_match(self): """Test violations are found with multiple items in rule""" processed_rule = { 'ancestor_resources': [Folder('45'), Organization('789')] } rule = engine_module.Rule(rule_name='test_multi_items_no_match', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertEqual(0, violation.rule_index) self.assertEqual('test_multi_items_no_match', violation.rule_name) self.assertEqual('projects/123', violation.full_name) self.assertEqual('projects/123,folders/456,organizations/7890', violation.resource_data) def test_multi_items_no_match_with_user(self): """Test violations are found with multiple items in rule with a user""" processed_rule = { 'ancestor_resources': [Folder('45'), Organization('789')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_multi_items_no_match_with_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertEqual(0, violation.rule_index) self.assertEqual('test_multi_items_no_match_with_user', violation.rule_name) self.assertEqual('projects/123', violation.full_name) self.assertEqual('projects/123,folders/456,organizations/7890', violation.resource_data) def test_multi_items_no_match_with_wrong_user(self): """Test violations are found with multiple items in rule with user that doesn't match the rule""" processed_rule = { 'ancestor_resources': [Folder('45'), Organization('789')], 'users': ['*****@*****.**'] } rule = engine_module.Rule(rule_name='test_multi_items_no_match_with_wrong_user', rule_index=0, rules=processed_rule) violation = rule.find_violation('*****@*****.**', self.TEST_ANCESTORS) self.assertEqual(0, violation.rule_index) self.assertEqual('test_multi_items_no_match_with_wrong_user', violation.rule_name) self.assertEqual('projects/123', violation.full_name) self.assertEqual('projects/123,folders/456,organizations/7890', violation.resource_data)
class ExternalProjectAccessRuleBookTest(ForsetiTestCase): """Tests for the ExternalProjectAccessRuleBook.""" TEST_GOOD_RULE = dict(name='default', allowed_ancestors=['organizations/7890'], users=['*****@*****.**']) TEST_BAD_RULE = dict(name='default', allowed_ancestors=['policy/12345'], users=['*****@*****.**', 'user1_at_example_dot_com']) TEST_RULE_DEFS = dict(rules=[TEST_GOOD_RULE]) TEST_ANCESTORS = [Project('123'), Folder('456'), Organization('7890')] TEST_BAD_ANCESTORS = [Project('123'), Folder('456'), Organization('ABC')] def setUp(self): """Set up.""" self.rule_index = 0 self.rules_engine = engine_module self.rules_engine.LOGGER = mock.MagicMock() self.inventory_config = mock.MagicMock() self.inventory_config.get_root_resource_id = ( mock.MagicMock(return_value='organizations/7890')) self.rule_book = ( engine_module.ExternalProjectAccessRuleBook(self.inventory_config)) def test_validate_good_ancestor(self): """Test proper rule validation""" self.assertIsNone( self.rule_book.validate_ancestors( self.TEST_GOOD_RULE['allowed_ancestors'], 0)) def test_validate_bad_ancestor(self): """Test proper rule validation against bad ancestor""" with self.assertRaises(audit_errors.InvalidRulesSchemaError): self.rule_book.validate_ancestors( self.TEST_BAD_RULE['allowed_ancestors'], 0) def test_validate_good_user(self): """Test proper rule validation""" self.assertIsNone( self.rule_book.validate_users( self.TEST_GOOD_RULE['users'], 0)) def test_validate_bad_user(self): """Test proper rule validation against bad user""" with self.assertRaises(audit_errors.InvalidRulesSchemaError) as error: self.rule_book.validate_users( self.TEST_BAD_RULE['users'], 0) self.assertIn('user1_at_example_dot_com', str(error.exception)) self.assertNotIn('*****@*****.**', str(error.exception)) def test_missing_ancestors(self): """Test proper rule validation against missing ancestors""" with self.assertRaises(audit_errors.InvalidRulesSchemaError): self.rule_book.validate_ancestor(None, 0) def test_process_good_rule(self): """Test proper rule processing""" processed_rule = self.rule_book.process_rule(self.TEST_GOOD_RULE, 0) self.assertEqual(processed_rule['ancestor_resources'][0].id, '7890') self.assertTrue(isinstance(processed_rule['ancestor_resources'][0], Organization)) def test_process_bad_rule(self): """Test proper rule validation with exception""" with self.assertRaises(audit_errors.InvalidRulesSchemaError): self.rule_book.process_rule(self.TEST_BAD_RULE, 0) def test_add_rule(self): """Test proper rule addition""" self.rule_book.add_rule(self.TEST_GOOD_RULE, 0) self.assertEqual(1, len(self.rule_book.resource_rules_map)) def test_add_rules(self): """Test proper addtion of multiple rules""" self.rule_book.add_rules(self.TEST_RULE_DEFS) self.assertEqual(1, len(self.rule_book.resource_rules_map)) def test_no_violations(self): """Test no violations are found""" violations = self.rule_book.find_violations('*****@*****.**', self.TEST_ANCESTORS) self.assertEqual(0, len(violations)) def test_violations(self): """Test violations are found""" violations = self.rule_book.find_violations( '*****@*****.**', self.TEST_BAD_ANCESTORS) self.assertEqual(0, len(violations))
def _add_ancestor_bindings_test_data(self): """Establishes the hierarchy below. +-----------> billing_acct_abcd | | +----------------------------> proj_1 +-------> dataset_1_1 | | + +-------> bucket_3_1 org_234 +------> folder_1 +-----> proj_3 | +-------> bucket_3_2 + | +----------------------------> proj_2 +-------> bucket_2_1 """ self.org_234 = Organization('234', display_name='Organization 234', full_name='organization/234/', data='fake_org_data_234') self.billing_acct_abcd = BillingAccount( 'ABCD-1234', display_name='Billing Account ABCD', parent=self.org_234, full_name='organization/234/billing_account/ABCD-1234/', data='fake_billing_account_data_abcd') self.proj_1 = Project('proj-1', project_number=22345, display_name='My project 1', parent=self.org_234, full_name='organization/234/project/proj-1/', data='fake_project_data_111') self.dataset_1_1 = Dataset( 'proj-1:dataset-1-1', display_name='Dataset 1.1', parent=self.proj_1, full_name= 'organization/234/project/proj-1/dataset/proj-1:dataset-1-1', data='dataset_data') self.proj_2 = Project('proj-2', project_number=22346, display_name='My project 2', parent=self.org_234, full_name='organization/234/project/proj-2/', data='fake_project_data_222') self.folder_1 = Folder('333', display_name='Folder 1', parent=self.org_234, full_name='organization/234/folder/333/', data='fake_folder_data_111') self.proj_3 = Project( 'proj-3', project_number=22347, display_name='My project 3', parent=self.folder_1, full_name='organization/234/folder/333/project/proj-3/', data='fake_project_data_333') self.bucket_3_1 = Bucket( 'internal-3', display_name='My project 3, internal data1', parent=self.proj_3, full_name= 'organization/234/folder/333/project/proj-3/bucket/internal-3/', data='fake_project_data_333_bucket_1') self.bucket_3_2 = Bucket( 'public-3', display_name='My project 3, public data', parent=self.proj_3, full_name= 'organization/234/folder/333/project/proj-3/bucket/public-3/', data='fake_project_data_333_bucket_2') self.bucket_2_1 = Bucket( 'internal-2', display_name='My project 2, internal data', parent=self.proj_2, full_name='organization/234/project/proj-2/bucket/internal-2/', data='fake_project_data_222_bucket_1') self.org_234_policy_resource = mock.MagicMock() self.org_234_policy_resource.full_name = ( 'organization/234/iam_policy/organization:234/') self.billing_acct_abcd_policy_resource = mock.MagicMock() self.billing_acct_abcd_policy_resource.full_name = ( 'organization/234/billing_account/ABCD-1234/iam_policy' '/billing_account:ABCD-1234/') self.folder_1_policy_resource = mock.MagicMock() self.folder_1_policy_resource.full_name = ( 'organization/234/folder/333/iam_policy/folder:333/') self.proj_1_policy_resource = mock.MagicMock() self.proj_1_policy_resource.full_name = ( 'organization/234/project/proj-1/iam_policy/project:proj-1') self.proj_2_policy_resource = mock.MagicMock() self.proj_2_policy_resource.full_name = ( 'organization/234/project/proj-2/iam_policy/project:proj-2') self.proj_3_policy_resource = mock.MagicMock() self.proj_3_policy_resource.full_name = ( 'organization/234/folder/333/project/proj-3/iam_policy/project:proj-3' ) self.bucket_3_1_policy_resource = mock.MagicMock() self.bucket_3_1_policy_resource.full_name = ( 'organization/234/folder/333/project/proj-3/bucket/internal-3/iam_policy/bucket:internal-3' ) self.bucket_3_2_policy_resource = mock.MagicMock() self.bucket_3_2_policy_resource.full_name = ( 'organization/234/folder/333/project/proj-3/bucket/public-3/iam_policy/bucket:public-3' ) self.bucket_2_1_policy_resource = mock.MagicMock() self.bucket_2_1_policy_resource.full_name = ( 'organization/234/folder/333/project/proj-2/bucket/internal-2/iam_policy/bucket:internal-2' ) self.dataset_1_1_policy_resource = mock.MagicMock() self.dataset_1_1_policy_resource.full_name = ( 'organization/234/project/proj-1/dataset/proj-1:dataset-1-1/iam_policy/dataset:proj-1:dataset-1-1' )