Merge "Account generator for identity v3"
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 0724566..427a748 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -19,6 +19,7 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
+from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -36,7 +37,17 @@
     @classmethod
     def setup_clients(cls):
         super(ImagesMetadataTestJSON, cls).setup_clients()
-        cls.glance_client = cls.os.image_client
+        # Check if glance v1 is available to determine which client to use. We
+        # prefer glance v1 for the compute API tests since the compute image
+        # API proxy was written for glance v1.
+        if CONF.image_feature_enabled.api_v1:
+            cls.glance_client = cls.os.image_client
+        elif CONF.image_feature_enabled.api_v2:
+            cls.glance_client = cls.os.image_client_v2
+        else:
+            raise exceptions.InvalidConfiguration(
+                'Either api_v1 or api_v2 must be True in '
+                '[image-feature-enabled].')
         cls.client = cls.compute_images_client
 
     @classmethod
@@ -45,14 +56,22 @@
         cls.image_id = None
 
         name = data_utils.rand_name('image')
+        if CONF.image_feature_enabled.api_v1:
+            kwargs = dict(is_public=False)
+        else:
+            kwargs = dict(visibility='private')
         body = cls.glance_client.create_image(name=name,
                                               container_format='bare',
                                               disk_format='raw',
-                                              is_public=False)['image']
+                                              **kwargs)
+        body = body['image'] if 'image' in body else body
         cls.image_id = body['id']
         cls.images.append(cls.image_id)
         image_file = six.StringIO(('*' * 1024))
-        cls.glance_client.update_image(cls.image_id, data=image_file)
+        if CONF.image_feature_enabled.api_v1:
+            cls.glance_client.update_image(cls.image_id, data=image_file)
+        else:
+            cls.glance_client.store_image_file(cls.image_id, data=image_file)
         waiters.wait_for_image_status(cls.client, cls.image_id, 'ACTIVE')
 
     def setUp(self):
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index af840cc..e74ca67 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -22,6 +22,7 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
+from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -40,7 +41,17 @@
     def setup_clients(cls):
         super(ListImageFiltersTestJSON, cls).setup_clients()
         cls.client = cls.compute_images_client
-        cls.glance_client = cls.os.image_client
+        # Check if glance v1 is available to determine which client to use. We
+        # prefer glance v1 for the compute API tests since the compute image
+        # API proxy was written for glance v1.
+        if CONF.image_feature_enabled.api_v1:
+            cls.glance_client = cls.os.image_client
+        elif CONF.image_feature_enabled.api_v2:
+            cls.glance_client = cls.os.image_client_v2
+        else:
+            raise exceptions.InvalidConfiguration(
+                'Either api_v1 or api_v2 must be True in '
+                '[image-feature-enabled].')
 
     @classmethod
     def resource_setup(cls):
@@ -48,17 +59,25 @@
 
         def _create_image():
             name = data_utils.rand_name('image')
+            if CONF.image_feature_enabled.api_v1:
+                kwargs = dict(is_public=False)
+            else:
+                kwargs = dict(visibility='private')
             body = cls.glance_client.create_image(name=name,
                                                   container_format='bare',
                                                   disk_format='raw',
-                                                  is_public=False)['image']
+                                                  **kwargs)
+            body = body['image'] if 'image' in body else body
             image_id = body['id']
             cls.images.append(image_id)
             # Wait 1 second between creation and upload to ensure a delta
             # between created_at and updated_at.
             time.sleep(1)
             image_file = six.StringIO(('*' * 1024))
-            cls.glance_client.update_image(image_id, data=image_file)
+            if CONF.image_feature_enabled.api_v1:
+                cls.glance_client.update_image(image_id, data=image_file)
+            else:
+                cls.glance_client.store_image_file(image_id, data=image_file)
             waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE')
             body = cls.client.show_image(image_id)['image']
             return body
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 66aec84..3a4428a 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -24,6 +24,7 @@
 from tempest.common.utils.linux import remote_client
 from tempest.common import waiters
 from tempest import config
+from tempest import exceptions
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
@@ -320,6 +321,19 @@
     def test_create_backup(self):
         # Positive test:create backup successfully and rotate backups correctly
         # create the first and the second backup
