Merge "Docs: Add requirements authority module to documentation"
diff --git a/doc/source/framework/policy_authority.rst b/doc/source/framework/policy_authority.rst
index 7cd4421..822c7b6 100644
--- a/doc/source/framework/policy_authority.rst
+++ b/doc/source/framework/policy_authority.rst
@@ -9,7 +9,8 @@
 This module is only called for calculating the "Expected" result if
 ``[patrole] test_custom_requirements`` is ``False``.
 
-Using the Policy Authority Module, policy verification is performed by:
+Using the :class:`~patrole_tempest_plugin.policy_authority.PolicyAuthority`
+class, policy verification is performed by:
 
 #. Pooling together the default `in-code` policy rules.
 #. Overriding the defaults with custom policy rules located in a policy.json,
@@ -22,9 +23,40 @@
 #. Performing a call with all necessary data to ``oslo.policy`` and returning
    the expected result back to ``rbac_rule_validation`` decorator.
 
+When to use
+-----------
+
+This :class:`~patrole_tempest_plugin.rbac_authority.RbacAuthority` class
+can be used to validate the default OpenStack policy configuration. It
+is recommended that this approach be used for RBAC validation for clouds that
+use little to no policy customizations or overrides.
+
+This validation approach should be used when:
+
+* Validating the out-of-the-box policy-in-code OpenStack policy configuration.
+
+  It is important that the default OpenStack policy configuration be validated
+  before deploying OpenStack into production. Bugs exist in software and the
+  earlier they can be caught and prevented (via CI/CD, for example), the
+  better. Patrole continues to be used to identify default policy bugs
+  across OpenStack services.
+
+* Validating policy reliably and accurately.
+
+  Relying on ``oslo.policy`` to compute the expected test results provides
+  accurate tests, without the hassle of having to reinvent the wheel. Since
+  OpenStack APIs use ``oslo.policy`` for policy enforcement, it makes sense
+  to compute expected results by using the same library, ensuring test
+  reliability.
+
+* Continuously validating policy changes to OpenStack projects under
+  development by gating them against Patrole CI/CD jobs run by `Zuul`_.
+
+.. _Zuul: https://docs.openstack.org/infra/zuul/
+
 Implementation
 --------------
 
 .. automodule:: patrole_tempest_plugin.policy_authority
    :members:
