Merge "Adds volume summary test reno"
diff --git a/contrib/post_test_hook.sh b/contrib/post_test_hook.sh
index e934cc4..a0353ca 100644
--- a/contrib/post_test_hook.sh
+++ b/contrib/post_test_hook.sh
@@ -16,10 +16,6 @@
 # First argument ($1) expects 'rbac-role' as value for setting appropriate
 # tempest rbac option 'rbac_test_role'.
 
-# Install pip manually.
-PATROLE_DIR=$BASE/new/patrole
-sudo pip install -e $PATROLE_DIR
-
 # Allow tempest.conf to be modified by Jenkins.
 sudo chown -R jenkins:stack $BASE/new/tempest
 sudo chown -R jenkins:stack $BASE/data/tempest
diff --git a/contrib/pre_test_hook.sh b/contrib/pre_test_hook.sh
index ffa4c20..bbe05c7 100755
--- a/contrib/pre_test_hook.sh
+++ b/contrib/pre_test_hook.sh
@@ -14,6 +14,5 @@
 
 # This script is executed inside pre_test_hook function in devstack gate.
 # Installs patrole tempest plugin manually.
-
 PATROLE_DIR=$BASE/new/patrole
 sudo pip install -e $PATROLE_DIR
diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py
index 60a0f10..c63ef90 100644
--- a/patrole_tempest_plugin/rbac_rule_validation.py
+++ b/patrole_tempest_plugin/rbac_rule_validation.py
@@ -116,7 +116,7 @@
             else:
                 if not allowed:
                     LOG.error("Role %s was allowed to perform %s",
-                              (role, rule))
+                              role, rule)
                     raise rbac_exceptions.RbacOverPermission(
                         "OverPermission: Role %s was allowed to perform %s" %
                         (role, rule))
diff --git a/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py
index d44dbac..7b35525 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py
@@ -28,7 +28,6 @@
     # Tests will fail with a 404 starting from microversion 2.36:
     # See the following link for details:
     # https://developer.openstack.org/api-ref/compute/#floating-ip-pools-os-floating-ip-pools-deprecated
-    min_microversion = '2.10'
     max_microversion = '2.35'
 
     @classmethod
diff --git a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py
index 7adc161..cceccd4 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py
@@ -28,7 +28,6 @@
     # Tests will fail with a 404 starting from microversion 2.36:
     # See the following link for details:
     # https://developer.openstack.org/api-ref/compute/#floating-ips-bulk-os-floating-ips-bulk-deprecated
-    min_microversion = '2.10'
     max_microversion = '2.35'
 
     @classmethod
diff --git a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py
index e6de908..764d165 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py
@@ -28,7 +28,6 @@
     # Tests will fail with a 404 starting from microversion 2.36:
     # See the following link for details:
     # https://developer.openstack.org/api-ref/compute/#floating-ips-os-floating-ips-deprecated
-    min_microversion = '2.10'
     max_microversion = '2.35'
 
     @classmethod
diff --git a/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
index d9e9144..e687fb4 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
@@ -44,6 +44,14 @@
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         self.hypervisor_client.list_hypervisors()['hypervisors']
 
