Merge "Cleanup the orchestration client init and attr"
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 23f732e..201d387 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -36,7 +36,8 @@
     subprocess.call(['tools/generate-tempest-plugins-list.sh'], cwd=root_dir)
 
 def setup(app):
-    app.connect('builder-inited', build_plugin_registry)
+    if os.getenv('GENERATE_TEMPEST_PLUGIN_LIST', 'true').lower() == 'true':
+        app.connect('builder-inited', build_plugin_registry)
 
 
 
diff --git a/releasenotes/notes/tempest-identity-catalog-client-f5c8589a9d7c1eb5.yaml b/releasenotes/notes/tempest-identity-catalog-client-f5c8589a9d7c1eb5.yaml
new file mode 100644
index 0000000..dcaaceb
--- /dev/null
+++ b/releasenotes/notes/tempest-identity-catalog-client-f5c8589a9d7c1eb5.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - Add a new identity catalog client. At this point, the new client
+    contains a single functionality, "show_catalog", which returns a
+    catalog object.
diff --git a/requirements.txt b/requirements.txt
index 259a4cf..b7ebf8a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,7 +11,7 @@
 oslo.concurrency>=3.8.0 # Apache-2.0
 oslo.config!=4.3.0,!=4.4.0,>=4.0.0 # Apache-2.0
 oslo.log>=3.22.0 # Apache-2.0
-oslo.serialization>=1.10.0 # Apache-2.0
+oslo.serialization!=2.19.1,>=1.10.0 # Apache-2.0
 oslo.utils>=3.20.0 # Apache-2.0
 six>=1.9.0 # MIT
 fixtures>=3.0.0 # Apache-2.0/BSD
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 705e567..3f1bdce 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -48,7 +48,6 @@
     @classmethod
     def setup_clients(cls):
         super(LiveMigrationTest, cls).setup_clients()
-        cls.admin_hosts_client = cls.os_admin.hosts_client
         cls.admin_migration_client = cls.os_admin.migrations_client
 
     def _migrate_server_to(self, server_id, dest_host, volume_backed=False):
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 9023759..3656770 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -32,7 +32,6 @@
     def setup_clients(cls):
         super(ServersAdminNegativeTestJSON, cls).setup_clients()
         cls.client = cls.os_admin.servers_client
-        cls.non_adm_client = cls.servers_client
         cls.quotas_client = cls.os_admin.quotas_client
 
     @classmethod
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 4495cbf..30d2a36 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -187,6 +187,7 @@
         cls.non_admin_users_client = cls.os_primary.users_v3_client
         cls.non_admin_token = cls.os_primary.token_v3_client
         cls.non_admin_projects_client = cls.os_primary.projects_client
+        cls.non_admin_catalog_client = cls.os_primary.catalog_client
         cls.non_admin_versions_client =\
             cls.os_primary.identity_versions_v3_client
 
diff --git a/tempest/api/identity/v3/test_catalog.py b/tempest/api/identity/v3/test_catalog.py
new file mode 100755
index 0000000..deec2dc
--- /dev/null
+++ b/tempest/api/identity/v3/test_catalog.py
@@ -0,0 +1,41 @@
+#    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.api.identity import base
+from tempest import config
+from tempest.lib import decorators
+
+
+CONF = config.CONF
+
+
+class IdentityCatalogTest(base.BaseIdentityV3Test):
+
+    @decorators.idempotent_id('56b57ced-22b8-4127-9b8a-565dfb0207e2')
+    def test_catalog_standardization(self):
+        # http://git.openstack.org/cgit/openstack/service-types-authority
+        # /tree/service-types.yaml
+        standard_service_values = [{'name': 'keystone', 'type': 'identity'},
+                                   {'name': 'nova', 'type': 'compute'},
+                                   {'name': 'glance', 'type': 'image'},
+                                   {'name': 'swift', 'type': 'object-store'}]
+        # next, we need to GET the catalog using the catalog client
+        catalog = self.non_admin_catalog_client.show_catalog()['catalog']
+        # get list of the service types present in the catalog
+        catalog_services = []
+        for service in catalog:
+            catalog_services.append(service['type'])
+        for service in standard_service_values:
+            # if service enabled, check if it has a standard typevalue
+            if service['name'] == 'keystone' or\
+                    getattr(CONF.service_available, service['name']):
+                self.assertIn(service['type'], catalog_services)
diff --git a/tempest/clients.py b/tempest/clients.py
index b278e3c..85c2242 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -195,6 +195,7 @@
             self.identity_v3.EndPointsFilterClient(**params_v3)
         self.endpoint_groups_client = self.identity_v3.EndPointGroupsClient(
             **params_v3)
+        self.catalog_client = self.identity_v3.CatalogClient(**params_v3)
 
         # Token clients do not use the catalog. They only need default_params.
         # They read auth_url, so they should only be set if the corresponding
diff --git a/tempest/lib/services/identity/v3/__init__.py b/tempest/lib/services/identity/v3/__init__.py
index e271a58..a539d08 100644
--- a/tempest/lib/services/identity/v3/__init__.py
+++ b/tempest/lib/services/identity/v3/__init__.py
@@ -12,6 +12,8 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+from tempest.lib.services.identity.v3.catalog_client import \
+    CatalogClient
 from tempest.lib.services.identity.v3.credentials_client import \
     CredentialsClient
 from tempest.lib.services.identity.v3.domain_configuration_client \
@@ -42,10 +44,11 @@
 from tempest.lib.services.identity.v3.users_client import UsersClient
 from tempest.lib.services.identity.v3.versions_client import VersionsClient
 
