Fixes policy rules in neutron containing the keyword tenant_id.

The owner policy in neutron's policy.json is "tenant_id:%(tenant_id)s".
Currently, the rbac_role_converter does not populate the target dict,
responsible for providing oslo policy with as much information
about the target or user performing an action as possible, with
the key 'tenant_id'. Consequently, the rules containing the format
outlined above fail.

This patch adds 'tenant_id' as well as 'network:tenant_id' to the
target dict, in order to work with neutron's policy.json.

Change-Id: Iecf30d714ed0e9ebde2bff6013551accdf250cef
Closes-Bug: #1661062
diff --git a/tests/test_rbac_role_converter.py b/tests/test_rbac_role_converter.py
index f3a97ab..09fa081 100644
--- a/tests/test_rbac_role_converter.py
+++ b/tests/test_rbac_role_converter.py
@@ -39,6 +39,9 @@
         self.alt_admin_policy_file = os.path.join(current_directory,
                                                   'resources',
                                                   'alt_admin_rbac_policy.json')
+        self.tenant_policy_file = os.path.join(current_directory,
+                                               'resources',
+                                               'tenant_rbac_policy.json')
 
     @mock.patch.object(rbac_role_converter, 'LOG', autospec=True)
     def test_custom_policy(self, m_log):
@@ -136,3 +139,44 @@
         for rule in disallowed_rules:
             allowed = converter.allowed(rule, role)
             self.assertFalse(allowed)
+
+    def test_tenant_policy(self):
+        """Test whether rules with format tenant_id:%(tenant_id)s work.
+
+        Test whether Neutron rules that contain project_id, tenant_id, and
+        network:tenant_id pass.
+        """
+        test_tenant_id = mock.sentinel.tenant_id
+        converter = rbac_role_converter.RbacPolicyConverter(
+            test_tenant_id, "test", self.tenant_policy_file)
+
+        # Check whether Member role can perform expected actions.
+        allowed_rules = ['rule1', 'rule2', 'rule3']
+        for rule in allowed_rules:
+            allowed = converter.allowed(rule, 'Member')
+            self.assertTrue(allowed)
+        self.assertFalse(converter.allowed('admin_rule', 'Member'))
+
+        # Check whether admin role can perform expected actions.
+        allowed_rules.append('admin_rule')
+        for rule in allowed_rules:
+            allowed = converter.allowed(rule, 'admin')
+            self.assertTrue(allowed)
+
+        # Check whether _try_rule is called with the correct target dictionary.
+        with mock.patch.object(converter, '_try_rule', autospec=True) \
+            as mock_try_rule:
+            mock_try_rule.return_value = True
+
+            expected_target = {
+                "project_id": test_tenant_id,
+                "tenant_id": test_tenant_id,
+                "network:tenant_id": test_tenant_id
+            }
+
+            for rule in allowed_rules:
+                allowed = converter.allowed(rule, 'Member')
+                self.assertTrue(allowed)
+                mock_try_rule.assert_called_once_with(
+                    rule, expected_target, mock.ANY, mock.ANY)
+                mock_try_rule.reset_mock()