Merge "Identity V3 Tests - Domain Configurations"
diff --git a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
new file mode 100644
index 0000000..505ec18
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
@@ -0,0 +1,70 @@
+# Copyright 2017 AT&T Corporation.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.compute import rbac_base
+
+from tempest import config
+
+CONF = config.CONF
+
+
+class VolumeV235RbacTest(rbac_base.BaseV2ComputeRbacTest):
+    """RBAC tests for the Nova Volume client."""
+
+    # These tests will fail with a 404 starting from microversion 2.36.
+    # For more information, see:
+    # https://developer.openstack.org/api-ref/compute/volume-extension-os-volumes-os-snapshots-deprecated
+    min_microversion = '2.10'
+    max_microversion = '2.35'
+
+    @decorators.idempotent_id('2402013e-a624-43e3-9518-44a5d1dbb32d')
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-volumes")
+    def test_create_volume(self):
+        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'])
+
+    @decorators.idempotent_id('69b3888c-dff2-47b0-9fa4-0672619c9054')
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-volumes")
+    def test_list_volumes(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.volumes_extensions_client.list_volumes()
+
+    @decorators.idempotent_id('4ba0a820-040f-488b-86bb-be2e920ea12c')
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-volumes")
+    def test_show_volume(self):
+        volume = self.create_volume()
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.volumes_extensions_client.show_volume(volume['id'])
+
+    @decorators.idempotent_id('6e7870f2-1bb2-4b58-96f8-6782071ef327')
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-volumes")
+    def test_delete_volume(self):
+        volume = self.create_volume()
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.volumes_extensions_client.delete_volume(volume['id'])
diff --git a/patrole_tempest_plugin/tests/api/identity/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
index ed3c0da..6504844 100644
--- a/patrole_tempest_plugin/tests/api/identity/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
@@ -12,6 +12,7 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+
 from oslo_log import log as logging
 
 from tempest.api.identity import base
@@ -216,6 +217,7 @@
         cls.domain_config_client = cls.os_primary.domain_config_client
         cls.endpoints_client = cls.os_primary.endpoints_v3_client
         cls.groups_client = cls.os_primary.groups_client
+        cls.identity_client = cls.os_primary.identity_v3_client
         cls.projects_client = cls.os_primary.projects_client
         cls.policies_client = cls.os_primary.policies_client
         cls.regions_client = cls.os_primary.regions_client
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py
new file mode 100644
index 0000000..2327cbb
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py
@@ -0,0 +1,43 @@
+# Copyright 2017 AT&T Corporation.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.identity import rbac_base
+
+
+class IdentityAuthV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
+    """Tests the APIs that enforce the auth policy actions.
+
+    For more information about the auth policy actions, see:
+    https://github.com/openstack/keystone/blob/master/keystone/common/policies/auth.py
+    """
+
+    # TODO(felipemonteiro): Add tests for identity:get_auth_catalog and
+    # identity:get_auth_domains once the endpoints are implemented in Tempest's
+    # identity v3 client.
+
+    @classmethod
+    def setup_clients(cls):
+        super(IdentityAuthV3RbacTest, cls).setup_clients()
+        cls.client = cls.identity_client
+
+    @decorators.idempotent_id('2a9fbf7f-6feb-4161-ae4b-faf7d6421b1a')
+    @rbac_rule_validation.action(service="keystone",
+                                 rule="identity:get_auth_projects")
+    def test_list_auth_projects(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.list_auth_projects()['projects']
diff --git a/patrole_tempest_plugin/tests/api/image/rbac_base.py b/patrole_tempest_plugin/tests/api/image/rbac_base.py
index 2a45ccb..a825c71 100644
--- a/patrole_tempest_plugin/tests/api/image/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/image/rbac_base.py
@@ -28,7 +28,7 @@
         super(BaseV1ImageRbacTest, cls).skip_checks()
         if not CONF.rbac.enable_rbac:
             raise cls.skipException(
-                "%s skipped as RBAC Flag not enabled" % cls.__name__)
+                "%s skipped as RBAC testing not enabled" % cls.__name__)
 
     @classmethod
     def setup_clients(cls):
@@ -47,7 +47,7 @@
         super(BaseV2ImageRbacTest, cls).skip_checks()
         if not CONF.rbac.enable_rbac:
             raise cls.skipException(
-                "%s skipped as RBAC Flag not enabled" % cls.__name__)
+                "%s skipped as RBAC testing not enabled" % cls.__name__)
 
     @classmethod
     def setup_clients(cls):