-   :special-members:
+   :undoc-members:
diff --git a/doc/source/framework/rbac_authority.rst b/doc/source/framework/rbac_authority.rst
new file mode 100644
index 0000000..84c372b
--- /dev/null
+++ b/doc/source/framework/rbac_authority.rst
@@ -0,0 +1,37 @@
+.. rbac-authority:
+
+RBAC Authority Module
+=====================
+
+Overview
+--------
+
+This module implements an abstract class that is implemented by the classes
+below. Each implementation is used by the :ref:`rbac-validation` framework
+to determine each expected test result.
+
+:ref:`policy-authority`
+-----------------------
+
+The *default* :class:`~patrole_tempest_plugin.rbac_authority.RbacAuthority`
+implementation class which is used for policy validation. Uses ``oslo.policy``
+to determine the expected test result.
+
+All Patrole `Zuul`_ gates use this
+:class:`~patrole_tempest_plugin.rbac_authority.RbacAuthority` class by default.
+
+.. _Zuul: https://docs.openstack.org/infra/zuul/
+
+:ref:`requirements-authority`
+-----------------------------
+
+Optional :class:`~patrole_tempest_plugin.rbac_authority.RbacAuthority`
+implementation class which is used for policy validation. It uses a high-level
+requirements-driven approach to validating RBAC in Patrole.
+
+Implementation
+--------------
+
+.. automodule:: patrole_tempest_plugin.rbac_authority
+   :members:
+   :undoc-members:
diff --git a/doc/source/framework/requirements_authority.rst b/doc/source/framework/requirements_authority.rst
new file mode 100644
index 0000000..6c4fcc0
--- /dev/null
+++ b/doc/source/framework/requirements_authority.rst
@@ -0,0 +1,105 @@
+.. _requirements-authority:
+
+Requirements Authority Module
+=============================
+
+Overview
+--------
+
+Requirements-driven approach to declaring the expected RBAC test results
+referenced by Patrole. Uses a high-level YAML syntax to crystallize policy
+requirements concisely and unambiguously.
+
+.. note::
+
+    The :ref:`custom-requirements-file` is required to use this validation
+    approach and, currently, must be manually generated.
+
+This validation approach can be toggled on by setting the
+``[patrole].test_custom_requirements`` configuration option to ``True``;
+see :ref:`patrole-configuration` for more information.
+
+When to use
+-----------
+
+This :class:`~patrole_tempest_plugin.rbac_authority.RbacAuthority` class
+can be used to achieve a requirements-driven approach to validating an
+OpenStack cloud's RBAC implementation. Using this approach, Patrole computes
+expected test results by performing lookups against a
+:ref:`custom-requirements-file` which precisely defines the cloud's RBAC
+requirements.
+
+Using a high-level declarative language, the requirements are captured
+unambiguously in the :ref:`custom-requirements-file`, allowing operators to
+validate their requirements against their OpenStack cloud.
+
+This validation approach should be used when:
+
+* The cloud has heavily customized policy files that require careful validation
+  against one's requirements.
+
+  Heavily customized policy files can contain relatively nuanced/technical
+  syntax that impinges upon the goal of using a clear and concise syntax
+  present in the :ref:`custom-requirements-file` to drive RBAC validation.
+
+* The cloud has non-OpenStack services that require RBAC validation but which
+  don't leverage the ``oslo.policy`` framework.
+
+  Services like `Contrail`_ that are present in an OpenStack-based cloud that
+  interface with OpenStack services like Neutron also require RBAC validation.
+  The requirements-driven approach to RBAC validation is framework-agnostic
+  and so can work with any policy engine.
+
+* Expected results are captured as clear-cut, unambiguous requirements.
+
+  Validating a cloud's RBAC against high-level, clear-cut requirements is
+  a valid use case. Relying on ``oslo.policy`` validating customized policy
+  files is not sufficient to satisfy this use case.
+
+As mentioned above, the trade-off with this approach is having to manually
+generate the :ref:`custom-requirements-file`. There is currently no
+tooling to automatically do this.
+
+.. _Contrail: https://github.com/Juniper/contrail-controller/wiki/RBAC
+
+.. _custom-requirements-file:
+
+Custom Requirements File
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+File path of the YAML file that defines your RBAC requirements. This
+file must be located on the same host that Patrole runs on. The YAML
+file should be written as follows:
+
+.. code-block:: yaml
+
+    <service_foo>:
+      <api_action_a>:
+        - <allowed_role_1>
+        - <allowed_role_2>
+        - <allowed_role_3>
+      <api_action_b>:
+        - <allowed_role_2>
+        - <allowed_role_4>
+    <service_bar>:
+      <api_action_c>:
+        - <allowed_role_3>
+
+Where:
+
+service = the service that is being tested (Cinder, Nova, etc.).
+
+api_action = the policy action that is being tested. Examples:
+
+* volume:create
+* os_compute_api:servers:start
+* add_image
+
+allowed_role = the ``oslo.policy`` role that is allowed to perform the API.
+
+Implementation
+--------------
+
+.. automodule:: patrole_tempest_plugin.requirements_authority
+   :members:
+   :undoc-members:
diff --git a/doc/source/index.rst b/doc/source/index.rst
index d964845..8368262 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -47,7 +47,9 @@
 
    framework/overview
    framework/rbac_validation
+   framework/rbac_authority
    framework/policy_authority
+   framework/requirements_authority
    framework/rbac_utils
 
 Indices and tables
diff --git a/etc/patrole.conf.sample b/etc/patrole.conf.sample
index 518d38a..8e7931b 100644
--- a/etc/patrole.conf.sample
+++ b/etc/patrole.conf.sample
@@ -29,9 +29,10 @@
 #
 # This option determines whether Patrole should run against a
 # ``custom_requirements_file`` which defines RBAC requirements. The
