summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/clientmanager.py12
-rw-r--r--openstackclient/common/utils.py6
-rw-r--r--openstackclient/compute/client.py5
-rw-r--r--openstackclient/compute/v2/flavor.py1
-rw-r--r--openstackclient/identity/client.py5
-rw-r--r--openstackclient/identity/common.py24
-rw-r--r--openstackclient/identity/v2_0/catalog.py6
-rw-r--r--openstackclient/identity/v3/trust.py4
-rw-r--r--openstackclient/identity/v3/user.py14
-rw-r--r--openstackclient/image/client.py4
-rw-r--r--openstackclient/image/v2/image.py2
-rw-r--r--openstackclient/network/client.py5
-rw-r--r--openstackclient/object/client.py2
-rw-r--r--openstackclient/object/v1/lib/__init__.py0
-rw-r--r--openstackclient/shell.py23
-rw-r--r--openstackclient/tests/common/test_clientmanager.py8
-rw-r--r--openstackclient/tests/common/test_extension.py7
-rw-r--r--openstackclient/tests/fakes.py2
-rw-r--r--openstackclient/tests/identity/v2_0/test_catalog.py40
-rw-r--r--openstackclient/tests/identity/v3/test_trust.py4
-rw-r--r--openstackclient/tests/identity/v3/test_user.py95
-rw-r--r--openstackclient/tests/test_shell.py10
-rw-r--r--openstackclient/tests/volume/v1/test_qos_specs.py16
-rw-r--r--openstackclient/tests/volume/v2/test_qos_specs.py16
-rw-r--r--openstackclient/volume/client.py5
-rw-r--r--openstackclient/volume/v1/qos_specs.py75
-rw-r--r--openstackclient/volume/v1/snapshot.py1
-rw-r--r--openstackclient/volume/v1/volume.py1
-rw-r--r--openstackclient/volume/v1/volume_type.py (renamed from openstackclient/volume/v1/type.py)25
-rw-r--r--openstackclient/volume/v2/qos_specs.py75
30 files changed, 330 insertions, 163 deletions
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index c77a7848..742509e4 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -86,7 +86,7 @@ class ClientManager(object):
self._pw_callback = pw_func
self._url = self._cli_options.auth.get('url', None)
self._region_name = self._cli_options.region_name
- self._endpoint_type = self._cli_options.endpoint_type
+ self._interface = self._cli_options.interface
self.timing = self._cli_options.timing
@@ -185,22 +185,22 @@ class ClientManager(object):
return self._auth_ref
def get_endpoint_for_service_type(self, service_type, region_name=None,
- endpoint_type='public'):
+ interface='public'):
"""Return the endpoint URL for the service type."""
- if not endpoint_type:
- endpoint_type = 'public'
+ if not interface:
+ interface = 'public'
# See if we are using password flow auth, i.e. we have a
# service catalog to select endpoints from
if self.auth_ref:
endpoint = self.auth_ref.service_catalog.url_for(
service_type=service_type,
region_name=region_name,
- endpoint_type=endpoint_type,
+ endpoint_type=interface,
)
else:
# Get the passed endpoint directly from the auth plugin
endpoint = self.auth.get_endpoint(self.session,
- interface=endpoint_type)
+ interface=interface)
return endpoint
diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py
index 6cd35c05..2f8419f4 100644
--- a/openstackclient/common/utils.py
+++ b/openstackclient/common/utils.py
@@ -186,9 +186,9 @@ def sort_items(items, sort_str):
:param items: a list or generator object of items
:param sort_str: a string defining the sort rules, the format is
- '<key1>:[direction1],<key2>:[direction2]...', direction can be 'asc'
- for ascending or 'desc' for descending, if direction is not given,
- it's ascending by default
+ '<key1>:[direction1],<key2>:[direction2]...', direction can be 'asc'
+ for ascending or 'desc' for descending, if direction is not given,
+ it's ascending by default
:return: sorted items
"""
if not sort_str:
diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py
index 27d63a95..6ae87b79 100644
--- a/openstackclient/compute/client.py
+++ b/openstackclient/compute/client.py
@@ -48,9 +48,8 @@ def make_client(instance):
extensions = [extension.Extension('list_extensions', list_extensions)]
- # Remember endpoint_type only if it is set
- kwargs = utils.build_kwargs_dict('endpoint_type',
- instance._endpoint_type)
+ # Remember interface only if it is set
+ kwargs = utils.build_kwargs_dict('endpoint_type', instance._interface)
client = compute_client(
session=instance.session,
diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py
index eb18a433..3458cf79 100644
--- a/openstackclient/compute/v2/flavor.py
+++ b/openstackclient/compute/v2/flavor.py
@@ -295,6 +295,7 @@ class UnsetFlavor(show.ShowOne):
action='append',
help='Property to remove from flavor '
'(repeat option to unset multiple properties)',
+ required=True,
)
parser.add_argument(
"flavor",
diff --git a/openstackclient/identity/client.py b/openstackclient/identity/client.py
index cc803511..d7b663dd 100644
--- a/openstackclient/identity/client.py
+++ b/openstackclient/identity/client.py
@@ -46,9 +46,8 @@ def make_client(instance):
API_VERSIONS)
LOG.debug('Instantiating identity client: %s', identity_client)
- # Remember interface only if endpoint_type is set
- kwargs = utils.build_kwargs_dict('interface',
- instance._endpoint_type)
+ # Remember interface only if interface is set
+ kwargs = utils.build_kwargs_dict('interface', instance._interface)
client = identity_client(
session=instance.session,
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py
index 2638b797..d0edb0bd 100644
--- a/openstackclient/identity/common.py
+++ b/openstackclient/identity/common.py
@@ -57,20 +57,32 @@ def find_domain(identity_client, name_or_id):
def find_group(identity_client, name_or_id, domain_name_or_id=None):
domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id)
- return _find_identity_resource(identity_client.groups, name_or_id,
- groups.Group, domain_id=domain_id)
+ if not domain_id:
+ return _find_identity_resource(identity_client.groups, name_or_id,
+ groups.Group)
+ else:
+ return _find_identity_resource(identity_client.groups, name_or_id,
+ groups.Group, domain_id=domain_id)
def find_project(identity_client, name_or_id, domain_name_or_id=None):
domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id)
- return _find_identity_resource(identity_client.projects, name_or_id,
- projects.Project, domain_id=domain_id)
+ if not domain_id:
+ return _find_identity_resource(identity_client.projects, name_or_id,
+ projects.Project)
+ else:
+ return _find_identity_resource(identity_client.projects, name_or_id,
+ projects.Project, domain_id=domain_id)
def find_user(identity_client, name_or_id, domain_name_or_id=None):
domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id)
- return _find_identity_resource(identity_client.users, name_or_id,
- users.User, domain_id=domain_id)
+ if not domain_id:
+ return _find_identity_resource(identity_client.users, name_or_id,
+ users.User)
+ else:
+ return _find_identity_resource(identity_client.users, name_or_id,
+ users.User, domain_id=domain_id)
def _find_identity_resource(identity_client_manager, name_or_id,
diff --git a/openstackclient/identity/v2_0/catalog.py b/openstackclient/identity/v2_0/catalog.py
index c10001d0..e166c855 100644
--- a/openstackclient/identity/v2_0/catalog.py
+++ b/openstackclient/identity/v2_0/catalog.py
@@ -30,8 +30,10 @@ def _format_endpoints(eps=None):
for index, ep in enumerate(eps):
region = eps[index].get('region', '<none>')
ret += region + '\n'
- for url in ['publicURL', 'internalURL', 'adminURL']:
- ret += " %s: %s\n" % (url, eps[index][url])
+ for endpoint_type in ['publicURL', 'internalURL', 'adminURL']:
+ url = eps[index].get(endpoint_type)
+ if url:
+ ret += " %s: %s\n" % (endpoint_type, url)
return ret
diff --git a/openstackclient/identity/v3/trust.py b/openstackclient/identity/v3/trust.py
index c8e5c4c7..5104864c 100644
--- a/openstackclient/identity/v3/trust.py
+++ b/openstackclient/identity/v3/trust.py
@@ -144,7 +144,7 @@ class CreateTrust(show.ShowOne):
# Format roles into something sensible
roles = trust._info.pop('roles')
- msg = ''.join([r['name'] + ' ' for r in roles])
+ msg = ' '.join(r['name'] for r in roles)
trust._info['roles'] = msg
return zip(*sorted(six.iteritems(trust._info)))
@@ -215,7 +215,7 @@ class ShowTrust(show.ShowOne):
# Format roles into something sensible
roles = trust._info.pop('roles')
- msg = ''.join([r['name'] + ' ' for r in roles])
+ msg = ' '.join(r['name'] for r in roles)
trust._info['roles'] = msg
return zip(*sorted(six.iteritems(trust._info)))
diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py
index b72e0d15..459707d2 100644
--- a/openstackclient/identity/v3/user.py
+++ b/openstackclient/identity/v3/user.py
@@ -51,6 +51,7 @@ class CreateUser(show.ShowOne):
metavar='<project>',
help='Default project (name or ID)',
)
+ common.add_project_domain_option_to_parser(parser)
parser.add_argument(
'--password',
metavar='<password>',
@@ -96,10 +97,9 @@ class CreateUser(show.ShowOne):
project_id = None
if parsed_args.project:
- project_id = utils.find_resource(
- identity_client.projects,
- parsed_args.project,
- ).id
+ project_id = common.find_project(identity_client,
+ parsed_args.project,
+ parsed_args.project_domain).id
domain_id = None
if parsed_args.domain:
@@ -301,6 +301,7 @@ class SetUser(command.Command):
metavar='<project>',
help='Set default project (name or ID)',
)
+ common.add_project_domain_option_to_parser(parser)
parser.add_argument(
'--password',
metavar='<password>',
@@ -367,8 +368,9 @@ class SetUser(command.Command):
if parsed_args.description:
kwargs['description'] = parsed_args.description
if parsed_args.project:
- project_id = utils.find_resource(
- identity_client.projects, parsed_args.project).id
+ project_id = common.find_project(identity_client,
+ parsed_args.project,
+ parsed_args.project_domain).id
kwargs['default_project'] = project_id
kwargs['enabled'] = user.enabled
if parsed_args.enable:
diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py
index 8e2d6cd9..8fbf8c0f 100644
--- a/openstackclient/image/client.py
+++ b/openstackclient/image/client.py
@@ -46,7 +46,7 @@ def make_client(instance):
endpoint = instance.get_endpoint_for_service_type(
API_NAME,
region_name=instance._region_name,
- endpoint_type=instance._endpoint_type,
+ interface=instance._interface,
)
client = image_client(
@@ -69,7 +69,7 @@ def make_client(instance):
endpoint=instance.get_endpoint_for_service_type(
IMAGE_API_TYPE,
region_name=instance._region_name,
- endpoint_type=instance._endpoint_type,
+ interface=instance._interface,
)
)
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index 30485202..4c019db6 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -299,7 +299,7 @@ class SaveImage(command.Command):
image_client.images,
parsed_args.image,
)
- data = image_client.images.data(image)
+ data = image_client.images.data(image.id)
gc_utils.save_image(data, parsed_args.file)
diff --git a/openstackclient/network/client.py b/openstackclient/network/client.py
index de08e5e2..0ef68852 100644
--- a/openstackclient/network/client.py
+++ b/openstackclient/network/client.py
@@ -47,12 +47,11 @@ def make_client(instance):
endpoint = instance.get_endpoint_for_service_type(
API_NAME,
region_name=instance._region_name,
- endpoint_type=instance._endpoint_type,
+ interface=instance._interface,
)
# Remember endpoint_type only if it is set
- kwargs = utils.build_kwargs_dict('endpoint_type',
- instance._endpoint_type)
+ kwargs = utils.build_kwargs_dict('endpoint_type', instance._interface)
client = network_client(
session=instance.session,
diff --git a/openstackclient/object/client.py b/openstackclient/object/client.py
index 676f6642..0359940d 100644
--- a/openstackclient/object/client.py
+++ b/openstackclient/object/client.py
@@ -36,7 +36,7 @@ def make_client(instance):
endpoint = instance.get_endpoint_for_service_type(
'object-store',
region_name=instance._region_name,
- endpoint_type=instance._endpoint_type,
+ interface=instance._interface,
)
client = object_store_v1.APIv1(
diff --git a/openstackclient/object/v1/lib/__init__.py b/openstackclient/object/v1/lib/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstackclient/object/v1/lib/__init__.py
+++ /dev/null
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index b4e5904c..319f10de 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -209,14 +209,14 @@ class OpenStackShell(app.App):
DEFAULT_DOMAIN +
' (Env: OS_DEFAULT_DOMAIN)')
parser.add_argument(
- '--os-endpoint-type',
- metavar='<endpoint-type>',
- dest='endpoint_type',
+ '--os-interface',
+ metavar='<interface>',
+ dest='interface',
choices=['admin', 'public', 'internal'],
- default=utils.env('OS_ENDPOINT_TYPE'),
- help='Select an endpoint type.'
- ' Valid endpoint types: [admin, public, internal].'
- ' (Env: OS_ENDPOINT_TYPE)')
+ default=utils.env('OS_INTERFACE'),
+ help='Select an interface type.'
+ ' Valid interface types: [admin, public, internal].'
+ ' (Env: OS_INTERFACE)')
parser.add_argument(
'--timing',
default=False,
@@ -240,9 +240,9 @@ class OpenStackShell(app.App):
# Set the default plugin to token_endpoint if url and token are given
if (self.options.url and self.options.token):
# Use service token authentication
- cloud_config.set_default('auth_type', 'token_endpoint')
+ auth_type = 'token_endpoint'
else:
- cloud_config.set_default('auth_type', 'osc_password')
+ auth_type = 'osc_password'
self.log.debug("options: %s", self.options)
project_id = getattr(self.options, 'project_id', None)
@@ -263,10 +263,11 @@ class OpenStackShell(app.App):
self.options.project_name = tenant_name
# Do configuration file handling
- # Ignore the default value of endpoint_type. Only if it is set later
+ # Ignore the default value of interface. Only if it is set later
# will it be used.
cc = cloud_config.OpenStackConfig(
- override_defaults={'endpoint_type': None, })
+ override_defaults={'interface': None,
+ 'auth_type': auth_type, })
self.log.debug("defaults: %s", cc.defaults)
self.cloud = cc.get_one_cloud(
diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py
index e86ef509..29cc59ed 100644
--- a/openstackclient/tests/common/test_clientmanager.py
+++ b/openstackclient/tests/common/test_clientmanager.py
@@ -54,7 +54,7 @@ class FakeOptions(object):
self.identity_api_version = '2.0'
self.timing = None
self.region_name = None
- self.endpoint_type = None
+ self.interface = None
self.url = None
self.auth = {}
self.default_domain = 'default'
@@ -124,7 +124,7 @@ class TestClientManager(utils.TestCase):
auth_url=fakes.AUTH_URL,
),
auth_type='v2token',
- endpoint_type=fakes.ENDPOINT_TYPE,
+ interface=fakes.INTERFACE,
region_name=fakes.REGION_NAME,
),
api_version=API_VERSION,
@@ -141,8 +141,8 @@ class TestClientManager(utils.TestCase):
auth_v2.Token,
)
self.assertEqual(
- fakes.ENDPOINT_TYPE,
- client_manager._endpoint_type,
+ fakes.INTERFACE,
+ client_manager._interface,
)
self.assertEqual(
fakes.REGION_NAME,
diff --git a/openstackclient/tests/common/test_extension.py b/openstackclient/tests/common/test_extension.py
index 8327a414..6d34bdd8 100644
--- a/openstackclient/tests/common/test_extension.py
+++ b/openstackclient/tests/common/test_extension.py
@@ -52,13 +52,6 @@ class TestExtensionList(TestExtension):
loaded=True,
),
]
- self.network_extensions_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.EXTENSION),
- loaded=True,
- ),
- ]
# Get the command object to test
self.cmd = extension.ListExtension(self.app, None)
diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py
index a9322ec3..ff69c190 100644
--- a/openstackclient/tests/fakes.py
+++ b/openstackclient/tests/fakes.py
@@ -27,7 +27,7 @@ USERNAME = "itchy"
PASSWORD = "scratchy"
PROJECT_NAME = "poochie"
REGION_NAME = "richie"
-ENDPOINT_TYPE = "catchy"
+INTERFACE = "catchy"
TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN,
user_name=USERNAME)
diff --git a/openstackclient/tests/identity/v2_0/test_catalog.py b/openstackclient/tests/identity/v2_0/test_catalog.py
index fe13d78d..7f1835d6 100644
--- a/openstackclient/tests/identity/v2_0/test_catalog.py
+++ b/openstackclient/tests/identity/v2_0/test_catalog.py
@@ -84,6 +84,46 @@ class TestCatalogList(TestCatalog):
), )
self.assertEqual(datalist, tuple(data))
+ def test_catalog_list_with_endpoint_url(self):
+ fake_service = {
+ 'id': 'qwertyuiop',
+ 'type': 'compute',
+ 'name': 'supernova',
+ 'endpoints': [
+ {
+ 'region': 'one',
+ 'publicURL': 'https://public.one.example.com',
+ },
+ {
+ 'region': 'two',
+ 'publicURL': 'https://public.two.example.com',
+ 'internalURL': 'https://internal.two.example.com',
+ },
+ ],
+ }
+ self.sc_mock.service_catalog.get_data.return_value = [
+ fake_service,
+ ]
+
+ arglist = []
+ verifylist = []
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+ self.sc_mock.service_catalog.get_data.assert_called_with()
+
+ collist = ('Name', 'Type', 'Endpoints')
+ self.assertEqual(collist, columns)
+ datalist = ((
+ 'supernova',
+ 'compute',
+ 'one\n publicURL: https://public.one.example.com\n'
+ 'two\n publicURL: https://public.two.example.com\n '
+ 'internalURL: https://internal.two.example.com\n'
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
class TestCatalogShow(TestCatalog):
diff --git a/openstackclient/tests/identity/v3/test_trust.py b/openstackclient/tests/identity/v3/test_trust.py
index b3fbe7f0..b90e7815 100644
--- a/openstackclient/tests/identity/v3/test_trust.py
+++ b/openstackclient/tests/identity/v3/test_trust.py
@@ -107,7 +107,7 @@ class TestTrustCreate(TestTrust):
identity_fakes.trust_id,
identity_fakes.trust_impersonation,
identity_fakes.project_id,
- identity_fakes.role_name + ' ',
+ identity_fakes.role_name,
identity_fakes.user_id,
identity_fakes.user_id
)
@@ -222,7 +222,7 @@ class TestTrustShow(TestTrust):
identity_fakes.trust_id,
identity_fakes.trust_impersonation,
identity_fakes.project_id,
- identity_fakes.role_name + ' ',
+ identity_fakes.role_name,
identity_fakes.user_id,
identity_fakes.user_id
)
diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py
index 18fe9016..76d5f834 100644
--- a/openstackclient/tests/identity/v3/test_user.py
+++ b/openstackclient/tests/identity/v3/test_user.py
@@ -320,6 +320,68 @@ class TestUserCreate(TestUser):
)
self.assertEqual(datalist, data)
+ def test_user_create_project_domain(self):
+ # Return the new project
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.PROJECT_2),
+ loaded=True,
+ )
+ # Set up to return an updated user
+ USER_2 = copy.deepcopy(identity_fakes.USER)
+ USER_2['default_project_id'] = identity_fakes.PROJECT_2['id']
+ self.users_mock.create.return_value = fakes.FakeResource(
+ None,
+ USER_2,
+ loaded=True,
+ )
+
+ arglist = [
+ '--project', identity_fakes.PROJECT_2['name'],
+ '--project-domain', identity_fakes.PROJECT_2['domain_id'],
+ identity_fakes.user_name,
+ ]
+ verifylist = [
+ ('project', identity_fakes.PROJECT_2['name']),
+ ('project_domain', identity_fakes.PROJECT_2['domain_id']),
+ ('enable', False),
+ ('disable', False),
+ ('name', identity_fakes.user_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': identity_fakes.user_name,
+ 'default_project': identity_fakes.PROJECT_2['id'],
+ 'description': None,
+ 'domain': None,
+ 'email': None,
+ 'enabled': True,
+ 'password': None,
+ }
+ # UserManager.create(name=, domain=, project=, password=, email=,
+ # description=, enabled=, default_project=)
+ self.users_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ collist = ('default_project_id', 'domain_id', 'email',
+ 'enabled', 'id', 'name')
+ self.assertEqual(collist, columns)
+ datalist = (
+ identity_fakes.PROJECT_2['id'],
+ identity_fakes.domain_id,
+ identity_fakes.user_email,
+ True,
+ identity_fakes.user_id,
+ identity_fakes.user_name,
+ )
+ self.assertEqual(datalist, data)
+
def test_user_create_domain(self):
arglist = [
'--domain', identity_fakes.domain_name,
@@ -894,6 +956,39 @@ class TestUserSet(TestUser):
**kwargs
)
+ def test_user_set_project_domain(self):
+ arglist = [
+ '--project', identity_fakes.project_id,
+ '--project-domain', identity_fakes.domain_id,
+ identity_fakes.user_name,
+ ]
+ verifylist = [
+ ('name', None),
+ ('password', None),
+ ('email', None),
+ ('project', identity_fakes.project_id),
+ ('project_domain', identity_fakes.domain_id),
+ ('enable', False),
+ ('disable', False),
+ ('user', identity_fakes.user_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'enabled': True,
+ 'default_project': identity_fakes.project_id,
+ }
+ # UserManager.update(user, name=, domain=, project=, password=,
+ # email=, description=, enabled=, default_project=)
+ self.users_mock.update.assert_called_with(
+ identity_fakes.user_id,
+ **kwargs
+ )
+
def test_user_set_enable(self):
arglist = [
'--enable',
diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py
index 0b4ff685..e2f0580b 100644
--- a/openstackclient/tests/test_shell.py
+++ b/openstackclient/tests/test_shell.py
@@ -39,7 +39,7 @@ DEFAULT_REGION_NAME = "ZZ9_Plural_Z_Alpha"
DEFAULT_TOKEN = "token"
DEFAULT_SERVICE_URL = "http://127.0.0.1:8771/v3.0/"
DEFAULT_AUTH_PLUGIN = "v2password"
-DEFAULT_ENDPOINT_TYPE = "internal"
+DEFAULT_INTERFACE = "internal"
DEFAULT_COMPUTE_API_VERSION = "2"
DEFAULT_IDENTITY_API_VERSION = "2"
@@ -63,7 +63,7 @@ CLOUD_1 = {
},
'region_name': 'occ-cloud',
'donut': 'glazed',
- 'endpoint_type': 'public',
+ 'interface': 'public',
}
}
}
@@ -107,7 +107,7 @@ global_options = {
'--os-default-domain': (DEFAULT_DOMAIN_NAME, True, True),
'--os-cacert': ('/dev/null', True, True),
'--timing': (True, True, False),
- '--os-endpoint-type': (DEFAULT_ENDPOINT_TYPE, True, True)
+ '--os-interface': (DEFAULT_INTERFACE, True, True)
}
auth_options = {
@@ -127,7 +127,7 @@ auth_options = {
'--os-auth-type': ("v2password", True, True),
'--os-token': (DEFAULT_TOKEN, True, True),
'--os-url': (DEFAULT_SERVICE_URL, True, True),
- '--os-endpoint-type': (DEFAULT_ENDPOINT_TYPE, True, True),
+ '--os-interface': (DEFAULT_INTERFACE, True, True),
}
@@ -616,7 +616,7 @@ class TestShellCli(TestShell):
)
self.assertEqual(
'public',
- _shell.cloud.config['endpoint_type'],
+ _shell.cloud.config['interface'],
)
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
diff --git a/openstackclient/tests/volume/v1/test_qos_specs.py b/openstackclient/tests/volume/v1/test_qos_specs.py
index 226fe673..c2e6c0af 100644
--- a/openstackclient/tests/volume/v1/test_qos_specs.py
+++ b/openstackclient/tests/volume/v1/test_qos_specs.py
@@ -56,7 +56,7 @@ class TestQosAssociate(TestQos):
volume_fakes.type_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('volume_type', volume_fakes.type_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -210,7 +210,7 @@ class TestQosDelete(TestQos):
volume_fakes.qos_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id)
+ ('qos_specs', [volume_fakes.qos_id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -223,7 +223,7 @@ class TestQosDelete(TestQos):
volume_fakes.qos_name
]
verifylist = [
- ('qos_specs', volume_fakes.qos_name)
+ ('qos_specs', [volume_fakes.qos_name])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -255,7 +255,7 @@ class TestQosDisassociate(TestQos):
'--volume-type', volume_fakes.type_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('volume_type', volume_fakes.type_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -278,7 +278,7 @@ class TestQosDisassociate(TestQos):
'--all'
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id)
+ ('qos_spec', volume_fakes.qos_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -351,7 +351,7 @@ class TestQosSet(TestQos):
'--property', 'iops=9001'
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('property', volume_fakes.qos_specs)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -386,7 +386,7 @@ class TestQosShow(TestQos):
volume_fakes.qos_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id)
+ ('qos_spec', volume_fakes.qos_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -434,7 +434,7 @@ class TestQosUnset(TestQos):
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('property', ['iops', 'foo'])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/volume/v2/test_qos_specs.py b/openstackclient/tests/volume/v2/test_qos_specs.py
index 6a550988..4222ed07 100644
--- a/openstackclient/tests/volume/v2/test_qos_specs.py
+++ b/openstackclient/tests/volume/v2/test_qos_specs.py
@@ -56,7 +56,7 @@ class TestQosAssociate(TestQos):
volume_fakes.type_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('volume_type', volume_fakes.type_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -210,7 +210,7 @@ class TestQosDelete(TestQos):
volume_fakes.qos_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id)
+ ('qos_specs', [volume_fakes.qos_id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -223,7 +223,7 @@ class TestQosDelete(TestQos):
volume_fakes.qos_name
]
verifylist = [
- ('qos_specs', volume_fakes.qos_name)
+ ('qos_specs', [volume_fakes.qos_name])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -255,7 +255,7 @@ class TestQosDisassociate(TestQos):
'--volume-type', volume_fakes.type_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('volume_type', volume_fakes.type_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -278,7 +278,7 @@ class TestQosDisassociate(TestQos):
'--all'
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id)
+ ('qos_spec', volume_fakes.qos_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -351,7 +351,7 @@ class TestQosSet(TestQos):
'--property', 'iops=9001'
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('property', volume_fakes.qos_specs)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -386,7 +386,7 @@ class TestQosShow(TestQos):
volume_fakes.qos_id
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id)
+ ('qos_spec', volume_fakes.qos_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -434,7 +434,7 @@ class TestQosUnset(TestQos):
]
verifylist = [
- ('qos_specs', volume_fakes.qos_id),
+ ('qos_spec', volume_fakes.qos_id),
('property', ['iops', 'foo'])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py
index 965c42ec..093178e3 100644
--- a/openstackclient/volume/client.py
+++ b/openstackclient/volume/client.py
@@ -53,9 +53,8 @@ def make_client(instance):
extensions = [extension.Extension('list_extensions', list_extensions)]
- # Remember endpoint_type only if it is set
- kwargs = utils.build_kwargs_dict('endpoint_type',
- instance._endpoint_type)
+ # Remember interface only if it is set
+ kwargs = utils.build_kwargs_dict('endpoint_type', instance._interface)
client = volume_client(
session=instance.session,
diff --git a/openstackclient/volume/v1/qos_specs.py b/openstackclient/volume/v1/qos_specs.py
index eacb9706..8e909e3d 100644
--- a/openstackclient/volume/v1/qos_specs.py
+++ b/openstackclient/volume/v1/qos_specs.py
@@ -34,8 +34,8 @@ class AssociateQos(command.Command):
def get_parser(self, prog_name):
parser = super(AssociateQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
parser.add_argument(
@@ -48,12 +48,12 @@ class AssociateQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
volume_type = utils.find_resource(volume_client.volume_types,
parsed_args.volume_type)
- volume_client.qos_specs.associate(qos_specs.id, volume_type.id)
+ volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
return
@@ -97,9 +97,9 @@ class CreateQos(show.ShowOne):
if parsed_args.property:
specs.update(parsed_args.property)
- qos_specs = volume_client.qos_specs.create(parsed_args.name, specs)
+ qos_spec = volume_client.qos_specs.create(parsed_args.name, specs)
- return zip(*sorted(six.iteritems(qos_specs._info)))
+ return zip(*sorted(six.iteritems(qos_spec._info)))
class DeleteQos(command.Command):
@@ -111,19 +111,18 @@ class DeleteQos(command.Command):
parser = super(DeleteQos, self).get_parser(prog_name)
parser.add_argument(
'qos_specs',
- metavar='<qos-specs>',
- help='QoS specification to delete (name or ID)',
+ metavar='<qos-spec>',
+ nargs="+",
+ help='QoS specification(s) to delete (name or ID)',
)
return parser
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
-
- volume_client.qos_specs.delete(qos_specs.id)
-
+ for qos in parsed_args.qos_specs:
+ qos_spec = utils.find_resource(volume_client.qos_specs, qos)
+ volume_client.qos_specs.delete(qos_spec.id)
return
@@ -135,8 +134,8 @@ class DisassociateQos(command.Command):
def get_parser(self, prog_name):
parser = super(DisassociateQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
volume_type_group = parser.add_mutually_exclusive_group()
@@ -157,15 +156,15 @@ class DisassociateQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
if parsed_args.volume_type:
volume_type = utils.find_resource(volume_client.volume_types,
parsed_args.volume_type)
- volume_client.qos_specs.disassociate(qos_specs.id, volume_type.id)
+ volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id)
elif parsed_args.all:
- volume_client.qos_specs.disassociate_all(qos_specs.id)
+ volume_client.qos_specs.disassociate_all(qos_spec.id)
return
@@ -206,8 +205,8 @@ class SetQos(command.Command):
def get_parser(self, prog_name):
parser = super(SetQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
parser.add_argument(
@@ -222,11 +221,11 @@ class SetQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
if parsed_args.property:
- volume_client.qos_specs.set_keys(qos_specs.id,
+ volume_client.qos_specs.set_keys(qos_spec.id,
parsed_args.property)
else:
self.app.log.error("No changes requested\n")
@@ -242,8 +241,8 @@ class ShowQos(show.ShowOne):
def get_parser(self, prog_name):
parser = super(ShowQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to display (name or ID)',
)
return parser
@@ -251,19 +250,19 @@ class ShowQos(show.ShowOne):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
- qos_associations = volume_client.qos_specs.get_associations(qos_specs)
+ qos_associations = volume_client.qos_specs.get_associations(qos_spec)
if qos_associations:
associations = [association.name
for association in qos_associations]
- qos_specs._info.update({
+ qos_spec._info.update({
'associations': utils.format_list(associations)
})
- qos_specs._info.update({'specs': utils.format_dict(qos_specs.specs)})
+ qos_spec._info.update({'specs': utils.format_dict(qos_spec.specs)})
- return zip(*sorted(six.iteritems(qos_specs._info)))
+ return zip(*sorted(six.iteritems(qos_spec._info)))
class UnsetQos(command.Command):
@@ -274,8 +273,8 @@ class UnsetQos(command.Command):
def get_parser(self, prog_name):
parser = super(UnsetQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
parser.add_argument(
@@ -291,11 +290,11 @@ class UnsetQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
if parsed_args.property:
- volume_client.qos_specs.unset_keys(qos_specs.id,
+ volume_client.qos_specs.unset_keys(qos_spec.id,
parsed_args.property)
else:
self.app.log.error("No changes requested\n")
diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py
index 5ec2b3c5..e81efb5a 100644
--- a/openstackclient/volume/v1/snapshot.py
+++ b/openstackclient/volume/v1/snapshot.py
@@ -263,6 +263,7 @@ class UnsetSnapshot(command.Command):
default=[],
help='Property to remove from snapshot '
'(repeat to remove multiple values)',
+ required=True,
)
return parser
diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py
index ad9671e3..884611ec 100644
--- a/openstackclient/volume/v1/volume.py
+++ b/openstackclient/volume/v1/volume.py
@@ -437,6 +437,7 @@ class UnsetVolume(command.Command):
default=[],
help='Property to remove from volume '
'(repeat option to remove multiple properties)',
+ required=True,
)
return parser
diff --git a/openstackclient/volume/v1/type.py b/openstackclient/volume/v1/volume_type.py
index 46d1828b..d5c617b2 100644
--- a/openstackclient/volume/v1/type.py
+++ b/openstackclient/volume/v1/volume_type.py
@@ -166,6 +166,7 @@ class UnsetVolumeType(command.Command):
default=[],
help='Property to remove from volume type '
'(repeat option to remove multiple properties)',
+ required=True,
)
return parser
@@ -182,3 +183,27 @@ class UnsetVolumeType(command.Command):
else:
self.app.log.error("No changes requested\n")
return
+
+
+class ShowVolumeType(show.ShowOne):
+ """Display volume type details"""
+
+ log = logging.getLogger(__name__ + ".ShowVolumeType")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowVolumeType, self).get_parser(prog_name)
+ parser.add_argument(
+ "volume_type",
+ metavar="<volume-type>",
+ help="Volume type to display (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action: (%s)", parsed_args)
+ volume_client = self.app.client_manager.volume
+ volume_type = utils.find_resource(
+ volume_client.volume_types, parsed_args.volume_type)
+ properties = utils.format_dict(volume_type._info.pop('extra_specs'))
+ volume_type._info.update({'properties': properties})
+ return zip(*sorted(six.iteritems(volume_type._info)))
diff --git a/openstackclient/volume/v2/qos_specs.py b/openstackclient/volume/v2/qos_specs.py
index 7f02fa4a..ac78ca15 100644
--- a/openstackclient/volume/v2/qos_specs.py
+++ b/openstackclient/volume/v2/qos_specs.py
@@ -34,8 +34,8 @@ class AssociateQos(command.Command):
def get_parser(self, prog_name):
parser = super(AssociateQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
parser.add_argument(
@@ -48,12 +48,12 @@ class AssociateQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
volume_type = utils.find_resource(volume_client.volume_types,
parsed_args.volume_type)
- volume_client.qos_specs.associate(qos_specs.id, volume_type.id)
+ volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
return
@@ -97,9 +97,9 @@ class CreateQos(show.ShowOne):
if parsed_args.property:
specs.update(parsed_args.property)
- qos_specs = volume_client.qos_specs.create(parsed_args.name, specs)
+ qos_spec = volume_client.qos_specs.create(parsed_args.name, specs)
- return zip(*sorted(six.iteritems(qos_specs._info)))
+ return zip(*sorted(six.iteritems(qos_spec._info)))
class DeleteQos(command.Command):
@@ -111,19 +111,18 @@ class DeleteQos(command.Command):
parser = super(DeleteQos, self).get_parser(prog_name)
parser.add_argument(
'qos_specs',
- metavar='<qos-specs>',
- help='QoS specification to delete (name or ID)',
+ metavar='<qos-spec>',
+ nargs="+",
+ help='QoS specification(s) to delete (name or ID)',
)
return parser
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
-
- volume_client.qos_specs.delete(qos_specs.id)
-
+ for qos in parsed_args.qos_specs:
+ qos_spec = utils.find_resource(volume_client.qos_specs, qos)
+ volume_client.qos_specs.delete(qos_spec.id)
return
@@ -135,8 +134,8 @@ class DisassociateQos(command.Command):
def get_parser(self, prog_name):
parser = super(DisassociateQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
volume_type_group = parser.add_mutually_exclusive_group()
@@ -157,15 +156,15 @@ class DisassociateQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
if parsed_args.volume_type:
volume_type = utils.find_resource(volume_client.volume_types,
parsed_args.volume_type)
- volume_client.qos_specs.disassociate(qos_specs.id, volume_type.id)
+ volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id)
elif parsed_args.all:
- volume_client.qos_specs.disassociate_all(qos_specs.id)
+ volume_client.qos_specs.disassociate_all(qos_spec.id)
return
@@ -206,8 +205,8 @@ class SetQos(command.Command):
def get_parser(self, prog_name):
parser = super(SetQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
parser.add_argument(
@@ -222,11 +221,11 @@ class SetQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
if parsed_args.property:
- volume_client.qos_specs.set_keys(qos_specs.id,
+ volume_client.qos_specs.set_keys(qos_spec.id,
parsed_args.property)
else:
self.app.log.error("No changes requested\n")
@@ -242,8 +241,8 @@ class ShowQos(show.ShowOne):
def get_parser(self, prog_name):
parser = super(ShowQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to display (name or ID)',
)
return parser
@@ -251,19 +250,19 @@ class ShowQos(show.ShowOne):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
- qos_associations = volume_client.qos_specs.get_associations(qos_specs)
+ qos_associations = volume_client.qos_specs.get_associations(qos_spec)
if qos_associations:
associations = [association.name
for association in qos_associations]
- qos_specs._info.update({
+ qos_spec._info.update({
'associations': utils.format_list(associations)
})
- qos_specs._info.update({'specs': utils.format_dict(qos_specs.specs)})
+ qos_spec._info.update({'specs': utils.format_dict(qos_spec.specs)})
- return zip(*sorted(six.iteritems(qos_specs._info)))
+ return zip(*sorted(six.iteritems(qos_spec._info)))
class UnsetQos(command.Command):
@@ -274,8 +273,8 @@ class UnsetQos(command.Command):
def get_parser(self, prog_name):
parser = super(UnsetQos, self).get_parser(prog_name)
parser.add_argument(
- 'qos_specs',
- metavar='<qos-specs>',
+ 'qos_spec',
+ metavar='<qos-spec>',
help='QoS specification to modify (name or ID)',
)
parser.add_argument(
@@ -291,11 +290,11 @@ class UnsetQos(command.Command):
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
- qos_specs = utils.find_resource(volume_client.qos_specs,
- parsed_args.qos_specs)
+ qos_spec = utils.find_resource(volume_client.qos_specs,
+ parsed_args.qos_spec)
if parsed_args.property:
- volume_client.qos_specs.unset_keys(qos_specs.id,
+ volume_client.qos_specs.unset_keys(qos_spec.id,
parsed_args.property)
else:
self.app.log.error("No changes requested\n")