diff --git a/patrole_tempest_plugin/tests/api/network/rbac_base.py b/patrole_tempest_plugin/tests/api/network/rbac_base.py
index 629f0ca..d033174 100644
--- a/patrole_tempest_plugin/tests/api/network/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/network/rbac_base.py
@@ -30,7 +30,7 @@
         super(BaseNetworkRbacTest, cls).skip_checks()
         if not CONF.rbac.enable_rbac:
             raise cls.skipException(
-                "%s skipped as RBAC Flag not enabled" % cls.__name__)
+                "%s skipped as RBAC testing not enabled" % cls.__name__)
 
     @classmethod
     def setup_clients(cls):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
index b98c39a..4be10cb 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
@@ -13,18 +13,20 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
 
 from patrole_tempest_plugin import rbac_rule_validation
 from patrole_tempest_plugin.tests.api.volume import rbac_base
 
-CONF = config.CONF
-
 
 class VolumesV2BasicCrudRbacTest(rbac_base.BaseVolumeRbacTest):
 
+    @classmethod
+    def resource_setup(cls):
+        super(VolumesV2BasicCrudRbacTest, cls).resource_setup()
+        cls.volume = cls.create_volume()
+
     @rbac_rule_validation.action(service="cinder",
                                  rule="volume:create")
     @decorators.idempotent_id('426b08ef-6394-4d06-9128-965d5a6c38ef')
@@ -43,36 +45,32 @@
     @rbac_rule_validation.action(service="cinder", rule="volume:get")
     @decorators.idempotent_id('c4c3fdd5-b1b1-49c3-b977-a9f40ee9257a')
     def test_get_volume(self):
-        volume = self.create_volume()
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.volumes_client.show_volume(volume['id'])
+        self.volumes_client.show_volume(self.volume['id'])
 
     @rbac_rule_validation.action(service="cinder",
                                  rule="volume:get_all")
     @decorators.idempotent_id('e3ab7906-b04b-4c45-aa11-1104d302f940')
     def test_volume_list(self):
-        # Get a list of Volumes
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         self.volumes_client.list_volumes()
 
+    @rbac_rule_validation.action(service="cinder", rule="volume:update")
+    @decorators.idempotent_id('b751b889-9a9b-40d8-ae7d-4b0f65e71ac7')
+    def test_update_volume(self):
+        update_name = data_utils.rand_name('volume')
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.volumes_client.update_volume(self.volume['id'],
+                                          name=update_name)
+
     @rbac_rule_validation.action(
         service="cinder",
         rule="volume_extension:volume_image_metadata")
     @decorators.idempotent_id('3d48ca91-f02b-4616-a69d-4a8b296c8529')
     def test_volume_list_image_metadata(self):
-        # Get a list of Volumes
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         self.volumes_client.list_volumes(detail=True)
 
-    @rbac_rule_validation.action(service="cinder", rule="volume:update")
-    @decorators.idempotent_id('b751b889-9a9b-40d8-ae7d-4b0f65e71ac7')
-    def test_update_volume(self):
-        volume = self.create_volume()
-        new_name = data_utils.rand_name('volume')
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.volumes_client.update_volume(volume['id'],
-                                          name=new_name)
-
 
 class VolumesV3BasicCrudRbacTest(VolumesV2BasicCrudRbacTest):
     _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
index d07e5c6..8ee8713 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
@@ -23,6 +23,7 @@
 
 
 class VolumeMetadataRbacTest(rbac_base.BaseVolumeRbacTest):
+
     @classmethod
     def setup_clients(cls):
         super(VolumeMetadataRbacTest, cls).setup_clients()
@@ -31,36 +32,38 @@
             cls.image_client = cls.os_primary.image_client
         elif CONF.image_feature_enabled.api_v2:
             cls.image_client = cls.os_primary.image_client_v2
