Add support for testing custom RBAC requirements

Add support of running Patrole against a custom requirements YAML that
defines RBAC requirements. The YAML file lists all the APIs and the roles
that should have access to the APIs. The purpose of running Patrole against
a requirements YAML is to verify that the RBAC policy is in accordance to
deployment specific requirements. Running Patrole against a requirements
YAML is completely optional and can be enabled through the rbac section of
the tempest.conf.

Change-Id: I8ba89ab5e134b15e97ac20a7aacbfd70896e192f
Implements: blueprint support-custom-yaml
Co-Authored-By: Sangeet Gupta <sg774j@att.com>
Co-Authored-By: David Purcell <d.purcell222@gmail.com>
diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py
index 53f84ff..c7e0b2b 100644
--- a/patrole_tempest_plugin/rbac_rule_validation.py
+++ b/patrole_tempest_plugin/rbac_rule_validation.py
@@ -25,6 +25,7 @@
 
 from patrole_tempest_plugin import rbac_exceptions
 from patrole_tempest_plugin import rbac_policy_parser
+from patrole_tempest_plugin import requirements_authority
 
 CONF = config.CONF
 LOG = logging.getLogger(__name__)
@@ -39,6 +40,9 @@
     A decorator which allows for positive and negative RBAC testing. Given
     an OpenStack service and a policy action enforced by that service, an
     oslo.policy lookup is performed by calling `authority.get_permission`.
+    Alternatively, the RBAC tests can run against a YAML file that defines
+    policy requirements.
+
     The following cases are possible:
 
     * If `allowed` is True and the test passes, this is a success.
@@ -141,12 +145,17 @@
 
     try:
         role = CONF.rbac.rbac_test_role
-        formatted_target_data = _format_extra_target_data(
-            test_obj, extra_target_data)
-        policy_parser = rbac_policy_parser.RbacPolicyParser(
-            project_id, user_id, service,
-            extra_target_data=formatted_target_data)
-        is_allowed = policy_parser.allowed(rule_name, role)
+        # Test RBAC against custom requirements. Otherwise use oslo.policy
+        if CONF.rbac.test_custom_requirements:
+            authority = requirements_authority.RequirementsAuthority(
+                CONF.rbac.custom_requirements_file, service)
+        else:
+            formatted_target_data = _format_extra_target_data(
+                test_obj, extra_target_data)
+            authority = rbac_policy_parser.RbacPolicyParser(
+                project_id, user_id, service,
+                extra_target_data=formatted_target_data)
+        is_allowed = authority.allowed(rule_name, role)
 
         if is_allowed:
             LOG.debug("[Action]: %s, [Role]: %s is allowed!", rule_name,