-# purpose of setting this flag to True is to verify that RBAC policy
+# purpose of setting this flag to ``True`` is to verify that RBAC
+# policy
 # is in accordance to requirements. The idea is that the
-# ``custom_requirements_file`` perfectly defines what the RBAC
+# ``custom_requirements_file`` precisely defines what the RBAC
 # requirements are.
 #
 # Here are the possible outcomes when running the Patrole tests
@@ -57,28 +58,32 @@
 # file must be located on the same host that Patrole runs on. The YAML
 # file should be written as follows:
 #
-# ```
-# <service_foo>:
-#   <api_action_x>:
-#     - <allowed_role_a>
-#     - <allowed_role_b>
-#     - <allowed_role_c>
-#   <api_action_y>:
-#     - <allowed_role_d>
-#     - <allowed_role_e>
-# <service_bar>:
-#   <api_action_z>:
-#     - <allowed_role_b>
-# ```
+# .. code-block:: yaml
+#
+#     <service_foo>:
+#       <api_action_a>:
+#         - <allowed_role_1>
+#         - <allowed_role_2>
+#         - <allowed_role_3>
+#       <api_action_b>:
+#         - <allowed_role_2>
+#         - <allowed_role_4>
+#     <service_bar>:
+#       <api_action_c>:
+#         - <allowed_role_3>
 #
 # Where:
 #
-# service = the service that is being tested (Cinder, Nova, etc.)
+# service = the service that is being tested (Cinder, Nova, etc.).
+#
 # api_action = the policy action that is being tested. Examples:
-#              - volume:create
-#              - os_compute_api:servers:start
-#              - add_image
-# allowed_role = the Keystone role that is allowed to perform the API.
+#
+# * volume:create
+# * os_compute_api:servers:start
+# * add_image
+#
+# allowed_role = the ``oslo.policy`` role that is allowed to perform
+# the API.
 #  (string value)
 #custom_requirements_file = <None>
 
diff --git a/patrole_tempest_plugin/config.py b/patrole_tempest_plugin/config.py
index f379859..ee7a6c5 100644
--- a/patrole_tempest_plugin/config.py
+++ b/patrole_tempest_plugin/config.py
@@ -42,9 +42,9 @@
                 help="""
 This option determines whether Patrole should run against a
 ``custom_requirements_file`` which defines RBAC requirements. The
-purpose of setting this flag to True is to verify that RBAC policy
+purpose of setting this flag to ``True`` is to verify that RBAC policy
 is in accordance to requirements. The idea is that the
-``custom_requirements_file`` perfectly defines what the RBAC requirements are.
+``custom_requirements_file`` precisely defines what the RBAC requirements are.
 
 Here are the possible outcomes when running the Patrole tests against
 a ``custom_requirements_file``:
@@ -67,28 +67,31 @@
 file must be located on the same host that Patrole runs on. The YAML
 file should be written as follows:
 
-```
-<service_foo>:
-  <api_action_x>:
-    - <allowed_role_a>
-    - <allowed_role_b>
-    - <allowed_role_c>
-  <api_action_y>:
-    - <allowed_role_d>
-    - <allowed_role_e>
-<service_bar>:
-  <api_action_z>:
-    - <allowed_role_b>
-```
+.. code-block:: yaml
+
+    <service_foo>:
+      <api_action_a>:
+        - <allowed_role_1>
+        - <allowed_role_2>
+        - <allowed_role_3>
+      <api_action_b>:
+        - <allowed_role_2>
+        - <allowed_role_4>
+    <service_bar>:
+      <api_action_c>:
+        - <allowed_role_3>
 
 Where:
 
-service = the service that is being tested (Cinder, Nova, etc.)
+service = the service that is being tested (Cinder, Nova, etc.).
+
 api_action = the policy action that is being tested. Examples:
-             - volume:create
-             - os_compute_api:servers:start
-             - add_image
-allowed_role = the Keystone role that is allowed to perform the API.
+
+* volume:create
+* os_compute_api:servers:start
+* add_image
+
+allowed_role = the ``oslo.policy`` role that is allowed to perform the API.
 """)
 ]