-        cls.image_id = CONF.compute.image_ref
 
     @classmethod
     def resource_setup(cls):
         super(VolumeMetadataRbacTest, cls).resource_setup()
         cls.volume = cls.create_volume()
-        cls._add_metadata(cls.volume)
         cls.image_id = CONF.compute.image_ref
 
-    @classmethod
-    def _add_metadata(cls, volume):
+    def setUp(self):
+        super(VolumeMetadataRbacTest, self).setUp()
+        self._add_metadata(self.volume)
+
+    def tearDown(self):
+        self.volumes_client.update_volume_metadata(self.volume['id'], {})
+        super(VolumeMetadataRbacTest, self).tearDown()
+
+    def _add_metadata(self, volume):
         # Create metadata for the volume
-        metadata = {"key1": "value1",
-                    "key2": "value2",
-                    "key3": "value3",
-                    "key4": "<value&special_chars>"}
-        cls.client.create_volume_metadata(cls.volume['id'],
-                                          metadata)['metadata']
+        metadata = {"key1": "value1"}
+        self.client.create_volume_metadata(self.volume['id'], metadata)[
+            'metadata']
 
     @rbac_rule_validation.action(service="cinder",
-                                 rule="volume:update_volume_metadata")
+                                 rule="volume:create_volume_metadata")
     @decorators.idempotent_id('232bbb8b-4c29-44dc-9077-b1398c20b738')
     def test_create_volume_metadata(self):
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         self._add_metadata(self.volume)
 
     @rbac_rule_validation.action(service="cinder",
-                                 rule="volume:get")
+                                 rule="volume:get_volume_metadata")
     @decorators.idempotent_id('87ea37d9-23ab-47b2-a59c-16fc4d2c6dfa')
-    def test_get_volume_metadata(self):
+    def test_show_volume_metadata(self):
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         self.client.show_volume_metadata(self.volume['id'])['metadata']
 
@@ -85,21 +88,18 @@
                                  rule="volume:update_volume_metadata")
     @decorators.idempotent_id('8ce2ff80-99ba-49ae-9bb1-7e96729ee5af')
     def test_update_volume_metadata_item(self):
-        # Metadata to update
-        update_item = {"key3": "value3_update"}
+        updated_metadata_item = {"key1": "value1_update"}
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.client.update_volume_metadata_item(self.volume['id'], "key3",
-                                                update_item)['meta']
+        self.client.update_volume_metadata_item(
+            self.volume['id'], "key1", updated_metadata_item)['meta']
 
     @decorators.idempotent_id('a231b445-97a5-4657-b05f-245895e88da9')
     @rbac_rule_validation.action(service="cinder",
                                  rule="volume:update_volume_metadata")
     def test_update_volume_metadata(self):
-        # Metadata to update
-        update = {"key1": "value1",
-                  "key3": "value3"}
+        updated_metadata = {"key1": "value1"}
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.client.update_volume_metadata(self.volume['id'], update)
+        self.client.update_volume_metadata(self.volume['id'], updated_metadata)
 
     @decorators.idempotent_id('a9d9e825-5ea3-42e6-96f3-7ac4e97b2ed0')
     @rbac_rule_validation.action(
@@ -107,9 +107,5 @@
         rule="volume:update_volume_metadata")
     def test_update_volume_image_metadata(self):
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.client.update_volume_image_metadata(self.volume['id'],
-                                                 image_id=self.image_id)
-
-
-class VolumeMetadataV3RbacTest(VolumeMetadataRbacTest):
-    _api_version = 3
+        self.client.update_volume_image_metadata(
+            self.volume['id'], image_id=self.image_id)
diff --git a/releasenotes/notes/nova_volume_client-75e153a1c84e4ff8.yaml b/releasenotes/notes/nova_volume_client-75e153a1c84e4ff8.yaml
new file mode 100644
index 0000000..0562137
--- /dev/null
+++ b/releasenotes/notes/nova_volume_client-75e153a1c84e4ff8.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Adds RBAC tests for the Nova os-volumes API which is deprecated
+    from microversion 2.36 onward.