summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/api/utils.py84
-rw-r--r--openstackclient/common/clientmanager.py7
-rw-r--r--openstackclient/common/commandmanager.py59
-rw-r--r--openstackclient/compute/v2/aggregate.py2
-rw-r--r--openstackclient/compute/v2/fixedip.py100
-rw-r--r--openstackclient/compute/v2/flavor.py2
-rw-r--r--openstackclient/compute/v2/floatingip.py97
-rw-r--r--openstackclient/compute/v2/server.py226
-rw-r--r--openstackclient/compute/v2/server_event.py12
-rw-r--r--openstackclient/identity/v2_0/project.py2
-rw-r--r--openstackclient/identity/v2_0/role.py148
-rw-r--r--openstackclient/identity/v2_0/service.py30
-rw-r--r--openstackclient/identity/v3/endpoint_group.py6
-rw-r--r--openstackclient/identity/v3/role.py125
-rw-r--r--openstackclient/image/v1/image.py32
-rw-r--r--openstackclient/image/v2/image.py51
-rw-r--r--openstackclient/network/v2/port.py35
-rw-r--r--openstackclient/network/v2/router.py19
-rw-r--r--openstackclient/network/v2/security_group_rule.py63
-rw-r--r--openstackclient/shell.py2
-rw-r--r--openstackclient/tests/functional/compute/v2/test_aggregate.py147
-rw-r--r--openstackclient/tests/functional/compute/v2/test_server.py80
-rw-r--r--openstackclient/tests/functional/identity/v2/test_role.py32
-rw-r--r--openstackclient/tests/functional/identity/v3/test_role.py41
-rw-r--r--openstackclient/tests/functional/network/v2/test_floating_ip.py2
-rw-r--r--openstackclient/tests/functional/network/v2/test_subnet_pool.py4
-rw-r--r--openstackclient/tests/functional/volume/v2/test_volume_backup.py (renamed from openstackclient/tests/functional/volume/v2/test_backup.py)4
-rw-r--r--openstackclient/tests/functional/volume/v2/test_volume_snapshot.py (renamed from openstackclient/tests/functional/volume/v2/test_snapshot.py)0
-rw-r--r--openstackclient/tests/functional/volume/v3/test_volume_snapshot.py (renamed from openstackclient/tests/functional/volume/v3/test_snapshot.py)2
-rw-r--r--openstackclient/tests/unit/api/test_object_store_v1.py2
-rw-r--r--openstackclient/tests/unit/api/test_utils.py115
-rw-r--r--openstackclient/tests/unit/common/test_commandmanager.py107
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server.py624
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_role.py133
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_service.py45
-rw-r--r--openstackclient/tests/unit/identity/v3/fakes.py62
-rw-r--r--openstackclient/tests/unit/identity/v3/test_endpoint_group.py495
-rw-r--r--openstackclient/tests/unit/identity/v3/test_role.py232
-rw-r--r--openstackclient/tests/unit/image/v1/test_image.py2
-rw-r--r--openstackclient/tests/unit/image/v2/test_image.py54
-rw-r--r--openstackclient/tests/unit/integ/cli/test_shell.py19
-rw-r--r--openstackclient/tests/unit/network/v2/test_router.py46
-rw-r--r--openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py83
-rw-r--r--openstackclient/tests/unit/network/v2/test_security_group_rule_network.py32
-rw-r--r--openstackclient/tests/unit/test_shell.py37
-rw-r--r--openstackclient/tests/unit/volume/v1/test_snapshot.py580
-rw-r--r--openstackclient/tests/unit/volume/v1/test_transfer_request.py20
-rw-r--r--openstackclient/tests/unit/volume/v1/test_volume_backup.py (renamed from openstackclient/tests/unit/volume/v1/test_backup.py)12
-rw-r--r--openstackclient/tests/unit/volume/v2/test_snapshot.py741
-rw-r--r--openstackclient/tests/unit/volume/v2/test_transfer_request.py30
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume.py34
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume_backup.py (renamed from openstackclient/tests/unit/volume/v2/test_backup.py)14
-rw-r--r--openstackclient/volume/v1/snapshot.py318
-rw-r--r--openstackclient/volume/v1/volume_backup.py (renamed from openstackclient/volume/v1/backup.py)85
-rw-r--r--openstackclient/volume/v1/volume_transfer_request.py22
-rw-r--r--openstackclient/volume/v2/snapshot.py351
-rw-r--r--openstackclient/volume/v2/volume.py36
-rw-r--r--openstackclient/volume/v2/volume_backup.py (renamed from openstackclient/volume/v2/backup.py)85
-rw-r--r--openstackclient/volume/v2/volume_transfer_request.py23
-rw-r--r--openstackclient/volume/v2/volume_type.py2
60 files changed, 1666 insertions, 4189 deletions
diff --git a/openstackclient/api/utils.py b/openstackclient/api/utils.py
deleted file mode 100644
index 6407cd44..00000000
--- a/openstackclient/api/utils.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-"""API Utilities Library"""
-
-
-def simple_filter(
- data=None,
- attr=None,
- value=None,
- property_field=None,
-):
- """Filter a list of dicts
-
- :param list data:
- The list to be filtered. The list is modified in-place and will
- be changed if any filtering occurs.
- :param string attr:
- The name of the attribute to filter. If attr does not exist no
- match will succeed and no rows will be returned. If attr is
- None no filtering will be performed and all rows will be returned.
- :param string value:
- The value to filter. None is considered to be a 'no filter' value.
- '' matches against a Python empty string.
- :param string property_field:
- The name of the data field containing a property dict to filter.
- If property_field is None, attr is a field name. If property_field
- is not None, attr is a property key name inside the named property
- field.
-
- :returns:
- Returns the filtered list
- :rtype list:
-
- This simple filter (one attribute, one exact-match value) searches a
- list of dicts to select items. It first searches the item dict for a
- matching ``attr`` then does an exact-match on the ``value``. If
- ``property_field`` is given, it will look inside that field (if it
- exists and is a dict) for a matching ``value``.
- """
-
- # Take the do-nothing case shortcut
- if not data or not attr or value is None:
- return data
-
- # NOTE:(dtroyer): This filter modifies the provided list in-place using
- # list.remove() so we need to start at the end so the loop pointer does
- # not skip any items after a deletion.
- for d in reversed(data):
- if attr in d:
- # Searching data fields
- search_value = d[attr]
- elif (property_field and property_field in d and
- isinstance(d[property_field], dict)):
- # Searching a properties field - do this separately because
- # we don't want to fail over to checking the fields if a
- # property name is given.
- if attr in d[property_field]:
- search_value = d[property_field][attr]
- else:
- search_value = None
- else:
- search_value = None
-
- # could do regex here someday...
- if not search_value or search_value != value:
- # remove from list
- try:
- data.remove(d)
- except ValueError:
- # it's already gone!
- pass
-
- return data
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index aa1045e4..c1118ad3 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -91,13 +91,6 @@ class ClientManager(clientmanager.ClientManager):
return super(ClientManager, self).setup_auth()
- @property
- def auth_ref(self):
- if not self._auth_required:
- return None
- else:
- return super(ClientManager, self).auth_ref
-
def _fallback_load_auth_plugin(self, e):
# NOTES(RuiChen): Hack to avoid auth plugins choking on data they don't
# expect, delete fake token and endpoint, then try to
diff --git a/openstackclient/common/commandmanager.py b/openstackclient/common/commandmanager.py
deleted file mode 100644
index c190e33e..00000000
--- a/openstackclient/common/commandmanager.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2012-2013 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-"""Modify cliff.CommandManager"""
-
-import pkg_resources
-
-import cliff.commandmanager
-
-
-class CommandManager(cliff.commandmanager.CommandManager):
- """Add additional functionality to cliff.CommandManager
-
- Load additional command groups after initialization
- Add _command_group() methods
- """
-
- def __init__(self, namespace, convert_underscores=True):
- self.group_list = []
- super(CommandManager, self).__init__(namespace, convert_underscores)
-
- def load_commands(self, namespace):
- self.group_list.append(namespace)
- return super(CommandManager, self).load_commands(namespace)
-
- def add_command_group(self, group=None):
- """Adds another group of command entrypoints"""
- if group:
- self.load_commands(group)
-
- def get_command_groups(self):
- """Returns a list of the loaded command groups"""
- return self.group_list
-
- def get_command_names(self, group=None):
- """Returns a list of commands loaded for the specified group"""
- group_list = []
- if group is not None:
- for ep in pkg_resources.iter_entry_points(group):
- cmd_name = (
- ep.name.replace('_', ' ')
- if self.convert_underscores
- else ep.name
- )
- group_list.append(cmd_name)
- return group_list
- return list(self.commands.keys())
diff --git a/openstackclient/compute/v2/aggregate.py b/openstackclient/compute/v2/aggregate.py
index 7f9161a9..fa646478 100644
--- a/openstackclient/compute/v2/aggregate.py
+++ b/openstackclient/compute/v2/aggregate.py
@@ -101,6 +101,8 @@ class CreateAggregate(command.ShowOne):
parsed_args.property,
)._info)
+ # TODO(dtroyer): re-format metadata field to properites as
+ # in the set command
return zip(*sorted(six.iteritems(info)))
diff --git a/openstackclient/compute/v2/fixedip.py b/openstackclient/compute/v2/fixedip.py
deleted file mode 100644
index 0c0b619e..00000000
--- a/openstackclient/compute/v2/fixedip.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-"""Fixed IP action implementations"""
-
-import logging
-
-from osc_lib.command import command
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-class AddFixedIP(command.Command):
- _description = _("Add fixed IP address to server")
-
- # TODO(tangchen): Remove this class and ``ip fixed add`` command
- # two cycles after Mitaka.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def get_parser(self, prog_name):
- parser = super(AddFixedIP, self).get_parser(prog_name)
- parser.add_argument(
- "network",
- metavar="<network>",
- help=_("Network to fetch an IP address from (name or ID)"),
- )
- parser.add_argument(
- "server",
- metavar="<server>",
- help=_("Server to receive the IP address (name or ID)"),
- )
- return parser
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "server add fixed ip" instead.'))
-
- compute_client = self.app.client_manager.compute
-
- network = utils.find_resource(
- compute_client.networks, parsed_args.network)
-
- server = utils.find_resource(
- compute_client.servers, parsed_args.server)
-
- server.add_fixed_ip(network.id)
-
-
-class RemoveFixedIP(command.Command):
- _description = _("Remove fixed IP address from server")
-
- # TODO(tangchen): Remove this class and ``ip fixed remove`` command
- # two cycles after Mitaka.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def get_parser(self, prog_name):
- parser = super(RemoveFixedIP, self).get_parser(prog_name)
- parser.add_argument(
- "ip_address",
- metavar="<ip-address>",
- help=_("IP address to remove from server (name only)"),
- )
- parser.add_argument(
- "server",
- metavar="<server>",
- help=_("Server to remove the IP address from (name or ID)"),
- )
- return parser
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "server remove fixed ip" instead.'))
-
- compute_client = self.app.client_manager.compute
-
- server = utils.find_resource(
- compute_client.servers, parsed_args.server)
-
- server.remove_fixed_ip(parsed_args.ip_address)
diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py
index 2cc5f1e8..4f1e48af 100644
--- a/openstackclient/compute/v2/flavor.py
+++ b/openstackclient/compute/v2/flavor.py
@@ -432,7 +432,7 @@ class ShowFlavor(command.ShowOne):
projects = [utils.get_field(access, 'tenant_id')
for access in flavor_access]
# TODO(Huanxuan Ao): This format case can be removed after
- # patch https://review.openstack.org/#/c/330223/ merged.
+ # patch https://review.opendev.org/#/c/330223/ merged.
access_projects = utils.format_list(projects)
except Exception as e:
msg = _("Failed to get access projects list "
diff --git a/openstackclient/compute/v2/floatingip.py b/openstackclient/compute/v2/floatingip.py
deleted file mode 100644
index 69595bed..00000000
--- a/openstackclient/compute/v2/floatingip.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-"""Floating IP action implementations"""
-
-import logging
-
-from osc_lib.command import command
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-class AddFloatingIP(command.Command):
- _description = _("Add floating IP address to server")
-
- # TODO(tangchen): Remove this class and ``ip floating add`` command
- # two cycles after Mitaka.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def get_parser(self, prog_name):
- parser = super(AddFloatingIP, self).get_parser(prog_name)
- parser.add_argument(
- "ip_address",
- metavar="<ip-address>",
- help=_("IP address to add to server (name only)"),
- )
- parser.add_argument(
- "server",
- metavar="<server>",
- help=_("Server to receive the IP address (name or ID)"),
- )
- return parser
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "server add floating ip" instead.'))
-
- compute_client = self.app.client_manager.compute
-
- server = utils.find_resource(
- compute_client.servers, parsed_args.server)
-
- server.add_floating_ip(parsed_args.ip_address)
-
-
-class RemoveFloatingIP(command.Command):
- _description = _("Remove floating IP address from server")
-
- # TODO(tangchen): Remove this class and ``ip floating remove`` command
- # two cycles after Mitaka.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def get_parser(self, prog_name):
- parser = super(RemoveFloatingIP, self).get_parser(prog_name)
- parser.add_argument(
- "ip_address",
- metavar="<ip-address>",
- help=_("IP address to remove from server (name only)"),
- )
- parser.add_argument(
- "server",
- metavar="<server>",
- help=_("Server to remove the IP address from (name or ID)"),
- )
- return parser
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "server remove floating ip" instead.'))
-
- compute_client = self.app.client_manager.compute
-
- server = utils.find_resource(
- compute_client.servers, parsed_args.server)
-
- server.remove_floating_ip(parsed_args.ip_address)
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index cb9f8d43..2792e315 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -424,7 +424,10 @@ class AddServerSecurityGroup(command.Command):
class AddServerVolume(command.Command):
- _description = _("Add volume to server")
+ _description = _(
+ "Add volume to server. "
+ "Specify ``--os-compute-api-version 2.20`` or higher to add a volume "
+ "to a server with status ``SHELVED`` or ``SHELVED_OFFLOADED``.")
def get_parser(self, prog_name):
parser = super(AddServerVolume, self).get_parser(prog_name)
@@ -540,6 +543,12 @@ class CreateServer(command.ShowOne):
help=_('User data file to serve from the metadata server'),
)
parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_('Set description for the server (supported by '
+ '--os-compute-api-version 2.19 or above)'),
+ )
+ parser.add_argument(
'--availability-zone',
metavar='<zone-name>',
help=_('Select an availability zone for the server'),
@@ -749,6 +758,12 @@ class CreateServer(command.ShowOne):
"exception": e}
)
+ if parsed_args.description:
+ if compute_client.api_version < api_versions.APIVersion("2.19"):
+ msg = _("Description is not supported for "
+ "--os-compute-api-version less than 2.19")
+ raise exceptions.CommandError(msg)
+
block_device_mapping_v2 = []
if volume:
block_device_mapping_v2 = [{'uuid': volume,
@@ -909,6 +924,9 @@ class CreateServer(command.ShowOne):
scheduler_hints=hints,
config_drive=config_drive)
+ if parsed_args.description:
+ boot_kwargs['description'] = parsed_args.description
+
LOG.debug('boot_args: %s', boot_args)
LOG.debug('boot_kwargs: %s', boot_kwargs)
@@ -1129,12 +1147,36 @@ class ListServer(command.Lister):
help=_('Only display deleted servers (Admin only).')
)
parser.add_argument(
+ '--changes-before',
+ metavar='<changes-before>',
+ default=None,
+ help=_("List only servers changed before a certain point of time. "
+ "The provided time should be an ISO 8061 formatted time "
+ "(e.g., 2016-03-05T06:27:59Z). "
+ "(Supported by API versions '2.66' - '2.latest')")
+ )
+ parser.add_argument(
'--changes-since',
metavar='<changes-since>',
default=None,
help=_("List only servers changed after a certain point of time."
- " The provided time should be an ISO 8061 formatted time."
- " ex 2016-03-04T06:27:59Z .")
+ " The provided time should be an ISO 8061 formatted time"
+ " (e.g., 2016-03-04T06:27:59Z).")
+ )
+ lock_group = parser.add_mutually_exclusive_group()
+ lock_group.add_argument(
+ '--locked',
+ action='store_true',
+ default=False,
+ help=_('Only display locked servers. '
+ 'Requires ``--os-compute-api-version`` 2.73 or greater.'),
+ )
+ lock_group.add_argument(
+ '--unlocked',
+ action='store_true',
+ default=False,
+ help=_('Only display unlocked servers. '
+ 'Requires ``--os-compute-api-version`` 2.73 or greater.'),
)
return parser
@@ -1188,10 +1230,36 @@ class ListServer(command.Lister):
'all_tenants': parsed_args.all_projects,
'user_id': user_id,
'deleted': parsed_args.deleted,
+ 'changes-before': parsed_args.changes_before,
'changes-since': parsed_args.changes_since,
}
+ support_locked = (compute_client.api_version >=
+ api_versions.APIVersion('2.73'))
+ if not support_locked and (parsed_args.locked or parsed_args.unlocked):
+ msg = _('--os-compute-api-version 2.73 or greater is required to '
+ 'use the (un)locked filter option.')
+ raise exceptions.CommandError(msg)
+ elif support_locked:
+ # Only from 2.73.
+ if parsed_args.locked:
+ search_opts['locked'] = True
+ if parsed_args.unlocked:
+ search_opts['locked'] = False
LOG.debug('search options: %s', search_opts)
+ if search_opts['changes-before']:
+ if compute_client.api_version < api_versions.APIVersion('2.66'):
+ msg = _('--os-compute-api-version 2.66 or later is required')
+ raise exceptions.CommandError(msg)
+
+ try:
+ timeutils.parse_isotime(search_opts['changes-before'])
+ except ValueError:
+ raise exceptions.CommandError(
+ _('Invalid changes-before value: %s') %
+ search_opts['changes-before']
+ )
+
if search_opts['changes-since']:
try:
timeutils.parse_isotime(search_opts['changes-since'])
@@ -1374,16 +1442,28 @@ class LockServer(command.Command):
nargs='+',
help=_('Server(s) to lock (name or ID)'),
)
+ parser.add_argument(
+ '--reason',
+ metavar='<reason>',
+ default=None,
+ help=_("Reason for locking the server(s). Requires "
+ "``--os-compute-api-version`` 2.73 or greater.")
+ )
return parser
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
+ support_reason = compute_client.api_version >= api_versions.APIVersion(
+ '2.73')
+ if not support_reason and parsed_args.reason:
+ msg = _('--os-compute-api-version 2.73 or greater is required to '
+ 'use the --reason option.')
+ raise exceptions.CommandError(msg)
for server in parsed_args.server:
- utils.find_resource(
- compute_client.servers,
- server,
- ).lock()
+ serv = utils.find_resource(compute_client.servers, server)
+ (serv.lock(reason=parsed_args.reason) if support_reason
+ else serv.lock())
# FIXME(dtroyer): Here is what I want, how with argparse/cliff?
@@ -1407,9 +1487,38 @@ class MigrateServer(command.Command):
help=_('Server (name or ID)'),
)
parser.add_argument(
+ '--live-migration',
+ dest='live_migration',
+ action='store_true',
+ help=_('Live migrate the server. Use the ``--host`` option to '
+ 'specify a target host for the migration which will be '
+ 'validated by the scheduler.'),
+ )
+ # The --live and --host options are mutually exclusive ways of asking
+ # for a target host during a live migration.
+ host_group = parser.add_mutually_exclusive_group()
+ # TODO(mriedem): Remove --live in the next major version bump after
+ # the Train release.
+ host_group.add_argument(
'--live',
metavar='<hostname>',
- help=_('Target hostname'),
+ help=_('**Deprecated** This option is problematic in that it '
+ 'requires a host and prior to compute API version 2.30, '
+ 'specifying a host during live migration will bypass '
+ 'validation by the scheduler which could result in '
+ 'failures to actually migrate the server to the specified '
+ 'host or over-subscribe the host. Use the '
+ '``--live-migration`` option instead. If both this option '
+ 'and ``--live-migration`` are used, ``--live-migration`` '
+ 'takes priority.'),
+ )
+ host_group.add_argument(
+ '--host',
+ metavar='<hostname>',
+ help=_('Migrate the server to the specified host. Requires '
+ '``--os-compute-api-version`` 2.30 or greater when used '
+ 'with the ``--live-migration`` option, otherwise requires '
+ '``--os-compute-api-version`` 2.56 or greater.'),
)
migration_group = parser.add_mutually_exclusive_group()
migration_group.add_argument(
@@ -1447,6 +1556,15 @@ class MigrateServer(command.Command):
)
return parser
+ def _log_warning_for_live(self, parsed_args):
+ if parsed_args.live:
+ # NOTE(mriedem): The --live option requires a host and if
+ # --os-compute-api-version is less than 2.30 it will forcefully
+ # bypass the scheduler which is dangerous.
+ self.log.warning(_(
+ 'The --live option has been deprecated. Please use the '
+ '--live-migration option instead.'))
+
def take_action(self, parsed_args):
def _show_progress(progress):
@@ -1460,20 +1578,52 @@ class MigrateServer(command.Command):
compute_client.servers,
parsed_args.server,
)
- if parsed_args.live:
+ # Check for live migration.
+ if parsed_args.live or parsed_args.live_migration:
+ # Always log a warning if --live is used.
+ self._log_warning_for_live(parsed_args)
kwargs = {
- 'host': parsed_args.live,
'block_migration': parsed_args.block_migration
}
+ # Prefer --live-migration over --live if both are specified.
+ if parsed_args.live_migration:
+ # Technically we could pass a non-None host with
+ # --os-compute-api-version < 2.30 but that is the same thing
+ # as the --live option bypassing the scheduler which we don't
+ # want to support, so if the user is using --live-migration
+ # and --host, we want to enforce that they are using version
+ # 2.30 or greater.
+ if (parsed_args.host and
+ compute_client.api_version <
+ api_versions.APIVersion('2.30')):
+ raise exceptions.CommandError(
+ '--os-compute-api-version 2.30 or greater is required '
+ 'when using --host')
+ # The host parameter is required in the API even if None.
+ kwargs['host'] = parsed_args.host
+ else:
+ kwargs['host'] = parsed_args.live
+
if compute_client.api_version < api_versions.APIVersion('2.25'):
kwargs['disk_over_commit'] = parsed_args.disk_overcommit
server.live_migrate(**kwargs)
else:
if parsed_args.block_migration or parsed_args.disk_overcommit:
- raise exceptions.CommandError("--live must be specified if "
- "--block-migration or "
- "--disk-overcommit is specified")
- server.migrate()
+ raise exceptions.CommandError(
+ "--live-migration must be specified if "
+ "--block-migration or --disk-overcommit is "
+ "specified")
+ if parsed_args.host:
+ if (compute_client.api_version <
+ api_versions.APIVersion('2.56')):
+ msg = _(
+ '--os-compute-api-version 2.56 or greater is '
+ 'required to use --host without --live-migration.'
+ )
+ raise exceptions.CommandError(msg)
+
+ kwargs = {'host': parsed_args.host} if parsed_args.host else {}
+ server.migrate(**kwargs)
if parsed_args.wait:
if utils.wait_for_status(
@@ -1601,6 +1751,12 @@ class RebuildServer(command.ShowOne):
'(repeat option to set multiple values)'),
)
parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_('New description for the server (supported by '
+ '--os-compute-api-version 2.19 or above'),
+ )
+ parser.add_argument(
'--wait',
action='store_true',
help=_('Wait for rebuild to complete'),
@@ -1644,6 +1800,12 @@ class RebuildServer(command.ShowOne):
kwargs = {}
if parsed_args.property:
kwargs['meta'] = parsed_args.property
+ if parsed_args.description:
+ if server.api_version < api_versions.APIVersion("2.19"):
+ msg = _("Description is not supported for "
+ "--os-compute-api-version less than 2.19")
+ raise exceptions.CommandError(msg)
+ kwargs['description'] = parsed_args.description
if parsed_args.key_name or parsed_args.key_unset:
if compute_client.api_version < api_versions.APIVersion('2.54'):
@@ -1835,7 +1997,11 @@ class RemoveServerSecurityGroup(command.Command):
class RemoveServerVolume(command.Command):
- _description = _("Remove volume from server")
+ _description = _(
+ "Remove volume from server. "
+ "Specify ``--os-compute-api-version 2.20`` or higher to remove a "
+ "volume from a server with status ``SHELVED`` or "
+ "``SHELVED_OFFLOADED``.")
def get_parser(self, prog_name):
parser = super(RemoveServerVolume, self).get_parser(prog_name)
@@ -2065,6 +2231,12 @@ class SetServer(command.Command):
choices=['active', 'error'],
help=_('New server state (valid value: active, error)'),
)
+ parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_('New server description (supported by '
+ '--os-compute-api-version 2.19 or above)'),
+ )
return parser
def take_action(self, parsed_args):
@@ -2096,6 +2268,13 @@ class SetServer(command.Command):
msg = _("Passwords do not match, password unchanged")
raise exceptions.CommandError(msg)
+ if parsed_args.description:
+ if server.api_version < api_versions.APIVersion("2.19"):
+ msg = _("Description is not supported for "
+ "--os-compute-api-version less than 2.19")
+ raise exceptions.CommandError(msg)
+ server.update(description=parsed_args.description)
+
class ShelveServer(command.Command):
_description = _("Shelve server(s)")
@@ -2455,6 +2634,13 @@ class UnsetServer(command.Command):
help=_('Property key to remove from server '
'(repeat option to remove multiple values)'),
)
+ parser.add_argument(
+ '--description',
+ dest='description',
+ action='store_true',
+ help=_('Unset server description (supported by '
+ '--os-compute-api-version 2.19 or above)'),
+ )
return parser
def take_action(self, parsed_args):
@@ -2470,6 +2656,16 @@ class UnsetServer(command.Command):
parsed_args.property,
)
+ if parsed_args.description:
+ if compute_client.api_version < api_versions.APIVersion("2.19"):
+ msg = _("Description is not supported for "
+ "--os-compute-api-version less than 2.19")
+ raise exceptions.CommandError(msg)
+ compute_client.servers.update(
+ server,
+ description="",
+ )
+
class UnshelveServer(command.Command):
_description = _("Unshelve server(s)")
diff --git a/openstackclient/compute/v2/server_event.py b/openstackclient/compute/v2/server_event.py
index c7d2e2e3..6d33d02d 100644
--- a/openstackclient/compute/v2/server_event.py
+++ b/openstackclient/compute/v2/server_event.py
@@ -28,7 +28,10 @@ LOG = logging.getLogger(__name__)
class ListServerEvent(command.Lister):
- _description = _("List recent events of a server")
+ _description = _(
+ "List recent events of a server. "
+ "Specify ``--os-compute-api-version 2.21`` "
+ "or higher to show events for a deleted server.")
def get_parser(self, prog_name):
parser = super(ListServerEvent, self).get_parser(prog_name)
@@ -92,8 +95,11 @@ class ListServerEvent(command.Lister):
class ShowServerEvent(command.ShowOne):
_description = _(
- "Show server event details. Specify ``--os-compute-api-version 2.51`` "
- "or higher to show events for non-admin users.")
+ "Show server event details. "
+ "Specify ``--os-compute-api-version 2.21`` "
+ "or higher to show event details for a deleted server. "
+ "Specify ``--os-compute-api-version 2.51`` "
+ "or higher to show event details for non-admin users.")
def get_parser(self, prog_name):
parser = super(ShowServerEvent, self).get_parser(prog_name)
diff --git a/openstackclient/identity/v2_0/project.py b/openstackclient/identity/v2_0/project.py
index 04d422ec..9bb5fc4d 100644
--- a/openstackclient/identity/v2_0/project.py
+++ b/openstackclient/identity/v2_0/project.py
@@ -289,7 +289,7 @@ class ShowProject(command.ShowOne):
# the API has and handle the extra top level properties.
reserved = ('name', 'id', 'enabled', 'description')
properties = {}
- for k, v in info.items():
+ for k, v in list(info.items()):
if k not in reserved:
# If a key is not in `reserved` it's a property, pop it
info.pop(k)
diff --git a/openstackclient/identity/v2_0/role.py b/openstackclient/identity/v2_0/role.py
index e254e05f..e9fe50fa 100644
--- a/openstackclient/identity/v2_0/role.py
+++ b/openstackclient/identity/v2_0/role.py
@@ -148,155 +148,11 @@ class DeleteRole(command.Command):
class ListRole(command.Lister):
_description = _("List roles")
- def get_parser(self, prog_name):
- parser = super(ListRole, self).get_parser(prog_name)
- parser.add_argument(
- '--project',
- metavar='<project>',
- help=_('Filter roles by <project> (name or ID)'),
- )
- parser.add_argument(
- '--user',
- metavar='<user>',
- help=_('Filter roles by <user> (name or ID)'),
- )
- return parser
-
def take_action(self, parsed_args):
-
- def _deprecated():
- # NOTE(henry-nash): Deprecated as of Newton, so we should remove
- # this in the 'P' release.
- self.log.warning(_('Listing assignments using role list is '
- 'deprecated as of the Newton release. Use role '
- 'assignment list --user <user-name> --project '
- '<project-name> --names instead.'))
-
identity_client = self.app.client_manager.identity
- auth_ref = self.app.client_manager.auth_ref
-
- # No user or project specified, list all roles in the system
- if not parsed_args.user and not parsed_args.project:
- columns = ('ID', 'Name')
- data = identity_client.roles.list()
- elif parsed_args.user and parsed_args.project:
- user = utils.find_resource(
- identity_client.users,
- parsed_args.user,
- )
- project = utils.find_resource(
- identity_client.projects,
- parsed_args.project,
- )
- _deprecated()
- data = identity_client.roles.roles_for_user(user.id, project.id)
-
- elif parsed_args.user:
- user = utils.find_resource(
- identity_client.users,
- parsed_args.user,
- )
- if self.app.client_manager.auth_ref:
- project = utils.find_resource(
- identity_client.projects,
- auth_ref.project_id
- )
- else:
- msg = _("Project must be specified")
- raise exceptions.CommandError(msg)
- _deprecated()
- data = identity_client.roles.roles_for_user(user.id, project.id)
- elif parsed_args.project:
- project = utils.find_resource(
- identity_client.projects,
- parsed_args.project,
- )
- if self.app.client_manager.auth_ref:
- user = utils.find_resource(
- identity_client.users,
- auth_ref.user_id
- )
- else:
- msg = _("User must be specified")
- raise exceptions.CommandError(msg)
- _deprecated()
- data = identity_client.roles.roles_for_user(user.id, project.id)
-
- if parsed_args.user or parsed_args.project:
- columns = ('ID', 'Name', 'Project', 'User')
- for user_role in data:
- user_role.user = user.name
- user_role.project = project.name
-
- return (columns,
- (utils.get_item_properties(
- s, columns,
- formatters={},
- ) for s in data))
-
-
-class ListUserRole(command.Lister):
- _description = _("List user-role assignments")
-
- def get_parser(self, prog_name):
- parser = super(ListUserRole, self).get_parser(prog_name)
- parser.add_argument(
- 'user',
- metavar='<user>',
- nargs='?',
- help=_('User to list (name or ID)'),
- )
- parser.add_argument(
- '--project',
- metavar='<project>',
- help=_('Filter users by <project> (name or ID)'),
- )
- return parser
-
- def take_action(self, parsed_args):
- identity_client = self.app.client_manager.identity
- auth_ref = self.app.client_manager.auth_ref
-
- # Project and user are required, if not included in command args
- # default to the values used for authentication. For token-flow
- # authentication they must be included on the command line.
- if (not parsed_args.project and
- self.app.client_manager.auth_ref.project_id):
- parsed_args.project = auth_ref.project_id
- if not parsed_args.project:
- msg = _("Project must be specified")
- raise exceptions.CommandError(msg)
-
- if (not parsed_args.user and
- self.app.client_manager.auth_ref.user_id):
- parsed_args.user = auth_ref.user_id
- if not parsed_args.user:
- msg = _("User must be specified")
- raise exceptions.CommandError(msg)
-
- self.log.warning(_('Listing assignments using user role list is '
- 'deprecated as of the Newton release. Use role '
- 'assignment list --user <user-name> --project '
- '<project-name> --names instead.'))
- project = utils.find_resource(
- identity_client.tenants,
- parsed_args.project,
- )
- user = utils.find_resource(identity_client.users, parsed_args.user)
-
- data = identity_client.roles.roles_for_user(user.id, project.id)
-
- columns = (
- 'ID',
- 'Name',
- 'Project',
- 'User',
- )
- # Add the names to the output even though they will be constant
- for role in data:
- role.user = user.name
- role.project = project.name
+ columns = ('ID', 'Name')
+ data = identity_client.roles.list()
return (columns,
(utils.get_item_properties(
diff --git a/openstackclient/identity/v2_0/service.py b/openstackclient/identity/v2_0/service.py
index 80f2d72a..653de8eb 100644
--- a/openstackclient/identity/v2_0/service.py
+++ b/openstackclient/identity/v2_0/service.py
@@ -15,7 +15,6 @@
"""Service action implementations"""
-import argparse
import logging
from osc_lib.command import command
@@ -36,17 +35,11 @@ class CreateService(command.ShowOne):
def get_parser(self, prog_name):
parser = super(CreateService, self).get_parser(prog_name)
parser.add_argument(
- 'type_or_name',
+ 'type',
metavar='<type>',
help=_('New service type (compute, image, identity, volume, etc)'),
)
- type_or_name_group = parser.add_mutually_exclusive_group()
- type_or_name_group.add_argument(
- '--type',
- metavar='<type>',
- help=argparse.SUPPRESS,
- )
- type_or_name_group.add_argument(
+ parser.add_argument(
'--name',
metavar='<name>',
help=_('New service name'),
@@ -61,29 +54,14 @@ class CreateService(command.ShowOne):
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- type_or_name = parsed_args.type_or_name
name = parsed_args.name
type = parsed_args.type
- # If only a single positional is present, it's a <type>.
- # This is not currently legal so it is considered a new case.
- if not type and not name:
- type = type_or_name
- # If --type option is present then positional is handled as <name>;
- # display deprecation message.
- elif type:
- name = type_or_name
- LOG.warning(_('The argument --type is deprecated, use service'
- ' create --name <service-name> type instead.'))
- # If --name option is present the positional is handled as <type>.
- # Making --type optional is new, but back-compatible
- elif name:
- type = type_or_name
-
service = identity_client.services.create(
name,
type,
- parsed_args.description)
+ parsed_args.description,
+ )
info = {}
info.update(service._info)
diff --git a/openstackclient/identity/v3/endpoint_group.py b/openstackclient/identity/v3/endpoint_group.py
index e254973b..66bd164d 100644
--- a/openstackclient/identity/v3/endpoint_group.py
+++ b/openstackclient/identity/v3/endpoint_group.py
@@ -204,11 +204,11 @@ class ListEndpointGroup(command.Lister):
if endpointgroup:
# List projects associated to the endpoint group
- columns = ('ID', 'Name')
+ columns = ('ID', 'Name', 'Description')
data = client.endpoint_filter.list_projects_for_endpoint_group(
endpoint_group=endpointgroup.id)
elif project:
- columns = ('ID', 'Name')
+ columns = ('ID', 'Name', 'Description')
data = client.endpoint_filter.list_endpoint_groups_for_project(
project=project.id)
else:
@@ -251,7 +251,7 @@ class RemoveProjectFromEndpointGroup(command.Command):
parsed_args.project,
parsed_args.project_domain)
- client.endpoint_filter.delete_endpoint_group_to_project(
+ client.endpoint_filter.delete_endpoint_group_from_project(
endpoint_group=endpointgroup.id,
project=project.id)
diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py
index 58a76f8a..0eeddd37 100644
--- a/openstackclient/identity/v3/role.py
+++ b/openstackclient/identity/v3/role.py
@@ -266,131 +266,28 @@ class ListRole(command.Lister):
def get_parser(self, prog_name):
parser = super(ListRole, self).get_parser(prog_name)
-
- # TODO(henry-nash): The use of the List Role command to list
- # assignments (as well as roles) has been deprecated. In order
- # to support domain specific roles, we are overriding the domain
- # option to allow specification of the domain for the role. This does
- # not conflict with any existing commands, since for the deprecated
- # assignments listing you were never allowed to only specify a domain
- # (you also needed to specify a user).
- #
- # Once we have removed the deprecated options entirely, we must
- # replace the call to _add_identity_and_resource_options_to_parser()
- # below with just adding the domain option into the parser.
- _add_identity_and_resource_options_to_parser(parser)
+ parser.add_argument(
+ '--domain',
+ metavar='<domain>',
+ help=_('Include <domain> (name or ID)'),
+ )
return parser
def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
- if parsed_args.user:
- user = common.find_user(
- identity_client,
- parsed_args.user,
- parsed_args.user_domain,
- )
- elif parsed_args.group:
- group = common.find_group(
- identity_client,
- parsed_args.group,
- parsed_args.group_domain,
- )
-
if parsed_args.domain:
domain = common.find_domain(
identity_client,
parsed_args.domain,
)
- elif parsed_args.project:
- project = common.find_project(
- identity_client,
- parsed_args.project,
- parsed_args.project_domain,
- )
-
- # no user or group specified, list all roles in the system
- if not parsed_args.user and not parsed_args.group:
- if not parsed_args.domain:
- columns = ('ID', 'Name')
- data = identity_client.roles.list()
- else:
- columns = ('ID', 'Name', 'Domain')
- data = identity_client.roles.list(domain_id=domain.id)
- for role in data:
- role.domain = domain.name
- elif parsed_args.user and parsed_args.domain:
- columns = ('ID', 'Name', 'Domain', 'User')
- data = identity_client.roles.list(
- user=user,
- domain=domain,
- os_inherit_extension_inherited=parsed_args.inherited
- )
- for user_role in data:
- user_role.user = user.name
- user_role.domain = domain.name
- self.log.warning(_('Listing assignments using role list is '
- 'deprecated. Use role assignment list --user '
- '<user-name> --domain <domain-name> --names '
- 'instead.'))
- elif parsed_args.user and parsed_args.project:
- columns = ('ID', 'Name', 'Project', 'User')
- data = identity_client.roles.list(
- user=user,
- project=project,
- os_inherit_extension_inherited=parsed_args.inherited
- )
- for user_role in data:
- user_role.user = user.name
- user_role.project = project.name
- self.log.warning(_('Listing assignments using role list is '
- 'deprecated. Use role assignment list --user '
- '<user-name> --project <project-name> --names '
- 'instead.'))
- elif parsed_args.user:
- columns = ('ID', 'Name')
- data = identity_client.roles.list(
- user=user,
- domain='default',
- os_inherit_extension_inherited=parsed_args.inherited
- )
- self.log.warning(_('Listing assignments using role list is '
- 'deprecated. Use role assignment list --user '
- '<user-name> --domain default --names '
- 'instead.'))
- elif parsed_args.group and parsed_args.domain:
- columns = ('ID', 'Name', 'Domain', 'Group')
- data = identity_client.roles.list(
- group=group,
- domain=domain,
- os_inherit_extension_inherited=parsed_args.inherited
- )
- for group_role in data:
- group_role.group = group.name
- group_role.domain = domain.name
- self.log.warning(_('Listing assignments using role list is '
- 'deprecated. Use role assignment list --group '
- '<group-name> --domain <domain-name> --names '
- 'instead.'))
- elif parsed_args.group and parsed_args.project:
- columns = ('ID', 'Name', 'Project', 'Group')
- data = identity_client.roles.list(
- group=group,
- project=project,
- os_inherit_extension_inherited=parsed_args.inherited
- )
- for group_role in data:
- group_role.group = group.name
- group_role.project = project.name
- self.log.warning(_('Listing assignments using role list is '
- 'deprecated. Use role assignment list --group '
- '<group-name> --project <project-name> --names '
- 'instead.'))
+ columns = ('ID', 'Name', 'Domain')
+ data = identity_client.roles.list(domain_id=domain.id)
+ for role in data:
+ role.domain = domain.name
else:
- msg = _("Error: If a user or group is specified, "
- "either --domain or --project must also be "
- "specified to list role grants.")
- raise exceptions.CommandError(msg)
+ columns = ('ID', 'Name')
+ data = identity_client.roles.list()
return (columns,
(utils.get_item_properties(
diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index 7ecaa3ef..caf3d54f 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -22,12 +22,12 @@ import os
import sys
from glanceclient.common import utils as gc_utils
+from osc_lib.api import utils as api_utils
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import utils
import six
-from openstackclient.api import utils as api_utils
from openstackclient.i18n import _
if os.name == "nt":
@@ -182,29 +182,16 @@ class CreateImage(command.ShowOne):
help=_("Set a property on this image "
"(repeat option to set multiple properties)"),
)
- # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
- # 2.x release. Do not remove before Jan 2017
- # and a 3.x release.
- project_group = parser.add_mutually_exclusive_group()
- project_group.add_argument(
+ parser.add_argument(
"--project",
metavar="<project>",
help=_("Set an alternate project on this image (name or ID)"),
)
- project_group.add_argument(
- "--owner",
- metavar="<project>",
- help=argparse.SUPPRESS,
- )
return parser
def take_action(self, parsed_args):
image_client = self.app.client_manager.image
- if getattr(parsed_args, 'owner', None) is not None:
- LOG.warning(_('The --owner option is deprecated, '
- 'please use --project instead.'))
-
# Build an attribute dict from the parsed args, only include
# attributes that were actually set on the command line
kwargs = {}
@@ -599,29 +586,16 @@ class SetImage(command.Command):
metavar="<checksum>",
help=_("Image hash used for verification"),
)
- # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
- # 2.x release. Do not remove before Jan 2017
- # and a 3.x release.
- project_group = parser.add_mutually_exclusive_group()
- project_group.add_argument(
+ parser.add_argument(
"--project",
metavar="<project>",
help=_("Set an alternate project on this image (name or ID)"),
)
- project_group.add_argument(
- "--owner",
- metavar="<project>",
- help=argparse.SUPPRESS,
- )
return parser
def take_action(self, parsed_args):
image_client = self.app.client_manager.image
- if getattr(parsed_args, 'owner', None) is not None:
- LOG.warning(_('The --owner option is deprecated, '
- 'please use --project instead.'))
-
kwargs = {}
copy_attrs = ('name', 'owner', 'min_disk', 'min_ram', 'properties',
'container_format', 'disk_format', 'size', 'store',
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index 3efde808..97169a92 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -21,13 +21,13 @@ import logging
from glanceclient.common import utils as gc_utils
from openstack.image import image_signer
+from osc_lib.api import utils as api_utils
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
-from openstackclient.api import utils as api_utils
from openstackclient.i18n import _
from openstackclient.identity import common
@@ -250,20 +250,11 @@ class CreateImage(command.ShowOne):
help=_("Set a tag on this image "
"(repeat option to set multiple tags)"),
)
- # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
- # 2.x release. Do not remove before Jan 2017
- # and a 3.x release.
- project_group = parser.add_mutually_exclusive_group()
- project_group.add_argument(
+ parser.add_argument(
"--project",
metavar="<project>",
help=_("Set an alternate project on this image (name or ID)"),
)
- project_group.add_argument(
- "--owner",
- metavar="<project>",
- help=argparse.SUPPRESS,
- )
common.add_project_domain_option_to_parser(parser)
for deadopt in self.deadopts:
parser.add_argument(
@@ -321,16 +312,10 @@ class CreateImage(command.ShowOne):
kwargs['visibility'] = 'community'
if parsed_args.shared:
kwargs['visibility'] = 'shared'
- # Handle deprecated --owner option
- project_arg = parsed_args.project
- if parsed_args.owner:
- project_arg = parsed_args.owner
- LOG.warning(_('The --owner option is deprecated, '
- 'please use --project instead.'))
- if project_arg:
+ if parsed_args.project:
kwargs['owner'] = common.find_project(
identity_client,
- project_arg,
+ parsed_args.project,
parsed_args.project_domain,
).id
@@ -347,13 +332,6 @@ class CreateImage(command.ShowOne):
LOG.warning(_("Failed to get an image file."))
return {}, {}
- if parsed_args.owner:
- kwargs['owner'] = common.find_project(
- identity_client,
- parsed_args.owner,
- parsed_args.project_domain,
- ).id
-
# sign an image using a given local private key file
if parsed_args.sign_key_path or parsed_args.sign_cert_id:
if not parsed_args.file:
@@ -933,20 +911,11 @@ class SetImage(command.Command):
action="store_true",
help=_("Activate the image"),
)
- # NOTE(dtroyer): --owner is deprecated in Jan 2016 in an early
- # 2.x release. Do not remove before Jan 2017
- # and a 3.x release.
- project_group = parser.add_mutually_exclusive_group()
- project_group.add_argument(
+ parser.add_argument(
"--project",
metavar="<project>",
help=_("Set an alternate project on this image (name or ID)"),
)
- project_group.add_argument(
- "--owner",
- metavar="<project>",
- help=argparse.SUPPRESS,
- )
common.add_project_domain_option_to_parser(parser)
for deadopt in self.deadopts:
parser.add_argument(
@@ -1020,17 +989,11 @@ class SetImage(command.Command):
kwargs['visibility'] = 'community'
if parsed_args.shared:
kwargs['visibility'] = 'shared'
- # Handle deprecated --owner option
- project_arg = parsed_args.project
- if parsed_args.owner:
- project_arg = parsed_args.owner
- LOG.warning(_('The --owner option is deprecated, '
- 'please use --project instead.'))
project_id = None
- if project_arg:
+ if parsed_args.project:
project_id = common.find_project(
identity_client,
- project_arg,
+ parsed_args.project,
parsed_args.project_domain,
).id
kwargs['owner'] = project_id
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
index 6094dfc4..d42fbb68 100644
--- a/openstackclient/network/v2/port.py
+++ b/openstackclient/network/v2/port.py
@@ -99,21 +99,6 @@ class JSONKeyValueAction(argparse.Action):
def _get_attrs(client_manager, parsed_args):
attrs = {}
- # Handle deprecated options
- # NOTE(dtroyer): --device-id and --host-id were deprecated in Mar 2016.
- # Do not remove before 3.x release or Mar 2017.
- if parsed_args.device_id:
- attrs['device_id'] = parsed_args.device_id
- LOG.warning(_(
- 'The --device-id option is deprecated, '
- 'please use --device instead.'
- ))
- if parsed_args.host_id:
- attrs['binding:host_id'] = parsed_args.host_id
- LOG.warning(_(
- 'The --host-id option is deprecated, '
- 'please use --host instead.'
- ))
if parsed_args.description is not None:
attrs['description'] = parsed_args.description
if parsed_args.device:
@@ -238,19 +223,11 @@ def _add_updatable_args(parser):
metavar='<description>',
help=_("Description of this port")
)
- # NOTE(dtroyer): --device-id is deprecated in Mar 2016. Do not
- # remove before 3.x release or Mar 2017.
- device_group = parser.add_mutually_exclusive_group()
- device_group.add_argument(
+ parser.add_argument(
'--device',
metavar='<device-id>',
help=_("Port device ID")
)
- device_group.add_argument(
- '--device-id',
- metavar='<device-id>',
- help=argparse.SUPPRESS,
- )
parser.add_argument(
'--mac-address',
metavar='<mac-address>',
@@ -271,19 +248,11 @@ def _add_updatable_args(parser):
"macvtap | normal | baremetal | virtio-forwarder, "
"default: normal)")
)
- # NOTE(dtroyer): --host-id is deprecated in Mar 2016. Do not
- # remove before 3.x release or Mar 2017.
- host_group = parser.add_mutually_exclusive_group()
- host_group.add_argument(
+ parser.add_argument(
'--host',
metavar='<host-id>',
help=_("Allocate port on host <host-id> (ID only)")
)
- host_group.add_argument(
- '--host-id',
- metavar='<host-id>',
- help=argparse.SUPPRESS,
- )
parser.add_argument(
'--dns-domain',
metavar='dns-domain',
diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py
index fd6a24fd..11b012e6 100644
--- a/openstackclient/network/v2/router.py
+++ b/openstackclient/network/v2/router.py
@@ -13,7 +13,6 @@
"""Router action implementations"""
-import argparse
import copy
import json
import logging
@@ -533,8 +532,6 @@ class SetRouter(command.Command):
action='store_true',
help=_("Set router to centralized mode (disabled router only)")
)
- routes_group = parser.add_mutually_exclusive_group()
- # ToDo(Reedip):Remove mutual exclusiveness once clear-routes is removed
parser.add_argument(
'--route',
metavar='destination=<subnet>,gateway=<ip-address>',
@@ -547,18 +544,13 @@ class SetRouter(command.Command):
"gateway: nexthop IP address "
"(repeat option to set multiple routes)")
)
- routes_group.add_argument(
+ parser.add_argument(
'--no-route',
action='store_true',
help=_("Clear routes associated with the router. "
"Specify both --route and --no-route to overwrite "
"current value of route.")
)
- routes_group.add_argument(
- '--clear-routes',
- action='store_true',
- help=argparse.SUPPRESS,
- )
routes_ha = parser.add_mutually_exclusive_group()
routes_ha.add_argument(
'--ha',
@@ -624,21 +616,16 @@ class SetRouter(command.Command):
attrs['ha'] = True
elif parsed_args.no_ha:
attrs['ha'] = False
- if parsed_args.clear_routes:
- LOG.warning(_(
- 'The --clear-routes option is deprecated, '
- 'please use --no-route instead.'
- ))
if parsed_args.routes is not None:
for route in parsed_args.routes:
route['nexthop'] = route.pop('gateway')
attrs['routes'] = parsed_args.routes
- if not (parsed_args.no_route or parsed_args.clear_routes):
+ if not parsed_args.no_route:
# Map the route keys and append to the current routes.
# The REST API will handle route validation and duplicates.
attrs['routes'] += obj.routes
- elif parsed_args.no_route or parsed_args.clear_routes:
+ elif parsed_args.no_route:
attrs['routes'] = []
if (parsed_args.disable_snat or parsed_args.enable_snat or
parsed_args.fixed_ip) and not parsed_args.external_gateway:
diff --git a/openstackclient/network/v2/security_group_rule.py b/openstackclient/network/v2/security_group_rule.py
index 961125a9..df19af20 100644
--- a/openstackclient/network/v2/security_group_rule.py
+++ b/openstackclient/network/v2/security_group_rule.py
@@ -115,19 +115,6 @@ class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
metavar="<group>",
help=_("Remote security group (name or ID)"),
)
- # Handle deprecated options
- # NOTE(dtroyer): --src-ip and --src-group were deprecated in Nov 2016.
- # Do not remove before 4.x release or Nov 2017.
- remote_group.add_argument(
- "--src-ip",
- metavar="<ip-address>",
- help=argparse.SUPPRESS,
- )
- remote_group.add_argument(
- "--src-group",
- metavar="<group>",
- help=argparse.SUPPRESS,
- )
return parser
def update_parser_network(self, parser):
@@ -310,31 +297,13 @@ class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
if parsed_args.icmp_code is not None and parsed_args.icmp_code >= 0:
attrs['port_range_max'] = parsed_args.icmp_code
- # NOTE(dtroyer): --src-ip and --src-group were deprecated in Nov 2016.
- # Do not remove before 4.x release or Nov 2017.
- if not (parsed_args.remote_group is None and
- parsed_args.src_group is None):
+ if parsed_args.remote_group is not None:
attrs['remote_group_id'] = client.find_security_group(
- parsed_args.remote_group or parsed_args.src_group,
+ parsed_args.remote_group,
ignore_missing=False
).id
- if parsed_args.src_group:
- LOG.warning(
- _("The %(old)s option is deprecated, "
- "please use %(new)s instead."),
- {'old': '--src-group', 'new': '--remote-group'},
- )
- elif not (parsed_args.remote_ip is None and
- parsed_args.src_ip is None):
- attrs['remote_ip_prefix'] = (
- parsed_args.remote_ip or parsed_args.src_ip
- )
- if parsed_args.src_ip:
- LOG.warning(
- _("The %(old)s option is deprecated, "
- "please use %(new)s instead."),
- {'old': '--src-ip', 'new': '--remote-ip'},
- )
+ elif parsed_args.remote_ip is not None:
+ attrs['remote_ip_prefix'] = parsed_args.remote_ip
elif attrs['ethertype'] == 'IPv4':
attrs['remote_ip_prefix'] = '0.0.0.0/0'
attrs['security_group_id'] = security_group_id
@@ -361,29 +330,13 @@ class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
else:
from_port, to_port = parsed_args.dst_port
- # NOTE(dtroyer): --src-ip and --src-group were deprecated in Nov 2016.
- # Do not remove before 4.x release or Nov 2017.
remote_ip = None
- if not (parsed_args.remote_group is None and
- parsed_args.src_group is None):
+ if parsed_args.remote_group is not None:
parsed_args.remote_group = client.api.security_group_find(
- parsed_args.remote_group or parsed_args.src_group,
+ parsed_args.remote_group,
)['id']
- if parsed_args.src_group:
- LOG.warning(
- _("The %(old)s option is deprecated, "
- "please use %(new)s instead."),
- {'old': '--src-group', 'new': '--remote-group'},
- )
- if not (parsed_args.remote_ip is None and
- parsed_args.src_ip is None):
- remote_ip = parsed_args.remote_ip or parsed_args.src_ip
- if parsed_args.src_ip:
- LOG.warning(
- _("The %(old)s option is deprecated, "
- "please use %(new)s instead."),
- {'old': '--src-ip', 'new': '--remote-ip'},
- )
+ if parsed_args.remote_ip is not None:
+ remote_ip = parsed_args.remote_ip
else:
remote_ip = '0.0.0.0/0'
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index 58a77120..22d8412c 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -20,13 +20,13 @@ import locale
import sys
from osc_lib.api import auth
+from osc_lib.command import commandmanager
from osc_lib import shell
import six
import openstackclient
from openstackclient.common import client_config as cloud_config
from openstackclient.common import clientmanager
-from openstackclient.common import commandmanager
DEFAULT_DOMAIN = 'default'
diff --git a/openstackclient/tests/functional/compute/v2/test_aggregate.py b/openstackclient/tests/functional/compute/v2/test_aggregate.py
index 71026757..c591dd61 100644
--- a/openstackclient/tests/functional/compute/v2/test_aggregate.py
+++ b/openstackclient/tests/functional/compute/v2/test_aggregate.py
@@ -11,7 +11,6 @@
# under the License.
import json
-import time
import uuid
from openstackclient.tests.functional import base
@@ -20,12 +19,13 @@ from openstackclient.tests.functional import base
class AggregateTests(base.TestCase):
"""Functional tests for aggregate"""
- def test_aggregate_create_and_delete(self):
+ def test_aggregate_crud(self):
"""Test create, delete multiple"""
name1 = uuid.uuid4().hex
cmd_output = json.loads(self.openstack(
'aggregate create -f json ' +
'--zone nova ' +
+ '--property a=b ' +
name1
))
self.assertEqual(
@@ -36,11 +36,17 @@ class AggregateTests(base.TestCase):
'nova',
cmd_output['availability_zone']
)
+ # TODO(dtroyer): enable the following once the properties field
+ # is correctly formatted in the create output
+ # self.assertIn(
+ # "a='b'",
+ # cmd_output['properties']
+ # )
name2 = uuid.uuid4().hex
cmd_output = json.loads(self.openstack(
'aggregate create -f json ' +
- '--zone nova ' +
+ '--zone external ' +
name2
))
self.assertEqual(
@@ -48,101 +54,15 @@ class AggregateTests(base.TestCase):
cmd_output['name']
)
self.assertEqual(
- 'nova',
+ 'external',
cmd_output['availability_zone']
)
- # Loop a few times since this is timing-sensitive
- # Just hard-code it for now, since there is no pause and it is
- # racy we shouldn't have to wait too long, a minute seems reasonable
- wait_time = 0
- while wait_time < 60:
- cmd_output = json.loads(self.openstack(
- 'aggregate show -f json ' +
- name2
- ))
- if cmd_output['name'] != name2:
- # Hang out for a bit and try again
- print('retrying aggregate check')
- wait_time += 10
- time.sleep(10)
- else:
- break
-
- del_output = self.openstack(
- 'aggregate delete ' +
- name1 + ' ' +
- name2
- )
- self.assertOutput('', del_output)
-
- def test_aggregate_list(self):
- """Test aggregate list"""
- name1 = uuid.uuid4().hex
- self.openstack(
- 'aggregate create ' +
- '--zone nova ' +
- '--property a=b ' +
- name1
- )
- self.addCleanup(
- self.openstack,
- 'aggregate delete ' + name1,
- fail_ok=True,
- )
-
- name2 = uuid.uuid4().hex
- self.openstack(
- 'aggregate create ' +
- '--zone internal ' +
- '--property c=d ' +
- name2
- )
- self.addCleanup(
- self.openstack,
- 'aggregate delete ' + name2,
- fail_ok=True,
- )
-
- cmd_output = json.loads(self.openstack(
- 'aggregate list -f json'
- ))
- names = [x['Name'] for x in cmd_output]
- self.assertIn(name1, names)
- self.assertIn(name2, names)
- zones = [x['Availability Zone'] for x in cmd_output]
- self.assertIn('nova', zones)
- self.assertIn('internal', zones)
-
- # Test aggregate list --long
- cmd_output = json.loads(self.openstack(
- 'aggregate list --long -f json'
- ))
- names = [x['Name'] for x in cmd_output]
- self.assertIn(name1, names)
- self.assertIn(name2, names)
- zones = [x['Availability Zone'] for x in cmd_output]
- self.assertIn('nova', zones)
- self.assertIn('internal', zones)
- properties = [x['Properties'] for x in cmd_output]
- self.assertIn({'a': 'b'}, properties)
- self.assertIn({'c': 'd'}, properties)
-
- def test_aggregate_set_and_unset(self):
- """Test aggregate set, show and unset"""
- name1 = uuid.uuid4().hex
- name2 = uuid.uuid4().hex
- self.openstack(
- 'aggregate create ' +
- '--zone nova ' +
- '--property a=b ' +
- name1
- )
- self.addCleanup(self.openstack, 'aggregate delete ' + name2)
-
+ # Test aggregate set
+ name3 = uuid.uuid4().hex
raw_output = self.openstack(
'aggregate set ' +
- '--name ' + name2 + ' ' +
+ '--name ' + name3 + ' ' +
'--zone internal ' +
'--no-property ' +
'--property c=d ' +
@@ -152,10 +72,10 @@ class AggregateTests(base.TestCase):
cmd_output = json.loads(self.openstack(
'aggregate show -f json ' +
- name2
+ name3
))
self.assertEqual(
- name2,
+ name3,
cmd_output['name']
)
self.assertEqual(
@@ -171,23 +91,56 @@ class AggregateTests(base.TestCase):
cmd_output['properties']
)
+ # Test aggregate list
+ cmd_output = json.loads(self.openstack(
+ 'aggregate list -f json'
+ ))
+ names = [x['Name'] for x in cmd_output]
+ self.assertIn(name3, names)
+ self.assertIn(name2, names)
+ zones = [x['Availability Zone'] for x in cmd_output]
+ self.assertIn('external', zones)
+ self.assertIn('internal', zones)
+
+ # Test aggregate list --long
+ cmd_output = json.loads(self.openstack(
+ 'aggregate list --long -f json'
+ ))
+ names = [x['Name'] for x in cmd_output]
+ self.assertIn(name3, names)
+ self.assertIn(name2, names)
+ zones = [x['Availability Zone'] for x in cmd_output]
+ self.assertIn('external', zones)
+ self.assertIn('internal', zones)
+ properties = [x['Properties'] for x in cmd_output]
+ self.assertNotIn({'a': 'b'}, properties)
+ self.assertIn({'c': 'd'}, properties)
+
# Test unset
raw_output = self.openstack(
'aggregate unset ' +
'--property c ' +
- name2
+ name3
)
self.assertOutput('', raw_output)
cmd_output = json.loads(self.openstack(
'aggregate show -f json ' +
- name2
+ name3
))
self.assertNotIn(
"c='d'",
cmd_output['properties']
)
+ # test aggregate delete
+ del_output = self.openstack(
+ 'aggregate delete ' +
+ name3 + ' ' +
+ name2
+ )
+ self.assertOutput('', del_output)
+
def test_aggregate_add_and_remove_host(self):
"""Test aggregate add and remove host"""
# Get a host
diff --git a/openstackclient/tests/functional/compute/v2/test_server.py b/openstackclient/tests/functional/compute/v2/test_server.py
index c8fb44d3..e52a42d3 100644
--- a/openstackclient/tests/functional/compute/v2/test_server.py
+++ b/openstackclient/tests/functional/compute/v2/test_server.py
@@ -63,6 +63,84 @@ class ServerTests(common.ComputeTestCase):
self.assertNotIn(name1, col_name)
self.assertIn(name2, col_name)
+ def test_server_list_with_changes_before(self):
+ """Test server list.
+
+ Getting the servers list with updated_at time equal or
+ before than changes-before.
+ """
+ cmd_output = self.server_create()
+ server_name1 = cmd_output['name']
+
+ cmd_output = self.server_create()
+ server_name2 = cmd_output['name']
+ updated_at2 = cmd_output['updated']
+
+ cmd_output = self.server_create()
+ server_name3 = cmd_output['name']
+
+ cmd_output = json.loads(self.openstack(
+ '--os-compute-api-version 2.66 ' +
+ 'server list -f json '
+ '--changes-before ' + updated_at2
+ ))
+
+ col_updated = [server["Name"] for server in cmd_output]
+ self.assertIn(server_name1, col_updated)
+ self.assertIn(server_name2, col_updated)
+ self.assertNotIn(server_name3, col_updated)
+
+ def test_server_list_with_changes_since(self):
+ """Test server list.
+
+ Getting the servers list with updated_at time equal or
+ later than changes-since.
+ """
+ cmd_output = self.server_create()
+ server_name1 = cmd_output['name']
+ cmd_output = self.server_create()
+ server_name2 = cmd_output['name']
+ updated_at2 = cmd_output['updated']
+ cmd_output = self.server_create()
+ server_name3 = cmd_output['name']
+
+ cmd_output = json.loads(self.openstack(
+ 'server list -f json '
+ '--changes-since ' + updated_at2
+ ))
+
+ col_updated = [server["Name"] for server in cmd_output]
+ self.assertNotIn(server_name1, col_updated)
+ self.assertIn(server_name2, col_updated)
+ self.assertIn(server_name3, col_updated)
+
+ def test_server_list_with_changes_before_and_changes_since(self):
+ """Test server list.
+
+ Getting the servers list with updated_at time equal or before than
+ changes-before and equal or later than changes-since.
+ """
+ cmd_output = self.server_create()
+ server_name1 = cmd_output['name']
+ cmd_output = self.server_create()
+ server_name2 = cmd_output['name']
+ updated_at2 = cmd_output['updated']
+ cmd_output = self.server_create()
+ server_name3 = cmd_output['name']
+ updated_at3 = cmd_output['updated']
+
+ cmd_output = json.loads(self.openstack(
+ '--os-compute-api-version 2.66 ' +
+ 'server list -f json ' +
+ '--changes-since ' + updated_at2 +
+ ' --changes-before ' + updated_at3
+ ))
+
+ col_updated = [server["Name"] for server in cmd_output]
+ self.assertNotIn(server_name1, col_updated)
+ self.assertIn(server_name2, col_updated)
+ self.assertIn(server_name3, col_updated)
+
def test_server_set(self):
"""Test server create, delete, set, show"""
cmd_output = self.server_create()
@@ -407,7 +485,7 @@ class ServerTests(common.ComputeTestCase):
cmd_output['status'],
)
- # NOTE(dtroyer): Prior to https://review.openstack.org/#/c/407111
+ # NOTE(dtroyer): Prior to https://review.opendev.org/#/c/407111
# --block-device-mapping was ignored if --volume
# present on the command line. Now we should see the
# attachment.
diff --git a/openstackclient/tests/functional/identity/v2/test_role.py b/openstackclient/tests/functional/identity/v2/test_role.py
index 82e19aab..124603d8 100644
--- a/openstackclient/tests/functional/identity/v2/test_role.py
+++ b/openstackclient/tests/functional/identity/v2/test_role.py
@@ -29,38 +29,6 @@ class RoleTests(common.IdentityTests):
items = self.parse_listing(raw_output)
self.assert_table_structure(items, common.BASIC_LIST_HEADERS)
- def test_role_list_with_user_project(self):
- project_name = self._create_dummy_project()
- role_name = self._create_dummy_role()
- username = self._create_dummy_user()
- raw_output = self.openstack(
- 'role add '
- '--project %(project)s '
- '--user %(user)s '
- '%(role)s' % {'project': project_name,
- 'user': username,
- 'role': role_name})
- self.addCleanup(
- self.openstack,
- 'role remove '
- '--project %(project)s '
- '--user %(user)s '
- '%(role)s' % {'project': project_name,
- 'user': username,
- 'role': role_name})
- items = self.parse_show(raw_output)
- self.assert_show_fields(items, self.ROLE_FIELDS)
-
- raw_output = self.openstack(
- 'role list '
- '--project %(project)s '
- '--user %(user)s '
- '' % {'project': project_name,
- 'user': username})
- items = self.parse_listing(raw_output)
- self.assert_table_structure(items, common.BASIC_LIST_HEADERS)
- self.assertEqual(1, len(items))
-
def test_role_show(self):
role_name = self._create_dummy_role()
raw_output = self.openstack('role show %s' % role_name)
diff --git a/openstackclient/tests/functional/identity/v3/test_role.py b/openstackclient/tests/functional/identity/v3/test_role.py
index fb9e0614..38bfff71 100644
--- a/openstackclient/tests/functional/identity/v3/test_role.py
+++ b/openstackclient/tests/functional/identity/v3/test_role.py
@@ -31,47 +31,6 @@ class RoleTests(common.IdentityTests):
items = self.parse_listing(raw_output)
self.assert_table_structure(items, common.BASIC_LIST_HEADERS)
- def test_role_list_with_user_project(self):
- role_name = self._create_dummy_role()
- username = self._create_dummy_user()
- raw_output = self.openstack(
- 'role add '
- '--project %(project)s '
- '--project-domain %(project_domain)s '
- '--user %(user)s '
- '--user-domain %(user_domain)s '
- '%(role)s' % {'project': self.project_name,
- 'project_domain': self.domain_name,
- 'user': username,
- 'user_domain': self.domain_name,
- 'role': role_name})
- self.addCleanup(
- self.openstack,
- 'role remove '
- '--project %(project)s '
- '--project-domain %(project_domain)s '
- '--user %(user)s '
- '--user-domain %(user_domain)s '
- '%(role)s' % {'project': self.project_name,
- 'project_domain': self.domain_name,
- 'user': username,
- 'user_domain': self.domain_name,
- 'role': role_name})
- self.assertEqual(0, len(raw_output))
- raw_output = self.openstack(
- 'role list '
- '--project %(project)s '
- '--project-domain %(project_domain)s '
- '--user %(user)s '
- '--user-domain %(user_domain)s '
- '' % {'project': self.project_name,
- 'project_domain': self.domain_name,
- 'user': username,
- 'user_domain': self.domain_name})
- items = self.parse_listing(raw_output)
- self.assert_table_structure(items, common.BASIC_LIST_HEADERS)
- self.assertEqual(1, len(items))
-
def test_role_show(self):
role_name = self._create_dummy_role()
raw_output = self.openstack('role show %s' % role_name)
diff --git a/openstackclient/tests/functional/network/v2/test_floating_ip.py b/openstackclient/tests/functional/network/v2/test_floating_ip.py
index 1d11fc5d..f189c2da 100644
--- a/openstackclient/tests/functional/network/v2/test_floating_ip.py
+++ b/openstackclient/tests/functional/network/v2/test_floating_ip.py
@@ -83,7 +83,7 @@ class FloatingIpTests(common.NetworkTests):
raise
pass
else:
- # break and no longer retry if create sucessfully
+ # break and no longer retry if create successfully
break
@classmethod
diff --git a/openstackclient/tests/functional/network/v2/test_subnet_pool.py b/openstackclient/tests/functional/network/v2/test_subnet_pool.py
index dad97f84..dbcf01e2 100644
--- a/openstackclient/tests/functional/network/v2/test_subnet_pool.py
+++ b/openstackclient/tests/functional/network/v2/test_subnet_pool.py
@@ -266,7 +266,7 @@ class SubnetPoolTests(common.NetworkTagTests):
# pool. The error appears to be in a lower layer,
# once that is fixed add a test for subnet pool unset
# --default-quota.
- # The unset command of --pool-prefixes also doesnt work
+ # The unset command of --pool-prefixes also doesn't work
# right now. It would be fixed in a separate patch once
# the lower layer is fixed.
# cmd_output = self.openstack(
@@ -319,7 +319,7 @@ class SubnetPoolTests(common.NetworkTagTests):
raise
pass
else:
- # Break and no longer retry if create is sucessful
+ # Break and no longer retry if create is successful
break
return cmd_output, pool_prefix
diff --git a/openstackclient/tests/functional/volume/v2/test_backup.py b/openstackclient/tests/functional/volume/v2/test_volume_backup.py
index 8f5c032c..6868bd40 100644
--- a/openstackclient/tests/functional/volume/v2/test_backup.py
+++ b/openstackclient/tests/functional/volume/v2/test_volume_backup.py
@@ -46,14 +46,14 @@ class VolumeBackupTests(common.BaseVolumeTests):
'volume backup create -f json ' +
vol_id
))
- self.wait_for_status("backup", backup['id'], "available")
+ self.wait_for_status("volume backup", backup['id'], "available")
# restore the backup
backup_restored = json.loads(self.openstack(
'volume backup restore -f json %s %s'
% (backup['id'], vol_id)))
self.assertEqual(backup_restored['backup_id'], backup['id'])
- self.wait_for_status("backup", backup['id'], "available")
+ self.wait_for_status("volume backup", backup['id'], "available")
self.wait_for_status("volume", backup_restored['volume_id'],
"available")
self.addCleanup(self.openstack, 'volume delete %s' % vol_id)
diff --git a/openstackclient/tests/functional/volume/v2/test_snapshot.py b/openstackclient/tests/functional/volume/v2/test_volume_snapshot.py
index 264f4adb..264f4adb 100644
--- a/openstackclient/tests/functional/volume/v2/test_snapshot.py
+++ b/openstackclient/tests/functional/volume/v2/test_volume_snapshot.py
diff --git a/openstackclient/tests/functional/volume/v3/test_snapshot.py b/openstackclient/tests/functional/volume/v3/test_volume_snapshot.py
index 38e0563a..28eee6d2 100644
--- a/openstackclient/tests/functional/volume/v3/test_snapshot.py
+++ b/openstackclient/tests/functional/volume/v3/test_volume_snapshot.py
@@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from openstackclient.tests.functional.volume.v2 import test_snapshot as v2
+from openstackclient.tests.functional.volume.v2 import test_volume_snapshot as v2 # noqa
from openstackclient.tests.functional.volume.v3 import common
diff --git a/openstackclient/tests/unit/api/test_object_store_v1.py b/openstackclient/tests/unit/api/test_object_store_v1.py
index acf95550..74b62493 100644
--- a/openstackclient/tests/unit/api/test_object_store_v1.py
+++ b/openstackclient/tests/unit/api/test_object_store_v1.py
@@ -184,7 +184,7 @@ class TestObject(TestObjectAPIv1):
}
# TODO(dtroyer): When requests_mock gains the ability to
# match against request.body add this check
- # https://review.openstack.org/127316
+ # https://review.opendev.org/127316
self.requests_mock.register_uri(
'PUT',
FAKE_URL + '/qaz/counter.txt',
diff --git a/openstackclient/tests/unit/api/test_utils.py b/openstackclient/tests/unit/api/test_utils.py
deleted file mode 100644
index 1f528558..00000000
--- a/openstackclient/tests/unit/api/test_utils.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-"""API Utilities Library Tests"""
-
-import copy
-
-from openstackclient.api import api
-from openstackclient.api import utils as api_utils
-from openstackclient.tests.unit.api import fakes as api_fakes
-
-
-class TestBaseAPIFilter(api_fakes.TestSession):
- """The filters can be tested independently"""
-
- def setUp(self):
- super(TestBaseAPIFilter, self).setUp()
- self.api = api.BaseAPI(
- session=self.sess,
- endpoint=self.BASE_URL,
- )
-
- self.input_list = [
- api_fakes.RESP_ITEM_1,
- api_fakes.RESP_ITEM_2,
- api_fakes.RESP_ITEM_3,
- ]
-
- def test_simple_filter_none(self):
- output = api_utils.simple_filter(
- )
- self.assertIsNone(output)
-
- def test_simple_filter_no_attr(self):
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- )
- self.assertEqual(self.input_list, output)
-
- def test_simple_filter_attr_only(self):
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='status',
- )
- self.assertEqual(self.input_list, output)
-
- def test_simple_filter_attr_value(self):
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='status',
- value='',
- )
- self.assertEqual([], output)
-
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='status',
- value='UP',
- )
- self.assertEqual(
- [api_fakes.RESP_ITEM_1, api_fakes.RESP_ITEM_3],
- output,
- )
-
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='fred',
- value='UP',
- )
- self.assertEqual([], output)
-
- def test_simple_filter_prop_attr_only(self):
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='b',
- property_field='props',
- )
- self.assertEqual(self.input_list, output)
-
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='status',
- property_field='props',
- )
- self.assertEqual(self.input_list, output)
-
- def test_simple_filter_prop_attr_value(self):
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='b',
- value=2,
- property_field='props',
- )
- self.assertEqual(
- [api_fakes.RESP_ITEM_1, api_fakes.RESP_ITEM_2],
- output,
- )
-
- output = api_utils.simple_filter(
- copy.deepcopy(self.input_list),
- attr='b',
- value=9,
- property_field='props',
- )
- self.assertEqual([], output)
diff --git a/openstackclient/tests/unit/common/test_commandmanager.py b/openstackclient/tests/unit/common/test_commandmanager.py
deleted file mode 100644
index 0c6c99c0..00000000
--- a/openstackclient/tests/unit/common/test_commandmanager.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright 2012-2013 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-import mock
-
-from openstackclient.common import commandmanager
-from openstackclient.tests.unit import utils
-
-
-class FakeCommand(object):
-
- @classmethod
- def load(cls):
- return cls
-
- def __init__(self):
- return
-
-FAKE_CMD_ONE = FakeCommand
-FAKE_CMD_TWO = FakeCommand
-FAKE_CMD_ALPHA = FakeCommand
-FAKE_CMD_BETA = FakeCommand
-
-
-class FakeCommandManager(commandmanager.CommandManager):
- commands = {}
-
- def load_commands(self, namespace):
- if namespace == 'test':
- self.commands['one'] = FAKE_CMD_ONE
- self.commands['two'] = FAKE_CMD_TWO
- self.group_list.append(namespace)
- elif namespace == 'greek':
- self.commands['alpha'] = FAKE_CMD_ALPHA
- self.commands['beta'] = FAKE_CMD_BETA
- self.group_list.append(namespace)
-
-
-class TestCommandManager(utils.TestCase):
-
- def test_add_command_group(self):
- mgr = FakeCommandManager('test')
-
- # Make sure add_command() still functions
- mock_cmd_one = mock.Mock()
- mgr.add_command('mock', mock_cmd_one)
- cmd_mock, name, args = mgr.find_command(['mock'])
- self.assertEqual(mock_cmd_one, cmd_mock)
-
- # Find a command added in initialization
- cmd_one, name, args = mgr.find_command(['one'])
- self.assertEqual(FAKE_CMD_ONE, cmd_one)
-
- # Load another command group
- mgr.add_command_group('greek')
-
- # Find a new command
- cmd_alpha, name, args = mgr.find_command(['alpha'])
- self.assertEqual(FAKE_CMD_ALPHA, cmd_alpha)
-
- # Ensure that the original commands were not overwritten
- cmd_two, name, args = mgr.find_command(['two'])
- self.assertEqual(FAKE_CMD_TWO, cmd_two)
-
- def test_get_command_groups(self):
- mgr = FakeCommandManager('test')
-
- # Make sure add_command() still functions
- mock_cmd_one = mock.Mock()
- mgr.add_command('mock', mock_cmd_one)
- cmd_mock, name, args = mgr.find_command(['mock'])
- self.assertEqual(mock_cmd_one, cmd_mock)
-
- # Load another command group
- mgr.add_command_group('greek')
-
- gl = mgr.get_command_groups()
- self.assertEqual(['test', 'greek'], gl)
-
- def test_get_command_names(self):
- mock_cmd_one = mock.Mock()
- mock_cmd_one.name = 'one'
- mock_cmd_two = mock.Mock()
- mock_cmd_two.name = 'cmd two'
- mock_pkg_resources = mock.Mock(
- return_value=[mock_cmd_one, mock_cmd_two],
- )
- with mock.patch(
- 'pkg_resources.iter_entry_points',
- mock_pkg_resources,
- ) as iter_entry_points:
- mgr = commandmanager.CommandManager('test')
- iter_entry_points.assert_called_once_with('test')
- cmds = mgr.get_command_names('test')
- self.assertEqual(['one', 'cmd two'], cmds)
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index c30af8fb..8ea59a38 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -23,6 +23,7 @@ from openstack import exceptions as sdk_exceptions
from osc_lib import exceptions
from osc_lib import utils as common_utils
from oslo_utils import timeutils
+import six
from openstackclient.compute.v2 import server
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
@@ -90,7 +91,14 @@ class TestServer(compute_fakes.TestComputev2):
for s in servers:
method = getattr(s, method_name)
- method.assert_called_with()
+ if method_name == 'lock':
+ version = self.app.client_manager.compute.api_version
+ if version >= api_versions.APIVersion('2.73'):
+ method.assert_called_with(reason=None)
+ else:
+ method.assert_called_with()
+ else:
+ method.assert_called_with()
self.assertIsNone(result)
@@ -1834,6 +1842,90 @@ class TestServerCreate(TestServer):
self.cmd.take_action,
parsed_args)
+ def test_server_create_with_description_api_newer(self):
+
+ # Description is supported for nova api version 2.19 or above
+ self.app.client_manager.compute.api_version = 2.19
+
+ arglist = [
+ '--image', 'image1',
+ '--flavor', 'flavor1',
+ '--description', 'description1',
+ self.new_server.name,
+ ]
+ verifylist = [
+ ('image', 'image1'),
+ ('flavor', 'flavor1'),
+ ('description', 'description1'),
+ ('config_drive', False),
+ ('server_name', self.new_server.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ # In base command class ShowOne in cliff, abstract method
+ # take_action() returns a two-part tuple with a tuple of
+ # column names and a tuple of data to be shown.
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = dict(
+ meta=None,
+ files={},
+ reservation_id=None,
+ min_count=1,
+ max_count=1,
+ security_groups=[],
+ userdata=None,
+ key_name=None,
+ availability_zone=None,
+ block_device_mapping_v2=[],
+ nics='auto',
+ scheduler_hints={},
+ config_drive=None,
+ description='description1',
+ )
+ # ServerManager.create(name, image, flavor, **kwargs)
+ self.servers_mock.create.assert_called_with(
+ self.new_server.name,
+ self.image,
+ self.flavor,
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist(), data)
+ self.assertFalse(self.images_mock.called)
+ self.assertFalse(self.flavors_mock.called)
+
+ def test_server_create_with_description_api_older(self):
+
+ # Description is not supported for nova api version below 2.19
+ self.app.client_manager.compute.api_version = 2.18
+
+ arglist = [
+ '--image', 'image1',
+ '--flavor', 'flavor1',
+ '--description', 'description1',
+ self.new_server.name,
+ ]
+ verifylist = [
+ ('image', 'image1'),
+ ('flavor', 'flavor1'),
+ ('description', 'description1'),
+ ('config_drive', False),
+ ('server_name', self.new_server.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
class TestServerDelete(TestServer):
@@ -1991,6 +2083,7 @@ class TestServerList(TestServer):
'user_id': None,
'deleted': False,
'changes-since': None,
+ 'changes-before': None,
}
# Default params of the core function of the command in the case of no
@@ -2210,6 +2303,80 @@ class TestServerList(TestServer):
self.assertEqual(self.columns, columns)
self.assertEqual(tuple(self.data), tuple(data))
+ def test_server_list_with_locked_pre_v273(self):
+
+ arglist = [
+ '--locked'
+ ]
+ verifylist = [
+ ('locked', True)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ ex = self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-compute-api-version 2.73 or greater is required', str(ex))
+
+ def test_server_list_with_locked_v273(self):
+
+ self.app.client_manager.compute.api_version = \
+ api_versions.APIVersion('2.73')
+ arglist = [
+ '--locked'
+ ]
+ verifylist = [
+ ('locked', True)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.search_opts['locked'] = True
+ self.servers_mock.list.assert_called_with(**self.kwargs)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(tuple(self.data), tuple(data))
+
+ def test_server_list_with_unlocked_v273(self):
+
+ self.app.client_manager.compute.api_version = \
+ api_versions.APIVersion('2.73')
+ arglist = [
+ '--unlocked'
+ ]
+ verifylist = [
+ ('unlocked', True)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.search_opts['locked'] = False
+ self.servers_mock.list.assert_called_with(**self.kwargs)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(tuple(self.data), tuple(data))
+
+ def test_server_list_with_locked_and_unlocked_v273(self):
+
+ self.app.client_manager.compute.api_version = \
+ api_versions.APIVersion('2.73')
+ arglist = [
+ '--locked',
+ '--unlocked'
+ ]
+ verifylist = [
+ ('locked', True),
+ ('unlocked', True)
+ ]
+
+ ex = self.assertRaises(
+ utils.ParserException,
+ self.check_parser, self.cmd, arglist, verifylist)
+ self.assertIn('Argument parse failed', str(ex))
+
def test_server_list_with_flavor(self):
arglist = [
@@ -2272,6 +2439,71 @@ class TestServerList(TestServer):
'Invalid time value'
)
+ def test_server_list_v266_with_changes_before(self):
+ self.app.client_manager.compute.api_version = (
+ api_versions.APIVersion('2.66'))
+ arglist = [
+ '--changes-before', '2016-03-05T06:27:59Z',
+ '--deleted'
+ ]
+ verifylist = [
+ ('changes_before', '2016-03-05T06:27:59Z'),
+ ('deleted', True),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.search_opts['changes-before'] = '2016-03-05T06:27:59Z'
+ self.search_opts['deleted'] = True
+ self.servers_mock.list.assert_called_with(**self.kwargs)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(tuple(self.data), tuple(data))
+
+ @mock.patch.object(timeutils, 'parse_isotime', side_effect=ValueError)
+ def test_server_list_v266_with_invalid_changes_before(
+ self, mock_parse_isotime):
+ self.app.client_manager.compute.api_version = (
+ api_versions.APIVersion('2.66'))
+
+ arglist = [
+ '--changes-before', 'Invalid time value',
+ ]
+ verifylist = [
+ ('changes_before', 'Invalid time value'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('Invalid changes-before value: Invalid time '
+ 'value', str(e))
+ mock_parse_isotime.assert_called_once_with(
+ 'Invalid time value'
+ )
+
+ def test_server_with_changes_before_older_version(self):
+ self.app.client_manager.compute.api_version = (
+ api_versions.APIVersion('2.65'))
+
+ arglist = [
+ '--changes-before', '2016-03-05T06:27:59Z',
+ '--deleted'
+ ]
+ verifylist = [
+ ('changes_before', '2016-03-05T06:27:59Z'),
+ ('deleted', True),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+
def test_server_list_v269_with_partial_constructs(self):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.69')
@@ -2336,6 +2568,72 @@ class TestServerLock(TestServer):
def test_server_lock_multi_servers(self):
self.run_method_with_servers('lock', 3)
+ def test_server_lock_with_reason(self):
+ server = compute_fakes.FakeServer.create_one_server()
+ arglist = [
+ server.id,
+ '--reason', "blah",
+ ]
+ verifylist = [
+ ('reason', "blah"),
+ ('server', [server.id])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ ex = self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-compute-api-version 2.73 or greater is required', str(ex))
+
+
+class TestServerLockV273(TestServerLock):
+
+ def setUp(self):
+ super(TestServerLockV273, self).setUp()
+
+ self.server = compute_fakes.FakeServer.create_one_server(
+ methods=self.methods)
+
+ # This is the return value for utils.find_resource()
+ self.servers_mock.get.return_value = self.server
+
+ self.app.client_manager.compute.api_version = \
+ api_versions.APIVersion('2.73')
+
+ # Get the command object to test
+ self.cmd = server.LockServer(self.app, None)
+
+ def test_server_lock_with_reason(self):
+ arglist = [
+ self.server.id,
+ '--reason', "blah",
+ ]
+ verifylist = [
+ ('reason', "blah"),
+ ('server', [self.server.id])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.server.lock.assert_called_with(reason="blah")
+
+ def test_server_lock_multi_servers_with_reason(self):
+ server2 = compute_fakes.FakeServer.create_one_server(
+ methods=self.methods)
+ arglist = [
+ self.server.id, server2.id,
+ '--reason', "choo..choo",
+ ]
+ verifylist = [
+ ('reason', "choo..choo"),
+ ('server', [self.server.id, server2.id])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+ self.assertEqual(2, self.servers_mock.get.call_count)
+ self.server.lock.assert_called_with(reason="choo..choo")
+ self.assertEqual(2, self.server.lock.call_count)
+
class TestServerMigrate(TestServer):
@@ -2377,6 +2675,32 @@ class TestServerMigrate(TestServer):
self.assertNotCalled(self.servers_mock.live_migrate)
self.assertIsNone(result)
+ def test_server_migrate_with_host_2_56(self):
+ # Tests that --host is allowed for a cold migration
+ # for microversion 2.56 and greater.
+ arglist = [
+ '--host', 'fakehost', self.server.id,
+ ]
+ verifylist = [
+ ('live', None),
+ ('live_migration', False),
+ ('host', 'fakehost'),
+ ('block_migration', False),
+ ('disk_overcommit', False),
+ ('wait', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.app.client_manager.compute.api_version = \
+ api_versions.APIVersion('2.56')
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.server.migrate.assert_called_with(host='fakehost')
+ self.assertNotCalled(self.servers_mock.live_migrate)
+ self.assertIsNone(result)
+
def test_server_migrate_with_block_migration(self):
arglist = [
'--block-migration', self.server.id,
@@ -2415,12 +2739,42 @@ class TestServerMigrate(TestServer):
self.assertNotCalled(self.servers_mock.live_migrate)
self.assertNotCalled(self.servers_mock.migrate)
+ def test_server_migrate_with_host_pre_2_56(self):
+ # Tests that --host is not allowed for a cold migration
+ # before microversion 2.56 (the test defaults to 2.1).
+ arglist = [
+ '--host', 'fakehost', self.server.id,
+ ]
+ verifylist = [
+ ('live', None),
+ ('live_migration', False),
+ ('host', 'fakehost'),
+ ('block_migration', False),
+ ('disk_overcommit', False),
+ ('wait', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ ex = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+ # Make sure it's the error we expect.
+ self.assertIn('--os-compute-api-version 2.56 or greater is required '
+ 'to use --host without --live-migration.',
+ six.text_type(ex))
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.assertNotCalled(self.servers_mock.live_migrate)
+ self.assertNotCalled(self.servers_mock.migrate)
+
def test_server_live_migrate(self):
arglist = [
'--live', 'fakehost', self.server.id,
]
verifylist = [
('live', 'fakehost'),
+ ('live_migration', False),
+ ('host', None),
('block_migration', False),
('disk_overcommit', False),
('wait', False),
@@ -2430,7 +2784,8 @@ class TestServerMigrate(TestServer):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.24')
- result = self.cmd.take_action(parsed_args)
+ with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
+ result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id)
self.server.live_migrate.assert_called_with(block_migration=False,
@@ -2438,6 +2793,132 @@ class TestServerMigrate(TestServer):
host='fakehost')
self.assertNotCalled(self.servers_mock.migrate)
self.assertIsNone(result)
+ # A warning should have been logged for using --live.
+ mock_warning.assert_called_once()
+ self.assertIn('The --live option has been deprecated.',
+ six.text_type(mock_warning.call_args[0][0]))
+
+ def test_server_live_migrate_host_pre_2_30(self):
+ # Tests that the --host option is not supported for --live-migration
+ # before microversion 2.30 (the test defaults to 2.1).
+ arglist = [
+ '--live-migration', '--host', 'fakehost', self.server.id,
+ ]
+ verifylist = [
+ ('live', None),
+ ('live_migration', True),
+ ('host', 'fakehost'),
+ ('block_migration', False),
+ ('disk_overcommit', False),
+ ('wait', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ ex = self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+ # Make sure it's the error we expect.
+ self.assertIn('--os-compute-api-version 2.30 or greater is required '
+ 'when using --host', six.text_type(ex))
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.assertNotCalled(self.servers_mock.live_migrate)
+ self.assertNotCalled(self.servers_mock.migrate)
+
+ def test_server_live_migrate_no_host(self):
+ # Tests the --live-migration option without --host or --live.
+ arglist = [
+ '--live-migration', self.server.id,
+ ]
+ verifylist = [
+ ('live', None),
+ ('live_migration', True),
+ ('host', None),
+ ('block_migration', False),
+ ('disk_overcommit', False),
+ ('wait', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
+ result = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.server.live_migrate.assert_called_with(block_migration=False,
+ disk_over_commit=False,
+ host=None)
+ self.assertNotCalled(self.servers_mock.migrate)
+ self.assertIsNone(result)
+ # Since --live wasn't used a warning shouldn't have been logged.
+ mock_warning.assert_not_called()
+
+ def test_server_live_migrate_with_host(self):
+ # Tests the --live-migration option with --host but no --live.
+ # This requires --os-compute-api-version >= 2.30 so the test uses 2.30.
+ arglist = [
+ '--live-migration', '--host', 'fakehost', self.server.id,
+ ]
+ verifylist = [
+ ('live', None),
+ ('live_migration', True),
+ ('host', 'fakehost'),
+ ('block_migration', False),
+ ('disk_overcommit', False),
+ ('wait', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.app.client_manager.compute.api_version = \
+ api_versions.APIVersion('2.30')
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ # No disk_overcommit with microversion >= 2.25.
+ self.server.live_migrate.assert_called_with(block_migration=False,
+ host='fakehost')
+ self.assertNotCalled(self.servers_mock.migrate)
+ self.assertIsNone(result)
+
+ def test_server_live_migrate_without_host_override_live(self):
+ # Tests the --live-migration option without --host and with --live.
+ # The --live-migration option will take precedence and a warning is
+ # logged for using --live.
+ arglist = [
+ '--live', 'fakehost', '--live-migration', self.server.id,
+ ]
+ verifylist = [
+ ('live', 'fakehost'),
+ ('live_migration', True),
+ ('host', None),
+ ('block_migration', False),
+ ('disk_overcommit', False),
+ ('wait', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
+ result = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.server.live_migrate.assert_called_with(block_migration=False,
+ disk_over_commit=False,
+ host=None)
+ self.assertNotCalled(self.servers_mock.migrate)
+ self.assertIsNone(result)
+ # A warning should have been logged for using --live.
+ mock_warning.assert_called_once()
+ self.assertIn('The --live option has been deprecated.',
+ six.text_type(mock_warning.call_args[0][0]))
+
+ def test_server_live_migrate_live_and_host_mutex(self):
+ # Tests specifying both the --live and --host options which are in a
+ # mutex group so argparse should fail.
+ arglist = [
+ '--live', 'fakehost', '--host', 'fakehost', self.server.id,
+ ]
+ self.assertRaises(utils.ParserException,
+ self.check_parser, self.cmd, arglist, verify_args=[])
def test_server_block_live_migrate(self):
arglist = [
@@ -2663,6 +3144,55 @@ class TestServerRebuild(TestServer):
self.images_mock.get.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, password)
+ def test_rebuild_with_description_api_older(self):
+
+ # Description is not supported for nova api version below 2.19
+ self.server.api_version = 2.18
+
+ description = 'description1'
+ arglist = [
+ self.server.id,
+ '--description', description
+ ]
+ verifylist = [
+ ('server', self.server.id),
+ ('description', description)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+ def test_rebuild_with_description_api_newer(self):
+
+ # Description is supported for nova api version 2.19 or above
+ self.server.api_version = 2.19
+
+ description = 'description1'
+ arglist = [
+ self.server.id,
+ '--description', description
+ ]
+ verifylist = [
+ ('server', self.server.id),
+ ('description', description)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ # Get the command object to test
+ self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.images_mock.get.assert_called_with(self.image.id)
+ self.server.rebuild.assert_called_with(self.image, None,
+ description=description)
+
@mock.patch.object(common_utils, 'wait_for_status', return_value=True)
def test_rebuild_with_wait_ok(self, mock_wait_for_status):
arglist = [
@@ -3400,6 +3930,10 @@ class TestServerSet(TestServer):
def setUp(self):
super(TestServerSet, self).setUp()
+ self.attrs = {
+ 'api_version': None,
+ }
+
self.methods = {
'update': None,
'reset_state': None,
@@ -3502,6 +4036,48 @@ class TestServerSet(TestServer):
mock.sentinel.fake_pass)
self.assertIsNone(result)
+ def test_server_set_with_description_api_newer(self):
+
+ # Description is supported for nova api version 2.19 or above
+ self.fake_servers[0].api_version = 2.19
+
+ arglist = [
+ '--description', 'foo_description',
+ 'foo_vm',
+ ]
+ verifylist = [
+ ('description', 'foo_description'),
+ ('server', 'foo_vm'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ result = self.cmd.take_action(parsed_args)
+ self.fake_servers[0].update.assert_called_once_with(
+ description='foo_description')
+ self.assertIsNone(result)
+
+ def test_server_set_with_description_api_older(self):
+
+ # Description is not supported for nova api version below 2.19
+ self.fake_servers[0].api_version = 2.18
+
+ arglist = [
+ '--description', 'foo_description',
+ 'foo_vm',
+ ]
+ verifylist = [
+ ('description', 'foo_description'),
+ ('server', 'foo_vm'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
class TestServerShelve(TestServer):
@@ -3783,6 +4359,50 @@ class TestServerUnset(TestServer):
self.fake_server, ['key1', 'key2'])
self.assertIsNone(result)
+ def test_server_unset_with_description_api_newer(self):
+
+ # Description is supported for nova api version 2.19 or above
+ self.app.client_manager.compute.api_version = 2.19
+
+ arglist = [
+ '--description',
+ 'foo_vm',
+ ]
+ verifylist = [
+ ('description', True),
+ ('server', 'foo_vm'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ result = self.cmd.take_action(parsed_args)
+ self.servers_mock.update.assert_called_once_with(
+ self.fake_server, description="")
+ self.assertIsNone(result)
+
+ def test_server_unset_with_description_api_older(self):
+
+ # Description is not supported for nova api version below 2.19
+ self.app.client_manager.compute.api_version = 2.18
+
+ arglist = [
+ '--description',
+ 'foo_vm',
+ ]
+ verifylist = [
+ ('description', True),
+ ('server', 'foo_vm'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch.object(api_versions,
+ 'APIVersion',
+ return_value=2.19):
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
class TestServerUnshelve(TestServer):
diff --git a/openstackclient/tests/unit/identity/v2_0/test_role.py b/openstackclient/tests/unit/identity/v2_0/test_role.py
index 684ce803..643d77f6 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_role.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_role.py
@@ -278,7 +278,7 @@ class TestRoleList(TestRole):
# Get the command object to test
self.cmd = role.ListRole(self.app, None)
- def test_role_list_no_options(self):
+ def test_role_list(self):
arglist = []
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -299,137 +299,6 @@ class TestRoleList(TestRole):
self.assertEqual(datalist, tuple(data))
-class TestUserRoleList(TestRole):
-
- columns = (
- 'ID',
- 'Name',
- 'Project',
- 'User'
- )
-
- def setUp(self):
- super(TestUserRoleList, self).setUp()
-
- self.projects_mock.get.return_value = self.fake_project
-
- self.users_mock.get.return_value = self.fake_user
-
- self.roles_mock.roles_for_user.return_value = [self.fake_role]
-
- # Get the command object to test
- self.cmd = role.ListUserRole(self.app, None)
-
- def test_user_role_list_no_options_unscoped_token(self):
- auth_ref = identity_fakes.fake_auth_ref(
- identity_fakes.UNSCOPED_TOKEN,
- fake_service=self.fake_service,
- )
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
-
- arglist = []
- verifylist = []
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # This argument combination should raise a CommandError
- self.assertRaises(
- exceptions.CommandError,
- self.cmd.take_action,
- parsed_args,
- )
-
- def test_user_role_list_no_options_scoped_token(self):
- arglist = []
- verifylist = []
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- self.roles_mock.roles_for_user.assert_called_with(
- self.fake_user.id,
- self.fake_project.id,
- )
-
- collist = ('ID', 'Name', 'Project', 'User')
- self.assertEqual(collist, columns)
- datalist = ((
- self.fake_role.id,
- self.fake_role.name,
- self.fake_project.name,
- self.fake_user.name,
- ), )
- self.assertEqual(datalist, tuple(data))
-
- def test_user_role_list_project_unscoped_token(self):
- auth_ref = identity_fakes.fake_auth_ref(
- identity_fakes.UNSCOPED_TOKEN,
- fake_service=self.fake_service,
- )
- self.ar_mock = mock.PropertyMock(return_value=auth_ref)
- type(self.app.client_manager).auth_ref = self.ar_mock
-
- self.projects_mock.get.return_value = self.fake_project
- arglist = [
- '--project', self.fake_project.name,
- ]
- verifylist = [
- ('project', self.fake_project.name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- self.roles_mock.roles_for_user.assert_called_with(
- self.fake_user.id,
- self.fake_project.id,
- )
-
- self.assertEqual(columns, columns)
- datalist = ((
- self.fake_role.id,
- self.fake_role.name,
- self.fake_project.name,
- self.fake_user.name,
- ), )
- self.assertEqual(datalist, tuple(data))
-
- def test_user_role_list_project_scoped_token(self):
- self.projects_mock.get.return_value = self.fake_project
- arglist = [
- '--project', self.fake_project.name,
- ]
- verifylist = [
- ('project', self.fake_project.name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- self.roles_mock.roles_for_user.assert_called_with(
- self.fake_user.id,
- self.fake_project.id,
- )
-
- self.assertEqual(columns, columns)
- datalist = ((
- self.fake_role.id,
- self.fake_role.name,
- self.fake_project.name,
- self.fake_user.name,
- ), )
- self.assertEqual(datalist, tuple(data))
-
-
class TestRoleRemove(TestRole):
def setUp(self):
diff --git a/openstackclient/tests/unit/identity/v2_0/test_service.py b/openstackclient/tests/unit/identity/v2_0/test_service.py
index 1948bf4a..6c4374ef 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_service.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_service.py
@@ -55,43 +55,14 @@ class TestServiceCreate(TestService):
# Get the command object to test
self.cmd = service.CreateService(self.app, None)
- def test_service_create_with_type_positional(self):
+ def test_service_create(self):
arglist = [
self.fake_service_c.type,
]
verifylist = [
- ('type_or_name', self.fake_service_c.type),
- ('type', None),
- ('description', None),
- ('name', None),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class ShowOne in cliff, abstract method take_action()
- # returns a two-part tuple with a tuple of column names and a tuple of
- # data to be shown.
- columns, data = self.cmd.take_action(parsed_args)
-
- # ServiceManager.create(name, service_type, description)
- self.services_mock.create.assert_called_with(
- None,
- self.fake_service_c.type,
- None,
- )
-
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.datalist, data)
-
- def test_service_create_with_type_option(self):
- arglist = [
- '--type', self.fake_service_c.type,
- self.fake_service_c.name,
- ]
- verifylist = [
- ('type_or_name', self.fake_service_c.name),
('type', self.fake_service_c.type),
- ('description', None),
('name', None),
+ ('description', None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -102,7 +73,7 @@ class TestServiceCreate(TestService):
# ServiceManager.create(name, service_type, description)
self.services_mock.create.assert_called_with(
- self.fake_service_c.name,
+ None,
self.fake_service_c.type,
None,
)
@@ -116,10 +87,9 @@ class TestServiceCreate(TestService):
self.fake_service_c.type,
]
verifylist = [
- ('type_or_name', self.fake_service_c.type),
- ('type', None),
- ('description', None),
+ ('type', self.fake_service_c.type),
('name', self.fake_service_c.name),
+ ('description', None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -145,10 +115,9 @@ class TestServiceCreate(TestService):
self.fake_service_c.type,
]
verifylist = [
- ('type_or_name', self.fake_service_c.type),
- ('type', None),
- ('description', self.fake_service_c.description),
+ ('type', self.fake_service_c.type),
('name', self.fake_service_c.name),
+ ('description', self.fake_service_c.description),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/unit/identity/v3/fakes.py b/openstackclient/tests/unit/identity/v3/fakes.py
index 27ee9fd0..e5727a6a 100644
--- a/openstackclient/tests/unit/identity/v3/fakes.py
+++ b/openstackclient/tests/unit/identity/v3/fakes.py
@@ -235,6 +235,10 @@ endpoint_group_filters = {
'service_id': service_id,
'region_id': endpoint_region,
}
+endpoint_group_filters_2 = {
+ 'region_id': endpoint_region,
+}
+endpoint_group_file_path = '/tmp/path/to/file'
ENDPOINT_GROUP = {
'id': endpoint_group_id,
@@ -1044,6 +1048,64 @@ class FakeEndpoint(object):
return endpoint_filter
+class FakeEndpointGroup(object):
+ """Fake one or more endpoint group."""
+
+ @staticmethod
+ def create_one_endpointgroup(attrs=None):
+ """Create a fake endpoint group.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object, with id, url, and so on
+ """
+
+ attrs = attrs or {}
+
+ # set default attributes.
+ endpointgroup_info = {
+ 'id': 'endpoint-group-id-' + uuid.uuid4().hex,
+ 'name': 'endpoint-group-name-' + uuid.uuid4().hex,
+ 'filters': {
+ 'region': 'region-' + uuid.uuid4().hex,
+ 'service_id': 'service-id-' + uuid.uuid4().hex,
+ },
+ 'description': 'endpoint-group-description-' + uuid.uuid4().hex,
+ 'links': 'links-' + uuid.uuid4().hex,
+ }
+ endpointgroup_info.update(attrs)
+
+ endpoint = fakes.FakeResource(info=copy.deepcopy(endpointgroup_info),
+ loaded=True)
+ return endpoint
+
+ @staticmethod
+ def create_one_endpointgroup_filter(attrs=None):
+ """Create a fake endpoint project relationship.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes of endpointgroup filter
+ :return:
+ A FakeResource object with project, endpointgroup and so on
+ """
+ attrs = attrs or {}
+
+ # Set default attribute
+ endpointgroup_filter_info = {
+ 'project': 'project-id-' + uuid.uuid4().hex,
+ 'endpointgroup': 'endpointgroup-id-' + uuid.uuid4().hex,
+ }
+
+ # Overwrite default attributes if there are some attributes set
+ endpointgroup_filter_info.update(attrs)
+
+ endpointgroup_filter = fakes.FakeModel(
+ copy.deepcopy(endpointgroup_filter_info))
+
+ return endpointgroup_filter
+
+
class FakeService(object):
"""Fake one or more service."""
diff --git a/openstackclient/tests/unit/identity/v3/test_endpoint_group.py b/openstackclient/tests/unit/identity/v3/test_endpoint_group.py
new file mode 100644
index 00000000..6e9da9c7
--- /dev/null
+++ b/openstackclient/tests/unit/identity/v3/test_endpoint_group.py
@@ -0,0 +1,495 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import mock
+
+from openstackclient.identity.v3 import endpoint_group
+from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
+
+
+class TestEndpointGroup(identity_fakes.TestIdentityv3):
+
+ def setUp(self):
+ super(TestEndpointGroup, self).setUp()
+
+ # Get a shortcut to the EndpointManager Mock
+ self.endpoint_groups_mock = (
+ self.app.client_manager.identity.endpoint_groups
+ )
+ self.endpoint_groups_mock.reset_mock()
+ self.epf_mock = (
+ self.app.client_manager.identity.endpoint_filter
+ )
+ self.epf_mock.reset_mock()
+
+ # Get a shortcut to the ServiceManager Mock
+ self.services_mock = self.app.client_manager.identity.services
+ self.services_mock.reset_mock()
+
+ # Get a shortcut to the DomainManager Mock
+ self.domains_mock = self.app.client_manager.identity.domains
+ self.domains_mock.reset_mock()
+
+ # Get a shortcut to the ProjectManager Mock
+ self.projects_mock = self.app.client_manager.identity.projects
+ self.projects_mock.reset_mock()
+
+
+class TestEndpointGroupCreate(TestEndpointGroup):
+
+ columns = (
+ 'description',
+ 'filters',
+ 'id',
+ 'name',
+ )
+
+ def setUp(self):
+ super(TestEndpointGroupCreate, self).setUp()
+
+ self.endpoint_group = (
+ identity_fakes.FakeEndpointGroup.create_one_endpointgroup(
+ attrs={'filters': identity_fakes.endpoint_group_filters}))
+
+ self.endpoint_groups_mock.create.return_value = self.endpoint_group
+
+ # Get the command object to test
+ self.cmd = endpoint_group.CreateEndpointGroup(self.app, None)
+
+ def test_endpointgroup_create_no_options(self):
+ arglist = [
+ '--description', self.endpoint_group.description,
+ self.endpoint_group.name,
+ identity_fakes.endpoint_group_file_path,
+ ]
+ verifylist = [
+ ('name', self.endpoint_group.name),
+ ('filters', identity_fakes.endpoint_group_file_path),
+ ('description', self.endpoint_group.description),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ mocker = mock.Mock()
+ mocker.return_value = identity_fakes.endpoint_group_filters
+ with mock.patch("openstackclient.identity.v3.endpoint_group."
+ "CreateEndpointGroup._read_filters", mocker):
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': self.endpoint_group.name,
+ 'filters': identity_fakes.endpoint_group_filters,
+ 'description': self.endpoint_group.description,
+ }
+
+ self.endpoint_groups_mock.create.assert_called_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ self.endpoint_group.description,
+ identity_fakes.endpoint_group_filters,
+ self.endpoint_group.id,
+ self.endpoint_group.name,
+ )
+ self.assertEqual(datalist, data)
+
+
+class TestEndpointGroupDelete(TestEndpointGroup):
+
+ endpoint_group = (
+ identity_fakes.FakeEndpointGroup.create_one_endpointgroup())
+
+ def setUp(self):
+ super(TestEndpointGroupDelete, self).setUp()
+
+ # This is the return value for utils.find_resource(endpoint)
+ self.endpoint_groups_mock.get.return_value = self.endpoint_group
+ self.endpoint_groups_mock.delete.return_value = None
+
+ # Get the command object to test
+ self.cmd = endpoint_group.DeleteEndpointGroup(self.app, None)
+
+ def test_endpointgroup_delete(self):
+ arglist = [
+ self.endpoint_group.id,
+ ]
+ verifylist = [
+ ('endpointgroup', [self.endpoint_group.id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.endpoint_groups_mock.delete.assert_called_with(
+ self.endpoint_group.id,
+ )
+ self.assertIsNone(result)
+
+
+class TestEndpointGroupList(TestEndpointGroup):
+
+ endpoint_group = (
+ identity_fakes.FakeEndpointGroup.create_one_endpointgroup())
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+
+ columns = (
+ 'ID',
+ 'Name',
+ 'Description',
+ )
+
+ def setUp(self):
+ super(TestEndpointGroupList, self).setUp()
+
+ self.endpoint_groups_mock.list.return_value = [self.endpoint_group]
+ self.endpoint_groups_mock.get.return_value = self.endpoint_group
+ self.epf_mock.list_projects_for_endpoint_group.return_value = [
+ self.project]
+ self.epf_mock.list_endpoint_groups_for_project.return_value = [
+ self.endpoint_group]
+
+ # Get the command object to test
+ self.cmd = endpoint_group.ListEndpointGroup(self.app, None)
+
+ def test_endpoint_group_list_no_options(self):
+ arglist = []
+ verifylist = []
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class Lister in cliff, abstract method take_action()
+ # returns a tuple containing the column names and an iterable
+ # containing the data to be listed.
+ columns, data = self.cmd.take_action(parsed_args)
+ self.endpoint_groups_mock.list.assert_called_with()
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ self.endpoint_group.id,
+ self.endpoint_group.name,
+ self.endpoint_group.description,
+ ),
+ )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_endpoint_group_list_projects_by_endpoint_group(self):
+ arglist = [
+ '--endpointgroup', self.endpoint_group.id,
+ ]
+ verifylist = [
+ ('endpointgroup', self.endpoint_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class Lister in cliff, abstract method take_action()
+ # returns a tuple containing the column names and an iterable
+ # containing the data to be listed.
+ columns, data = self.cmd.take_action(parsed_args)
+ self.epf_mock.list_projects_for_endpoint_group.assert_called_with(
+ endpoint_group=self.endpoint_group.id
+ )
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ self.project.id,
+ self.project.name,
+ self.project.description,
+ ),
+ )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_endpoint_group_list_by_project(self):
+ self.epf_mock.list_endpoints_for_project.return_value = [
+ self.endpoint_group
+ ]
+ self.projects_mock.get.return_value = self.project
+
+ arglist = [
+ '--project', self.project.name,
+ '--domain', self.domain.name
+ ]
+ verifylist = [
+ ('project', self.project.name),
+ ('domain', self.domain.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # In base command class Lister in cliff, abstract method take_action()
+ # returns a tuple containing the column names and an iterable
+ # containing the data to be listed.
+ columns, data = self.cmd.take_action(parsed_args)
+ self.epf_mock.list_endpoint_groups_for_project.assert_called_with(
+ project=self.project.id
+ )
+
+ self.assertEqual(self.columns, columns)
+ datalist = (
+ (
+ self.endpoint_group.id,
+ self.endpoint_group.name,
+ self.endpoint_group.description,
+ ),
+ )
+ self.assertEqual(datalist, tuple(data))
+
+
+class TestEndpointGroupSet(TestEndpointGroup):
+
+ endpoint_group = (
+ identity_fakes.FakeEndpointGroup.create_one_endpointgroup())
+
+ def setUp(self):
+ super(TestEndpointGroupSet, self).setUp()
+
+ # This is the return value for utils.find_resource(endpoint)
+ self.endpoint_groups_mock.get.return_value = self.endpoint_group
+
+ self.endpoint_groups_mock.update.return_value = self.endpoint_group
+
+ # Get the command object to test
+ self.cmd = endpoint_group.SetEndpointGroup(self.app, None)
+
+ def test_endpoint_group_set_no_options(self):
+ arglist = [
+ self.endpoint_group.id,
+ ]
+ verifylist = [
+ ('endpointgroup', self.endpoint_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ kwargs = {
+ 'name': None,
+ 'filters': None,
+ 'description': ''
+ }
+ self.endpoint_groups_mock.update.assert_called_with(
+ self.endpoint_group.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_endpoint_group_set_name(self):
+ arglist = [
+ '--name', 'qwerty',
+ self.endpoint_group.id
+ ]
+ verifylist = [
+ ('name', 'qwerty'),
+ ('endpointgroup', self.endpoint_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': 'qwerty',
+ 'filters': None,
+ 'description': ''
+ }
+ self.endpoint_groups_mock.update.assert_called_with(
+ self.endpoint_group.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_endpoint_group_set_filters(self):
+ arglist = [
+ '--filters', identity_fakes.endpoint_group_file_path,
+ self.endpoint_group.id,
+ ]
+ verifylist = [
+ ('filters', identity_fakes.endpoint_group_file_path),
+ ('endpointgroup', self.endpoint_group.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ mocker = mock.Mock()
+ mocker.return_value = identity_fakes.endpoint_group_filters_2
+ with mock.patch("openstackclient.identity.v3.endpoint_group."
+ "SetEndpointGroup._read_filters", mocker):
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': None,
+ 'filters': identity_fakes.endpoint_group_filters_2,
+ 'description': '',
+ }
+
+ self.endpoint_groups_mock.update.assert_called_with(
+ self.endpoint_group.id,
+ **kwargs
+ )
+
+ self.assertIsNone(result)
+
+ def test_endpoint_group_set_description(self):
+ arglist = [
+ '--description', 'qwerty',
+ self.endpoint_group.id
+ ]
+ verifylist = [
+ ('description', 'qwerty'),
+ ('endpointgroup', self.endpoint_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'name': None,
+ 'filters': None,
+ 'description': 'qwerty',
+ }
+ self.endpoint_groups_mock.update.assert_called_with(
+ self.endpoint_group.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+
+class TestAddProjectToEndpointGroup(TestEndpointGroup):
+
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+ endpoint_group = (
+ identity_fakes.FakeEndpointGroup.create_one_endpointgroup())
+
+ new_ep_filter = (
+ identity_fakes.FakeEndpointGroup.create_one_endpointgroup_filter(
+ attrs={'endpointgroup': endpoint_group.id,
+ 'project': project.id}))
+
+ def setUp(self):
+ super(TestAddProjectToEndpointGroup, self).setUp()
+
+ # This is the return value for utils.find_resource()
+ self.endpoint_groups_mock.get.return_value = self.endpoint_group
+
+ # Update the image_id in the MEMBER dict
+ self.epf_mock.create.return_value = self.new_ep_filter
+ self.projects_mock.get.return_value = self.project
+ self.domains_mock.get.return_value = self.domain
+
+ # Get the command object to test
+ self.cmd = endpoint_group.AddProjectToEndpointGroup(self.app, None)
+
+ def test_add_project_to_endpoint_no_option(self):
+ arglist = [
+ self.endpoint_group.id,
+ self.project.id,
+ ]
+ verifylist = [
+ ('endpointgroup', self.endpoint_group.id),
+ ('project', self.project.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.epf_mock.add_endpoint_group_to_project.assert_called_with(
+ project=self.project.id,
+ endpoint_group=self.endpoint_group.id,
+ )
+ self.assertIsNone(result)
+
+ def test_add_project_to_endpoint_with_option(self):
+ arglist = [
+ self.endpoint_group.id,
+ self.project.id,
+ '--project-domain', self.domain.id,
+ ]
+ verifylist = [
+ ('endpointgroup', self.endpoint_group.id),
+ ('project', self.project.id),
+ ('project_domain', self.domain.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.epf_mock.add_endpoint_group_to_project.assert_called_with(
+ project=self.project.id,
+ endpoint_group=self.endpoint_group.id,
+ )
+ self.assertIsNone(result)
+
+
+class TestRemoveProjectEndpointGroup(TestEndpointGroup):
+
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+ endpoint_group = (
+ identity_fakes.FakeEndpointGroup.create_one_endpointgroup())
+
+ def setUp(self):
+ super(TestRemoveProjectEndpointGroup, self).setUp()
+
+ # This is the return value for utils.find_resource()
+ self.endpoint_groups_mock.get.return_value = self.endpoint_group
+
+ self.projects_mock.get.return_value = self.project
+ self.domains_mock.get.return_value = self.domain
+ self.epf_mock.delete.return_value = None
+
+ # Get the command object to test
+ self.cmd = endpoint_group.RemoveProjectFromEndpointGroup(
+ self.app, None)
+
+ def test_remove_project_endpoint_no_options(self):
+ arglist = [
+ self.endpoint_group.id,
+ self.project.id,
+ ]
+ verifylist = [
+ ('endpointgroup', self.endpoint_group.id),
+ ('project', self.project.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.epf_mock.delete_endpoint_group_from_project.assert_called_with(
+ project=self.project.id,
+ endpoint_group=self.endpoint_group.id,
+ )
+ self.assertIsNone(result)
+
+ def test_remove_project_endpoint_with_options(self):
+ arglist = [
+ self.endpoint_group.id,
+ self.project.id,
+ '--project-domain', self.domain.id,
+ ]
+ verifylist = [
+ ('endpointgroup', self.endpoint_group.id),
+ ('project', self.project.id),
+ ('project_domain', self.domain.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.epf_mock.delete_endpoint_group_from_project.assert_called_with(
+ project=self.project.id,
+ endpoint_group=self.endpoint_group.id,
+ )
+ self.assertIsNone(result)
diff --git a/openstackclient/tests/unit/identity/v3/test_role.py b/openstackclient/tests/unit/identity/v3/test_role.py
index 281d530c..99f3a2de 100644
--- a/openstackclient/tests/unit/identity/v3/test_role.py
+++ b/openstackclient/tests/unit/identity/v3/test_role.py
@@ -508,21 +508,6 @@ class TestRoleList(TestRole):
copy.deepcopy(identity_fakes.DOMAIN),
loaded=True,
)
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
- self.groups_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.GROUP),
- loaded=True,
- )
# Get the command object to test
self.cmd = role.ListRole(self.app, None)
@@ -542,212 +527,6 @@ class TestRoleList(TestRole):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
- def test_user_list_inherited(self):
- arglist = [
- '--user', identity_fakes.user_id,
- '--inherited',
- ]
- verifylist = [
- ('user', identity_fakes.user_id),
- ('inherited', True),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- # Set expected values
- kwargs = {
- 'domain': 'default',
- 'user': self.users_mock.get(),
- 'os_inherit_extension_inherited': True,
- }
- # RoleManager.list(user=, group=, domain=, project=, **kwargs)
- self.roles_mock.list.assert_called_with(
- **kwargs
- )
-
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.datalist, tuple(data))
-
- def test_user_list_user(self):
- arglist = [
- '--user', identity_fakes.user_id,
- ]
- verifylist = [
- ('user', identity_fakes.user_id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- # Set expected values
- kwargs = {
- 'domain': 'default',
- 'user': self.users_mock.get(),
- 'os_inherit_extension_inherited': False
- }
- # RoleManager.list(user=, group=, domain=, project=, **kwargs)
- self.roles_mock.list.assert_called_with(
- **kwargs
- )
-
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.datalist, tuple(data))
-
- def test_role_list_domain_user(self):
- arglist = [
- '--domain', identity_fakes.domain_name,
- '--user', identity_fakes.user_id,
- ]
- verifylist = [
- ('domain', identity_fakes.domain_name),
- ('user', identity_fakes.user_id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- # Set expected values
- kwargs = {
- 'domain': self.domains_mock.get(),
- 'user': self.users_mock.get(),
- 'os_inherit_extension_inherited': False
- }
- # RoleManager.list(user=, group=, domain=, project=, **kwargs)
- self.roles_mock.list.assert_called_with(
- **kwargs
- )
-
- collist = ('ID', 'Name', 'Domain', 'User')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- identity_fakes.domain_name,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
-
- def test_role_list_domain_group(self):
- arglist = [
- '--domain', identity_fakes.domain_name,
- '--group', identity_fakes.group_id,
- ]
- verifylist = [
- ('domain', identity_fakes.domain_name),
- ('group', identity_fakes.group_id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- # Set expected values
- kwargs = {
- 'domain': self.domains_mock.get(),
- 'group': self.groups_mock.get(),
- 'os_inherit_extension_inherited': False
- }
- # RoleManager.list(user=, group=, domain=, project=, **kwargs)
- self.roles_mock.list.assert_called_with(
- **kwargs
- )
-
- collist = ('ID', 'Name', 'Domain', 'Group')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- identity_fakes.domain_name,
- identity_fakes.group_name,
- ), )
- self.assertEqual(datalist, tuple(data))
-
- def test_role_list_project_user(self):
- arglist = [
- '--project', identity_fakes.project_name,
- '--user', identity_fakes.user_id,
- ]
- verifylist = [
- ('project', identity_fakes.project_name),
- ('user', identity_fakes.user_id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- # Set expected values
- kwargs = {
- 'project': self.projects_mock.get(),
- 'user': self.users_mock.get(),
- 'os_inherit_extension_inherited': False
- }
- # RoleManager.list(user=, group=, domain=, project=, **kwargs)
- self.roles_mock.list.assert_called_with(
- **kwargs
- )
-
- collist = ('ID', 'Name', 'Project', 'User')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- identity_fakes.project_name,
- identity_fakes.user_name,
- ), )
- self.assertEqual(datalist, tuple(data))
-
- def test_role_list_project_group(self):
- arglist = [
- '--project', identity_fakes.project_name,
- '--group', identity_fakes.group_id,
- ]
- verifylist = [
- ('project', identity_fakes.project_name),
- ('group', identity_fakes.group_id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # In base command class Lister in cliff, abstract method take_action()
- # returns a tuple containing the column names and an iterable
- # containing the data to be listed.
- columns, data = self.cmd.take_action(parsed_args)
-
- # Set expected values
- kwargs = {
- 'project': self.projects_mock.get(),
- 'group': self.groups_mock.get(),
- 'os_inherit_extension_inherited': False
- }
- # RoleManager.list(user=, group=, domain=, project=, **kwargs)
- self.roles_mock.list.assert_called_with(
- **kwargs
- )
-
- collist = ('ID', 'Name', 'Project', 'Group')
- self.assertEqual(collist, columns)
- datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- identity_fakes.project_name,
- identity_fakes.group_name,
- ), )
- self.assertEqual(datalist, tuple(data))
-
def test_role_list_domain_role(self):
self.roles_mock.list.return_value = [
fakes.FakeResource(
@@ -787,17 +566,6 @@ class TestRoleList(TestRole):
), )
self.assertEqual(datalist, tuple(data))
- def test_role_list_group_with_error(self):
- arglist = [
- '--group', identity_fakes.group_id,
- ]
- verifylist = [
- ('group', identity_fakes.group_id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- self.assertRaises(exceptions.CommandError,
- self.cmd.take_action, parsed_args)
-
class TestRoleRemove(TestRole):
diff --git a/openstackclient/tests/unit/image/v1/test_image.py b/openstackclient/tests/unit/image/v1/test_image.py
index ae578d91..6babd4ff 100644
--- a/openstackclient/tests/unit/image/v1/test_image.py
+++ b/openstackclient/tests/unit/image/v1/test_image.py
@@ -417,7 +417,7 @@ class TestImageList(TestImage):
), )
self.assertEqual(datalist, tuple(data))
- @mock.patch('openstackclient.api.utils.simple_filter')
+ @mock.patch('osc_lib.api.utils.simple_filter')
def test_image_list_property_option(self, sf_mock):
sf_mock.side_effect = [
[self.image_info], [],
diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py
index 16a393df..45b5a0a8 100644
--- a/openstackclient/tests/unit/image/v2/test_image.py
+++ b/openstackclient/tests/unit/image/v2/test_image.py
@@ -188,40 +188,6 @@ class TestImageCreate(TestImage):
image_fakes.FakeImage.get_image_data(self.new_image),
data)
- def test_image_create_with_unexist_owner(self):
- self.project_mock.get.side_effect = exceptions.NotFound(None)
- self.project_mock.find.side_effect = exceptions.NotFound(None)
-
- arglist = [
- '--container-format', 'ovf',
- '--disk-format', 'ami',
- '--min-disk', '10',
- '--min-ram', '4',
- '--owner', 'unexist_owner',
- '--protected',
- '--private',
- image_fakes.image_name,
- ]
- verifylist = [
- ('container_format', 'ovf'),
- ('disk_format', 'ami'),
- ('min_disk', 10),
- ('min_ram', 4),
- ('owner', 'unexist_owner'),
- ('protected', True),
- ('unprotected', False),
- ('public', False),
- ('private', True),
- ('name', image_fakes.image_name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.assertRaises(
- exceptions.CommandError,
- self.cmd.take_action,
- parsed_args,
- )
-
def test_image_create_with_unexist_project(self):
self.project_mock.get.side_effect = exceptions.NotFound(None)
self.project_mock.find.side_effect = exceptions.NotFound(None)
@@ -734,7 +700,7 @@ class TestImageList(TestImage):
), )
self.assertEqual(datalist, tuple(data))
- @mock.patch('openstackclient.api.utils.simple_filter')
+ @mock.patch('osc_lib.api.utils.simple_filter')
def test_image_list_property_option(self, sf_mock):
sf_mock.return_value = [copy.deepcopy(self._image)]
@@ -1146,24 +1112,6 @@ class TestImageSet(TestImage):
image_fakes.image_id, **kwargs)
self.assertIsNone(result)
- def test_image_set_with_unexist_owner(self):
- self.project_mock.get.side_effect = exceptions.NotFound(None)
- self.project_mock.find.side_effect = exceptions.NotFound(None)
-
- arglist = [
- '--owner', 'unexist_owner',
- image_fakes.image_id,
- ]
- verifylist = [
- ('owner', 'unexist_owner'),
- ('image', image_fakes.image_id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.assertRaises(
- exceptions.CommandError,
- self.cmd.take_action, parsed_args)
-
def test_image_set_with_unexist_project(self):
self.project_mock.get.side_effect = exceptions.NotFound(None)
self.project_mock.find.side_effect = exceptions.NotFound(None)
diff --git a/openstackclient/tests/unit/integ/cli/test_shell.py b/openstackclient/tests/unit/integ/cli/test_shell.py
index 70303be3..200f9b18 100644
--- a/openstackclient/tests/unit/integ/cli/test_shell.py
+++ b/openstackclient/tests/unit/integ/cli/test_shell.py
@@ -12,6 +12,7 @@
import copy
+import fixtures
import mock
from osc_lib.tests import utils as osc_lib_utils
@@ -399,6 +400,16 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg):
test_shell.PUBLIC_1['public-clouds']['megadodo']['auth']['auth_url'] \
= test_base.V3_AUTH_URL
+ def get_temp_file_path(self, filename):
+ """Returns an absolute path for a temporary file.
+
+ :param filename: filename
+ :type filename: string
+ :returns: absolute file path string
+ """
+ temp_dir = self.useFixture(fixtures.TempDir())
+ return temp_dir.join(filename)
+
@mock.patch(CONFIG_MOCK_BASE + ".OpenStackConfig._load_vendor_file")
@mock.patch(CONFIG_MOCK_BASE + ".OpenStackConfig._load_config_file")
def test_shell_args_precedence_1(self, config_mock, vendor_mock):
@@ -408,7 +419,9 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg):
"""
def config_mock_return():
- return ('file.yaml', copy.deepcopy(test_shell.CLOUD_2))
+ log_file = self.get_temp_file_path('test_log_file')
+ cloud2 = test_shell.get_cloud(log_file)
+ return ('file.yaml', cloud2)
config_mock.side_effect = config_mock_return
def vendor_mock_return():
@@ -478,7 +491,9 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg):
"""
def config_mock_return():
- return ('file.yaml', copy.deepcopy(test_shell.CLOUD_2))
+ log_file = self.get_temp_file_path('test_log_file')
+ cloud2 = test_shell.get_cloud(log_file)
+ return ('file.yaml', cloud2)
config_mock.side_effect = config_mock_return
def vendor_mock_return():
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index 3e5ceac4..079b9746 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -939,52 +939,6 @@ class TestSetRouter(TestRouter):
_testrouter, **attrs)
self.assertIsNone(result)
- def test_set_clear_routes(self):
- arglist = [
- self._router.name,
- '--clear-routes',
- ]
- verifylist = [
- ('router', self._router.name),
- ('clear_routes', True),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- attrs = {
- 'routes': [],
- }
- self.network.update_router.assert_called_once_with(
- self._router, **attrs)
- self.assertIsNone(result)
-
- def test_overwrite_route_clear_routes(self):
- _testrouter = network_fakes.FakeRouter.create_one_router(
- {'routes': [{"destination": "10.0.0.2",
- "nexthop": "1.1.1.1"}]})
- self.network.find_router = mock.Mock(return_value=_testrouter)
- arglist = [
- _testrouter.name,
- '--route', 'destination=10.20.30.0/24,gateway=10.20.30.1',
- '--clear-routes',
- ]
- verifylist = [
- ('router', _testrouter.name),
- ('routes', [{'destination': '10.20.30.0/24',
- 'gateway': '10.20.30.1'}]),
- ('clear_routes', True),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
- attrs = {
- 'routes': [{'destination': '10.20.30.0/24',
- 'nexthop': '10.20.30.1'}]
- }
- self.network.update_router.assert_called_once_with(
- _testrouter, **attrs)
- self.assertIsNone(result)
-
def test_set_nothing(self):
arglist = [
self._router.name,
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py b/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py
index 5c1937e3..6814c197 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py
@@ -72,15 +72,6 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
self.assertRaises(tests_utils.ParserException,
self.check_parser, self.cmd, [], [])
- def test_security_group_rule_create_all_source_options(self, sgr_mock):
- arglist = [
- '--src-ip', '10.10.0.0/24',
- '--src-group', self._security_group['id'],
- self._security_group['id'],
- ]
- self.assertRaises(tests_utils.ParserException,
- self.check_parser, self.cmd, arglist, [])
-
def test_security_group_rule_create_all_remote_options(self, sgr_mock):
arglist = [
'--remote-ip', '10.10.0.0/24',
@@ -151,41 +142,6 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
self.assertEqual(expected_columns, columns)
self.assertEqual(expected_data, data)
- def test_security_group_rule_create_source_group(self, sgr_mock):
- expected_columns, expected_data = self._setup_security_group_rule({
- 'from_port': 22,
- 'to_port': 22,
- 'group': {'name': self._security_group['name']},
- })
- sgr_mock.return_value = self._security_group_rule
- arglist = [
- '--dst-port', str(self._security_group_rule['from_port']),
- '--src-group', self._security_group['name'],
- self._security_group['id'],
- ]
- verifylist = [
- ('dst_port', (self._security_group_rule['from_port'],
- self._security_group_rule['to_port'])),
- ('src_group', self._security_group['name']),
- ('group', self._security_group['id']),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- # TODO(dtroyer): save this for the security group rule changes
- # self.compute.api.security_group_rule_create.assert_called_once_with(
- sgr_mock.assert_called_once_with(
- security_group_id=self._security_group['id'],
- ip_protocol=self._security_group_rule['ip_protocol'],
- from_port=self._security_group_rule['from_port'],
- to_port=self._security_group_rule['to_port'],
- remote_ip=self._security_group_rule['ip_range']['cidr'],
- remote_group=self._security_group['id'],
- )
- self.assertEqual(expected_columns, columns)
- self.assertEqual(expected_data, data)
-
def test_security_group_rule_create_remote_group(self, sgr_mock):
expected_columns, expected_data = self._setup_security_group_rule({
'from_port': 22,
@@ -221,41 +177,6 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
self.assertEqual(expected_columns, columns)
self.assertEqual(expected_data, data)
- def test_security_group_rule_create_source_ip(self, sgr_mock):
- expected_columns, expected_data = self._setup_security_group_rule({
- 'ip_protocol': 'icmp',
- 'from_port': -1,
- 'to_port': -1,
- 'ip_range': {'cidr': '10.0.2.0/24'},
- })
- sgr_mock.return_value = self._security_group_rule
- arglist = [
- '--protocol', self._security_group_rule['ip_protocol'],
- '--src-ip', self._security_group_rule['ip_range']['cidr'],
- self._security_group['id'],
- ]
- verifylist = [
- ('protocol', self._security_group_rule['ip_protocol']),
- ('src_ip', self._security_group_rule['ip_range']['cidr']),
- ('group', self._security_group['id']),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- # TODO(dtroyer): save this for the security group rule changes
- # self.compute.api.security_group_rule_create.assert_called_once_with(
- sgr_mock.assert_called_once_with(
- security_group_id=self._security_group['id'],
- ip_protocol=self._security_group_rule['ip_protocol'],
- from_port=self._security_group_rule['from_port'],
- to_port=self._security_group_rule['to_port'],
- remote_ip=self._security_group_rule['ip_range']['cidr'],
- remote_group=None,
- )
- self.assertEqual(expected_columns, columns)
- self.assertEqual(expected_data, data)
-
def test_security_group_rule_create_remote_ip(self, sgr_mock):
expected_columns, expected_data = self._setup_security_group_rule({
'ip_protocol': 'icmp',
@@ -301,13 +222,13 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
sgr_mock.return_value = self._security_group_rule
arglist = [
'--proto', self._security_group_rule['ip_protocol'],
- '--src-ip', self._security_group_rule['ip_range']['cidr'],
+ '--remote-ip', self._security_group_rule['ip_range']['cidr'],
self._security_group['id'],
]
verifylist = [
('proto', self._security_group_rule['ip_protocol']),
('protocol', None),
- ('src_ip', self._security_group_rule['ip_range']['cidr']),
+ ('remote_ip', self._security_group_rule['ip_range']['cidr']),
('group', self._security_group['id']),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py b/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
index b070ab6a..2b0de0d2 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
@@ -99,15 +99,6 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertRaises(tests_utils.ParserException,
self.check_parser, self.cmd, [], [])
- def test_create_all_source_options(self):
- arglist = [
- '--src-ip', '10.10.0.0/24',
- '--src-group', self._security_group.id,
- self._security_group.id,
- ]
- self.assertRaises(tests_utils.ParserException,
- self.check_parser, self.cmd, arglist, [])
-
def test_create_all_remote_options(self):
arglist = [
'--remote-ip', '10.10.0.0/24',
@@ -212,13 +203,13 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
})
arglist = [
'--proto', self._security_group_rule.protocol,
- '--src-ip', self._security_group_rule.remote_ip_prefix,
+ '--remote-ip', self._security_group_rule.remote_ip_prefix,
self._security_group.id,
]
verifylist = [
('proto', self._security_group_rule.protocol),
('protocol', None),
- ('src_ip', self._security_group_rule.remote_ip_prefix),
+ ('remote_ip', self._security_group_rule.remote_ip_prefix),
('group', self._security_group.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -242,13 +233,13 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
})
arglist = [
'--proto', 'any',
- '--src-ip', self._security_group_rule.remote_ip_prefix,
+ '--remote-ip', self._security_group_rule.remote_ip_prefix,
self._security_group.id,
]
verifylist = [
('proto', 'any'),
('protocol', None),
- ('src_ip', self._security_group_rule.remote_ip_prefix),
+ ('remote_ip', self._security_group_rule.remote_ip_prefix),
('group', self._security_group.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -269,19 +260,18 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self._setup_security_group_rule({
'port_range_max': 22,
'port_range_min': 22,
- 'remote_group_id': self._security_group.id,
})
arglist = [
'--dst-port', str(self._security_group_rule.port_range_min),
'--ingress',
- '--src-group', self._security_group.name,
+ '--remote-group', self._security_group.name,
self._security_group.id,
]
verifylist = [
('dst_port', (self._security_group_rule.port_range_min,
self._security_group_rule.port_range_max)),
('ingress', True),
- ('src_group', self._security_group.name),
+ ('remote_group', self._security_group.name),
('group', self._security_group.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -294,7 +284,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
'port_range_max': self._security_group_rule.port_range_max,
'port_range_min': self._security_group_rule.port_range_min,
'protocol': self._security_group_rule.protocol,
- 'remote_group_id': self._security_group_rule.remote_group_id,
+ 'remote_group_id': self._security_group.id,
'security_group_id': self._security_group.id,
})
self.assertEqual(self.expected_columns, columns)
@@ -306,12 +296,12 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
})
arglist = [
'--ingress',
- '--src-group', self._security_group.name,
+ '--remote-group', self._security_group.name,
self._security_group.id,
]
verifylist = [
('ingress', True),
- ('src_group', self._security_group.name),
+ ('remote_group', self._security_group.name),
('group', self._security_group.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -335,12 +325,12 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
})
arglist = [
'--protocol', self._security_group_rule.protocol,
- '--src-ip', self._security_group_rule.remote_ip_prefix,
+ '--remote-ip', self._security_group_rule.remote_ip_prefix,
self._security_group.id,
]
verifylist = [
('protocol', self._security_group_rule.protocol),
- ('src_ip', self._security_group_rule.remote_ip_prefix),
+ ('remote_ip', self._security_group_rule.remote_ip_prefix),
('group', self._security_group.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/unit/test_shell.py b/openstackclient/tests/unit/test_shell.py
index dff37f10..5d413e7e 100644
--- a/openstackclient/tests/unit/test_shell.py
+++ b/openstackclient/tests/unit/test_shell.py
@@ -70,23 +70,6 @@ CLOUD_1 = {
}
}
-CLOUD_2 = {
- 'clouds': {
- 'megacloud': {
- 'cloud': 'megadodo',
- 'auth': {
- 'project_name': 'heart-o-gold',
- 'username': 'zaphod',
- },
- 'region_name': 'occ-cloud,krikkit,occ-env',
- 'log_file': '/tmp/test_log_file',
- 'log_level': 'debug',
- 'cert': 'mycert',
- 'key': 'mickey',
- }
- }
-}
-
PUBLIC_1 = {
'public-clouds': {
'megadodo': {
@@ -118,6 +101,26 @@ global_options = {
}
+def get_cloud(log_file):
+ CLOUD = {
+ 'clouds': {
+ 'megacloud': {
+ 'cloud': 'megadodo',
+ 'auth': {
+ 'project_name': 'heart-o-gold',
+ 'username': 'zaphod',
+ },
+ 'region_name': 'occ-cloud,krikkit,occ-env',
+ 'log_file': log_file,
+ 'log_level': 'debug',
+ 'cert': 'mycert',
+ 'key': 'mickey',
+ }
+ }
+ }
+ return CLOUD
+
+
# Wrap the osc_lib make_shell() function to set the shell class since
# osc-lib's TestShell class doesn't allow us to specify it yet.
# TODO(dtroyer): remove this once the shell_class_patch patch is released
diff --git a/openstackclient/tests/unit/volume/v1/test_snapshot.py b/openstackclient/tests/unit/volume/v1/test_snapshot.py
deleted file mode 100644
index 70b55ce2..00000000
--- a/openstackclient/tests/unit/volume/v1/test_snapshot.py
+++ /dev/null
@@ -1,580 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-import mock
-from mock import call
-
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.tests.unit import utils as tests_utils
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import volume_snapshot
-
-
-class TestSnapshot(volume_fakes.TestVolumev1):
-
- def setUp(self):
- super(TestSnapshot, self).setUp()
-
- self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
- self.snapshots_mock.reset_mock()
- self.volumes_mock = self.app.client_manager.volume.volumes
- self.volumes_mock.reset_mock()
-
-
-class TestSnapshotCreate(TestSnapshot):
-
- columns = (
- 'created_at',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'volume_id',
- )
-
- def setUp(self):
- super(TestSnapshotCreate, self).setUp()
-
- self.volume = volume_fakes.FakeVolume.create_one_volume()
- self.new_snapshot = volume_fakes.FakeSnapshot.create_one_snapshot(
- attrs={'volume_id': self.volume.id})
-
- self.data = (
- self.new_snapshot.created_at,
- self.new_snapshot.display_description,
- self.new_snapshot.display_name,
- self.new_snapshot.id,
- utils.format_dict(self.new_snapshot.metadata),
- self.new_snapshot.size,
- self.new_snapshot.status,
- self.new_snapshot.volume_id,
- )
-
- self.volumes_mock.get.return_value = self.volume
- self.snapshots_mock.create.return_value = self.new_snapshot
- # Get the command object to test
- self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None)
-
- def test_snapshot_create(self):
- arglist = [
- "--volume", self.new_snapshot.volume_id,
- "--description", self.new_snapshot.display_description,
- "--force",
- self.new_snapshot.display_name,
- ]
- verifylist = [
- ("volume", self.new_snapshot.volume_id),
- ("description", self.new_snapshot.display_description),
- ("force", True),
- ("snapshot_name", self.new_snapshot.display_name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.create.assert_called_with(
- self.new_snapshot.volume_id,
- True,
- self.new_snapshot.display_name,
- self.new_snapshot.display_description,
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
- def test_snapshot_create_without_name(self):
- arglist = [
- "--volume", self.new_snapshot.volume_id,
- ]
- verifylist = [
- ("volume", self.new_snapshot.volume_id),
- ]
- self.assertRaises(
- tests_utils.ParserException,
- self.check_parser,
- self.cmd,
- arglist,
- verifylist,
- )
-
- def test_snapshot_create_without_volume(self):
- arglist = [
- "--description", self.new_snapshot.display_description,
- "--force",
- self.new_snapshot.display_name
- ]
- verifylist = [
- ("description", self.new_snapshot.display_description),
- ("force", True),
- ("snapshot_name", self.new_snapshot.display_name)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.volumes_mock.get.assert_called_once_with(
- self.new_snapshot.display_name)
- self.snapshots_mock.create.assert_called_once_with(
- self.new_snapshot.volume_id,
- True,
- self.new_snapshot.display_name,
- self.new_snapshot.display_description,
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
-
-class TestSnapshotDelete(TestSnapshot):
-
- snapshots = volume_fakes.FakeSnapshot.create_snapshots(count=2)
-
- def setUp(self):
- super(TestSnapshotDelete, self).setUp()
-
- self.snapshots_mock.get = (
- volume_fakes.FakeSnapshot.get_snapshots(self.snapshots))
- self.snapshots_mock.delete.return_value = None
-
- # Get the command object to mock
- self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None)
-
- def test_snapshot_delete(self):
- arglist = [
- self.snapshots[0].id
- ]
- verifylist = [
- ("snapshots", [self.snapshots[0].id])
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.delete.assert_called_with(
- self.snapshots[0].id)
- self.assertIsNone(result)
-
- def test_delete_multiple_snapshots(self):
- arglist = []
- for s in self.snapshots:
- arglist.append(s.id)
- verifylist = [
- ('snapshots', arglist),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
-
- calls = []
- for s in self.snapshots:
- calls.append(call(s.id))
- self.snapshots_mock.delete.assert_has_calls(calls)
- self.assertIsNone(result)
-
- def test_delete_multiple_snapshots_with_exception(self):
- arglist = [
- self.snapshots[0].id,
- 'unexist_snapshot',
- ]
- verifylist = [
- ('snapshots', arglist),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- find_mock_result = [self.snapshots[0], exceptions.CommandError]
- with mock.patch.object(utils, 'find_resource',
- side_effect=find_mock_result) as find_mock:
- try:
- self.cmd.take_action(parsed_args)
- self.fail('CommandError should be raised.')
- except exceptions.CommandError as e:
- self.assertEqual('1 of 2 snapshots failed to delete.',
- str(e))
-
- find_mock.assert_any_call(
- self.snapshots_mock, self.snapshots[0].id)
- find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
-
- self.assertEqual(2, find_mock.call_count)
- self.snapshots_mock.delete.assert_called_once_with(
- self.snapshots[0].id
- )
-
-
-class TestSnapshotList(TestSnapshot):
-
- volume = volume_fakes.FakeVolume.create_one_volume()
- snapshots = volume_fakes.FakeSnapshot.create_snapshots(
- attrs={'volume_id': volume.display_name}, count=3)
-
- columns = [
- "ID",
- "Name",
- "Description",
- "Status",
- "Size"
- ]
- columns_long = columns + [
- "Created At",
- "Volume",
- "Properties"
- ]
-
- data = []
- for s in snapshots:
- data.append((
- s.id,
- s.display_name,
- s.display_description,
- s.status,
- s.size,
- ))
- data_long = []
- for s in snapshots:
- data_long.append((
- s.id,
- s.display_name,
- s.display_description,
- s.status,
- s.size,
- s.created_at,
- s.volume_id,
- utils.format_dict(s.metadata),
- ))
-
- def setUp(self):
- super(TestSnapshotList, self).setUp()
-
- self.volumes_mock.list.return_value = [self.volume]
- self.volumes_mock.get.return_value = self.volume
- self.snapshots_mock.list.return_value = self.snapshots
- # Get the command to test
- self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
-
- def test_snapshot_list_without_options(self):
- arglist = []
- verifylist = [
- ('all_projects', False),
- ("long", False)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- search_opts={
- 'all_tenants': False,
- 'display_name': None,
- 'status': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_with_long(self):
- arglist = [
- "--long",
- ]
- verifylist = [
- ("long", True),
- ('all_projects', False),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- search_opts={
- 'all_tenants': False,
- 'display_name': None,
- 'status': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns_long, columns)
- self.assertEqual(self.data_long, list(data))
-
- def test_snapshot_list_name_option(self):
- arglist = [
- '--name', self.snapshots[0].display_name,
- ]
- verifylist = [
- ('all_projects', False),
- ('long', False),
- ('name', self.snapshots[0].display_name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- search_opts={
- 'all_tenants': False,
- 'display_name': self.snapshots[0].display_name,
- 'status': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_status_option(self):
- arglist = [
- '--status', self.snapshots[0].status,
- ]
- verifylist = [
- ('all_projects', False),
- ('long', False),
- ('status', self.snapshots[0].status),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- search_opts={
- 'all_tenants': False,
- 'display_name': None,
- 'status': self.snapshots[0].status,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_volumeid_option(self):
- arglist = [
- '--volume', self.volume.id,
- ]
- verifylist = [
- ('all_projects', False),
- ('long', False),
- ('volume', self.volume.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- search_opts={
- 'all_tenants': False,
- 'display_name': None,
- 'status': None,
- 'volume_id': self.volume.id
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_all_projects(self):
- arglist = [
- '--all-projects',
- ]
- verifylist = [
- ('long', False),
- ('all_projects', True)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- search_opts={
- 'all_tenants': True,
- 'display_name': None,
- 'status': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
-
-class TestSnapshotSet(TestSnapshot):
-
- snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
-
- def setUp(self):
- super(TestSnapshotSet, self).setUp()
-
- self.snapshots_mock.get.return_value = self.snapshot
- self.snapshots_mock.set_metadata.return_value = None
- # Get the command object to mock
- self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None)
-
- def test_snapshot_set_all(self):
- arglist = [
- "--name", "new_snapshot",
- "--description", "new_description",
- "--property", "foo_1=foo_1",
- "--property", "foo_2=foo_2",
- "--no-property",
- self.snapshot.id,
- ]
- new_property = {"foo_1": "foo_1", "foo_2": "foo_2"}
- verifylist = [
- ("name", "new_snapshot"),
- ("description", "new_description"),
- ("property", new_property),
- ("no_property", True),
- ("snapshot", self.snapshot.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- kwargs = {
- "display_name": "new_snapshot",
- "display_description": "new_description",
- }
- self.snapshot.update.assert_called_with(**kwargs)
- self.snapshots_mock.delete_metadata.assert_called_with(
- self.snapshot.id, ["foo"]
- )
- self.snapshots_mock.set_metadata.assert_called_with(
- self.snapshot.id, {"foo_2": "foo_2", "foo_1": "foo_1"}
- )
- self.assertIsNone(result)
-
- def test_snapshot_set_nothing(self):
- arglist = [
- self.snapshot.id,
- ]
- verifylist = [
- ("snapshot", self.snapshot.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
- self.assertIsNone(result)
-
- def test_snapshot_set_fail(self):
- self.snapshots_mock.set_metadata.side_effect = (
- exceptions.CommandError())
- arglist = [
- "--name", "new_snapshot",
- "--description", "new_description",
- "--property", "x=y",
- "--property", "foo=foo",
- self.snapshot.id,
- ]
- new_property = {"x": "y", "foo": "foo"}
- verifylist = [
- ("name", "new_snapshot"),
- ("description", "new_description"),
- ("property", new_property),
- ("snapshot", self.snapshot.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.assertRaises(exceptions.CommandError,
- self.cmd.take_action, parsed_args)
-
-
-class TestSnapshotShow(TestSnapshot):
-
- columns = (
- 'created_at',
- 'display_description',
- 'display_name',
- 'id',
- 'properties',
- 'size',
- 'status',
- 'volume_id',
- )
-
- def setUp(self):
- super(TestSnapshotShow, self).setUp()
-
- self.snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
-
- self.data = (
- self.snapshot.created_at,
- self.snapshot.display_description,
- self.snapshot.display_name,
- self.snapshot.id,
- utils.format_dict(self.snapshot.metadata),
- self.snapshot.size,
- self.snapshot.status,
- self.snapshot.volume_id,
- )
-
- self.snapshots_mock.get.return_value = self.snapshot
- # Get the command object to test
- self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
-
- def test_snapshot_show(self):
- arglist = [
- self.snapshot.id
- ]
- verifylist = [
- ("snapshot", self.snapshot.id)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
- self.snapshots_mock.get.assert_called_with(self.snapshot.id)
-
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
-
-class TestSnapshotUnset(TestSnapshot):
-
- snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
-
- def setUp(self):
- super(TestSnapshotUnset, self).setUp()
-
- self.snapshots_mock.get.return_value = self.snapshot
- self.snapshots_mock.delete_metadata.return_value = None
- # Get the command object to mock
- self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None)
-
- def test_snapshot_unset(self):
- arglist = [
- "--property", "foo",
- self.snapshot.id,
- ]
- verifylist = [
- ("property", ["foo"]),
- ("snapshot", self.snapshot.id),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.delete_metadata.assert_called_with(
- self.snapshot.id, ["foo"]
- )
- self.assertIsNone(result)
-
- def test_snapshot_unset_nothing(self):
- arglist = [
- self.snapshot.id,
- ]
- verifylist = [
- ("snapshot", self.snapshot.id),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
- self.assertIsNone(result)
diff --git a/openstackclient/tests/unit/volume/v1/test_transfer_request.py b/openstackclient/tests/unit/volume/v1/test_transfer_request.py
index 4c013dc0..680561d5 100644
--- a/openstackclient/tests/unit/volume/v1/test_transfer_request.py
+++ b/openstackclient/tests/unit/volume/v1/test_transfer_request.py
@@ -85,26 +85,6 @@ class TestTransferAccept(TestTransfer):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
- def test_transfer_accept_deprecated(self):
- arglist = [
- self.volume_transfer.id,
- 'key_value',
- ]
- verifylist = [
- ('transfer_request', self.volume_transfer.id),
- ('old_auth_key', 'key_value'),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.transfer_mock.accept.assert_called_once_with(
- self.volume_transfer.id,
- 'key_value',
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
def test_transfer_accept_no_option(self):
arglist = [
self.volume_transfer.id,
diff --git a/openstackclient/tests/unit/volume/v1/test_backup.py b/openstackclient/tests/unit/volume/v1/test_volume_backup.py
index 1097d3f1..22c1f8cf 100644
--- a/openstackclient/tests/unit/volume/v1/test_backup.py
+++ b/openstackclient/tests/unit/volume/v1/test_volume_backup.py
@@ -19,7 +19,7 @@ from osc_lib import exceptions
from osc_lib import utils
from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import backup
+from openstackclient.volume.v1 import volume_backup
class TestBackup(volume_fakes.TestVolumev1):
@@ -74,7 +74,7 @@ class TestBackupCreate(TestBackup):
self.backups_mock.create.return_value = self.new_backup
# Get the command object to test
- self.cmd = backup.CreateVolumeBackup(self.app, None)
+ self.cmd = volume_backup.CreateVolumeBackup(self.app, None)
def test_backup_create(self):
arglist = [
@@ -139,7 +139,7 @@ class TestBackupDelete(TestBackup):
self.backups_mock.delete.return_value = None
# Get the command object to mock
- self.cmd = backup.DeleteVolumeBackup(self.app, None)
+ self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
def test_backup_delete(self):
arglist = [
@@ -251,7 +251,7 @@ class TestBackupList(TestBackup):
self.backups_mock.list.return_value = self.backups
self.volumes_mock.get.return_value = self.volume
# Get the command to test
- self.cmd = backup.ListVolumeBackup(self.app, None)
+ self.cmd = volume_backup.ListVolumeBackup(self.app, None)
def test_backup_list_without_options(self):
arglist = []
@@ -325,7 +325,7 @@ class TestBackupRestore(TestBackup):
self.volumes_mock.get.return_value = self.volume
self.restores_mock.restore.return_value = None
# Get the command object to mock
- self.cmd = backup.RestoreVolumeBackup(self.app, None)
+ self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
def test_backup_restore(self):
arglist = [
@@ -376,7 +376,7 @@ class TestBackupShow(TestBackup):
)
self.backups_mock.get.return_value = self.backup
# Get the command object to test
- self.cmd = backup.ShowVolumeBackup(self.app, None)
+ self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
def test_backup_show(self):
arglist = [
diff --git a/openstackclient/tests/unit/volume/v2/test_snapshot.py b/openstackclient/tests/unit/volume/v2/test_snapshot.py
deleted file mode 100644
index e8f4ae5a..00000000
--- a/openstackclient/tests/unit/volume/v2/test_snapshot.py
+++ /dev/null
@@ -1,741 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-import argparse
-
-import mock
-from mock import call
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.tests.unit.identity.v3 import fakes as project_fakes
-from openstackclient.tests.unit import utils as tests_utils
-from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
-from openstackclient.volume.v2 import volume_snapshot
-
-
-class TestSnapshot(volume_fakes.TestVolume):
-
- def setUp(self):
- super(TestSnapshot, self).setUp()
-
- self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
- self.snapshots_mock.reset_mock()
- self.volumes_mock = self.app.client_manager.volume.volumes
- self.volumes_mock.reset_mock()
- self.project_mock = self.app.client_manager.identity.projects
- self.project_mock.reset_mock()
-
-
-class TestSnapshotCreate(TestSnapshot):
-
- columns = (
- 'created_at',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'status',
- 'volume_id',
- )
-
- def setUp(self):
- super(TestSnapshotCreate, self).setUp()
-
- self.volume = volume_fakes.FakeVolume.create_one_volume()
- self.new_snapshot = volume_fakes.FakeSnapshot.create_one_snapshot(
- attrs={'volume_id': self.volume.id})
-
- self.data = (
- self.new_snapshot.created_at,
- self.new_snapshot.description,
- self.new_snapshot.id,
- self.new_snapshot.name,
- utils.format_dict(self.new_snapshot.metadata),
- self.new_snapshot.size,
- self.new_snapshot.status,
- self.new_snapshot.volume_id,
- )
-
- self.volumes_mock.get.return_value = self.volume
- self.snapshots_mock.create.return_value = self.new_snapshot
- self.snapshots_mock.manage.return_value = self.new_snapshot
- # Get the command object to test
- self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None)
-
- def test_snapshot_create(self):
- arglist = [
- "--volume", self.new_snapshot.volume_id,
- "--description", self.new_snapshot.description,
- "--force",
- '--property', 'Alpha=a',
- '--property', 'Beta=b',
- self.new_snapshot.name,
- ]
- verifylist = [
- ("volume", self.new_snapshot.volume_id),
- ("description", self.new_snapshot.description),
- ("force", True),
- ('property', {'Alpha': 'a', 'Beta': 'b'}),
- ("snapshot_name", self.new_snapshot.name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.create.assert_called_with(
- self.new_snapshot.volume_id,
- force=True,
- name=self.new_snapshot.name,
- description=self.new_snapshot.description,
- metadata={'Alpha': 'a', 'Beta': 'b'},
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
- def test_snapshot_create_without_name(self):
- arglist = [
- "--volume", self.new_snapshot.volume_id,
- ]
- verifylist = [
- ("volume", self.new_snapshot.volume_id),
- ]
- self.assertRaises(
- tests_utils.ParserException,
- self.check_parser,
- self.cmd,
- arglist,
- verifylist,
- )
-
- def test_snapshot_create_without_volume(self):
- arglist = [
- "--description", self.new_snapshot.description,
- "--force",
- self.new_snapshot.name
- ]
- verifylist = [
- ("description", self.new_snapshot.description),
- ("force", True),
- ("snapshot_name", self.new_snapshot.name)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.volumes_mock.get.assert_called_once_with(
- self.new_snapshot.name)
- self.snapshots_mock.create.assert_called_once_with(
- self.new_snapshot.volume_id,
- force=True,
- name=self.new_snapshot.name,
- description=self.new_snapshot.description,
- metadata=None,
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
- def test_snapshot_create_with_remote_source(self):
- arglist = [
- '--remote-source', 'source-name=test_source_name',
- '--remote-source', 'source-id=test_source_id',
- '--volume', self.new_snapshot.volume_id,
- self.new_snapshot.name,
- ]
- ref_dict = {'source-name': 'test_source_name',
- 'source-id': 'test_source_id'}
- verifylist = [
- ('remote_source', ref_dict),
- ('volume', self.new_snapshot.volume_id),
- ("snapshot_name", self.new_snapshot.name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.manage.assert_called_with(
- volume_id=self.new_snapshot.volume_id,
- ref=ref_dict,
- name=self.new_snapshot.name,
- description=None,
- metadata=None,
- )
- self.snapshots_mock.create.assert_not_called()
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
-
-class TestSnapshotDelete(TestSnapshot):
-
- snapshots = volume_fakes.FakeSnapshot.create_snapshots(count=2)
-
- def setUp(self):
- super(TestSnapshotDelete, self).setUp()
-
- self.snapshots_mock.get = (
- volume_fakes.FakeSnapshot.get_snapshots(self.snapshots))
- self.snapshots_mock.delete.return_value = None
-
- # Get the command object to mock
- self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None)
-
- def test_snapshot_delete(self):
- arglist = [
- self.snapshots[0].id
- ]
- verifylist = [
- ("snapshots", [self.snapshots[0].id])
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.delete.assert_called_with(
- self.snapshots[0].id, False)
- self.assertIsNone(result)
-
- def test_snapshot_delete_with_force(self):
- arglist = [
- '--force',
- self.snapshots[0].id
- ]
- verifylist = [
- ('force', True),
- ("snapshots", [self.snapshots[0].id])
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.delete.assert_called_with(
- self.snapshots[0].id, True)
- self.assertIsNone(result)
-
- def test_delete_multiple_snapshots(self):
- arglist = []
- for s in self.snapshots:
- arglist.append(s.id)
- verifylist = [
- ('snapshots', arglist),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
-
- calls = []
- for s in self.snapshots:
- calls.append(call(s.id, False))
- self.snapshots_mock.delete.assert_has_calls(calls)
- self.assertIsNone(result)
-
- def test_delete_multiple_snapshots_with_exception(self):
- arglist = [
- self.snapshots[0].id,
- 'unexist_snapshot',
- ]
- verifylist = [
- ('snapshots', arglist),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- find_mock_result = [self.snapshots[0], exceptions.CommandError]
- with mock.patch.object(utils, 'find_resource',
- side_effect=find_mock_result) as find_mock:
- try:
- self.cmd.take_action(parsed_args)
- self.fail('CommandError should be raised.')
- except exceptions.CommandError as e:
- self.assertEqual('1 of 2 snapshots failed to delete.',
- str(e))
-
- find_mock.assert_any_call(
- self.snapshots_mock, self.snapshots[0].id)
- find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
-
- self.assertEqual(2, find_mock.call_count)
- self.snapshots_mock.delete.assert_called_once_with(
- self.snapshots[0].id, False
- )
-
-
-class TestSnapshotList(TestSnapshot):
-
- volume = volume_fakes.FakeVolume.create_one_volume()
- project = project_fakes.FakeProject.create_one_project()
- snapshots = volume_fakes.FakeSnapshot.create_snapshots(
- attrs={'volume_id': volume.name}, count=3)
-
- columns = [
- "ID",
- "Name",
- "Description",
- "Status",
- "Size"
- ]
- columns_long = columns + [
- "Created At",
- "Volume",
- "Properties"
- ]
-
- data = []
- for s in snapshots:
- data.append((
- s.id,
- s.name,
- s.description,
- s.status,
- s.size,
- ))
- data_long = []
- for s in snapshots:
- data_long.append((
- s.id,
- s.name,
- s.description,
- s.status,
- s.size,
- s.created_at,
- s.volume_id,
- utils.format_dict(s.metadata),
- ))
-
- def setUp(self):
- super(TestSnapshotList, self).setUp()
-
- self.volumes_mock.list.return_value = [self.volume]
- self.volumes_mock.get.return_value = self.volume
- self.project_mock.get.return_value = self.project
- self.snapshots_mock.list.return_value = self.snapshots
- # Get the command to test
- self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
-
- def test_snapshot_list_without_options(self):
- arglist = []
- verifylist = [
- ('all_projects', False),
- ('long', False)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- limit=None, marker=None,
- search_opts={
- 'all_tenants': False,
- 'name': None,
- 'status': None,
- 'project_id': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_with_options(self):
- arglist = [
- "--long",
- "--limit", "2",
- "--project", self.project.id,
- "--marker", self.snapshots[0].id,
- ]
- verifylist = [
- ("long", True),
- ("limit", 2),
- ("project", self.project.id),
- ("marker", self.snapshots[0].id),
- ('all_projects', False),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- limit=2,
- marker=self.snapshots[0].id,
- search_opts={
- 'all_tenants': True,
- 'project_id': self.project.id,
- 'name': None,
- 'status': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns_long, columns)
- self.assertEqual(self.data_long, list(data))
-
- def test_snapshot_list_all_projects(self):
- arglist = [
- '--all-projects',
- ]
- verifylist = [
- ('long', False),
- ('all_projects', True)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- limit=None, marker=None,
- search_opts={
- 'all_tenants': True,
- 'name': None,
- 'status': None,
- 'project_id': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_name_option(self):
- arglist = [
- '--name', self.snapshots[0].name,
- ]
- verifylist = [
- ('all_projects', False),
- ('long', False),
- ('name', self.snapshots[0].name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- limit=None, marker=None,
- search_opts={
- 'all_tenants': False,
- 'name': self.snapshots[0].name,
- 'status': None,
- 'project_id': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_status_option(self):
- arglist = [
- '--status', self.snapshots[0].status,
- ]
- verifylist = [
- ('all_projects', False),
- ('long', False),
- ('status', self.snapshots[0].status),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- limit=None, marker=None,
- search_opts={
- 'all_tenants': False,
- 'name': None,
- 'status': self.snapshots[0].status,
- 'project_id': None,
- 'volume_id': None
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_volumeid_option(self):
- arglist = [
- '--volume', self.volume.id,
- ]
- verifylist = [
- ('all_projects', False),
- ('long', False),
- ('volume', self.volume.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.list.assert_called_once_with(
- limit=None, marker=None,
- search_opts={
- 'all_tenants': False,
- 'name': None,
- 'status': None,
- 'project_id': None,
- 'volume_id': self.volume.id
- }
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, list(data))
-
- def test_snapshot_list_negative_limit(self):
- arglist = [
- "--limit", "-2",
- ]
- verifylist = [
- ("limit", -2),
- ]
- self.assertRaises(argparse.ArgumentTypeError, self.check_parser,
- self.cmd, arglist, verifylist)
-
-
-class TestSnapshotSet(TestSnapshot):
-
- snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
-
- def setUp(self):
- super(TestSnapshotSet, self).setUp()
-
- self.snapshots_mock.get.return_value = self.snapshot
- self.snapshots_mock.set_metadata.return_value = None
- self.snapshots_mock.update.return_value = None
- # Get the command object to mock
- self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None)
-
- def test_snapshot_set_no_option(self):
- arglist = [
- self.snapshot.id,
- ]
- verifylist = [
- ("snapshot", self.snapshot.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
- self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
- self.assertNotCalled(self.snapshots_mock.reset_state)
- self.assertNotCalled(self.snapshots_mock.update)
- self.assertNotCalled(self.snapshots_mock.set_metadata)
- self.assertIsNone(result)
-
- def test_snapshot_set_name_and_property(self):
- arglist = [
- "--name", "new_snapshot",
- "--property", "x=y",
- "--property", "foo=foo",
- self.snapshot.id,
- ]
- new_property = {"x": "y", "foo": "foo"}
- verifylist = [
- ("name", "new_snapshot"),
- ("property", new_property),
- ("snapshot", self.snapshot.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- kwargs = {
- "name": "new_snapshot",
- }
- self.snapshots_mock.update.assert_called_with(
- self.snapshot.id, **kwargs)
- self.snapshots_mock.set_metadata.assert_called_with(
- self.snapshot.id, new_property
- )
- self.assertIsNone(result)
-
- def test_snapshot_set_with_no_property(self):
- arglist = [
- "--no-property",
- self.snapshot.id,
- ]
- verifylist = [
- ("no_property", True),
- ("snapshot", self.snapshot.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
- self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
- self.assertNotCalled(self.snapshots_mock.reset_state)
- self.assertNotCalled(self.snapshots_mock.update)
- self.assertNotCalled(self.snapshots_mock.set_metadata)
- self.snapshots_mock.delete_metadata.assert_called_with(
- self.snapshot.id, ["foo"]
- )
- self.assertIsNone(result)
-
- def test_snapshot_set_with_no_property_and_property(self):
- arglist = [
- "--no-property",
- "--property", "foo_1=bar_1",
- self.snapshot.id,
- ]
- verifylist = [
- ("no_property", True),
- ("property", {"foo_1": "bar_1"}),
- ("snapshot", self.snapshot.id),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
- self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
- self.assertNotCalled(self.snapshots_mock.reset_state)
- self.assertNotCalled(self.snapshots_mock.update)
- self.snapshots_mock.delete_metadata.assert_called_with(
- self.snapshot.id, ["foo"]
- )
- self.snapshots_mock.set_metadata.assert_called_once_with(
- self.snapshot.id, {"foo_1": "bar_1"})
- self.assertIsNone(result)
-
- def test_snapshot_set_state_to_error(self):
- arglist = [
- "--state", "error",
- self.snapshot.id
- ]
- verifylist = [
- ("state", "error"),
- ("snapshot", self.snapshot.id)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.reset_state.assert_called_with(
- self.snapshot.id, "error")
- self.assertIsNone(result)
-
- def test_volume_set_state_failed(self):
- self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
- arglist = [
- '--state', 'error',
- self.snapshot.id
- ]
- verifylist = [
- ('state', 'error'),
- ('snapshot', self.snapshot.id)
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- try:
- self.cmd.take_action(parsed_args)
- self.fail('CommandError should be raised.')
- except exceptions.CommandError as e:
- self.assertEqual('One or more of the set operations failed',
- str(e))
- self.snapshots_mock.reset_state.assert_called_once_with(
- self.snapshot.id, 'error')
-
- def test_volume_set_name_and_state_failed(self):
- self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
- arglist = [
- '--state', 'error',
- "--name", "new_snapshot",
- self.snapshot.id
- ]
- verifylist = [
- ('state', 'error'),
- ("name", "new_snapshot"),
- ('snapshot', self.snapshot.id)
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- try:
- self.cmd.take_action(parsed_args)
- self.fail('CommandError should be raised.')
- except exceptions.CommandError as e:
- self.assertEqual('One or more of the set operations failed',
- str(e))
- kwargs = {
- "name": "new_snapshot",
- }
- self.snapshots_mock.update.assert_called_once_with(
- self.snapshot.id, **kwargs)
- self.snapshots_mock.reset_state.assert_called_once_with(
- self.snapshot.id, 'error')
-
-
-class TestSnapshotShow(TestSnapshot):
-
- columns = (
- 'created_at',
- 'description',
- 'id',
- 'name',
- 'properties',
- 'size',
- 'status',
- 'volume_id',
- )
-
- def setUp(self):
- super(TestSnapshotShow, self).setUp()
-
- self.snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
-
- self.data = (
- self.snapshot.created_at,
- self.snapshot.description,
- self.snapshot.id,
- self.snapshot.name,
- utils.format_dict(self.snapshot.metadata),
- self.snapshot.size,
- self.snapshot.status,
- self.snapshot.volume_id,
- )
-
- self.snapshots_mock.get.return_value = self.snapshot
- # Get the command object to test
- self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
-
- def test_snapshot_show(self):
- arglist = [
- self.snapshot.id
- ]
- verifylist = [
- ("snapshot", self.snapshot.id)
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
- self.snapshots_mock.get.assert_called_with(self.snapshot.id)
-
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
-
-class TestSnapshotUnset(TestSnapshot):
-
- snapshot = volume_fakes.FakeSnapshot.create_one_snapshot()
-
- def setUp(self):
- super(TestSnapshotUnset, self).setUp()
-
- self.snapshots_mock.get.return_value = self.snapshot
- self.snapshots_mock.delete_metadata.return_value = None
- # Get the command object to mock
- self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None)
-
- def test_snapshot_unset(self):
- arglist = [
- "--property", "foo",
- self.snapshot.id,
- ]
- verifylist = [
- ("property", ["foo"]),
- ("snapshot", self.snapshot.id),
- ]
-
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- result = self.cmd.take_action(parsed_args)
-
- self.snapshots_mock.delete_metadata.assert_called_with(
- self.snapshot.id, ["foo"]
- )
- self.assertIsNone(result)
diff --git a/openstackclient/tests/unit/volume/v2/test_transfer_request.py b/openstackclient/tests/unit/volume/v2/test_transfer_request.py
index 37eed11e..1ea6648f 100644
--- a/openstackclient/tests/unit/volume/v2/test_transfer_request.py
+++ b/openstackclient/tests/unit/volume/v2/test_transfer_request.py
@@ -18,6 +18,7 @@ from mock import call
from osc_lib import exceptions
from osc_lib import utils
+from openstackclient.tests.unit import utils as test_utils
from openstackclient.tests.unit.volume.v2 import fakes as transfer_fakes
from openstackclient.volume.v2 import volume_transfer_request
@@ -85,26 +86,6 @@ class TestTransferAccept(TestTransfer):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
- def test_transfer_accept_deprecated(self):
- arglist = [
- self.volume_transfer.id,
- 'key_value',
- ]
- verifylist = [
- ('transfer_request', self.volume_transfer.id),
- ('old_auth_key', 'key_value'),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- columns, data = self.cmd.take_action(parsed_args)
-
- self.transfer_mock.accept.assert_called_once_with(
- self.volume_transfer.id,
- 'key_value',
- )
- self.assertEqual(self.columns, columns)
- self.assertEqual(self.data, data)
-
def test_transfer_accept_no_option(self):
arglist = [
self.volume_transfer.id,
@@ -112,12 +93,13 @@ class TestTransferAccept(TestTransfer):
verifylist = [
('transfer_request', self.volume_transfer.id),
]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
- exceptions.CommandError,
- self.cmd.take_action,
- parsed_args,
+ test_utils.ParserException,
+ self.check_parser,
+ self.cmd,
+ arglist,
+ verifylist,
)
diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py
index dbe69ea0..97da1601 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume.py
@@ -183,40 +183,6 @@ class TestVolumeCreate(TestVolume):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
- def test_volume_create_user(self):
- arglist = [
- '--size', str(self.new_volume.size),
- '--user', self.user.id,
- self.new_volume.name,
- ]
- verifylist = [
- ('size', self.new_volume.size),
- ('user', self.user.id),
- ('name', self.new_volume.name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.assertRaises(exceptions.CommandError, self.cmd.take_action,
- parsed_args)
- self.volumes_mock.create.assert_not_called()
-
- def test_volume_create_project(self):
- arglist = [
- '--size', str(self.new_volume.size),
- '--project', self.project.id,
- self.new_volume.name,
- ]
- verifylist = [
- ('size', self.new_volume.size),
- ('project', self.project.id),
- ('name', self.new_volume.name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- self.assertRaises(exceptions.CommandError, self.cmd.take_action,
- parsed_args)
- self.volumes_mock.create.assert_not_called()
-
def test_volume_create_properties(self):
arglist = [
'--property', 'Alpha=a',
diff --git a/openstackclient/tests/unit/volume/v2/test_backup.py b/openstackclient/tests/unit/volume/v2/test_volume_backup.py
index 9a2ce718..d0d1da3b 100644
--- a/openstackclient/tests/unit/volume/v2/test_backup.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume_backup.py
@@ -19,7 +19,7 @@ from osc_lib import exceptions
from osc_lib import utils
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
-from openstackclient.volume.v2 import backup
+from openstackclient.volume.v2 import volume_backup
class TestBackup(volume_fakes.TestVolume):
@@ -77,7 +77,7 @@ class TestBackupCreate(TestBackup):
self.backups_mock.create.return_value = self.new_backup
# Get the command object to test
- self.cmd = backup.CreateVolumeBackup(self.app, None)
+ self.cmd = volume_backup.CreateVolumeBackup(self.app, None)
def test_backup_create(self):
arglist = [
@@ -154,7 +154,7 @@ class TestBackupDelete(TestBackup):
self.backups_mock.delete.return_value = None
# Get the command object to mock
- self.cmd = backup.DeleteVolumeBackup(self.app, None)
+ self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
def test_backup_delete(self):
arglist = [
@@ -283,7 +283,7 @@ class TestBackupList(TestBackup):
self.volumes_mock.get.return_value = self.volume
self.backups_mock.get.return_value = self.backups[0]
# Get the command to test
- self.cmd = backup.ListVolumeBackup(self.app, None)
+ self.cmd = volume_backup.ListVolumeBackup(self.app, None)
def test_backup_list_without_options(self):
arglist = []
@@ -371,7 +371,7 @@ class TestBackupRestore(TestBackup):
volume_fakes.FakeVolume.create_one_volume(
{'id': self.volume['id']}))
# Get the command object to mock
- self.cmd = backup.RestoreVolumeBackup(self.app, None)
+ self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
def test_backup_restore(self):
arglist = [
@@ -400,7 +400,7 @@ class TestBackupSet(TestBackup):
self.backups_mock.get.return_value = self.backup
# Get the command object to test
- self.cmd = backup.SetVolumeBackup(self.app, None)
+ self.cmd = volume_backup.SetVolumeBackup(self.app, None)
def test_backup_set_name(self):
arglist = [
@@ -517,7 +517,7 @@ class TestBackupShow(TestBackup):
self.backups_mock.get.return_value = self.backup
# Get the command object to test
- self.cmd = backup.ShowVolumeBackup(self.app, None)
+ self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
def test_backup_show(self):
arglist = [
diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py
deleted file mode 100644
index e9e3894b..00000000
--- a/openstackclient/volume/v1/snapshot.py
+++ /dev/null
@@ -1,318 +0,0 @@
-# Copyright 2012-2013 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-# TODO(Huanxuan Ao): Remove this file and "snapshot create", "snapshot delete",
-# "snapshot set", "snapshot show" and "snapshot unset"
-# commands two cycles after Ocata.
-
-"""Volume v1 Snapshot action implementations"""
-
-import copy
-import logging
-
-from osc_lib.cli import parseractions
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-import six
-
-from openstackclient.i18n import _
-
-
-deprecated = True
-LOG_DEP = logging.getLogger('deprecated')
-LOG = logging.getLogger(__name__)
-
-
-class CreateSnapshot(command.ShowOne):
- _description = _("Create new snapshot")
-
- def get_parser(self, prog_name):
- parser = super(CreateSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- 'volume',
- metavar='<volume>',
- help=_('Volume to snapshot (name or ID)'),
- )
- parser.add_argument(
- '--name',
- metavar='<name>',
- help=_('Name of the snapshot'),
- )
- parser.add_argument(
- '--description',
- metavar='<description>',
- help=_('Description of the snapshot'),
- )
- parser.add_argument(
- '--force',
- dest='force',
- action='store_true',
- default=False,
- help=_('Create a snapshot attached to an instance. '
- 'Default is False'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot create" instead.'))
- volume_client = self.app.client_manager.volume
- volume_id = utils.find_resource(volume_client.volumes,
- parsed_args.volume).id
- snapshot = volume_client.volume_snapshots.create(
- volume_id,
- parsed_args.force,
- parsed_args.name,
- parsed_args.description
- )
-
- snapshot._info.update(
- {'properties': utils.format_dict(snapshot._info.pop('metadata'))}
- )
-
- return zip(*sorted(six.iteritems(snapshot._info)))
-
-
-class DeleteSnapshot(command.Command):
- _description = _("Delete snapshot(s)")
-
- def get_parser(self, prog_name):
- parser = super(DeleteSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- 'snapshots',
- metavar='<snapshot>',
- nargs="+",
- help=_('Snapshot(s) to delete (name or ID)'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot delete" instead.'))
- volume_client = self.app.client_manager.volume
- result = 0
-
- for i in parsed_args.snapshots:
- try:
- snapshot_id = utils.find_resource(
- volume_client.volume_snapshots, i).id
- volume_client.volume_snapshots.delete(snapshot_id)
- except Exception as e:
- result += 1
- LOG.error(_("Failed to delete snapshot with "
- "name or ID '%(snapshot)s': %(e)s"),
- {'snapshot': i, 'e': e})
-
- if result > 0:
- total = len(parsed_args.snapshots)
- msg = (_("%(result)s of %(total)s snapshots failed "
- "to delete.") % {'result': result, 'total': total})
- raise exceptions.CommandError(msg)
-
-
-class ListSnapshot(command.Lister):
- _description = _("List snapshots")
-
- def get_parser(self, prog_name):
- parser = super(ListSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- '--all-projects',
- action='store_true',
- default=False,
- help=_('Include all projects (admin only)'),
- )
- parser.add_argument(
- '--long',
- action='store_true',
- default=False,
- help=_('List additional fields in output'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot list" instead.'))
-
- def _format_volume_id(volume_id):
- """Return a volume name if available
-
- :param volume_id: a volume ID
- :rtype: either the volume ID or name
- """
-
- volume = volume_id
- if volume_id in volume_cache.keys():
- volume = volume_cache[volume_id].display_name
- return volume
-
- if parsed_args.long:
- columns = ['ID', 'Display Name', 'Display Description', 'Status',
- 'Size', 'Created At', 'Volume ID', 'Metadata']
- column_headers = copy.deepcopy(columns)
- column_headers[6] = 'Volume'
- column_headers[7] = 'Properties'
- else:
- columns = ['ID', 'Display Name', 'Display Description', 'Status',
- 'Size']
- column_headers = copy.deepcopy(columns)
-
- # Always update Name and Description
- column_headers[1] = 'Name'
- column_headers[2] = 'Description'
-
- # Cache the volume list
- volume_cache = {}
- try:
- for s in self.app.client_manager.volume.volumes.list():
- volume_cache[s.id] = s
- except Exception:
- # Just forget it if there's any trouble
- pass
-
- search_opts = {
- 'all_tenants': parsed_args.all_projects,
- }
-
- data = self.app.client_manager.volume.volume_snapshots.list(
- search_opts=search_opts)
- return (column_headers,
- (utils.get_item_properties(
- s, columns,
- formatters={'Metadata': utils.format_dict,
- 'Volume ID': _format_volume_id},
- ) for s in data))
-
-
-class SetSnapshot(command.Command):
- _description = _("Set snapshot properties")
-
- def get_parser(self, prog_name):
- parser = super(SetSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- 'snapshot',
- metavar='<snapshot>',
- help=_('Snapshot to modify (name or ID)')
- )
- parser.add_argument(
- '--name',
- metavar='<name>',
- help=_('New snapshot name')
- )
- parser.add_argument(
- '--description',
- metavar='<description>',
- help=_('New snapshot description')
- )
- parser.add_argument(
- '--property',
- metavar='<key=value>',
- action=parseractions.KeyValueAction,
- help=_('Property to add/change for this snapshot '
- '(repeat option to set multiple properties)'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot set" instead.'))
- volume_client = self.app.client_manager.volume
- snapshot = utils.find_resource(volume_client.volume_snapshots,
- parsed_args.snapshot)
-
- result = 0
- if parsed_args.property:
- try:
- volume_client.volume_snapshots.set_metadata(
- snapshot.id, parsed_args.property)
- except Exception as e:
- LOG.error(_("Failed to set snapshot property: %s"), e)
- result += 1
-
- kwargs = {}
- if parsed_args.name:
- kwargs['display_name'] = parsed_args.name
- if parsed_args.description:
- kwargs['display_description'] = parsed_args.description
- if kwargs:
- try:
- snapshot.update(**kwargs)
- except Exception as e:
- LOG.error(_("Failed to update snapshot display name "
- "or display description: %s"), e)
- result += 1
-
- if result > 0:
- raise exceptions.CommandError(_("One or more of the "
- "set operations failed"))
-
-
-class ShowSnapshot(command.ShowOne):
- _description = _("Display snapshot details")
-
- def get_parser(self, prog_name):
- parser = super(ShowSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- 'snapshot',
- metavar='<snapshot>',
- help=_('Snapshot to display (name or ID)')
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot show" instead.'))
- volume_client = self.app.client_manager.volume
- snapshot = utils.find_resource(volume_client.volume_snapshots,
- parsed_args.snapshot)
-
- snapshot._info.update(
- {'properties': utils.format_dict(snapshot._info.pop('metadata'))}
- )
-
- return zip(*sorted(six.iteritems(snapshot._info)))
-
-
-class UnsetSnapshot(command.Command):
- _description = _("Unset snapshot properties")
-
- def get_parser(self, prog_name):
- parser = super(UnsetSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- 'snapshot',
- metavar='<snapshot>',
- help=_('Snapshot to modify (name or ID)'),
- )
- parser.add_argument(
- '--property',
- metavar='<key>',
- action='append',
- help=_('Property to remove from snapshot '
- '(repeat option to remove multiple properties)'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot unset" instead.'))
- volume_client = self.app.client_manager.volume
- snapshot = utils.find_resource(
- volume_client.volume_snapshots, parsed_args.snapshot)
-
- if parsed_args.property:
- volume_client.volume_snapshots.delete_metadata(
- snapshot.id,
- parsed_args.property,
- )
diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/volume_backup.py
index 9ac1302a..9af32705 100644
--- a/openstackclient/volume/v1/backup.py
+++ b/openstackclient/volume/v1/volume_backup.py
@@ -72,23 +72,6 @@ class CreateVolumeBackup(command.ShowOne):
return zip(*sorted(six.iteritems(backup._info)))
-class CreateBackup(CreateVolumeBackup):
- _description = _("Create new backup")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup create`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup create" instead.'))
- return super(CreateBackup, self).take_action(parsed_args)
-
-
class DeleteVolumeBackup(command.Command):
_description = _("Delete volume backup(s)")
@@ -124,23 +107,6 @@ class DeleteVolumeBackup(command.Command):
raise exceptions.CommandError(msg)
-class DeleteBackup(DeleteVolumeBackup):
- _description = _("Delete backup(s)")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup delete`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup delete" instead.'))
- return super(DeleteBackup, self).take_action(parsed_args)
-
-
class ListVolumeBackup(command.Lister):
_description = _("List volume backups")
@@ -234,23 +200,6 @@ class ListVolumeBackup(command.Lister):
) for s in data))
-class ListBackup(ListVolumeBackup):
- _description = _("List backups")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup list`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup list" instead.'))
- return super(ListBackup, self).take_action(parsed_args)
-
-
class RestoreVolumeBackup(command.Command):
_description = _("Restore volume backup")
@@ -278,23 +227,6 @@ class RestoreVolumeBackup(command.Command):
destination_volume.id)
-class RestoreBackup(RestoreVolumeBackup):
- _description = _("Restore backup")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup restore`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup restore" instead.'))
- return super(RestoreBackup, self).take_action(parsed_args)
-
-
class ShowVolumeBackup(command.ShowOne):
_description = _("Display volume backup details")
@@ -313,20 +245,3 @@ class ShowVolumeBackup(command.ShowOne):
parsed_args.backup)
backup._info.pop('links')
return zip(*sorted(six.iteritems(backup._info)))
-
-
-class ShowBackup(ShowVolumeBackup):
- _description = _("Display backup details")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup show`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup show" instead.'))
- return super(ShowBackup, self).take_action(parsed_args)
diff --git a/openstackclient/volume/v1/volume_transfer_request.py b/openstackclient/volume/v1/volume_transfer_request.py
index f5b567b9..6f79658e 100644
--- a/openstackclient/volume/v1/volume_transfer_request.py
+++ b/openstackclient/volume/v1/volume_transfer_request.py
@@ -14,7 +14,6 @@
"""Volume v1 transfer action implementations"""
-import argparse
import logging
from osc_lib.command import command
@@ -39,12 +38,6 @@ class AcceptTransferRequest(command.ShowOne):
help=_('Volume transfer request to accept (ID only)'),
)
parser.add_argument(
- 'old_auth_key',
- metavar="<key>",
- nargs="?",
- help=argparse.SUPPRESS,
- )
- parser.add_argument(
'--auth-key',
metavar="<key>",
help=_('Volume transfer request authentication key'),
@@ -64,20 +57,9 @@ class AcceptTransferRequest(command.ShowOne):
# move on and attempt with the user-supplied information
transfer_request_id = parsed_args.transfer_request
- # Remain backward-compatible for the previous command layout
- # TODO(dtroyer): Remove this back-compat in 4.0 or Oct 2017
if not parsed_args.auth_key:
- if parsed_args.old_auth_key:
- # Move the old one into the correct place
- parsed_args.auth_key = parsed_args.old_auth_key
- self.log.warning(_(
- 'Specifying the auth-key as a positional argument '
- 'has been deprecated. Please use the --auth-key '
- 'option in the future.'
- ))
- else:
- msg = _("argument --auth-key is required")
- raise exceptions.CommandError(msg)
+ msg = _("argument --auth-key is required")
+ raise exceptions.CommandError(msg)
transfer_accept = volume_client.transfers.accept(
transfer_request_id,
diff --git a/openstackclient/volume/v2/snapshot.py b/openstackclient/volume/v2/snapshot.py
deleted file mode 100644
index 82b31033..00000000
--- a/openstackclient/volume/v2/snapshot.py
+++ /dev/null
@@ -1,351 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-# TODO(Huanxuan Ao): Remove this file and "snapshot create", "snapshot delete",
-# "snapshot set", "snapshot show" and "snapshot unset"
-# commands two cycles after Ocata.
-
-"""Volume v2 snapshot action implementations"""
-
-import copy
-import logging
-
-from osc_lib.cli import parseractions
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-import six
-
-from openstackclient.i18n import _
-
-
-deprecated = True
-LOG_DEP = logging.getLogger('deprecated')
-LOG = logging.getLogger(__name__)
-
-
-class CreateSnapshot(command.ShowOne):
- _description = _("Create new snapshot")
-
- def get_parser(self, prog_name):
- parser = super(CreateSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- "volume",
- metavar="<volume>",
- help=_("Volume to snapshot (name or ID)")
- )
- parser.add_argument(
- "--name",
- metavar="<name>",
- help=_("Name of the snapshot")
- )
- parser.add_argument(
- "--description",
- metavar="<description>",
- help=_("Description of the snapshot")
- )
- parser.add_argument(
- "--force",
- action="store_true",
- default=False,
- help=_("Create a snapshot attached to an instance. "
- "Default is False")
- )
- parser.add_argument(
- "--property",
- metavar="<key=value>",
- action=parseractions.KeyValueAction,
- help=_("Set a property to this snapshot "
- "(repeat option to set multiple properties)"),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot create" instead.'))
- volume_client = self.app.client_manager.volume
- volume_id = utils.find_resource(
- volume_client.volumes, parsed_args.volume).id
- snapshot = volume_client.volume_snapshots.create(
- volume_id,
- force=parsed_args.force,
- name=parsed_args.name,
- description=parsed_args.description,
- metadata=parsed_args.property,
- )
- snapshot._info.update(
- {'properties': utils.format_dict(snapshot._info.pop('metadata'))}
- )
- return zip(*sorted(six.iteritems(snapshot._info)))
-
-
-class DeleteSnapshot(command.Command):
- _description = _("Delete volume snapshot(s)")
-
- def get_parser(self, prog_name):
- parser = super(DeleteSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- "snapshots",
- metavar="<snapshot>",
- nargs="+",
- help=_("Snapshot(s) to delete (name or ID)")
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot delete" instead.'))
- volume_client = self.app.client_manager.volume
- result = 0
-
- for i in parsed_args.snapshots:
- try:
- snapshot_id = utils.find_resource(
- volume_client.volume_snapshots, i).id
- volume_client.volume_snapshots.delete(snapshot_id)
- except Exception as e:
- result += 1
- LOG.error(_("Failed to delete snapshot with "
- "name or ID '%(snapshot)s': %(e)s")
- % {'snapshot': i, 'e': e})
-
- if result > 0:
- total = len(parsed_args.snapshots)
- msg = (_("%(result)s of %(total)s snapshots failed "
- "to delete.") % {'result': result, 'total': total})
- raise exceptions.CommandError(msg)
-
-
-class ListSnapshot(command.Lister):
- _description = _("List snapshots")
-
- def get_parser(self, prog_name):
- parser = super(ListSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- '--all-projects',
- action='store_true',
- default=False,
- help=_('Include all projects (admin only)'),
- )
- parser.add_argument(
- '--long',
- action='store_true',
- default=False,
- help=_('List additional fields in output'),
- )
- parser.add_argument(
- '--marker',
- metavar='<snapshot>',
- help=_('The last snapshot ID of the previous page'),
- )
- parser.add_argument(
- '--limit',
- type=int,
- action=parseractions.NonNegativeAction,
- metavar='<num-snapshots>',
- help=_('Maximum number of snapshots to display'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot list" instead.'))
-
- def _format_volume_id(volume_id):
- """Return a volume name if available
-
- :param volume_id: a volume ID
- :rtype: either the volume ID or name
- """
-
- volume = volume_id
- if volume_id in volume_cache.keys():
- volume = volume_cache[volume_id].name
- return volume
-
- if parsed_args.long:
- columns = ['ID', 'Name', 'Description', 'Status',
- 'Size', 'Created At', 'Volume ID', 'Metadata']
- column_headers = copy.deepcopy(columns)
- column_headers[6] = 'Volume'
- column_headers[7] = 'Properties'
- else:
- columns = ['ID', 'Name', 'Description', 'Status', 'Size']
- column_headers = copy.deepcopy(columns)
-
- # Cache the volume list
- volume_cache = {}
- try:
- for s in self.app.client_manager.volume.volumes.list():
- volume_cache[s.id] = s
- except Exception:
- # Just forget it if there's any trouble
- pass
-
- search_opts = {
- 'all_tenants': parsed_args.all_projects,
- }
-
- data = self.app.client_manager.volume.volume_snapshots.list(
- search_opts=search_opts,
- marker=parsed_args.marker,
- limit=parsed_args.limit,
- )
- return (column_headers,
- (utils.get_item_properties(
- s, columns,
- formatters={'Metadata': utils.format_dict,
- 'Volume ID': _format_volume_id},
- ) for s in data))
-
-
-class SetSnapshot(command.Command):
- _description = _("Set snapshot properties")
-
- def get_parser(self, prog_name):
- parser = super(SetSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- 'snapshot',
- metavar='<snapshot>',
- help=_('Snapshot to modify (name or ID)')
- )
- parser.add_argument(
- '--name',
- metavar='<name>',
- help=_('New snapshot name')
- )
- parser.add_argument(
- '--description',
- metavar='<description>',
- help=_('New snapshot description')
- )
- parser.add_argument(
- '--property',
- metavar='<key=value>',
- action=parseractions.KeyValueAction,
- help=_('Property to add/change for this snapshot '
- '(repeat option to set multiple properties)'),
- )
- parser.add_argument(
- '--state',
- metavar='<state>',
- choices=['available', 'error', 'creating', 'deleting',
- 'error-deleting'],
- help=_('New snapshot state. ("available", "error", "creating", '
- '"deleting", or "error_deleting") (admin only) '
- '(This option simply changes the state of the snapshot '
- 'in the database with no regard to actual status, '
- 'exercise caution when using)'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot set" instead.'))
- volume_client = self.app.client_manager.volume
- snapshot = utils.find_resource(volume_client.volume_snapshots,
- parsed_args.snapshot)
-
- result = 0
- if parsed_args.property:
- try:
- volume_client.volume_snapshots.set_metadata(
- snapshot.id, parsed_args.property)
- except Exception as e:
- LOG.error(_("Failed to set snapshot property: %s"), e)
- result += 1
-
- if parsed_args.state:
- try:
- volume_client.volume_snapshots.reset_state(
- snapshot.id, parsed_args.state)
- except Exception as e:
- LOG.error(_("Failed to set snapshot state: %s"), e)
- result += 1
-
- kwargs = {}
- if parsed_args.name:
- kwargs['name'] = parsed_args.name
- if parsed_args.description:
- kwargs['description'] = parsed_args.description
- if kwargs:
- try:
- volume_client.volume_snapshots.update(
- snapshot.id, **kwargs)
- except Exception as e:
- LOG.error(_("Failed to update snapshot name "
- "or description: %s"), e)
- result += 1
-
- if result > 0:
- raise exceptions.CommandError(_("One or more of the "
- "set operations failed"))
-
-
-class ShowSnapshot(command.ShowOne):
- _description = _("Display snapshot details")
-
- def get_parser(self, prog_name):
- parser = super(ShowSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- "snapshot",
- metavar="<snapshot>",
- help=_("Snapshot to display (name or ID)")
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot show" instead.'))
- volume_client = self.app.client_manager.volume
- snapshot = utils.find_resource(
- volume_client.volume_snapshots, parsed_args.snapshot)
- snapshot._info.update(
- {'properties': utils.format_dict(snapshot._info.pop('metadata'))}
- )
- return zip(*sorted(six.iteritems(snapshot._info)))
-
-
-class UnsetSnapshot(command.Command):
- _description = _("Unset snapshot properties")
-
- def get_parser(self, prog_name):
- parser = super(UnsetSnapshot, self).get_parser(prog_name)
- parser.add_argument(
- 'snapshot',
- metavar='<snapshot>',
- help=_('Snapshot to modify (name or ID)'),
- )
- parser.add_argument(
- '--property',
- metavar='<key>',
- action='append',
- default=[],
- help=_('Property to remove from snapshot '
- '(repeat option to remove multiple properties)'),
- )
- return parser
-
- def take_action(self, parsed_args):
- LOG_DEP.warning(_('This command has been deprecated. '
- 'Please use "volume snapshot unset" instead.'))
- volume_client = self.app.client_manager.volume
- snapshot = utils.find_resource(
- volume_client.volume_snapshots, parsed_args.snapshot)
-
- if parsed_args.property:
- volume_client.volume_snapshots.delete_metadata(
- snapshot.id,
- parsed_args.property,
- )
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
index fa587b5f..ef65d097 100644
--- a/openstackclient/volume/v2/volume.py
+++ b/openstackclient/volume/v2/volume.py
@@ -94,16 +94,6 @@ class CreateVolume(command.ShowOne):
help=_("Volume description"),
)
parser.add_argument(
- '--user',
- metavar='<user>',
- help=argparse.SUPPRESS,
- )
- parser.add_argument(
- '--project',
- metavar='<project>',
- help=argparse.SUPPRESS,
- )
- parser.add_argument(
"--availability-zone",
metavar="<availability-zone>",
help=_("Create volume in <availability-zone>"),
@@ -127,12 +117,6 @@ class CreateVolume(command.ShowOne):
help=_("Arbitrary scheduler hint key-value pairs to help boot "
"an instance (repeat option to set multiple hints)"),
)
- parser.add_argument(
- "--multi-attach",
- action="store_true",
- help=_("Allow volume to be attached more than once "
- "(default to False)")
- )
bootable_group = parser.add_mutually_exclusive_group()
bootable_group.add_argument(
"--bootable",
@@ -196,26 +180,6 @@ class CreateVolume(command.ShowOne):
# snapshot size.
size = max(size or 0, snapshot_obj.size)
- # NOTE(abishop): Cinder's volumes.create() has 'project_id' and
- # 'user_id' args, but they're not wired up to anything. The only way
- # to specify an alternate project or user for the volume is to use
- # the identity overrides (e.g. "--os-project-id").
- #
- # Now, if the project or user arg is specified then the command is
- # rejected. Otherwise, Cinder would actually create a volume, but
- # without the specified property.
- if parsed_args.project:
- raise exceptions.CommandError(
- _("ERROR: --project is deprecated, please use"
- " --os-project-name or --os-project-id instead."))
- if parsed_args.user:
- raise exceptions.CommandError(
- _("ERROR: --user is deprecated, please use"
- " --os-username instead."))
- if parsed_args.multi_attach:
- LOG.warning(_("'--multi-attach' option is no longer supported by "
- "the block storage service."))
-
volume = volume_client.volumes.create(
size=size,
snapshot_id=snapshot,
diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/volume_backup.py
index d4aec8d7..1d2b0cde 100644
--- a/openstackclient/volume/v2/backup.py
+++ b/openstackclient/volume/v2/volume_backup.py
@@ -94,23 +94,6 @@ class CreateVolumeBackup(command.ShowOne):
return zip(*sorted(six.iteritems(backup._info)))
-class CreateBackup(CreateVolumeBackup):
- _description = _("Create new backup")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup create`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup create" instead.'))
- return super(CreateBackup, self).take_action(parsed_args)
-
-
class DeleteVolumeBackup(command.Command):
_description = _("Delete volume backup(s)")
@@ -152,23 +135,6 @@ class DeleteVolumeBackup(command.Command):
raise exceptions.CommandError(msg)
-class DeleteBackup(DeleteVolumeBackup):
- _description = _("Delete backup(s)")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup delete`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup delete" instead.'))
- return super(DeleteBackup, self).take_action(parsed_args)
-
-
class ListVolumeBackup(command.Lister):
_description = _("List volume backups")
@@ -280,23 +246,6 @@ class ListVolumeBackup(command.Lister):
) for s in data))
-class ListBackup(ListVolumeBackup):
- _description = _("List backups")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup list`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup list" instead.'))
- return super(ListBackup, self).take_action(parsed_args)
-
-
class RestoreVolumeBackup(command.ShowOne):
_description = _("Restore volume backup")
@@ -324,23 +273,6 @@ class RestoreVolumeBackup(command.ShowOne):
return zip(*sorted(six.iteritems(backup._info)))
-class RestoreBackup(RestoreVolumeBackup):
- _description = _("Restore backup")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup restore`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup restore" instead.'))
- return super(RestoreBackup, self).take_action(parsed_args)
-
-
class SetVolumeBackup(command.Command):
_description = _("Set volume backup properties")
@@ -421,20 +353,3 @@ class ShowVolumeBackup(command.ShowOne):
parsed_args.backup)
backup._info.pop("links", None)
return zip(*sorted(six.iteritems(backup._info)))
-
-
-class ShowBackup(ShowVolumeBackup):
- _description = _("Display backup details")
-
- # TODO(Huanxuan Ao): Remove this class and ``backup show`` command
- # two cycles after Newton.
-
- # This notifies cliff to not display the help for this command
- deprecated = True
-
- log = logging.getLogger('deprecated')
-
- def take_action(self, parsed_args):
- self.log.warning(_('This command has been deprecated. '
- 'Please use "volume backup show" instead.'))
- return super(ShowBackup, self).take_action(parsed_args)
diff --git a/openstackclient/volume/v2/volume_transfer_request.py b/openstackclient/volume/v2/volume_transfer_request.py
index 2f531dc8..4c4741bc 100644
--- a/openstackclient/volume/v2/volume_transfer_request.py
+++ b/openstackclient/volume/v2/volume_transfer_request.py
@@ -14,7 +14,6 @@
"""Volume v2 transfer action implementations"""
-import argparse
import logging
from osc_lib.command import command
@@ -39,14 +38,9 @@ class AcceptTransferRequest(command.ShowOne):
help=_('Volume transfer request to accept (ID only)'),
)
parser.add_argument(
- 'old_auth_key',
- metavar="<key>",
- nargs="?",
- help=argparse.SUPPRESS,
- )
- parser.add_argument(
'--auth-key',
metavar="<key>",
+ required=True,
help=_('Volume transfer request authentication key'),
)
return parser
@@ -64,21 +58,6 @@ class AcceptTransferRequest(command.ShowOne):
# move on and attempt with the user-supplied information
transfer_request_id = parsed_args.transfer_request
- # Remain backward-compatible for the previous command layout
- # TODO(dtroyer): Remove this back-compat in 4.0 or Oct 2017
- if not parsed_args.auth_key:
- if parsed_args.old_auth_key:
- # Move the old one into the correct place
- parsed_args.auth_key = parsed_args.old_auth_key
- self.log.warning(_(
- 'Specifying the auth-key as a positional argument '
- 'has been deprecated. Please use the --auth-key '
- 'option in the future.'
- ))
- else:
- msg = _("argument --auth-key is required")
- raise exceptions.CommandError(msg)
-
transfer_accept = volume_client.transfers.accept(
transfer_request_id,
parsed_args.auth_key,
diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py
index 71e94a2b..749d1dd6 100644
--- a/openstackclient/volume/v2/volume_type.py
+++ b/openstackclient/volume/v2/volume_type.py
@@ -501,7 +501,7 @@ class ShowVolumeType(command.ShowOne):
project_ids = [utils.get_field(item, 'project_id')
for item in volume_type_access]
# TODO(Rui Chen): This format list case can be removed after
- # patch https://review.openstack.org/#/c/330223/ merged.
+ # patch https://review.opendev.org/#/c/330223/ merged.
access_project_ids = utils.format_list(project_ids)
except Exception as e:
msg = _('Failed to get access project list for volume type '