-__all__ = ['CredentialsClient', 'DomainsClient', 'DomainConfigurationClient',
-           'EndPointGroupsClient', 'EndPointsClient', 'EndPointsFilterClient',
-           'GroupsClient', 'IdentityClient', 'InheritedRolesClient',
-           'OAUTHConsumerClient', 'OAUTHTokenClient', 'PoliciesClient',
-           'ProjectsClient', 'RegionsClient', 'RoleAssignmentsClient',
-           'RolesClient', 'ServicesClient', 'V3TokenClient', 'TrustsClient',
-           'UsersClient', 'VersionsClient']
+__all__ = ['CatalogClient', 'CredentialsClient', 'DomainsClient',
+           'DomainConfigurationClient', 'EndPointGroupsClient',
+           'EndPointsClient', 'EndPointsFilterClient', 'GroupsClient',
+           'IdentityClient', 'InheritedRolesClient', 'OAUTHConsumerClient',
+           'OAUTHTokenClient', 'PoliciesClient', 'ProjectsClient',
+           'RegionsClient', 'RoleAssignmentsClient', 'RolesClient',
+           'ServicesClient', 'V3TokenClient', 'TrustsClient', 'UsersClient',
+           'VersionsClient']
diff --git a/tempest/lib/services/identity/v3/catalog_client.py b/tempest/lib/services/identity/v3/catalog_client.py
new file mode 100644
index 0000000..0f9d485
--- /dev/null
+++ b/tempest/lib/services/identity/v3/catalog_client.py
@@ -0,0 +1,30 @@
+#    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.
+
+"""
+https://developer.openstack.org/api-ref/identity/v3/index.html#\
+get-service-catalog
+"""
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+
+
+class CatalogClient(rest_client.RestClient):
+    api_version = "v3"
+
+    def show_catalog(self):
+        resp, body = self.get('auth/catalog')
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index aecb374..7690d3b 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -240,7 +240,7 @@
 
     def create_volume_type(self, client=None, name=None, backend_name=None):
         if not client:
-            client = self.admin_volume_types_client
+            client = self.os_admin.volume_types_v2_client
         if not name:
             class_name = self.__class__.__name__
             name = data_utils.rand_name(class_name + '-volume-type')
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
index 81b71b1..5667fbb 100644
--- a/tempest/scenario/test_volume_migrate_attached.py
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -40,7 +40,6 @@
     @classmethod
     def setup_clients(cls):
         super(TestVolumeMigrateRetypeAttached, cls).setup_clients()
-        cls.admin_volume_types_client = cls.os_admin.volume_types_v2_client
         cls.admin_volumes_client = cls.os_admin.volumes_v2_client
 
     @classmethod
diff --git a/tempest/tests/lib/services/identity/v3/test_catalog_client.py b/tempest/tests/lib/services/identity/v3/test_catalog_client.py
new file mode 100644
index 0000000..0ac8fe4
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_catalog_client.py
@@ -0,0 +1,86 @@
+# 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.services.identity.v3 import catalog_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestCatalogClient(base.BaseServiceTest):
+    FAKE_CATALOG_INFO = {
+        'catalog': [
+            {
+                'endpoints': [
+                    {
+                        'id': '39dc322ce86c4111b4f06c2eeae0841b',
+                        'interface': 'public',
+                        'region': 'RegionOne',
+                        'url': 'http://localhost:5000'
+                    },
+                ],
+                'id': 'ac58672276f848a7b1727850b3ebe826',
+                'type': 'compute',
+                'name': 'nova'
+            },
+            {
+                'endpoints': [
+                    {
+                        'id': '39dc322ce86c4111b4f06c2eeae0841b',
+                        'interface': 'public',
+                        'region': 'RegionOne',
+                        'url': 'http://localhost:5000'
+                    },
+                ],
+                'id': 'b7c5ed2b486a46dbb4c221499d22991c',
+                'type': 'image',
+                'name': 'glance'
+            },
+            {
+                'endpoints': [
+                    {
+                        'id': '39dc322ce86c4111b4f06c2eeae0841b',
+                        'interface': 'public',
+                        'region': 'RegionOne',
+                        'url': 'http://localhost:5000'
+                    },
+                ],
+                'id': '4363ae44bdf34a3981fde3b823cb9aa2',
+                'type': 'identity',
+                'name': 'keystone'
+            }
+
+        ],
+        'links': {
+            'self': 'http://localhost/identity/v3/catalog',
+            'previous': None,
+            'next': None
+        }
+    }
+
+    def setUp(self):
+        super(TestCatalogClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = catalog_client.CatalogClient(fake_auth, 'identity',
+                                                   'RegionOne')
+
+    def test_show_catalog_with_bytes_body(self):
+        self._test_show_catalog(bytes_body=True)
+
+    def test_show_catalog_with_str_body(self):
+        self._test_show_catalog()
+
+    def _test_show_catalog(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_catalog,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_CATALOG_INFO,
+            bytes_body)
diff --git a/tox.ini b/tox.ini
index 2120818..6f37d00 100644
--- a/tox.ini
+++ b/tox.ini
@@ -20,7 +20,7 @@
     PYTHONWARNINGS=default::DeprecationWarning
     BRANCH_NAME=master
     CLIENT_NAME=tempest
-passenv = OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_TEST_TIMEOUT OS_TEST_LOCK_PATH OS_TEST_PATH TEMPEST_CONFIG TEMPEST_CONFIG_DIR http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY ZUUL_CACHE_DIR REQUIREMENTS_PIP_LOCATION
+passenv = OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_TEST_TIMEOUT OS_TEST_LOCK_PATH OS_TEST_PATH TEMPEST_CONFIG TEMPEST_CONFIG_DIR http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY ZUUL_CACHE_DIR REQUIREMENTS_PIP_LOCATION GENERATE_TEMPEST_PLUGIN_LIST
 usedevelop = True
 install_command =
     {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}