+
+        # Check if glance v1 is available to determine which client to use. We
+        # prefer glance v1 for the compute API tests since the compute image
+        # API proxy was written for glance v1.
+        if CONF.image_feature_enabled.api_v1:
+            glance_client = self.os.image_client
+        elif CONF.image_feature_enabled.api_v2:
+            glance_client = self.os.image_client_v2
+        else:
+            raise exceptions.InvalidConfiguration(
+                'Either api_v1 or api_v2 must be True in '
+                '[image-feature-enabled].')
+
         backup1 = data_utils.rand_name('backup-1')
         resp = self.client.create_backup(self.server_id,
                                          backup_type='daily',
@@ -331,7 +345,7 @@
         def _clean_oldest_backup(oldest_backup):
             if oldest_backup_exist:
                 try:
-                    self.os.image_client.delete_image(oldest_backup)
+                    glance_client.delete_image(oldest_backup)
                 except lib_exc.NotFound:
                     pass
                 else:
@@ -341,7 +355,7 @@
 
         image1_id = data_utils.parse_image_id(resp['location'])
         self.addCleanup(_clean_oldest_backup, image1_id)
-        waiters.wait_for_image_status(self.os.image_client,
+        waiters.wait_for_image_status(glance_client,
                                       image1_id, 'active')
 
         backup2 = data_utils.rand_name('backup-2')
@@ -351,8 +365,8 @@
                                          rotation=2,
                                          name=backup2).response
         image2_id = data_utils.parse_image_id(resp['location'])
-        self.addCleanup(self.os.image_client.delete_image, image2_id)
-        waiters.wait_for_image_status(self.os.image_client,
+        self.addCleanup(glance_client.delete_image, image2_id)
+        waiters.wait_for_image_status(glance_client,
                                       image2_id, 'active')
 
         # verify they have been created
@@ -361,12 +375,20 @@
             'backup_type': "daily",
             'instance_uuid': self.server_id,
         }
-        image_list = self.os.image_client.list_images(
-            detail=True,
-            properties=properties,
-            status='active',
-            sort_key='created_at',
-            sort_dir='asc')['images']
+        if CONF.image_feature_enabled.api_v1:
+            params = dict(
+                properties=properties, status='active',
+                sort_key='created_at', sort_dir='asc',)
+            image_list = glance_client.list_images(
+                detail=True,
+                **params)['images']
+        else:
+            # Additional properties are flattened in glance v2.
+            params = dict(
+                status='active', sort_key='created_at', sort_dir='asc')
+            params.update(properties)
+            image_list = glance_client.list_images(params)['images']
+
         self.assertEqual(2, len(image_list))
         self.assertEqual((backup1, backup2),
                          (image_list[0]['name'], image_list[1]['name']))
@@ -380,17 +402,16 @@
                                          rotation=2,
                                          name=backup3).response
         image3_id = data_utils.parse_image_id(resp['location'])
-        self.addCleanup(self.os.image_client.delete_image, image3_id)
+        self.addCleanup(glance_client.delete_image, image3_id)
         # the first back up should be deleted
         waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
-        self.os.image_client.wait_for_resource_deletion(image1_id)
+        glance_client.wait_for_resource_deletion(image1_id)
         oldest_backup_exist = False
-        image_list = self.os.image_client.list_images(
-            detail=True,
-            properties=properties,
-            status='active',
-            sort_key='created_at',
-            sort_dir='asc')['images']
+        if CONF.image_feature_enabled.api_v1:
+            image_list = glance_client.list_images(
+                detail=True, **params)['images']
+        else:
+            image_list = glance_client.list_images(params)['images']
         self.assertEqual(2, len(image_list),
                          'Unexpected number of images for '
                          'v2:test_create_backup; was the oldest backup not '
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 38913ce..76cd36c 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -18,6 +18,7 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
+from tempest import exceptions
 from tempest.lib.common.utils import test_utils
 from tempest import test
 
@@ -30,7 +31,16 @@
     def setup_clients(cls):
         super(VolumesV2ActionsTest, cls).setup_clients()
         cls.client = cls.volumes_client
-        cls.image_client = cls.os.image_client
+        if CONF.service_available.glance:
+            # Check if glance v1 is available to determine which client to use.
+            if CONF.image_feature_enabled.api_v1:
+                cls.image_client = cls.os.image_client
+            elif CONF.image_feature_enabled.api_v2:
+                cls.image_client = cls.os.image_client_v2
+            else:
+                raise exceptions.InvalidConfiguration(
+                    'Either api_v1 or api_v2 must be True in '
+                    '[image-feature-enabled].')
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 8d0f2f6..1dfa86d 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -50,8 +50,15 @@
         cls.compute_floating_ips_client = (
             cls.manager.compute_floating_ips_client)
         if CONF.service_available.glance:
-            # Glance image client v1
-            cls.image_client = cls.manager.image_client
+            # Check if glance v1 is available to determine which client to use.
+            if CONF.image_feature_enabled.api_v1:
+                cls.image_client = cls.manager.image_client
+            elif CONF.image_feature_enabled.api_v2:
+                cls.image_client = cls.manager.image_client_v2
+            else:
+                raise exceptions.InvalidConfiguration(
+                    'Either api_v1 or api_v2 must be True in '
+                    '[image-feature-enabled].')
         # Compute image client
         cls.compute_images_client = cls.manager.compute_images_client
         cls.keypairs_client = cls.manager.keypairs_client
@@ -376,14 +383,23 @@
             'name': name,
             'container_format': fmt,
             'disk_format': disk_format or fmt,
-            'is_public': 'False',
         }