+    @decorators.idempotent_id('36b95c7d-1085-487a-a674-b7c1ca35f520')
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-hypervisors")
+    def test_list_hypervisors_with_details(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.hypervisor_client.list_hypervisors(detail=True)['hypervisors']
+
     @decorators.idempotent_id('8a7f6f9e-34a6-4480-8875-bba566c3a581')
     @rbac_rule_validation.action(
         service="nova",
diff --git a/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
index 39a87ed..3d66f2e 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
@@ -17,6 +17,7 @@
 from tempest.lib.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
 
 from patrole_tempest_plugin import rbac_rule_validation
 from patrole_tempest_plugin.tests.api.compute import rbac_base
@@ -24,7 +25,7 @@
 CONF = config.CONF
 
 
-class ImagesV235RbacTest(rbac_base.BaseV2ComputeRbacTest):
+class ImagesRbacTest(rbac_base.BaseV2ComputeRbacTest):
     """RBAC tests for the Nova images client.
 
     These APIs are proxy calls to the Image service. Consequently, no nova
@@ -34,31 +35,39 @@
     """
 
     # These tests will fail with a 404 starting from microversion 2.36.
-    min_microversion = '2.10'
+    # See the following link for details:
+    # https://developer.openstack.org/api-ref/compute/#images-deprecated
     max_microversion = '2.35'
 
     @classmethod
     def skip_checks(cls):
-        super(ImagesV235RbacTest, cls).skip_checks()
+        super(ImagesRbacTest, cls).skip_checks()
         if not CONF.service_available.glance:
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
     @classmethod
     def setup_clients(cls):
-        super(ImagesV235RbacTest, cls).setup_clients()
-        cls.glance_image_client = cls.os_primary.image_client_v2
+        super(ImagesRbacTest, cls).setup_clients()
+        if CONF.image_feature_enabled.api_v1:
+            cls.glance_image_client = cls.os_primary.image_client
+        elif CONF.image_feature_enabled.api_v2:
+            cls.glance_image_client = cls.os_primary.image_client_v2
+        else:
+            raise lib_exc.InvalidConfiguration(
+                'Either api_v1 or api_v2 must be True in '
+                '[image-feature-enabled].')
 
     @classmethod
     def resource_setup(cls):
-        super(ImagesV235RbacTest, cls).resource_setup()
+        super(ImagesRbacTest, cls).resource_setup()
         cls.image = cls.glance_image_client.create_image(
             name=data_utils.rand_name(cls.__name__ + '-image'))
 
     @classmethod
     def resource_cleanup(cls):
         cls.glance_image_client.delete_image(cls.image['id'])
-        super(ImagesV235RbacTest, cls).resource_cleanup()
+        super(ImagesRbacTest, cls).resource_cleanup()
 
     @decorators.idempotent_id('b861f302-b72b-4055-81db-c62ff30b136d')
     @rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/api/compute/test_multinic_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_multinic_rbac.py
index ca0ee26..e409269 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_multinic_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_multinic_rbac.py
@@ -22,14 +22,11 @@
 CONF = config.CONF
 
 
-class MultinicV210RbacTest(rbac_base.BaseV2ComputeRbacTest):
-
-    min_microversion = '2.10'
-    max_microversion = '2.36'
+class MultinicRbacTest(rbac_base.BaseV2ComputeRbacTest):
 
     @classmethod
     def skip_checks(cls):
-        super(MultinicV210RbacTest, cls).skip_checks()
+        super(MultinicRbacTest, cls).skip_checks()
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron is required")
         if not CONF.compute_feature_enabled.interface_attach:
@@ -39,11 +36,11 @@
     def setup_credentials(cls):
         # This test class requires network and subnet
         cls.set_network_resources(network=True, subnet=True)
-        super(MultinicV210RbacTest, cls).setup_credentials()
+        super(MultinicRbacTest, cls).setup_credentials()
 
     @classmethod
     def resource_setup(cls):
-        super(MultinicV210RbacTest, cls).resource_setup()
+        super(MultinicRbacTest, cls).resource_setup()
         cls.server = cls.create_test_server(wait_until='ACTIVE')
 
     @rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
index 505ec18..a2ae8e5 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest.common import waiters
 from tempest.lib import decorators
 
 from patrole_tempest_plugin import rbac_rule_validation
@@ -40,8 +41,12 @@
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         volume = self.volumes_extensions_client.create_volume(
             size=CONF.volume.volume_size)['volume']
-        self.addCleanup(self.volumes_extensions_client.delete_volume,
-                        volume['id'])
+        # Use the admin volumes client to wait, because waiting involves
+        # calling show API action which enforces a different policy.
+        waiters.wait_for_volume_resource_status(self.os_admin.volumes_client,
+                                                volume['id'], 'available')
+        # Use non-deprecated volumes_client for deletion.
+        self.addCleanup(self.volumes_client.delete_volume, volume['id'])
 
     @decorators.idempotent_id('69b3888c-dff2-47b0-9fa4-0672619c9054')
     @rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
index 9d34a15..a90ec2a 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
@@ -252,10 +252,9 @@
                               self.mock_args)
         self.assertIn(("OverPermission: Role Member was allowed to perform "
                       "sentinel.action"), e.__str__())
-
         mock_log.error.assert_called_once_with(
-            'Role %s was allowed to perform %s', ('Member',
-                                                  mock.sentinel.action))
+            'Role %s was allowed to perform %s', 'Member',
+            mock.sentinel.action)
 
     @mock.patch.object(rbac_rv, 'rbac_policy_parser', autospec=True)
     def test_invalid_policy_rule_throws_parsing_exception(
diff --git a/releasenotes/notes/hypervisor-list-with-details-test-655e873cd881c2bb.yaml b/releasenotes/notes/hypervisor-list-with-details-test-655e873cd881c2bb.yaml
new file mode 100644
index 0000000..30ccb45
--- /dev/null
+++ b/releasenotes/notes/hypervisor-list-with-details-test-655e873cd881c2bb.yaml
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    Add RBAC test for listing hypervisors with details.
diff --git a/requirements.txt b/requirements.txt
index 6d2c7f1..6871057 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,5 +6,6 @@
 urllib3>=1.15.1 # MIT
 oslo.log>=3.11.0 # Apache-2.0
 oslo.config>=3.22.0  # Apache-2.0
+oslo.policy>=1.17.0  # Apache-2.0
 tempest>=14.0.0  # Apache-2.0
 stevedore>=1.20.0  # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index 09b71eb..d8c9505 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -22,7 +22,7 @@
 
 [files]
 packages =
-    patrole
+    patrole_tempest_plugin
 
 [build_sphinx]
 source-dir = doc/source
@@ -53,4 +53,4 @@
 
 [entry_points]
 tempest.test_plugins =
-    patrole-tempest-plugin = patrole_tempest_plugin.plugin:PatroleTempestPlugin
+    patrole_tempest_plugin = patrole_tempest_plugin.plugin:PatroleTempestPlugin