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)