-        params['properties'] = properties
-        image = self.image_client.create_image(**params)['image']
+        if CONF.image_feature_enabled.api_v1:
+            params['is_public'] = 'False'
+            params['properties'] = properties
+        else:
+            params['visibility'] = 'private'
+            # Additional properties are flattened out in the v2 API.
+            params.update(properties)
+        body = self.image_client.create_image(**params)
+        image = body['image'] if 'image' in body else body
         self.addCleanup(self.image_client.delete_image, image['id'])
         self.assertEqual("queued", image['status'])
         with open(path, 'rb') as image_file:
-            self.image_client.update_image(image['id'], data=image_file)
+            if CONF.image_feature_enabled.api_v1:
+                self.image_client.update_image(image['id'], data=image_file)
+            else:
+                self.image_client.store_image_file(image['id'], image_file)
         return image['id']
 
     def glance_image_create(self):
@@ -394,7 +410,7 @@
         img_container_format = CONF.scenario.img_container_format
         img_disk_format = CONF.scenario.img_disk_format
         img_properties = CONF.scenario.img_properties
-        LOG.debug("paths: img: %s, container_fomat: %s, disk_format: %s, "
+        LOG.debug("paths: img: %s, container_format: %s, disk_format: %s, "
                   "properties: %s, ami: %s, ari: %s, aki: %s" %
                   (img_path, img_container_format, img_disk_format,
                    img_properties, ami_img_path, ari_img_path, aki_img_path))
@@ -450,9 +466,16 @@
             thing_id=image_id, thing_id_param='id',
             cleanup_callable=test_utils.call_and_ignore_notfound_exc,
             cleanup_args=[_image_client.delete_image, image_id])
-        snapshot_image = _image_client.check_image(image_id)
+        if CONF.image_feature_enabled.api_v1:
+            # In glance v1 the additional properties are stored in the headers.
+            snapshot_image = _image_client.check_image(image_id)
+            image_props = snapshot_image.get('properties', {})
+        else:
+            # In glance v2 the additional properties are flattened.
+            snapshot_image = _image_client.show_image(image_id)
+            image_props = snapshot_image
 
-        bdm = snapshot_image.get('properties', {}).get('block_device_mapping')
+        bdm = image_props.get('block_device_mapping')
         if bdm:
             bdm = json.loads(bdm)
             if bdm and 'snapshot_id' in bdm[0]:
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index b45ca22..63fb59d 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -14,9 +14,7 @@
 #    under the License.
 
 import copy
-import errno
 import functools
-import os
 
 from oslo_log import log as logging
 from oslo_serialization import jsonutils as json
@@ -31,6 +29,7 @@
 
 
 class ImagesClient(rest_client.RestClient):
+    api_version = "v1"
 
     def _image_meta_from_headers(self, headers):
         meta = {'properties': {}}
@@ -68,43 +67,14 @@
             headers['x-image-meta-%s' % key] = str(value)
         return headers
 
-    def _get_file_size(self, obj):
-        """Analyze file-like object and attempt to determine its size.
-
-        :param obj: file-like object, typically redirected from stdin.
-        :retval The file's size or None if it cannot be determined.
-        """
-        # For large images, we need to supply the size of the
-        # image file. See LP Bugs #827660 and #845788.
-        if hasattr(obj, 'seek') and hasattr(obj, 'tell'):
-            try:
-                obj.seek(0, os.SEEK_END)
-                obj_size = obj.tell()
-                obj.seek(0)
-                return obj_size
-            except IOError as e:
-                if e.errno == errno.ESPIPE:
-                    # Illegal seek. This means the user is trying
-                    # to pipe image data to the client, e.g.
-                    # echo testdata | bin/glance add blah..., or
-                    # that stdin is empty, or that a file-like
-                    # object which doesn't support 'seek/tell' has
-                    # been supplied.
-                    return None
-                else:
-                    raise
-        else:
-            # Cannot determine size of input image
-            return None
-
     def _create_with_data(self, headers, data):
         # We are going to do chunked transfert, so split the input data
         # info fixed-sized chunks.
         headers['Content-Type'] = 'application/octet-stream'
         data = iter(functools.partial(data.read, CHUNKSIZE), b'')
-        resp, body = self.request('POST', '/v1/images',
+        resp, body = self.request('POST', 'images',
                                   headers=headers, body=data, chunked=True)
-        self._error_checker('POST', '/v1/images', headers, data, resp,
+        self._error_checker('POST', 'images', headers, data, resp,
                             body)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
@@ -114,7 +84,7 @@
         # info fixed-sized chunks.
         headers['Content-Type'] = 'application/octet-stream'
         data = iter(functools.partial(data.read, CHUNKSIZE), b'')
-        url = '/v1/images/%s' % image_id
+        url = 'images/%s' % image_id
         resp, body = self.request('PUT', url, headers=headers,
                                   body=data, chunked=True)
         self._error_checker('PUT', url, headers, data,
@@ -136,7 +106,7 @@
         if data is not None:
             return self._create_with_data(headers, data)
 
-        resp, body = self.post('v1/images', None, headers)
+        resp, body = self.post('images', None, headers)
         self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
@@ -149,14 +119,14 @@
         if data is not None:
             return self._update_with_data(image_id, headers, data)
 
-        url = 'v1/images/%s' % image_id
+        url = 'images/%s' % image_id
         resp, body = self.put(url, None, headers)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_image(self, image_id):
-        url = 'v1/images/%s' % image_id
+        url = 'images/%s' % image_id
         resp, body = self.delete(url)
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
@@ -171,7 +141,7 @@
         any changes.
         :param changes_since: The name is changed to changes-since
         """
-        url = 'v1/images'
+        url = 'images'
 
         if detail:
             url += '/detail'
@@ -193,7 +163,7 @@
 
     def check_image(self, image_id):
         """Check image metadata."""
-        url = 'v1/images/%s' % image_id
+        url = 'images/%s' % image_id
         resp, __ = self.head(url)
         self.expected_success(200, resp.status)
         body = self._image_meta_from_headers(resp)
@@ -201,7 +171,7 @@
 
     def show_image(self, image_id):
         """Get image details plus the image itself."""
-        url = 'v1/images/%s' % image_id
+        url = 'images/%s' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         return rest_client.ResponseBodyData(resp, body)
@@ -220,7 +190,7 @@
         return 'image_meta'
 
     def list_image_members(self, image_id):
-        url = 'v1/images/%s/members' % image_id
+        url = 'images/%s/members' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
@@ -228,7 +198,7 @@
 
     def list_shared_images(self, tenant_id):
         """List shared images with the specified tenant"""
-        url = 'v1/shared-images/%s' % tenant_id
+        url = 'shared-images/%s' % tenant_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
@@ -240,14 +210,14 @@
         Available params: see http://developer.openstack.org/
                               api-ref-image-v1.html#addMember-v1
         """
-        url = 'v1/images/%s/members/%s' % (image_id, member_id)
+        url = 'images/%s/members/%s' % (image_id, member_id)
         body = json.dumps({'member': kwargs})
         resp, __ = self.put(url, body)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)
 
     def delete_member(self, member_id, image_id):
-        url = 'v1/images/%s/members/%s' % (image_id, member_id)
+        url = 'images/%s/members/%s' % (image_id, member_id)
         resp, __ = self.delete(url)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)
diff --git a/tempest/services/image/v2/json/images_client.py b/tempest/services/image/v2/json/images_client.py
index 83f56cc..f175dce 100644
--- a/tempest/services/image/v2/json/images_client.py
+++ b/tempest/services/image/v2/json/images_client.py
@@ -25,6 +25,7 @@
 
 
 class ImagesClient(rest_client.RestClient):
+    api_version = "v2"
 
     def update_image(self, image_id, patch):
         """Update an image.
@@ -35,7 +36,7 @@
         data = json.dumps(patch)
         headers = {"Content-Type": "application/openstack-images-v2.0"
                                    "-json-patch"}
-        resp, body = self.patch('v2/images/%s' % image_id, data, headers)
+        resp, body = self.patch('images/%s' % image_id, data, headers)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
@@ -47,31 +48,31 @@
                               api-ref-image-v2.html#createImage-v2
         """
         data = json.dumps(kwargs)
-        resp, body = self.post('v2/images', data)
+        resp, body = self.post('images', data)
         self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def deactivate_image(self, image_id):
-        url = 'v2/images/%s/actions/deactivate' % image_id
+        url = 'images/%s/actions/deactivate' % image_id
         resp, body = self.post(url, None)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def reactivate_image(self, image_id):
-        url = 'v2/images/%s/actions/reactivate' % image_id
+        url = 'images/%s/actions/reactivate' % image_id
         resp, body = self.post(url, None)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def delete_image(self, image_id):
-        url = 'v2/images/%s' % image_id
+        url = 'images/%s' % image_id
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)
 
     def list_images(self, params=None):
-        url = 'v2/images'
+        url = 'images'
 
         if params:
             url += '?%s' % urllib.urlencode(params)
@@ -82,7 +83,7 @@
         return rest_client.ResponseBody(resp, body)
 
     def show_image(self, image_id):
-        url = 'v2/images/%s' % image_id
+        url = 'images/%s' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
@@ -101,7 +102,7 @@
         return 'image'
 
     def store_image_file(self, image_id, data):
-        url = 'v2/images/%s/file' % image_id
+        url = 'images/%s/file' % image_id
 
         # We are going to do chunked transfert, so split the input data
         # info fixed-sized chunks.
@@ -114,25 +115,25 @@
         return rest_client.ResponseBody(resp, body)
 
     def show_image_file(self, image_id):
-        url = 'v2/images/%s/file' % image_id
+        url = 'images/%s/file' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         return rest_client.ResponseBodyData(resp, body)
 
     def add_image_tag(self, image_id, tag):
-        url = 'v2/images/%s/tags/%s' % (image_id, tag)
+        url = 'images/%s/tags/%s' % (image_id, tag)
         resp, body = self.put(url, body=None)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def delete_image_tag(self, image_id, tag):
-        url = 'v2/images/%s/tags/%s' % (image_id, tag)
+        url = 'images/%s/tags/%s' % (image_id, tag)
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)
 
     def list_image_members(self, image_id):
-        url = 'v2/images/%s/members' % image_id
+        url = 'images/%s/members' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
@@ -144,7 +145,7 @@
         Available params: see http://developer.openstack.org/
                               api-ref-image-v2.html#createImageMember-v2
         """
-        url = 'v2/images/%s/members' % image_id
+        url = 'images/%s/members' % image_id
         data = json.dumps(kwargs)
         resp, body = self.post(url, data)
         self.expected_success(200, resp.status)
@@ -157,7 +158,7 @@
         Available params: see http://developer.openstack.org/
                               api-ref-image-v2.html#updateImageMember-v2
         """
-        url = 'v2/images/%s/members/%s' % (image_id, member_id)
+        url = 'images/%s/members/%s' % (image_id, member_id)
         data = json.dumps(kwargs)
         resp, body = self.put(url, data)
         self.expected_success(200, resp.status)
@@ -165,26 +166,26 @@
         return rest_client.ResponseBody(resp, body)
 
     def show_image_member(self, image_id, member_id):
-        url = 'v2/images/%s/members/%s' % (image_id, member_id)
+        url = 'images/%s/members/%s' % (image_id, member_id)
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, json.loads(body))
 
     def delete_image_member(self, image_id, member_id):
-        url = 'v2/images/%s/members/%s' % (image_id, member_id)
+        url = 'images/%s/members/%s' % (image_id, member_id)
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)
 
     def show_schema(self, schema):
-        url = 'v2/schemas/%s' % schema
+        url = 'schemas/%s' % schema
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def list_resource_types(self):
-        url = '/v2/metadefs/resource_types'
+        url = 'metadefs/resource_types'
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
@@ -197,13 +198,13 @@
                               api-ref-image-v2.html#createNamespace-v2
         """
         data = json.dumps(kwargs)
-        resp, body = self.post('/v2/metadefs/namespaces', data)
+        resp, body = self.post('metadefs/namespaces', data)
         self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def show_namespace(self, namespace):
-        url = '/v2/metadefs/namespaces/%s' % namespace
+        url = 'metadefs/namespaces/%s' % namespace
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
@@ -220,14 +221,14 @@
         params = {'namespace': namespace}
         params.update(kwargs)
         data = json.dumps(params)
-        url = '/v2/metadefs/namespaces/%s' % namespace
+        url = 'metadefs/namespaces/%s' % namespace
         resp, body = self.put(url, body=data)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_namespace(self, namespace):
-        url = '/v2/metadefs/namespaces/%s' % namespace
+        url = 'metadefs/namespaces/%s' % namespace
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp)