diff options
Diffstat (limited to 'openstackclient')
67 files changed, 2491 insertions, 569 deletions
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index b6dab253..353a0a19 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -103,7 +103,7 @@ def get_extension_modules(group): """Add extension clients""" mod_list = [] for ep in pkg_resources.iter_entry_points(group): - LOG.debug('found extension %r' % ep.name) + LOG.debug('found extension %r', ep.name) __import__(ep.module_name) module = sys.modules[ep.module_name] diff --git a/openstackclient/common/commandmanager.py b/openstackclient/common/commandmanager.py index 553bc920..aa238a23 100644 --- a/openstackclient/common/commandmanager.py +++ b/openstackclient/common/commandmanager.py @@ -37,7 +37,6 @@ class CommandManager(cliff.commandmanager.CommandManager): group = self.namespace self.group_list.append(group) for ep in pkg_resources.iter_entry_points(group): - LOG.debug('found command %r' % ep.name) cmd_name = ( ep.name.replace('_', ' ') if self.convert_underscores diff --git a/openstackclient/common/extension.py b/openstackclient/common/extension.py new file mode 100644 index 00000000..a8b1a6b0 --- /dev/null +++ b/openstackclient/common/extension.py @@ -0,0 +1,78 @@ +# 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. +# + +"""Extension action implementations""" + +import logging + +from cliff import lister + +from openstackclient.common import exceptions as exc +from openstackclient.common import utils + + +class ListExtension(lister.Lister): + """List extension command""" + + # TODO(mfisch): add support for volume and compute + # when the underlying APIs support it. Add support + # for network when it's added to openstackclient. + + log = logging.getLogger(__name__ + '.ListExtension') + + def get_parser(self, prog_name): + parser = super(ListExtension, self).get_parser(prog_name) + parser.add_argument( + '--long', + action='store_true', + default=False, + help='List additional fields in output') + parser.add_argument( + '--identity', + action='store_true', + default=False, + help='List extensions for the Identity API') + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + + if parsed_args.long: + columns = ('Name', 'Namespace', 'Description', + 'Alias', 'Updated', 'Links') + else: + columns = ('Name', 'Alias', 'Description') + + data = [] + + # by default we want to show everything, unless the + # user specifies one or more of the APIs to show + # for now, only identity is supported + show_all = (not parsed_args.identity) + + if parsed_args.identity or show_all: + identity_client = self.app.client_manager.identity + try: + data += identity_client.extensions.list() + except Exception: + raise exc.CommandError( + "Extensions list not supported by" + " identity API") + + return (columns, + (utils.get_item_properties( + s, columns, + formatters={}, + ) for s in data)) diff --git a/openstackclient/common/limits.py b/openstackclient/common/limits.py index bbc15228..9c9458ab 100644 --- a/openstackclient/common/limits.py +++ b/openstackclient/common/limits.py @@ -52,7 +52,7 @@ class ShowLimits(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute volume_client = self.app.client_manager.volume diff --git a/openstackclient/common/module.py b/openstackclient/common/module.py index 4a7f0626..7f9c52db 100644 --- a/openstackclient/common/module.py +++ b/openstackclient/common/module.py @@ -39,7 +39,7 @@ class ListModule(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) data = {} # Get module versions diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py index fd482da9..e011fd36 100644 --- a/openstackclient/common/quota.py +++ b/openstackclient/common/quota.py @@ -79,7 +79,7 @@ class SetQuota(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute volume_client = self.app.client_manager.volume @@ -148,7 +148,7 @@ class ShowQuota(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute volume_client = self.app.client_manager.volume diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py index bc9ed264..a420dd51 100644 --- a/openstackclient/common/utils.py +++ b/openstackclient/common/utils.py @@ -21,7 +21,6 @@ import os import six import sys import time -import uuid from openstackclient.common import exceptions from openstackclient.openstack.common import strutils @@ -37,13 +36,6 @@ def find_resource(manager, name_or_id): except exceptions.NotFound: pass - # Try to get entity as uuid - try: - uuid.UUID(str(name_or_id)) - return manager.get(name_or_id) - except (ValueError, exceptions.NotFound): - pass - # Try directly using the passed value try: return manager.get(name_or_id) @@ -65,11 +57,6 @@ def find_resource(manager, name_or_id): # Eventually this should be pulled from a common set # of client exceptions. except Exception as ex: - try: - return manager.find(display_name=name_or_id) - except Exception: - pass - if type(ex).__name__ == 'NotFound': msg = "No %s with a name or ID of '%s' exists." % \ (manager.resource_class.__name__.lower(), name_or_id) diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py index 765a48db..3dacee88 100644 --- a/openstackclient/compute/client.py +++ b/openstackclient/compute/client.py @@ -34,7 +34,7 @@ def make_client(instance): API_NAME, instance._api_version[API_NAME], API_VERSIONS) - LOG.debug('instantiating compute client: %s' % compute_client) + LOG.debug('instantiating compute client: %s', compute_client) # Set client http_log_debug to True if verbosity level is high enough http_log_debug = utils.get_effective_log_level() <= logging.DEBUG diff --git a/openstackclient/compute/v2/agent.py b/openstackclient/compute/v2/agent.py index ae7ba962..14c4b2c7 100644 --- a/openstackclient/compute/v2/agent.py +++ b/openstackclient/compute/v2/agent.py @@ -60,7 +60,7 @@ class CreateAgent(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute args = ( parsed_args.os, @@ -88,7 +88,7 @@ class DeleteAgent(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute compute_client.agents.delete(parsed_args.id) return @@ -108,7 +108,7 @@ class ListAgent(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "Agent ID", @@ -152,7 +152,7 @@ class SetAgent(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute args = ( parsed_args.id, diff --git a/openstackclient/compute/v2/aggregate.py b/openstackclient/compute/v2/aggregate.py index d786d7e5..8fff4e6f 100644 --- a/openstackclient/compute/v2/aggregate.py +++ b/openstackclient/compute/v2/aggregate.py @@ -47,7 +47,7 @@ class AddAggregateHost(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute @@ -89,7 +89,7 @@ class CreateAggregate(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute @@ -124,7 +124,7 @@ class DeleteAggregate(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute data = utils.find_resource( @@ -150,7 +150,7 @@ class ListAggregate(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute @@ -207,7 +207,7 @@ class RemoveAggregateHost(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute @@ -257,7 +257,7 @@ class SetAggregate(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute aggregate = utils.find_resource( @@ -304,7 +304,7 @@ class ShowAggregate(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute data = utils.find_resource( diff --git a/openstackclient/compute/v2/console.py b/openstackclient/compute/v2/console.py index 032168b9..e1f84e23 100644 --- a/openstackclient/compute/v2/console.py +++ b/openstackclient/compute/v2/console.py @@ -48,7 +48,7 @@ class ShowConsoleLog(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( @@ -104,7 +104,7 @@ class ShowConsoleURL(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( compute_client.servers, diff --git a/openstackclient/compute/v2/fixedip.py b/openstackclient/compute/v2/fixedip.py index c41fed45..d105e391 100644 --- a/openstackclient/compute/v2/fixedip.py +++ b/openstackclient/compute/v2/fixedip.py @@ -42,7 +42,7 @@ class AddFixedIP(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute network = utils.find_resource( @@ -75,7 +75,7 @@ class RemoveFixedIP(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py index d1d08d8d..73429796 100644 --- a/openstackclient/compute/v2/flavor.py +++ b/openstackclient/compute/v2/flavor.py @@ -93,7 +93,7 @@ class CreateFlavor(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute args = ( @@ -128,7 +128,7 @@ class DeleteFlavor(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute flavor = utils.find_resource(compute_client.flavors, parsed_args.flavor) @@ -142,7 +142,7 @@ class ListFlavor(lister.Lister): log = logging.getLogger(__name__ + ".ListFlavor") def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "ID", @@ -177,7 +177,7 @@ class ShowFlavor(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute flavor = utils.find_resource(compute_client.flavors, parsed_args.flavor)._info.copy() diff --git a/openstackclient/compute/v2/floatingip.py b/openstackclient/compute/v2/floatingip.py index 3edc809e..72b19c6c 100644 --- a/openstackclient/compute/v2/floatingip.py +++ b/openstackclient/compute/v2/floatingip.py @@ -45,7 +45,7 @@ class AddFloatingIP(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( @@ -70,7 +70,7 @@ class CreateFloatingIP(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute floating_ip = compute_client.floating_ips.create(parsed_args.pool) @@ -94,7 +94,7 @@ class DeleteFloatingIP(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute floating_ip = utils.find_resource( @@ -112,7 +112,7 @@ class ListFloatingIP(lister.Lister): log = logging.getLogger(__name__ + '.ListFloatingIP') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute columns = ('ID', 'Pool', 'IP', 'Fixed IP', 'Instance ID') @@ -146,7 +146,7 @@ class RemoveFloatingIP(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( diff --git a/openstackclient/compute/v2/floatingippool.py b/openstackclient/compute/v2/floatingippool.py index e1da97c3..d5e8d0dd 100644 --- a/openstackclient/compute/v2/floatingippool.py +++ b/openstackclient/compute/v2/floatingippool.py @@ -28,7 +28,7 @@ class ListFloatingIPPool(lister.Lister): log = logging.getLogger(__name__ + '.ListFloatingIPPool') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute columns = ('Name',) diff --git a/openstackclient/compute/v2/host.py b/openstackclient/compute/v2/host.py index 44f457d9..4f727388 100644 --- a/openstackclient/compute/v2/host.py +++ b/openstackclient/compute/v2/host.py @@ -36,7 +36,7 @@ class ListHost(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "Host Name", @@ -64,7 +64,7 @@ class ShowHost(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "Host", diff --git a/openstackclient/compute/v2/hypervisor.py b/openstackclient/compute/v2/hypervisor.py index 535062e8..334987e2 100644 --- a/openstackclient/compute/v2/hypervisor.py +++ b/openstackclient/compute/v2/hypervisor.py @@ -39,7 +39,7 @@ class ListHypervisor(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "ID", @@ -71,7 +71,7 @@ class ShowHypervisor(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute hypervisor = utils.find_resource(compute_client.hypervisors, parsed_args.id)._info.copy() diff --git a/openstackclient/compute/v2/keypair.py b/openstackclient/compute/v2/keypair.py index 8a91f682..972443a4 100644 --- a/openstackclient/compute/v2/keypair.py +++ b/openstackclient/compute/v2/keypair.py @@ -48,7 +48,7 @@ class CreateKeypair(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute public_key = parsed_args.public_key @@ -93,7 +93,7 @@ class DeleteKeypair(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute compute_client.keypairs.delete(parsed_args.name) return @@ -105,7 +105,7 @@ class ListKeypair(lister.Lister): log = logging.getLogger(__name__ + ".ListKeypair") def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "Name", @@ -140,7 +140,7 @@ class ShowKeypair(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute keypair = utils.find_resource(compute_client.keypairs, parsed_args.name) diff --git a/openstackclient/compute/v2/security_group.py b/openstackclient/compute/v2/security_group.py index be64bd3a..0ba55c98 100644 --- a/openstackclient/compute/v2/security_group.py +++ b/openstackclient/compute/v2/security_group.py @@ -71,7 +71,7 @@ class CreateSecurityGroup(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute @@ -100,7 +100,7 @@ class DeleteSecurityGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute data = utils.find_resource( @@ -134,7 +134,7 @@ class ListSecurityGroup(lister.Lister): except KeyError: return project_id - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( @@ -187,7 +187,7 @@ class SetSecurityGroup(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute data = utils.find_resource( @@ -228,7 +228,7 @@ class ShowSecurityGroup(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute info = {} @@ -286,7 +286,7 @@ class CreateSecurityGroupRule(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute group = utils.find_resource( @@ -340,7 +340,7 @@ class DeleteSecurityGroupRule(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute group = utils.find_resource( @@ -374,7 +374,7 @@ class ListSecurityGroupRule(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute group = utils.find_resource( diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index 808741fd..f75444f2 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -121,7 +121,7 @@ class AddServerVolume(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute volume_client = self.app.client_manager.volume @@ -162,7 +162,7 @@ class AddServerSecurityGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute @@ -278,7 +278,7 @@ class CreateServer(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute # Lookup parsed_args.image @@ -363,8 +363,8 @@ class CreateServer(show.ShowOne): scheduler_hints=hints, config_drive=config_drive) - self.log.debug('boot_args: %s' % boot_args) - self.log.debug('boot_kwargs: %s' % boot_kwargs) + self.log.debug('boot_args: %s', boot_args) + self.log.debug('boot_kwargs: %s', boot_kwargs) server = compute_client.servers.create(*boot_args, **boot_kwargs) if parsed_args.wait: @@ -375,7 +375,7 @@ class CreateServer(show.ShowOne): ): sys.stdout.write('\n') else: - self.log.error('Error creating server: %s' % + self.log.error('Error creating server: %s', parsed_args.server_name) sys.stdout.write('\nError creating server') raise SystemExit @@ -393,7 +393,7 @@ class CreateServerImage(show.ShowOne): parser = super(CreateServerImage, self).get_parser(prog_name) parser.add_argument( 'server', - metavar='<server', + metavar='<server>', help='Server (name or ID)', ) parser.add_argument( @@ -409,7 +409,7 @@ class CreateServerImage(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute image_client = self.app.client_manager.image server = utils.find_resource( @@ -421,7 +421,7 @@ class CreateServerImage(show.ShowOne): else: name = server.name - image = compute_client.servers.create_image( + image_id = compute_client.servers.create_image( server, name, ) @@ -429,13 +429,13 @@ class CreateServerImage(show.ShowOne): if parsed_args.wait: if utils.wait_for_status( image_client.images.get, - image, + image_id, callback=_show_progress, ): sys.stdout.write('\n') else: self.log.error( - 'Error creating server snapshot: %s' % + 'Error creating server snapshot: %s', parsed_args.image_name, ) sys.stdout.write('\nError creating server snapshot') @@ -443,7 +443,7 @@ class CreateServerImage(show.ShowOne): image = utils.find_resource( image_client.images, - image.id, + image_id, ) info = {} @@ -465,7 +465,7 @@ class DeleteServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( compute_client.servers, parsed_args.server) @@ -530,7 +530,7 @@ class ListServer(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute search_opts = { 'reservation_id': parsed_args.reservation_id, @@ -600,7 +600,7 @@ class LockServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute utils.find_resource( @@ -672,7 +672,7 @@ class MigrateServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute @@ -716,7 +716,7 @@ class PauseServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute utils.find_resource( @@ -762,7 +762,7 @@ class RebootServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( compute_client.servers, parsed_args.server) @@ -811,7 +811,7 @@ class RebuildServer(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute # Lookup parsed_args.image @@ -856,7 +856,7 @@ class RemoveServerSecurityGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute @@ -892,7 +892,7 @@ class RemoveServerVolume(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute volume_client = self.app.client_manager.volume @@ -927,7 +927,7 @@ class RescueServer(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( @@ -968,7 +968,7 @@ class ResizeServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( @@ -1013,7 +1013,7 @@ class ResumeServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute utils.find_resource( @@ -1054,7 +1054,7 @@ class SetServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( @@ -1102,7 +1102,7 @@ class ShowServer(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource(compute_client.servers, parsed_args.server) @@ -1224,7 +1224,7 @@ class SshServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( @@ -1272,7 +1272,7 @@ class SshServer(command.Command): cmd += " -v" cmd += " %s@%s" - self.log.debug("ssh command: %s" % (cmd % (login, ip_address))) + self.log.debug("ssh command: %s", (cmd % (login, ip_address))) os.system(cmd % (login, ip_address)) @@ -1291,7 +1291,7 @@ class SuspendServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute utils.find_resource( @@ -1315,7 +1315,7 @@ class UnlockServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute utils.find_resource( @@ -1339,7 +1339,7 @@ class UnpauseServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute utils.find_resource( @@ -1363,7 +1363,7 @@ class UnrescueServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute utils.find_resource( @@ -1395,7 +1395,7 @@ class UnsetServer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) compute_client = self.app.client_manager.compute server = utils.find_resource( compute_client.servers, diff --git a/openstackclient/compute/v2/service.py b/openstackclient/compute/v2/service.py index 5e57e0aa..4b2ebac6 100644 --- a/openstackclient/compute/v2/service.py +++ b/openstackclient/compute/v2/service.py @@ -40,7 +40,7 @@ class ListService(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "Binary", @@ -88,7 +88,7 @@ class SetService(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) compute_client = self.app.client_manager.compute columns = ( "Host", diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py index 1dfe8c0a..ed98af26 100644 --- a/openstackclient/compute/v2/usage.py +++ b/openstackclient/compute/v2/usage.py @@ -36,7 +36,7 @@ class ListUsage(lister.Lister): metavar="<start>", default=None, help="Usage range start date, ex 2012-01-20" - " (default: 4 weeks ago)." + " (default: 4 weeks ago)." ) parser.add_argument( "--end", @@ -47,7 +47,7 @@ class ListUsage(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) def _format_project(project): if not project: diff --git a/openstackclient/identity/v2_0/ec2creds.py b/openstackclient/identity/v2_0/ec2creds.py index cb60b677..74c9d5eb 100644 --- a/openstackclient/identity/v2_0/ec2creds.py +++ b/openstackclient/identity/v2_0/ec2creds.py @@ -46,7 +46,7 @@ class CreateEC2Creds(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.project: @@ -93,7 +93,7 @@ class DeleteEC2Creds(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.user: @@ -123,7 +123,7 @@ class ListEC2Creds(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.user: @@ -166,7 +166,7 @@ class ShowEC2Creds(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.user: diff --git a/openstackclient/identity/v2_0/endpoint.py b/openstackclient/identity/v2_0/endpoint.py index 4ee1636f..36f52cad 100644 --- a/openstackclient/identity/v2_0/endpoint.py +++ b/openstackclient/identity/v2_0/endpoint.py @@ -57,7 +57,7 @@ class CreateEndpoint(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity service = common.find_service(identity_client, parsed_args.service) endpoint = identity_client.endpoints.create( @@ -88,7 +88,7 @@ class DeleteEndpoint(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity identity_client.endpoints.delete(parsed_args.endpoint) return @@ -109,7 +109,7 @@ class ListEndpoint(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.long: columns = ('ID', 'Region', 'Service Name', 'Service Type', @@ -143,7 +143,7 @@ class ShowEndpoint(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity data = identity_client.endpoints.list() match = None diff --git a/openstackclient/identity/v2_0/project.py b/openstackclient/identity/v2_0/project.py index 60a52ad4..7e19d5ae 100644 --- a/openstackclient/identity/v2_0/project.py +++ b/openstackclient/identity/v2_0/project.py @@ -64,7 +64,7 @@ class CreateProject(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity enabled = True @@ -101,7 +101,7 @@ class DeleteProject(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity project = utils.find_resource( @@ -129,7 +129,7 @@ class ListProject(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) if parsed_args.long: columns = ('ID', 'Name', 'Description', 'Enabled') else: @@ -185,7 +185,7 @@ class SetProject(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if (not parsed_args.name @@ -214,7 +214,7 @@ class SetProject(command.Command): if 'id' in kwargs: del kwargs['id'] if 'name' in kwargs: - # Hack around borken Identity API arg names + # Hack around broken Identity API arg names kwargs['tenant_name'] = kwargs['name'] del kwargs['name'] @@ -236,7 +236,7 @@ class ShowProject(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity project = utils.find_resource( identity_client.tenants, diff --git a/openstackclient/identity/v2_0/role.py b/openstackclient/identity/v2_0/role.py index fdf21108..faf48ed9 100644 --- a/openstackclient/identity/v2_0/role.py +++ b/openstackclient/identity/v2_0/role.py @@ -51,7 +51,7 @@ class AddRole(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource(identity_client.roles, parsed_args.role) project = utils.find_resource( @@ -84,7 +84,7 @@ class CreateRole(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = identity_client.roles.create(parsed_args.role_name) @@ -108,7 +108,7 @@ class DeleteRole(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource( @@ -126,7 +126,7 @@ class ListRole(lister.Lister): log = logging.getLogger(__name__ + '.ListRole') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ('ID', 'Name') data = self.app.client_manager.identity.roles.list() return (columns, @@ -156,7 +156,7 @@ class ListUserRole(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity auth_ref = self.app.client_manager.auth_ref @@ -228,7 +228,7 @@ class RemoveRole(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource(identity_client.roles, parsed_args.role) project = utils.find_resource( @@ -256,7 +256,7 @@ class ShowRole(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource(identity_client.roles, parsed_args.role) diff --git a/openstackclient/identity/v2_0/service.py b/openstackclient/identity/v2_0/service.py index d61804c8..138ed3b0 100644 --- a/openstackclient/identity/v2_0/service.py +++ b/openstackclient/identity/v2_0/service.py @@ -53,7 +53,7 @@ class CreateService(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity service = identity_client.services.create( @@ -81,7 +81,7 @@ class DeleteService(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity service = common.find_service(identity_client, parsed_args.service) identity_client.services.delete(service.id) @@ -103,7 +103,7 @@ class ListService(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) if parsed_args.long: columns = ('ID', 'Name', 'Type', 'Description') @@ -138,7 +138,7 @@ class ShowService(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.catalog: diff --git a/openstackclient/identity/v2_0/token.py b/openstackclient/identity/v2_0/token.py index 793354cf..5cd41bb3 100644 --- a/openstackclient/identity/v2_0/token.py +++ b/openstackclient/identity/v2_0/token.py @@ -32,7 +32,7 @@ class CreateToken(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity token = identity_client.service_catalog.get_token() token['project_id'] = token.pop('tenant_id') diff --git a/openstackclient/identity/v2_0/user.py b/openstackclient/identity/v2_0/user.py index 688306ba..60af6ddb 100644 --- a/openstackclient/identity/v2_0/user.py +++ b/openstackclient/identity/v2_0/user.py @@ -72,7 +72,7 @@ class CreateUser(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.project: @@ -123,7 +123,7 @@ class DeleteUser(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user = utils.find_resource( @@ -155,7 +155,7 @@ class ListUser(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity def _format_project(project): @@ -277,7 +277,7 @@ class SetUser(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.password_prompt: @@ -343,7 +343,7 @@ class ShowUser(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user = utils.find_resource( diff --git a/openstackclient/identity/v3/consumer.py b/openstackclient/identity/v3/consumer.py index ddeae618..7f546035 100644 --- a/openstackclient/identity/v3/consumer.py +++ b/openstackclient/identity/v3/consumer.py @@ -41,9 +41,9 @@ class CreateConsumer(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity - consumer = identity_client.consumers.create_consumer( + consumer = identity_client.oauth1.consumers.create( parsed_args.description ) info = {} @@ -66,11 +66,11 @@ class DeleteConsumer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity consumer = utils.find_resource( - identity_client.consumers, parsed_args.consumer) - identity_client.consumers.delete_consumer(consumer.id) + identity_client.oauth1.consumers, parsed_args.consumer) + identity_client.oauth1.consumers.delete(consumer.id) return @@ -80,9 +80,9 @@ class ListConsumer(lister.Lister): log = logging.getLogger(__name__ + '.ListConsumer') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ('ID', 'Description') - data = self.app.client_manager.identity.consumers.list_consumers() + data = self.app.client_manager.identity.oauth1.consumers.list() return (columns, (utils.get_item_properties( s, columns, @@ -110,10 +110,10 @@ class SetConsumer(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity consumer = utils.find_resource( - identity_client.consumers, parsed_args.consumer) + identity_client.oauth1.consumers, parsed_args.consumer) kwargs = {} if parsed_args.description: kwargs['description'] = parsed_args.description @@ -122,14 +122,9 @@ class SetConsumer(command.Command): sys.stdout.write("Consumer not updated, no arguments present") return - consumer = identity_client.consumers.update_consumer( - consumer.id, - **kwargs - ) - - info = {} - info.update(consumer._info) - return zip(*sorted(six.iteritems(info))) + consumer = identity_client.oauth1.consumers.update( + consumer.id, **kwargs) + return class ShowConsumer(show.ShowOne): @@ -147,10 +142,10 @@ class ShowConsumer(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity consumer = utils.find_resource( - identity_client.consumers, parsed_args.consumer) + identity_client.oauth1.consumers, parsed_args.consumer) info = {} info.update(consumer._info) diff --git a/openstackclient/identity/v3/credential.py b/openstackclient/identity/v3/credential.py index 93f67f6c..43d16c29 100644 --- a/openstackclient/identity/v3/credential.py +++ b/openstackclient/identity/v3/credential.py @@ -58,7 +58,7 @@ class CreateCredential(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user_id = utils.find_resource(identity_client.users, parsed_args.user).id @@ -91,7 +91,7 @@ class DeleteCredential(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity identity_client.credentials.delete(parsed_args.credential) return @@ -103,7 +103,7 @@ class ListCredential(lister.Lister): log = logging.getLogger(__name__ + '.ListCredential') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ('ID', 'Type', 'User ID', 'Data', 'Project ID') data = self.app.client_manager.identity.credentials.list() return (columns, @@ -149,7 +149,7 @@ class SetCredential(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user_id = utils.find_resource(identity_client.users, parsed_args.user).id @@ -187,7 +187,7 @@ class ShowCredential(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity credential = utils.find_resource(identity_client.credentials, parsed_args.credential) diff --git a/openstackclient/identity/v3/domain.py b/openstackclient/identity/v3/domain.py index a74b12e2..f9763847 100644 --- a/openstackclient/identity/v3/domain.py +++ b/openstackclient/identity/v3/domain.py @@ -58,7 +58,7 @@ class CreateDomain(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity domain = identity_client.domains.create( name=parsed_args.name, @@ -84,7 +84,7 @@ class DeleteDomain(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity domain = utils.find_resource(identity_client.domains, parsed_args.domain) @@ -98,7 +98,7 @@ class ListDomain(lister.Lister): log = logging.getLogger(__name__ + '.ListDomain') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ('ID', 'Name', 'Enabled', 'Description') data = self.app.client_manager.identity.domains.list() return (columns, @@ -147,7 +147,7 @@ class SetDomain(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity domain = utils.find_resource(identity_client.domains, parsed_args.domain) @@ -181,7 +181,7 @@ class ShowDomain(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity domain = utils.find_resource(identity_client.domains, parsed_args.domain) diff --git a/openstackclient/identity/v3/endpoint.py b/openstackclient/identity/v3/endpoint.py index 3cd5e086..93d77be3 100644 --- a/openstackclient/identity/v3/endpoint.py +++ b/openstackclient/identity/v3/endpoint.py @@ -68,7 +68,7 @@ class CreateEndpoint(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity service = common.find_service(identity_client, parsed_args.service) @@ -101,7 +101,7 @@ class DeleteEndpoint(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity endpoint_id = utils.find_resource(identity_client.endpoints, parsed_args.endpoint).id @@ -115,7 +115,7 @@ class ListEndpoint(lister.Lister): log = logging.getLogger(__name__ + '.ListEndpoint') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity columns = ('ID', 'Region', 'Service Name', 'Service Type', 'Enabled', 'Interface', 'URL') @@ -177,7 +177,7 @@ class SetEndpoint(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity endpoint = utils.find_resource(identity_client.endpoints, parsed_args.endpoint) @@ -214,7 +214,7 @@ class ShowEndpoint(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity endpoint = utils.find_resource(identity_client.endpoints, parsed_args.endpoint) diff --git a/openstackclient/identity/v3/group.py b/openstackclient/identity/v3/group.py index 38d810cb..f51129c9 100644 --- a/openstackclient/identity/v3/group.py +++ b/openstackclient/identity/v3/group.py @@ -46,7 +46,7 @@ class AddUserToGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user_id = utils.find_resource(identity_client.users, @@ -84,7 +84,7 @@ class CheckUserInGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user_id = utils.find_resource(identity_client.users, @@ -125,7 +125,7 @@ class CreateGroup(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.domain: domain = utils.find_resource(identity_client.domains, @@ -156,7 +156,7 @@ class DeleteGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity group = utils.find_resource(identity_client.groups, parsed_args.group) identity_client.groups.delete(group.id) @@ -202,7 +202,7 @@ class ListGroup(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.role: @@ -292,7 +292,7 @@ class RemoveUserFromGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user_id = utils.find_resource(identity_client.users, @@ -336,7 +336,7 @@ class SetGroup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity group = utils.find_resource(identity_client.groups, parsed_args.group) kwargs = {} @@ -370,7 +370,7 @@ class ShowGroup(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity group = utils.find_resource(identity_client.groups, parsed_args.group) diff --git a/openstackclient/identity/v3/identity_provider.py b/openstackclient/identity/v3/identity_provider.py index f577c314..b60678b5 100644 --- a/openstackclient/identity/v3/identity_provider.py +++ b/openstackclient/identity/v3/identity_provider.py @@ -59,7 +59,7 @@ class CreateIdentityProvider(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity idp = identity_client.identity_providers.create( parsed_args.identity_provider_id, @@ -85,7 +85,7 @@ class DeleteIdentityProvider(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity identity_client.identity_providers.delete( parsed_args.identity_provider) @@ -98,7 +98,7 @@ class ListIdentityProvider(lister.Lister): log = logging.getLogger(__name__ + '.ListIdentityProvider') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ('ID', 'Enabled', 'Description') data = self.app.client_manager.identity.identity_providers.list() return (columns, @@ -135,7 +135,7 @@ class SetIdentityProvider(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.enable is True: @@ -169,7 +169,7 @@ class ShowIdentityProvider(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity identity_provider = utils.find_resource( identity_client.identity_providers, diff --git a/openstackclient/identity/v3/policy.py b/openstackclient/identity/v3/policy.py index 3e3fd771..87f3cbe9 100644 --- a/openstackclient/identity/v3/policy.py +++ b/openstackclient/identity/v3/policy.py @@ -47,7 +47,7 @@ class CreatePolicy(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) blob = utils.read_blob_file_contents(parsed_args.blob_file) identity_client = self.app.client_manager.identity @@ -73,7 +73,7 @@ class DeletePolicy(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity identity_client.policies.delete(parsed_args.policy) return @@ -95,7 +95,7 @@ class ListPolicy(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) if parsed_args.include_blob: columns = ('ID', 'Type', 'Blob') else: @@ -133,7 +133,7 @@ class SetPolicy(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity blob = None @@ -168,7 +168,7 @@ class ShowPolicy(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity policy = utils.find_resource(identity_client.policies, parsed_args.policy) diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py index 36787bb0..00a98d19 100644 --- a/openstackclient/identity/v3/project.py +++ b/openstackclient/identity/v3/project.py @@ -69,7 +69,7 @@ class CreateProject(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.domain: @@ -115,7 +115,7 @@ class DeleteProject(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity project = utils.find_resource( @@ -148,7 +148,7 @@ class ListProject(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.long: columns = ('ID', 'Name', 'Domain ID', 'Description', 'Enabled') @@ -216,7 +216,7 @@ class SetProject(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if (not parsed_args.name @@ -251,7 +251,7 @@ class SetProject(command.Command): if 'id' in kwargs: del kwargs['id'] if 'domain_id' in kwargs: - # Hack around borken Identity API arg names + # Hack around broken Identity API arg names kwargs.update( {'domain': kwargs.pop('domain_id')} ) @@ -274,7 +274,7 @@ class ShowProject(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity project = utils.find_resource(identity_client.projects, parsed_args.project) diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py index 664a05dc..69c0aa6a 100644 --- a/openstackclient/identity/v3/role.py +++ b/openstackclient/identity/v3/role.py @@ -63,7 +63,7 @@ class AddRole(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if (not parsed_args.user and not parsed_args.domain @@ -152,7 +152,7 @@ class CreateRole(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = identity_client.roles.create(name=parsed_args.name) @@ -175,7 +175,7 @@ class DeleteRole(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource( @@ -193,7 +193,7 @@ class ListRole(lister.Lister): log = logging.getLogger(__name__ + '.ListRole') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ('ID', 'Name') data = self.app.client_manager.identity.roles.list() return (columns, @@ -240,7 +240,7 @@ class RemoveRole(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if (not parsed_args.user and not parsed_args.domain @@ -334,7 +334,7 @@ class SetRole(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if not parsed_args.name: @@ -364,7 +364,7 @@ class ShowRole(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity role = utils.find_resource( diff --git a/openstackclient/identity/v3/role_assignment.py b/openstackclient/identity/v3/role_assignment.py new file mode 100644 index 00000000..5cc97e8d --- /dev/null +++ b/openstackclient/identity/v3/role_assignment.py @@ -0,0 +1,156 @@ +# 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. +# + +"""Identity v3 Assignment action implementations """ + +import logging + +from cliff import lister + +from openstackclient.common import utils + + +class ListRoleAssignment(lister.Lister): + """Lists role assignments according to the given filters""" + + log = logging.getLogger(__name__ + '.ListRoleAssignment') + + def get_parser(self, prog_name): + parser = super(ListRoleAssignment, self).get_parser(prog_name) + parser.add_argument( + '--effective', + action="store_true", + default=False, + help='Returns only effective role assignments', + ) + parser.add_argument( + '--role', + metavar='<role>', + help='Name or ID of role to filter', + ) + user_or_group = parser.add_mutually_exclusive_group() + user_or_group.add_argument( + '--user', + metavar='<user>', + help='Name or ID of user to filter', + ) + user_or_group.add_argument( + '--group', + metavar='<group>', + help='Name or ID of group to filter', + ) + domain_or_project = parser.add_mutually_exclusive_group() + domain_or_project.add_argument( + '--domain', + metavar='<domain>', + help='Name or ID of domain to filter', + ) + domain_or_project.add_argument( + '--project', + metavar='<project>', + help='Name or ID of project to filter', + ) + + return parser + + def _as_tuple(self, assignment): + return (assignment.role, assignment.user, assignment.group, + assignment.project, assignment.domain) + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + identity_client = self.app.client_manager.identity + + role = None + if parsed_args.role: + role = utils.find_resource( + identity_client.roles, + parsed_args.role, + ) + + user = None + if parsed_args.user: + user = utils.find_resource( + identity_client.users, + parsed_args.user, + ) + + domain = None + if parsed_args.domain: + domain = utils.find_resource( + identity_client.domains, + parsed_args.domain, + ) + + project = None + if parsed_args.project: + project = utils.find_resource( + identity_client.projects, + parsed_args.project, + ) + + group = None + if parsed_args.group: + group = utils.find_resource( + identity_client.groups, + parsed_args.group, + ) + + effective = True if parsed_args.effective else False + self.log.debug('take_action(%s)' % parsed_args) + columns = ('Role', 'User', 'Group', 'Project', 'Domain') + data = identity_client.role_assignments.list( + domain=domain, + user=user, + group=group, + project=project, + role=role, + effective=effective) + + data_parsed = [] + for assignment in data: + # Removing the extra "scope" layer in the assignment json + scope = assignment.scope + if 'project' in scope: + setattr(assignment, 'project', scope['project']['id']) + assignment.domain = '' + elif 'domain' in scope: + setattr(assignment, 'domain', scope['domain']['id']) + assignment.project = '' + + else: + assignment.domain = '' + assignment.project = '' + + del assignment.scope + + if hasattr(assignment, 'user'): + setattr(assignment, 'user', assignment.user['id']) + assignment.group = '' + elif hasattr(assignment, 'group'): + setattr(assignment, 'group', assignment.group['id']) + assignment.user = '' + else: + assignment.user = '' + assignment.group = '' + + if hasattr(assignment, 'role'): + setattr(assignment, 'role', assignment.role['id']) + else: + assignment.role = '' + + # Creating a tuple from data object fields + # (including the blank ones) + data_parsed.append(self._as_tuple(assignment)) + + return columns, tuple(data_parsed) diff --git a/openstackclient/identity/v3/service.py b/openstackclient/identity/v3/service.py index f1aaca87..88301edc 100644 --- a/openstackclient/identity/v3/service.py +++ b/openstackclient/identity/v3/service.py @@ -57,7 +57,7 @@ class CreateService(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity enabled = True @@ -88,7 +88,7 @@ class DeleteService(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity service = common.find_service(identity_client, parsed_args.service) @@ -103,7 +103,7 @@ class ListService(lister.Lister): log = logging.getLogger(__name__ + '.ListService') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ('ID', 'Name', 'Type', 'Enabled') data = self.app.client_manager.identity.services.list() @@ -150,7 +150,7 @@ class SetService(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if (not parsed_args.name @@ -195,7 +195,7 @@ class ShowService(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity service = common.find_service(identity_client, parsed_args.service) diff --git a/openstackclient/identity/v3/token.py b/openstackclient/identity/v3/token.py index 3cc78cd7..b038e3fe 100644 --- a/openstackclient/identity/v3/token.py +++ b/openstackclient/identity/v3/token.py @@ -18,55 +18,8 @@ import logging import six -from cliff import command -from cliff import lister from cliff import show -from openstackclient.common import utils - - -class AuthenticateAccessToken(show.ShowOne): - """Authenticate access token to receive keystone token""" - - api = 'identity' - log = logging.getLogger(__name__ + '.AuthenticateAccessToken') - - def get_parser(self, prog_name): - parser = super(AuthenticateAccessToken, self).get_parser(prog_name) - parser.add_argument( - '--consumer-key', - metavar='<consumer-key>', - help='Consumer key', - required=True - ) - parser.add_argument( - '--consumer-secret', - metavar='<consumer-secret>', - help='Consumer secret', - required=True - ) - parser.add_argument( - '--access-key', - metavar='<access-key>', - help='Access token key', - required=True - ) - parser.add_argument( - '--access-secret', - metavar='<access-secret>', - help='Access token secret', - required=True - ) - return parser - - def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) - token_client = self.app.client_manager.identity.tokens - keystone_token = token_client.authenticate_access_token( - parsed_args.consumer_key, parsed_args.consumer_secret, - parsed_args.access_key, parsed_args.access_secret) - return zip(*sorted(six.iteritems(keystone_token))) - class AuthorizeRequestToken(show.ShowOne): """Authorize request token command""" @@ -78,17 +31,28 @@ class AuthorizeRequestToken(show.ShowOne): parser.add_argument( '--request-key', metavar='<request-key>', - help='Consumer key', + help='Request token key', + required=True + ) + parser.add_argument( + '--role-ids', + metavar='<role-ids>', + help='Requested role IDs', required=True ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) - token_client = self.app.client_manager.identity.tokens + identity_client = self.app.client_manager.identity - verifier_pin = token_client.authorize_request_token( - parsed_args.request_key) + roles = [] + for r_id in parsed_args.role_ids.split(): + roles.append(r_id) + + verifier_pin = identity_client.oauth1.request_tokens.authorize( + parsed_args.request_key, + roles) info = {} info.update(verifier_pin._info) return zip(*sorted(six.iteritems(info))) @@ -135,12 +99,14 @@ class CreateAccessToken(show.ShowOne): def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) - token_client = self.app.client_manager.identity.tokens - access_token = token_client.create_access_token( + token_client = self.app.client_manager.identity.oauth1.access_tokens + access_token = token_client.create( parsed_args.consumer_key, parsed_args.consumer_secret, parsed_args.request_key, parsed_args.request_secret, parsed_args.verifier) - return zip(*sorted(six.iteritems(access_token))) + info = {} + info.update(access_token._info) + return zip(*sorted(six.iteritems(info))) class CreateRequestToken(show.ShowOne): @@ -163,26 +129,23 @@ class CreateRequestToken(show.ShowOne): required=True ) parser.add_argument( - '--role-ids', - metavar='<role-ids>', - help='Requested role IDs', - ) - parser.add_argument( '--project-id', metavar='<project-id>', help='Requested project ID', + required=True ) return parser def take_action(self, parsed_args): self.log.debug('take_action(%s)' % parsed_args) - token_client = self.app.client_manager.identity.tokens - request_token = token_client.create_request_token( + token_client = self.app.client_manager.identity.oauth1.request_tokens + request_token = token_client.create( parsed_args.consumer_key, parsed_args.consumer_secret, - parsed_args.role_ids, parsed_args.project_id) - return zip(*sorted(six.iteritems(request_token))) + info = {} + info.update(request_token._info) + return zip(*sorted(six.iteritems(info))) class CreateToken(show.ShowOne): @@ -195,70 +158,9 @@ class CreateToken(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity token = identity_client.service_catalog.get_token() if 'tenant_id' in token: token['project_id'] = token.pop('tenant_id') return zip(*sorted(six.iteritems(token))) - - -class DeleteAccessToken(command.Command): - """Delete access token command""" - - log = logging.getLogger(__name__ + '.DeleteAccessToken') - - def get_parser(self, prog_name): - parser = super(DeleteAccessToken, self).get_parser(prog_name) - parser.add_argument( - 'user', - metavar='<user>', - help='Name or ID of user', - ) - parser.add_argument( - 'access_key', - metavar='<access-key>', - help='Access token to be deleted', - ) - return parser - - def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) - - identity_client = self.app.client_manager.identity - user = utils.find_resource( - identity_client.users, parsed_args.user).id - identity_client.tokens.delete_access_token(user, - parsed_args.access_key) - return - - -class ListAccessToken(lister.Lister): - """List access tokens command""" - - log = logging.getLogger(__name__ + '.ListAccessToken') - - def get_parser(self, prog_name): - parser = super(ListAccessToken, self).get_parser(prog_name) - parser.add_argument( - 'user', - metavar='<user>', - help='Name or ID of user', - ) - return parser - - def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) - - identity_client = self.app.client_manager.identity - user = utils.find_resource( - identity_client.users, parsed_args.user).id - - columns = ('ID', 'Consumer ID', 'Expires At', - 'Project Id', 'Authorizing User Id') - data = identity_client.tokens.list_access_tokens(user) - return (columns, - (utils.get_item_properties( - s, columns, - formatters={}, - ) for s in data)) diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py index a5209020..e628e884 100644 --- a/openstackclient/identity/v3/user.py +++ b/openstackclient/identity/v3/user.py @@ -83,7 +83,7 @@ class CreateUser(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.project: @@ -136,7 +136,7 @@ class DeleteUser(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user = utils.find_resource( @@ -187,7 +187,7 @@ class ListUser(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.role: @@ -321,7 +321,7 @@ class SetUser(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity if parsed_args.password_prompt: @@ -385,7 +385,7 @@ class ShowUser(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity user = utils.find_resource( diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py index 8c1501bd..92d09953 100644 --- a/openstackclient/image/v1/image.py +++ b/openstackclient/image/v1/image.py @@ -35,6 +35,10 @@ from openstackclient.common import parseractions from openstackclient.common import utils +DEFAULT_CONTAINER_FORMAT = 'bare' +DEFAULT_DISK_FORMAT = 'raw' + + class CreateImage(show.ShowOne): """Create/upload an image""" @@ -45,176 +49,208 @@ class CreateImage(show.ShowOne): parser.add_argument( "name", metavar="<name>", - help="Name of image", - ) - parser.add_argument( - "--disk-format", - default="raw", - metavar="<disk-format>", - help="Disk format of image", + help="New image name", ) parser.add_argument( "--id", metavar="<id>", - help="ID of image to reserve", + help="Image ID to reserve", ) parser.add_argument( "--store", metavar="<store>", - help="Store to upload image to", + help="Upload image to this store", ) parser.add_argument( "--container-format", - default="bare", + default=DEFAULT_CONTAINER_FORMAT, metavar="<container-format>", - help="Container format of image", + help="Image container format " + "(default: %s)" % DEFAULT_CONTAINER_FORMAT, + ) + parser.add_argument( + "--disk-format", + default=DEFAULT_DISK_FORMAT, + metavar="<disk-format>", + help="Image disk format " + "(default: %s)" % DEFAULT_DISK_FORMAT, ) parser.add_argument( "--owner", metavar="<project>", - help="Image owner (project name or ID)", + help="Image owner project name or ID", ) parser.add_argument( "--size", metavar="<size>", - help="Size of image in bytes. Only used with --location and" - " --copy-from", + help="Image size, in bytes (only used with --location and" + " --copy-from)", ) parser.add_argument( "--min-disk", metavar="<disk-gb>", - help="Minimum size of disk needed to boot image in gigabytes", + type=int, + help="Minimum disk size needed to boot image, in gigabytes", ) parser.add_argument( "--min-ram", - metavar="<disk-ram>", - help="Minimum amount of ram needed to boot image in megabytes", + metavar="<ram-mb>", + type=int, + help="Minimum RAM size needed to boot image, in megabytes", ) parser.add_argument( "--location", metavar="<image-url>", - help="URL where the data for this image already resides", - ) - parser.add_argument( - "--file", - metavar="<file>", - help="Local file that contains disk image", - ) - parser.add_argument( - "--checksum", - metavar="<checksum>", - help="Hash of image data used for verification", + help="Download image from an existing URL", ) parser.add_argument( "--copy-from", metavar="<image-url>", - help="Similar to --location, but this indicates that the image" - " should immediately be copied from the data store", + help="Copy image from the data store (similar to --location)", + ) + parser.add_argument( + "--file", + metavar="<file>", + help="Upload image from local file", ) parser.add_argument( "--volume", metavar="<volume>", - help="Create the image from the specified volume", + help="Create image from a volume", ) parser.add_argument( "--force", dest='force', action='store_true', default=False, - help="If the image is created from a volume, force creation of the" - " image even if volume is in use.", + help="Force image creation if volume is in use " + "(only meaningful with --volume)", ) parser.add_argument( - "--property", - dest="properties", - metavar="<key=value>", - action=parseractions.KeyValueAction, - help="Set property on this image " - '(repeat option to set multiple properties)', + "--checksum", + metavar="<checksum>", + help="Image hash used for verification", ) protected_group = parser.add_mutually_exclusive_group() protected_group.add_argument( "--protected", - dest="protected", action="store_true", - help="Prevent image from being deleted (default: False)", + help="Prevent image from being deleted", ) protected_group.add_argument( "--unprotected", - dest="protected", - action="store_false", - default=False, - help="Allow images to be deleted (default: True)", + action="store_true", + help="Allow image to be deleted (default)", ) public_group = parser.add_mutually_exclusive_group() public_group.add_argument( "--public", - dest="is_public", action="store_true", - default=True, - help="Image is accessible to the public (default)", + help="Image is accessible to the public", ) public_group.add_argument( "--private", - dest="is_public", - action="store_false", - help="Image is inaccessible to the public", + action="store_true", + help="Image is inaccessible to the public (default)", + ) + parser.add_argument( + "--property", + dest="properties", + metavar="<key=value>", + action=parseractions.KeyValueAction, + help="Set an image property " + "(repeat option to set multiple properties)", ) return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - - # NOTE(jk0): Since create() takes kwargs, it's easiest to just make a - # copy of parsed_args and remove what we don't need. - args = vars(parsed_args) - args = dict(filter(lambda x: x[1] is not None, args.items())) - args.pop("columns") - args.pop("formatter") - args.pop("prefix") - args.pop("variables") - - if "location" not in args and "copy_from" not in args: - if "volume" in args: - pass - elif "file" in args: - args["data"] = open(args.pop("file"), "rb") + self.log.debug("take_action(%s)", parsed_args) + image_client = self.app.client_manager.image + + # Build an attribute dict from the parsed args, only include + # attributes that were actually set on the command line + kwargs = {} + copy_attrs = ('name', 'id', 'store', 'container_format', + 'disk_format', 'owner', 'size', 'min_disk', 'min_ram', + 'localtion', 'copy_from', 'volume', 'force', + 'checksum', 'properties') + for attr in copy_attrs: + if attr in parsed_args: + val = getattr(parsed_args, attr, None) + if val: + # Only include a value in kwargs for attributes that are + # actually present on the command line + kwargs[attr] = val + # Handle exclusive booleans with care + # Avoid including attributes in kwargs if an option is not + # present on the command line. These exclusive booleans are not + # a single value for the pair of options because the default must be + # to do nothing when no options are present as opposed to always + # setting a default. + if parsed_args.protected: + kwargs['protected'] = True + if parsed_args.unprotected: + kwargs['protected'] = False + if parsed_args.public: + kwargs['is_public'] = True + if parsed_args.private: + kwargs['is_public'] = False + + if not parsed_args.location and not parsed_args.copy_from: + if parsed_args.volume: + volume_client = self.app.client_manager.volume + source_volume = utils.find_resource( + volume_client.volumes, + parsed_args.volume, + ) + response, body = volume_client.volumes.upload_to_image( + source_volume.id, + parsed_args.force, + parsed_args.name, + parsed_args.container_format, + parsed_args.disk_format, + ) + info = body['os-volume_upload_image'] + elif parsed_args.file: + # Send an open file handle to glanceclient so it will + # do a chunked transfer + kwargs["data"] = open(parsed_args.file, "rb") else: - args["data"] = None + # Read file from stdin + kwargs["data"] = None if sys.stdin.isatty() is not True: if msvcrt: msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) - args["data"] = sys.stdin - - if "volume" in args: - volume_client = self.app.client_manager.volume - source_volume = utils.find_resource(volume_client.volumes, - parsed_args.volume) - response, body = volume_client.volumes.upload_to_image( - source_volume, - parsed_args.force, - parsed_args.name, - parsed_args.container_format, - parsed_args.disk_format) - info = body['os-volume_upload_image'] - else: - image_client = self.app.client_manager.image - try: - image = utils.find_resource( - image_client.images, - parsed_args.name, - ) - except exceptions.CommandError: + # Send an open file handle to glanceclient so it will + # do a chunked transfer + kwargs["data"] = sys.stdin + + try: + image = utils.find_resource( + image_client.images, + parsed_args.name, + ) + + # Preserve previous properties if any are being set now + if image.properties: + if parsed_args.properties: + image.properties.update(kwargs['properties']) + kwargs['properties'] = image.properties + + except exceptions.CommandError: + if not parsed_args.volume: # This is normal for a create or reserve (create w/o an image) - image = image_client.images.create(**args) - else: - # It must be an update - # If an image is specified via --file, --location or - # --copy-from let the API handle it - image = image_client.images.update(image, **args) + # But skip for create from volume + image = image_client.images.create(**kwargs) + else: + # Update an existing reservation + + # If an image is specified via --file, --location or + # --copy-from let the API handle it + image = image_client.images.update(image.id, **kwargs) - info = {} - info.update(image._info) + info = {} + info.update(image._info) return zip(*sorted(six.iteritems(info))) @@ -233,7 +269,7 @@ class DeleteImage(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image image = utils.find_resource( @@ -258,7 +294,7 @@ class ListImage(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image @@ -292,7 +328,7 @@ class SaveImage(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image image = utils.find_resource( @@ -314,88 +350,104 @@ class SetImage(show.ShowOne): parser.add_argument( "image", metavar="<image>", - help="Name or ID of image to change", + help="Image name or ID to change", ) parser.add_argument( "--name", metavar="<name>", - help="Name of image", + help="New image name", ) parser.add_argument( "--owner", metavar="<project>", - help="Image owner (project name or ID)", + help="New image owner project name or ID", ) parser.add_argument( "--min-disk", metavar="<disk-gb>", - help="Minimum size of disk needed to boot image in gigabytes", + type=int, + help="Minimum disk size needed to boot image, in gigabytes", ) parser.add_argument( "--min-ram", metavar="<disk-ram>", - help="Minimum amount of ram needed to boot image in megabytes", - ) - parser.add_argument( - "--property", - dest="properties", - metavar="<key=value>", - default={}, - action=parseractions.KeyValueAction, - help="Set property on this image " - '(repeat option to set multiple properties)', + type=int, + help="Minimum RAM size needed to boot image, in megabytes", ) protected_group = parser.add_mutually_exclusive_group() protected_group.add_argument( "--protected", - dest="protected", action="store_true", - help="Prevent image from being deleted (default: False)", + help="Prevent image from being deleted", ) protected_group.add_argument( "--unprotected", - dest="protected", - action="store_false", - default=False, - help="Allow images to be deleted (default: True)", + action="store_true", + help="Allow image to be deleted (default)", ) public_group = parser.add_mutually_exclusive_group() public_group.add_argument( "--public", - dest="is_public", action="store_true", - default=True, - help="Image is accessible to the public (default)", + help="Image is accessible to the public", ) public_group.add_argument( "--private", - dest="is_public", - action="store_false", - help="Image is inaccessible to the public", + action="store_true", + help="Image is inaccessible to the public (default)", + ) + parser.add_argument( + "--property", + dest="properties", + metavar="<key=value>", + action=parseractions.KeyValueAction, + help="Set an image property " + "(repeat option to set multiple properties)", ) return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - - # NOTE(jk0): Since create() takes kwargs, it's easiest to just make a - # copy of parsed_args and remove what we don't need. - args = vars(parsed_args) - args = dict(filter(lambda x: x[1] is not None, args.items())) - args.pop("columns") - args.pop("formatter") - args.pop("prefix") - args.pop("variables") - image_arg = args.pop("image") - + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image + + kwargs = {} + copy_attrs = ('name', 'owner', 'min_disk', 'min_ram', 'properties') + for attr in copy_attrs: + if attr in parsed_args: + val = getattr(parsed_args, attr, None) + if val: + # Only include a value in kwargs for attributes that are + # actually present on the command line + kwargs[attr] = val + # Handle exclusive booleans with care + # Avoid including attributes in kwargs if an option is not + # present on the command line. These exclusive booleans are not + # a single value for the pair of options because the default must be + # to do nothing when no options are present as opposed to always + # setting a default. + if parsed_args.protected: + kwargs['protected'] = True + if parsed_args.unprotected: + kwargs['protected'] = False + if parsed_args.public: + kwargs['is_public'] = True + if parsed_args.private: + kwargs['is_public'] = False + + if not kwargs: + self.log.warning('no arguments specified') + return {}, {} + image = utils.find_resource( image_client.images, - image_arg, + parsed_args.image, ) - # Merge properties - args["properties"].update(image.properties) - image = image_client.images.update(image, **args) + + if image.properties and parsed_args.properties: + image.properties.update(kwargs['properties']) + kwargs['properties'] = image.properties + + image = image_client.images.update(image.id, **kwargs) info = {} info.update(image._info) @@ -417,7 +469,7 @@ class ShowImage(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image image = utils.find_resource( diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py index e84e0d01..08897b2b 100644 --- a/openstackclient/image/v2/image.py +++ b/openstackclient/image/v2/image.py @@ -41,7 +41,7 @@ class DeleteImage(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image image = utils.find_resource( @@ -66,7 +66,7 @@ class ListImage(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image @@ -100,7 +100,7 @@ class SaveImage(command.Command): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image image = utils.find_resource( @@ -127,7 +127,7 @@ class ShowImage(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) + self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image image = utils.find_resource( diff --git a/openstackclient/object/v1/container.py b/openstackclient/object/v1/container.py index fcfbd783..1e252aaf 100644 --- a/openstackclient/object/v1/container.py +++ b/openstackclient/object/v1/container.py @@ -69,7 +69,7 @@ class ListContainer(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) if parsed_args.long: columns = ('Name', 'Bytes', 'Count') @@ -116,7 +116,7 @@ class ShowContainer(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) data = lib_container.show_container( self.app.restapi, diff --git a/openstackclient/object/v1/object.py b/openstackclient/object/v1/object.py index f6a77030..ee30c842 100644 --- a/openstackclient/object/v1/object.py +++ b/openstackclient/object/v1/object.py @@ -79,7 +79,7 @@ class ListObject(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) if parsed_args.long: columns = ( @@ -140,7 +140,7 @@ class ShowObject(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) data = lib_object.show_object( self.app.restapi, diff --git a/openstackclient/shell.py b/openstackclient/shell.py index cc4570a1..67eaca55 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -123,6 +123,50 @@ class OpenStackShell(app.App): help="Show this help message and exit", ) + def configure_logging(self): + """Configure logging for the app + + Cliff sets some defaults we don't want so re-work it a bit + """ + + if self.options.debug: + # --debug forces verbose_level 3 + # Set this here so cliff.app.configure_logging() can work + self.options.verbose_level = 3 + + super(OpenStackShell, self).configure_logging() + root_logger = logging.getLogger('') + + # Requests logs some stuff at INFO that we don't want + # unless we have DEBUG + requests_log = logging.getLogger("requests") + requests_log.setLevel(logging.ERROR) + + # Other modules we don't want DEBUG output for so + # don't reset them below + iso8601_log = logging.getLogger("iso8601") + iso8601_log.setLevel(logging.ERROR) + + # Set logging to the requested level + self.dump_stack_trace = False + if self.options.verbose_level == 0: + # --quiet + root_logger.setLevel(logging.ERROR) + elif self.options.verbose_level == 1: + # This is the default case, no --debug, --verbose or --quiet + root_logger.setLevel(logging.WARNING) + elif self.options.verbose_level == 2: + # One --verbose + root_logger.setLevel(logging.INFO) + elif self.options.verbose_level >= 3: + # Two or more --verbose + root_logger.setLevel(logging.DEBUG) + requests_log.setLevel(logging.DEBUG) + + if self.options.debug: + # --debug forces traceback + self.dump_stack_trace = True + def run(self, argv): try: return super(OpenStackShell, self).run(argv) @@ -401,15 +445,6 @@ class OpenStackShell(app.App): super(OpenStackShell, self).initialize_app(argv) - # Set requests logging to a useful level - requests_log = logging.getLogger("requests") - if self.options.debug: - requests_log.setLevel(logging.DEBUG) - self.dump_stack_trace = True - else: - requests_log.setLevel(logging.WARNING) - self.dump_stack_trace = False - # Save default domain self.default_domain = self.options.os_default_domain @@ -422,13 +457,14 @@ class OpenStackShell(app.App): ver = getattr(self.options, mod.API_VERSION_OPTION, None) if ver: self.api_version[mod.API_NAME] = ver - self.log.debug('%s API version %s' % (mod.API_NAME, ver)) + self.log.debug('%(name)s API version %(version)s', + {'name': mod.API_NAME, 'version': ver}) # Add the API version-specific commands for api in self.api_version.keys(): version = '.v' + self.api_version[api].replace('.', '_') cmd_group = 'openstack.' + api.replace('-', '_') + version - self.log.debug('command group %s' % cmd_group) + self.log.debug('command group %s', cmd_group) self.command_manager.add_command_group(cmd_group) # Commands that span multiple APIs diff --git a/openstackclient/tests/common/test_extension.py b/openstackclient/tests/common/test_extension.py new file mode 100644 index 00000000..2e6e7050 --- /dev/null +++ b/openstackclient/tests/common/test_extension.py @@ -0,0 +1,128 @@ +# 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 copy + +from openstackclient.common import extension +from openstackclient.tests import fakes +from openstackclient.tests import utils + +from openstackclient.tests.identity.v2_0 import fakes as identity_fakes + + +class TestExtension(utils.TestCommand): + + def setUp(self): + super(TestExtension, self).setUp() + + self.app.client_manager.identity = identity_fakes.FakeIdentityv2Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + + # Get shortcuts to the ExtensionManager Mocks + self.identity_extensions_mock = ( + self.app.client_manager.identity.extensions) + self.identity_extensions_mock.reset_mock() + + +class TestExtensionList(TestExtension): + + def setUp(self): + super(TestExtensionList, self).setUp() + + self.identity_extensions_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.EXTENSION), + loaded=True, + ), + ] + + # Get the command object to test + self.cmd = extension.ListExtension(self.app, None) + + def test_extension_list_no_options(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # no args should output from all services + self.identity_extensions_mock.list.assert_called_with() + + collist = ('Name', 'Alias', 'Description') + self.assertEqual(columns, collist) + datalist = ( + ( + identity_fakes.extension_name, + identity_fakes.extension_alias, + identity_fakes.extension_description, + ), + ) + self.assertEqual(tuple(data), datalist) + + def test_extension_list_long(self): + arglist = [ + '--long', + ] + verifylist = [ + ('long', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # no args should output from all services + self.identity_extensions_mock.list.assert_called_with() + + collist = ('Name', 'Namespace', 'Description', 'Alias', 'Updated', + 'Links') + self.assertEqual(columns, collist) + datalist = ( + ( + identity_fakes.extension_name, + identity_fakes.extension_namespace, + identity_fakes.extension_description, + identity_fakes.extension_alias, + identity_fakes.extension_updated, + identity_fakes.extension_links, + ), + ) + self.assertEqual(tuple(data), datalist) + + def test_extension_list_identity(self): + arglist = [ + '--identity', + ] + verifylist = [ + ('identity', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.identity_extensions_mock.list.assert_called_with() + + collist = ('Name', 'Alias', 'Description') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.extension_name, + identity_fakes.extension_alias, + identity_fakes.extension_description, + ), ) + self.assertEqual(tuple(data), datalist) diff --git a/openstackclient/tests/common/test_parseractions.py b/openstackclient/tests/common/test_parseractions.py index 705e7e9c..f26f2891 100644 --- a/openstackclient/tests/common/test_parseractions.py +++ b/openstackclient/tests/common/test_parseractions.py @@ -88,7 +88,7 @@ class TestKeyValueAction(utils.TestCase): failhere = None actual = getattr(results, 'property', {}) - # Verify non-existant red key + # Verify non-existent red key try: failhere = actual['red'] except Exception as e: diff --git a/openstackclient/tests/common/test_utils.py b/openstackclient/tests/common/test_utils.py index 3650746b..6d75a9b5 100644 --- a/openstackclient/tests/common/test_utils.py +++ b/openstackclient/tests/common/test_utils.py @@ -107,8 +107,9 @@ class TestFindResource(test_utils.TestCase): def test_find_resource_find_not_found(self): self.manager.get = mock.Mock(side_effect=Exception('Boom!')) - self.manager.find = mock.Mock(side_effect= - exceptions.NotFound(404, "2")) + self.manager.find = mock.Mock( + side_effect=exceptions.NotFound(404, "2") + ) result = self.assertRaises(exceptions.CommandError, utils.find_resource, self.manager, @@ -116,7 +117,7 @@ class TestFindResource(test_utils.TestCase): self.assertEqual("No lego with a name or ID of 'legos' exists.", str(result)) self.manager.get.assert_called_with(self.name) - self.manager.find.assert_called_with(display_name=self.name) + self.manager.find.assert_called_with(name=self.name) def test_find_resource_find_no_unique(self): self.manager.get = mock.Mock(side_effect=Exception('Boom!')) @@ -128,4 +129,4 @@ class TestFindResource(test_utils.TestCase): self.assertEqual("More than one lego exists with the name 'legos'.", str(result)) self.manager.get.assert_called_with(self.name) - self.manager.find.assert_called_with(display_name=self.name) + self.manager.find.assert_called_with(name=self.name) diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py index 03ebd67c..cef5ee90 100644 --- a/openstackclient/tests/compute/v2/fakes.py +++ b/openstackclient/tests/compute/v2/fakes.py @@ -28,6 +28,25 @@ SERVER = { 'name': server_name, } +extension_name = 'Multinic' +extension_namespace = 'http://docs.openstack.org/compute/ext/'\ + 'multinic/api/v1.1' +extension_description = 'Multiple network support' +extension_updated = '2014-01-07T12:00:0-00:00' +extension_alias = 'NMN' +extension_links = '[{"href":'\ + '"https://github.com/openstack/compute-api", "type":'\ + ' "text/html", "rel": "describedby"}]' + +EXTENSION = { + 'name': extension_name, + 'namespace': extension_namespace, + 'description': extension_description, + 'updated': extension_updated, + 'alias': extension_alias, + 'links': extension_links, +} + class FakeComputev2Client(object): def __init__(self, **kwargs): @@ -35,6 +54,8 @@ class FakeComputev2Client(object): self.images.resource_class = fakes.FakeResource(None, {}) self.servers = mock.Mock() self.servers.resource_class = fakes.FakeResource(None, {}) + self.extensions = mock.Mock() + self.extensions.resource_class = fakes.FakeResource(None, {}) self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py index 4cd294cc..efe4c58b 100644 --- a/openstackclient/tests/compute/v2/test_server.py +++ b/openstackclient/tests/compute/v2/test_server.py @@ -80,11 +80,7 @@ class TestServerImageCreate(TestServer): loaded=True, ) - self.servers_mock.create_image.return_value = fakes.FakeResource( - None, - copy.deepcopy(image_fakes.IMAGE), - loaded=True, - ) + self.servers_mock.create_image.return_value = image_fakes.image_id self.images_mock.get.return_value = fakes.FakeResource( None, diff --git a/openstackclient/tests/identity/v2_0/fakes.py b/openstackclient/tests/identity/v2_0/fakes.py index e57a5b30..a8438e96 100644 --- a/openstackclient/tests/identity/v2_0/fakes.py +++ b/openstackclient/tests/identity/v2_0/fakes.py @@ -80,6 +80,46 @@ TOKEN = { 'user_id': user_id, } +endpoint_name = service_name +endpoint_adminurl = 'https://admin.example.com/v2/UUID' +endpoint_region = 'RegionOne' +endpoint_internalurl = 'https://internal.example.com/v2/UUID' +endpoint_type = service_type +endpoint_id = '11b41ee1b00841128b7333d4bf1a6140' +endpoint_publicurl = 'https://public.example.com/v2/UUID' +endpoint_service_id = service_id + +ENDPOINT = { + 'service_name': endpoint_name, + 'adminurl': endpoint_adminurl, + 'region': endpoint_region, + 'internalurl': endpoint_internalurl, + 'service_type': endpoint_type, + 'id': endpoint_id, + 'publicurl': endpoint_publicurl, + 'service_id': endpoint_service_id, +} + +extension_name = 'OpenStack Keystone User CRUD' +extension_namespace = 'http://docs.openstack.org/identity/'\ + 'api/ext/OS-KSCRUD/v1.0' +extension_description = 'OpenStack extensions to Keystone v2.0 API'\ + ' enabling User Operations.' +extension_updated = '2013-07-07T12:00:0-00:00' +extension_alias = 'OS-KSCRUD' +extension_links = '[{"href":'\ + '"https://github.com/openstack/identity-api", "type":'\ + ' "text/html", "rel": "describedby"}]' + +EXTENSION = { + 'name': extension_name, + 'namespace': extension_namespace, + 'description': extension_description, + 'updated': extension_updated, + 'alias': extension_alias, + 'links': extension_links, +} + class FakeIdentityv2Client(object): def __init__(self, **kwargs): @@ -96,6 +136,10 @@ class FakeIdentityv2Client(object): self.users.resource_class = fakes.FakeResource(None, {}) self.ec2 = mock.Mock() self.ec2.resource_class = fakes.FakeResource(None, {}) + self.endpoints = mock.Mock() + self.endpoints.resource_class = fakes.FakeResource(None, {}) + self.extensions = mock.Mock() + self.extensions.resource_class = fakes.FakeResource(None, {}) self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] diff --git a/openstackclient/tests/identity/v2_0/test_endpoint.py b/openstackclient/tests/identity/v2_0/test_endpoint.py new file mode 100644 index 00000000..0d7db0aa --- /dev/null +++ b/openstackclient/tests/identity/v2_0/test_endpoint.py @@ -0,0 +1,266 @@ +# 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 copy + +from openstackclient.identity.v2_0 import endpoint +from openstackclient.tests import fakes +from openstackclient.tests.identity.v2_0 import fakes as identity_fakes + + +class TestEndpoint(identity_fakes.TestIdentityv2): + + def setUp(self): + super(TestEndpoint, self).setUp() + + # Get a shortcut to the EndpointManager Mock + self.endpoints_mock = self.app.client_manager.identity.endpoints + self.endpoints_mock.reset_mock() + + # Get a shortcut to the ServiceManager Mock + self.services_mock = self.app.client_manager.identity.services + self.services_mock.reset_mock() + + +class TestEndpointCreate(TestEndpoint): + + def setUp(self): + super(TestEndpointCreate, self).setUp() + + self.endpoints_mock.create.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.ENDPOINT), + loaded=True, + ) + + self.services_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.SERVICE), + loaded=True, + ) + + # Get the command object to test + self.cmd = endpoint.CreateEndpoint(self.app, None) + + def test_endpoint_create(self): + arglist = [ + '--publicurl', identity_fakes.endpoint_publicurl, + '--internalurl', identity_fakes.endpoint_internalurl, + '--adminurl', identity_fakes.endpoint_adminurl, + '--region', identity_fakes.endpoint_region, + identity_fakes.endpoint_name, + ] + verifylist = [ + ('adminurl', identity_fakes.endpoint_adminurl), + ('internalurl', identity_fakes.endpoint_internalurl), + ('publicurl', identity_fakes.endpoint_publicurl), + ('region', identity_fakes.endpoint_region), + ('service', identity_fakes.service_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # EndpointManager.create(region, service_id, publicurl, adminurl, + # internalurl) + self.endpoints_mock.create.assert_called_with( + identity_fakes.endpoint_region, + identity_fakes.service_id, + identity_fakes.endpoint_publicurl, + identity_fakes.endpoint_adminurl, + identity_fakes.endpoint_internalurl, + ) + + collist = ('adminurl', 'id', 'internalurl', 'publicurl', + 'region', 'service_id', 'service_name', 'service_type') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.endpoint_adminurl, + identity_fakes.endpoint_id, + identity_fakes.endpoint_internalurl, + identity_fakes.endpoint_publicurl, + identity_fakes.endpoint_region, + identity_fakes.service_id, + identity_fakes.service_name, + identity_fakes.service_type, + ) + + self.assertEqual(data, datalist) + + +class TestEndpointDelete(TestEndpoint): + + def setUp(self): + super(TestEndpointDelete, self).setUp() + + self.endpoints_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.ENDPOINT), + loaded=True, + ) + + self.services_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.SERVICE), + loaded=True, + ) + + self.endpoints_mock.delete.return_value = None + + # Get the command object to test + self.cmd = endpoint.DeleteEndpoint(self.app, None) + + def test_endpoint_delete_no_options(self): + arglist = [ + identity_fakes.endpoint_id, + ] + verifylist = [ + ('endpoint', identity_fakes.endpoint_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + self.endpoints_mock.delete.assert_called_with( + identity_fakes.endpoint_id, + ) + + +class TestEndpointList(TestEndpoint): + + def setUp(self): + super(TestEndpointList, self).setUp() + + self.endpoints_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.ENDPOINT), + loaded=True, + ), + ] + + self.services_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.SERVICE), + loaded=True, + ) + + # Get the command object to test + self.cmd = endpoint.ListEndpoint(self.app, None) + + def test_endpoint_list_no_options(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.endpoints_mock.list.assert_called_with() + + collist = ('ID', 'Region', 'Service Name', 'Service Type') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.endpoint_id, + identity_fakes.endpoint_region, + identity_fakes.service_name, + identity_fakes.service_type, + ), ) + self.assertEqual(tuple(data), datalist) + + def test_endpoint_list_long(self): + arglist = [ + '--long', + ] + verifylist = [ + ('long', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.endpoints_mock.list.assert_called_with() + + collist = ('ID', 'Region', 'Service Name', 'Service Type', + 'PublicURL', 'AdminURL', 'InternalURL') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.endpoint_id, + identity_fakes.endpoint_region, + identity_fakes.service_name, + identity_fakes.service_type, + identity_fakes.endpoint_publicurl, + identity_fakes.endpoint_adminurl, + identity_fakes.endpoint_internalurl, + ), ) + self.assertEqual(tuple(data), datalist) + + +class TestEndpointShow(TestEndpoint): + + def setUp(self): + super(TestEndpointShow, self).setUp() + + self.endpoints_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.ENDPOINT), + loaded=True, + ), + ] + + self.services_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.SERVICE), + loaded=True, + ) + + # Get the command object to test + self.cmd = endpoint.ShowEndpoint(self.app, None) + + def test_endpoint_show(self): + arglist = [ + identity_fakes.endpoint_name, + ] + verifylist = [ + ('endpoint_or_service', identity_fakes.endpoint_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # EndpointManager.list() + self.endpoints_mock.list.assert_called_with() + # ServiceManager.get(name) + self.services_mock.get.assert_called_with( + identity_fakes.service_name, + ) + + collist = ('adminurl', 'id', 'internalurl', 'publicurl', + 'region', 'service_id', 'service_name', 'service_type') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.endpoint_adminurl, + identity_fakes.endpoint_id, + identity_fakes.endpoint_internalurl, + identity_fakes.endpoint_publicurl, + identity_fakes.endpoint_region, + identity_fakes.service_id, + identity_fakes.service_name, + identity_fakes.service_type, + ) + self.assertEqual(data, datalist) diff --git a/openstackclient/tests/identity/v3/fakes.py b/openstackclient/tests/identity/v3/fakes.py index ffa89a5f..711a423d 100644 --- a/openstackclient/tests/identity/v3/fakes.py +++ b/openstackclient/tests/identity/v3/fakes.py @@ -114,6 +114,68 @@ IDENTITY_PROVIDER = { 'description': idp_description } +#Assignments +ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID = { + 'scope': {'project': {'id': project_id}}, + 'user': {'id': user_id}, + 'role': {'id': role_id}, +} + +ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID = { + 'scope': {'project': {'id': project_id}}, + 'group': {'id': group_id}, + 'role': {'id': role_id}, +} + +ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID = { + 'scope': {'domain': {'id': domain_id}}, + 'user': {'id': user_id}, + 'role': {'id': role_id}, +} + +ASSIGNMENT_WITH_DOMAIN_ID_AND_GROUP_ID = { + 'scope': {'domain': {'id': domain_id}}, + 'group': {'id': group_id}, + 'role': {'id': role_id}, +} + +consumer_id = 'test consumer id' +consumer_description = 'someone we trust' +consumer_secret = 'test consumer secret' + +OAUTH_CONSUMER = { + 'id': consumer_id, + 'secret': consumer_secret, + 'description': consumer_description +} + +access_token_id = 'test access token id' +access_token_secret = 'test access token secret' +access_token_expires = '2014-05-18T03:13:18.152071Z' + +OAUTH_ACCESS_TOKEN = { + 'id': access_token_id, + 'expires': access_token_expires, + 'key': access_token_id, + 'secret': access_token_secret +} + +request_token_id = 'test request token id' +request_token_secret = 'test request token secret' +request_token_expires = '2014-05-17T11:10:51.511336Z' + +OAUTH_REQUEST_TOKEN = { + 'id': request_token_id, + 'expires': request_token_expires, + 'key': request_token_id, + 'secret': request_token_secret +} + +oauth_verifier_pin = '6d74XaDS' +OAUTH_VERIFIER = { + 'oauth_verifier': oauth_verifier_pin +} + class FakeIdentityv3Client(object): def __init__(self, **kwargs): @@ -121,6 +183,8 @@ class FakeIdentityv3Client(object): self.domains.resource_class = fakes.FakeResource(None, {}) self.groups = mock.Mock() self.groups.resource_class = fakes.FakeResource(None, {}) + self.oauth1 = mock.Mock() + self.oauth1.resource_class = fakes.FakeResource(None, {}) self.projects = mock.Mock() self.projects.resource_class = fakes.FakeResource(None, {}) self.roles = mock.Mock() @@ -130,6 +194,8 @@ class FakeIdentityv3Client(object): self.service_catalog = mock.Mock() self.users = mock.Mock() self.users.resource_class = fakes.FakeResource(None, {}) + self.role_assignments = mock.Mock() + self.role_assignments.resource_class = fakes.FakeResource(None, {}) self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] @@ -142,6 +208,18 @@ class FakeFederatedClient(FakeIdentityv3Client): self.identity_providers.resource_class = fakes.FakeResource(None, {}) +class FakeOAuth1Client(FakeIdentityv3Client): + def __init__(self, **kwargs): + super(FakeOAuth1Client, self).__init__(**kwargs) + + self.access_tokens = mock.Mock() + self.access_tokens.resource_class = fakes.FakeResource(None, {}) + self.consumers = mock.Mock() + self.consumers.resource_class = fakes.FakeResource(None, {}) + self.request_tokens = mock.Mock() + self.request_tokens.resource_class = fakes.FakeResource(None, {}) + + class TestIdentityv3(utils.TestCommand): def setUp(self): super(TestIdentityv3, self).setUp() @@ -160,3 +238,13 @@ class TestFederatedIdentity(utils.TestCommand): endpoint=fakes.AUTH_URL, token=fakes.AUTH_TOKEN ) + + +class TestOAuth1(utils.TestCommand): + def setUp(self): + super(TestOAuth1, self).setUp() + + self.app.client_manager.identity = FakeOAuth1Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN + ) diff --git a/openstackclient/tests/identity/v3/test_consumer.py b/openstackclient/tests/identity/v3/test_consumer.py new file mode 100644 index 00000000..a1095709 --- /dev/null +++ b/openstackclient/tests/identity/v3/test_consumer.py @@ -0,0 +1,200 @@ +# 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 copy + +from openstackclient.identity.v3 import consumer +from openstackclient.tests import fakes +from openstackclient.tests.identity.v3 import fakes as identity_fakes + + +class TestOAuth1(identity_fakes.TestOAuth1): + + def setUp(self): + super(TestOAuth1, self).setUp() + identity_client = self.app.client_manager.identity + self.consumers_mock = identity_client.oauth1.consumers + self.consumers_mock.reset_mock() + + +class TestConsumerCreate(TestOAuth1): + + def setUp(self): + super(TestConsumerCreate, self).setUp() + + self.consumers_mock.create.return_value = fakes.FakeResource( + None, copy.deepcopy(identity_fakes.OAUTH_CONSUMER), + loaded=True) + + self.cmd = consumer.CreateConsumer(self.app, None) + + def test_create_consumer(self): + arglist = [ + '--description', identity_fakes.consumer_description + ] + verifylist = [ + ('description', identity_fakes.consumer_description) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.consumers_mock.create.assert_called_with( + identity_fakes.consumer_description) + + collist = ('description', 'id', 'secret') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.consumer_description, + identity_fakes.consumer_id, + identity_fakes.consumer_secret + ) + self.assertEqual(data, datalist) + + +class TestConsumerDelete(TestOAuth1): + + def setUp(self): + super(TestConsumerDelete, self).setUp() + + # This is the return value for utils.find_resource() + self.consumers_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.OAUTH_CONSUMER), + loaded=True) + + self.consumers_mock.delete.return_value = None + self.cmd = consumer.DeleteConsumer(self.app, None) + + def test_delete_consumer(self): + arglist = [ + identity_fakes.consumer_id + ] + verifylist = [ + ('consumer', identity_fakes.consumer_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.run(parsed_args) + self.assertEqual(result, 0) + + self.consumers_mock.delete.assert_called_with( + identity_fakes.consumer_id, + ) + + +class TestConsumerList(TestOAuth1): + + def setUp(self): + super(TestConsumerList, self).setUp() + + self.consumers_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.OAUTH_CONSUMER), + loaded=True, + ) + self.consumers_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.OAUTH_CONSUMER), + loaded=True, + ), + ] + + # Get the command object to test + self.cmd = consumer.ListConsumer(self.app, None) + + def test_consumer_list(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + self.consumers_mock.list.assert_called_with() + + collist = ('ID', 'Description') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.consumer_id, + identity_fakes.consumer_description + ), ) + self.assertEqual(tuple(data), datalist) + + +class TestConsumerShow(TestOAuth1): + + def setUp(self): + super(TestConsumerShow, self).setUp() + + consumer_no_secret = copy.deepcopy(identity_fakes.OAUTH_CONSUMER) + del consumer_no_secret['secret'] + self.consumers_mock.get.return_value = fakes.FakeResource( + None, consumer_no_secret, loaded=True) + + # Get the command object to test + self.cmd = consumer.ShowConsumer(self.app, None) + + def test_consumer_show(self): + arglist = [ + identity_fakes.consumer_id + ] + verifylist = [ + ('consumer', identity_fakes.consumer_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.consumers_mock.get.assert_called_with( + identity_fakes.consumer_id) + + collist = ('description', 'id' ) + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.consumer_description, + identity_fakes.consumer_id + ) + self.assertEqual(data, datalist) + + +class TestConsumerSet(TestOAuth1): + + def setUp(self): + super(TestConsumerSet, self).setUp() + + self.consumers_mock.get.return_value = fakes.FakeResource( + None, copy.deepcopy(identity_fakes.OAUTH_CONSUMER), loaded=True) + + consumer_updated = copy.deepcopy(identity_fakes.OAUTH_CONSUMER) + consumer_updated['description'] = "consumer new description" + self.consumers_mock.update.return_value = fakes.FakeResource( + None, consumer_updated, loaded=True) + + self.cmd = consumer.SetConsumer(self.app, None) + + def test_consumer_update(self): + new_description = "consumer new description" + + arglist = [ + '--description', new_description, + identity_fakes.consumer_id + ] + verifylist = [ + ('description', new_description), + ('consumer', identity_fakes.consumer_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.run(parsed_args) + self.assertEqual(result, 0) + + kwargs = {'description': new_description} + self.consumers_mock.update.assert_called_with( + identity_fakes.consumer_id, **kwargs) diff --git a/openstackclient/tests/identity/v3/test_oauth.py b/openstackclient/tests/identity/v3/test_oauth.py new file mode 100644 index 00000000..5a528645 --- /dev/null +++ b/openstackclient/tests/identity/v3/test_oauth.py @@ -0,0 +1,152 @@ +# 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 copy + +from openstackclient.identity.v3 import token +from openstackclient.tests import fakes +from openstackclient.tests.identity.v3 import fakes as identity_fakes + + +class TestOAuth1(identity_fakes.TestOAuth1): + + def setUp(self): + super(TestOAuth1, self).setUp() + identity_client = self.app.client_manager.identity + self.access_tokens_mock = identity_client.oauth1.access_tokens + self.access_tokens_mock.reset_mock() + self.request_tokens_mock = identity_client.oauth1.request_tokens + self.request_tokens_mock.reset_mock() + + +class TestRequestTokenCreate(TestOAuth1): + + def setUp(self): + super(TestRequestTokenCreate, self).setUp() + + self.request_tokens_mock.create.return_value = fakes.FakeResource( + None, copy.deepcopy(identity_fakes.OAUTH_REQUEST_TOKEN), + loaded=True) + + self.cmd = token.CreateRequestToken(self.app, None) + + def test_create_request_tokens(self): + arglist = [ + '--consumer-key', identity_fakes.consumer_id, + '--consumer-secret', identity_fakes.consumer_secret, + '--project-id', identity_fakes.project_id + ] + verifylist = [ + ('consumer_key', identity_fakes.consumer_id), + ('consumer_secret', identity_fakes.consumer_secret), + ('project_id', identity_fakes.project_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.request_tokens_mock.create.assert_called_with( + identity_fakes.consumer_id, + identity_fakes.consumer_secret, + identity_fakes.project_id) + + collist = ('expires', 'id', 'key', 'secret') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.request_token_expires, + identity_fakes.request_token_id, + identity_fakes.request_token_id, + identity_fakes.request_token_secret + ) + self.assertEqual(data, datalist) + + +class TestRequestTokenAuthorize(TestOAuth1): + + def setUp(self): + super(TestRequestTokenAuthorize, self).setUp() + + self.request_tokens_mock.authorize.return_value = \ + fakes.FakeResource( + None, copy.deepcopy(identity_fakes.OAUTH_VERIFIER), + loaded=True) + + self.cmd = token.AuthorizeRequestToken(self.app, None) + + def test_authorize_request_tokens(self): + arglist = [ + '--request-key', identity_fakes.request_token_id, + '--role-ids', identity_fakes.role_id + ] + verifylist = [ + ('request_key', identity_fakes.request_token_id), + ('role_ids', identity_fakes.role_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.request_tokens_mock.authorize.assert_called_with( + identity_fakes.request_token_id, + [identity_fakes.role_id]) + + collist = ('oauth_verifier',) + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.oauth_verifier_pin, + ) + self.assertEqual(data, datalist) + + +class TestAccessTokenCreate(TestOAuth1): + + def setUp(self): + super(TestAccessTokenCreate, self).setUp() + + self.access_tokens_mock.create.return_value = fakes.FakeResource( + None, copy.deepcopy(identity_fakes.OAUTH_ACCESS_TOKEN), + loaded=True) + + self.cmd = token.CreateAccessToken(self.app, None) + + def test_create_access_tokens(self): + arglist = [ + '--consumer-key', identity_fakes.consumer_id, + '--consumer-secret', identity_fakes.consumer_secret, + '--request-key', identity_fakes.request_token_id, + '--request-secret', identity_fakes.request_token_secret, + '--verifier', identity_fakes.oauth_verifier_pin + ] + verifylist = [ + ('consumer_key', identity_fakes.consumer_id), + ('consumer_secret', identity_fakes.consumer_secret), + ('request_key', identity_fakes.request_token_id), + ('request_secret', identity_fakes.request_token_secret), + ('verifier', identity_fakes.oauth_verifier_pin) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.access_tokens_mock.create.assert_called_with( + identity_fakes.consumer_id, + identity_fakes.consumer_secret, + identity_fakes.request_token_id, + identity_fakes.request_token_secret, + identity_fakes.oauth_verifier_pin) + + collist = ('expires', 'id', 'key', 'secret') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.access_token_expires, + identity_fakes.access_token_id, + identity_fakes.access_token_id, + identity_fakes.access_token_secret + ) + self.assertEqual(data, datalist) diff --git a/openstackclient/tests/identity/v3/test_role_assignment.py b/openstackclient/tests/identity/v3/test_role_assignment.py new file mode 100644 index 00000000..6497ca8e --- /dev/null +++ b/openstackclient/tests/identity/v3/test_role_assignment.py @@ -0,0 +1,388 @@ +# 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 copy + +from openstackclient.identity.v3 import role_assignment +from openstackclient.tests import fakes +from openstackclient.tests.identity.v3 import fakes as identity_fakes + + +class TestRoleAssignment(identity_fakes.TestIdentityv3): + + def setUp(self): + super(TestRoleAssignment, self).setUp() + + +class TestRoleAssignmentList(TestRoleAssignment): + + def setUp(self): + super(TestRoleAssignment, self).setUp() + + # Get a shortcut to the UserManager Mock + self.users_mock = self.app.client_manager.identity.users + self.users_mock.reset_mock() + + # Get a shortcut to the GroupManager Mock + self.groups_mock = self.app.client_manager.identity.groups + self.groups_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() + + # Get a shortcut to the RoleManager Mock + self.roles_mock = self.app.client_manager.identity.roles + self.roles_mock.reset_mock() + + self.role_assignments_mock = self.app.client_manager.identity.\ + role_assignments + self.role_assignments_mock.reset_mock() + + # Get the command object to test + self.cmd = role_assignment.ListRoleAssignment(self.app, None) + + def test_role_assignment_list_no_filters(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID), + loaded=True, + ), + ] + + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=None, + group=None, + effective=False, + role=None, + user=None, + project=None) + + collist = ('Role', 'User', 'Group', 'Project', 'Domain') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.role_id, + identity_fakes.user_id, + '', + identity_fakes.project_id, + '' + ), (identity_fakes.role_id, + '', + identity_fakes.group_id, + identity_fakes.project_id, + '' + ),) + self.assertEqual(tuple(data), datalist) + + def test_role_assignment_list_user(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID), + loaded=True, + ), + ] + + arglist = [ + '--user', identity_fakes.user_name + ] + verifylist = [ + ('user', identity_fakes.user_name), + ('group', None), + ('domain', None), + ('project', None), + ('role', None), + ('effective', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=None, + user=self.users_mock.get(), + group=None, + project=None, + role=None, + effective=False) + + collist = ('Role', 'User', 'Group', 'Project', 'Domain') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.role_id, + identity_fakes.user_id, + '', + '', + identity_fakes.domain_id + ), (identity_fakes.role_id, + identity_fakes.user_id, + '', + identity_fakes.project_id, + '' + ),) + self.assertEqual(tuple(data), datalist) + + def test_role_assignment_list_group(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_GROUP_ID), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID), + loaded=True, + ), + ] + + arglist = [ + '--group', identity_fakes.group_name + ] + verifylist = [ + ('user', None), + ('group', identity_fakes.group_name), + ('domain', None), + ('project', None), + ('role', None), + ('effective', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=None, + group=self.groups_mock.get(), + effective=False, + project=None, + role=None, + user=None) + + collist = ('Role', 'User', 'Group', 'Project', 'Domain') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.role_id, + '', + identity_fakes.group_id, + '', + identity_fakes.domain_id + ), (identity_fakes.role_id, + '', + identity_fakes.group_id, + identity_fakes.project_id, + '' + ),) + self.assertEqual(tuple(data), datalist) + + def test_role_assignment_list_domain(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_GROUP_ID), + loaded=True, + ), + ] + + arglist = [ + '--domain', identity_fakes.domain_name + ] + verifylist = [ + ('user', None), + ('group', None), + ('domain', identity_fakes.domain_name), + ('project', None), + ('role', None), + ('effective', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=self.domains_mock.get(), + group=None, + effective=False, + project=None, + role=None, + user=None) + + collist = ('Role', 'User', 'Group', 'Project', 'Domain') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.role_id, + identity_fakes.user_id, + '', + '', + identity_fakes.domain_id + ), (identity_fakes.role_id, + '', + identity_fakes.group_id, + '', + identity_fakes.domain_id + ),) + self.assertEqual(tuple(data), datalist) + + def test_role_assignment_list_project(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_GROUP_ID), + loaded=True, + ), + ] + + arglist = [ + '--project', identity_fakes.project_name + ] + verifylist = [ + ('user', None), + ('group', None), + ('domain', None), + ('project', identity_fakes.project_name), + ('role', None), + ('effective', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=None, + group=None, + effective=False, + project=self.projects_mock.get(), + role=None, + user=None) + + collist = ('Role', 'User', 'Group', 'Project', 'Domain') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.role_id, + identity_fakes.user_id, + '', + identity_fakes.project_id, + '' + ), (identity_fakes.role_id, + '', + identity_fakes.group_id, + identity_fakes.project_id, + '' + ),) + self.assertEqual(tuple(data), datalist) + + def test_role_assignment_list_effective(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes.ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID), + loaded=True, + ), + ] + + arglist = ['--effective'] + verifylist = [ + ('user', None), + ('group', None), + ('domain', None), + ('project', None), + ('role', None), + ('effective', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=None, + group=None, + effective=True, + project=None, + role=None, + user=None) + + collist = ('Role', 'User', 'Group', 'Project', 'Domain') + self.assertEqual(columns, collist) + datalist = (( + identity_fakes.role_id, + identity_fakes.user_id, + '', + identity_fakes.project_id, + '' + ), (identity_fakes.role_id, + identity_fakes.user_id, + '', + '', + identity_fakes.domain_id, + ),) + self.assertEqual(tuple(data), datalist) diff --git a/openstackclient/tests/image/v1/fakes.py b/openstackclient/tests/image/v1/fakes.py index ea2af84c..972e6415 100644 --- a/openstackclient/tests/image/v1/fakes.py +++ b/openstackclient/tests/image/v1/fakes.py @@ -17,16 +17,38 @@ import mock from openstackclient.tests import fakes from openstackclient.tests import utils +from openstackclient.tests.volume.v1 import fakes as volume_fakes image_id = 'im1' image_name = 'graven' +image_owner = 'baal' +image_protected = False +image_public = True +image_properties = { + 'Alpha': 'a', + 'Beta': 'b', + 'Gamma': 'g', +} +image_properties_str = "{'Alpha': 'a', 'Beta': 'b', 'Gamma': 'g'}" +image_data = 'line 1\nline 2\n' IMAGE = { 'id': image_id, - 'name': image_name + 'name': image_name, + 'container_format': '', + 'disk_format': '', + 'owner': image_owner, + 'min_disk': 0, + 'min_ram': 0, + 'is_public': image_public, + 'protected': image_protected, + 'properties': image_properties, } +IMAGE_columns = tuple(sorted(IMAGE)) +IMAGE_data = tuple((IMAGE[x] for x in sorted(IMAGE))) + class FakeImagev1Client(object): def __init__(self, **kwargs): @@ -44,3 +66,7 @@ class TestImagev1(utils.TestCommand): endpoint=fakes.AUTH_URL, token=fakes.AUTH_TOKEN, ) + self.app.client_manager.volume = volume_fakes.FakeVolumev1Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py index d7547f76..b746a538 100644 --- a/openstackclient/tests/image/v1/test_image.py +++ b/openstackclient/tests/image/v1/test_image.py @@ -16,6 +16,7 @@ import copy import mock +from openstackclient.common import exceptions from openstackclient.image.v1 import image from openstackclient.tests import fakes from openstackclient.tests.image.v1 import fakes as image_fakes @@ -35,75 +36,228 @@ class TestImageCreate(TestImage): def setUp(self): super(TestImageCreate, self).setUp() + + self.images_mock.create.return_value = fakes.FakeResource( + None, + copy.deepcopy(image_fakes.IMAGE), + loaded=True, + ) + # This is the return value for utils.find_resource() self.images_mock.get.return_value = fakes.FakeResource( None, copy.deepcopy(image_fakes.IMAGE), loaded=True, ) + self.images_mock.update.return_value = fakes.FakeResource( + None, + copy.deepcopy(image_fakes.IMAGE), + loaded=True, + ) + + # Get the command object to test self.cmd = image.CreateImage(self.app, None) - def test_create_volume(self): + def test_image_reserve_no_options(self): + mock_exception = { + 'find.side_effect': exceptions.CommandError('x'), + 'get.side_effect': exceptions.CommandError('x'), + } + self.images_mock.configure_mock(**mock_exception) arglist = [ - '--volume', 'volly', image_fakes.image_name, ] verifylist = [ - ('volume', 'volly'), + ('container_format', image.DEFAULT_CONTAINER_FORMAT), + ('disk_format', image.DEFAULT_DISK_FORMAT), ('name', image_fakes.image_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.app.client_manager.volume = mock.Mock() - self.app.client_manager.volume.volumes = mock.Mock() - volumes = self.app.client_manager.volume.volumes - volumes.upload_to_image = mock.Mock() - response = {"id": 'volume_id', - "updated_at": 'updated_at', - "status": 'uploading', - "display_description": 'desc', - "size": 'size', - "volume_type": 'volume_type', - "image_id": 'image1', - "container_format": parsed_args.container_format, - "disk_format": parsed_args.disk_format, - "image_name": parsed_args.name} - full_response = {"os-volume_upload_image": response} - volumes.upload_to_image.return_value = (201, full_response) - volume_resource = fakes.FakeResource( + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # ImageManager.create(name=, **) + self.images_mock.create.assert_called_with( + name=image_fakes.image_name, + container_format=image.DEFAULT_CONTAINER_FORMAT, + disk_format=image.DEFAULT_DISK_FORMAT, + data=mock.ANY, + ) + + # Verify update() was not called, if it was show the args + self.assertEqual(self.images_mock.update.call_args_list, []) + + self.assertEqual(image_fakes.IMAGE_columns, columns) + self.assertEqual(image_fakes.IMAGE_data, data) + + def test_image_reserve_options(self): + mock_exception = { + 'find.side_effect': exceptions.CommandError('x'), + 'get.side_effect': exceptions.CommandError('x'), + } + self.images_mock.configure_mock(**mock_exception) + arglist = [ + '--container-format', 'ovf', + '--disk-format', 'fs', + '--min-disk', '10', + '--min-ram', '4', + '--protected', + '--private', + image_fakes.image_name, + ] + verifylist = [ + ('container_format', 'ovf'), + ('disk_format', 'fs'), + ('min_disk', 10), + ('min_ram', 4), + ('protected', True), + ('unprotected', False), + ('public', False), + ('private', True), + ('name', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # ImageManager.create(name=, **) + self.images_mock.create.assert_called_with( + name=image_fakes.image_name, + container_format='ovf', + disk_format='fs', + min_disk=10, + min_ram=4, + protected=True, + is_public=False, + data=mock.ANY, + ) + + # Verify update() was not called, if it was show the args + self.assertEqual(self.images_mock.update.call_args_list, []) + + self.assertEqual(image_fakes.IMAGE_columns, columns) + self.assertEqual(image_fakes.IMAGE_data, data) + + @mock.patch('__builtin__.open') + def test_image_create_file(self, open_mock): + mock_exception = { + 'find.side_effect': exceptions.CommandError('x'), + 'get.side_effect': exceptions.CommandError('x'), + } + self.images_mock.configure_mock(**mock_exception) + open_mock.return_value = image_fakes.image_data + arglist = [ + '--file', 'filer', + '--unprotected', + '--public', + '--property', 'Alpha=1', + '--property', 'Beta=2', + image_fakes.image_name, + ] + verifylist = [ + ('file', 'filer'), + ('protected', False), + ('unprotected', True), + ('public', True), + ('private', False), + ('properties', {'Alpha': '1', 'Beta': '2'}), + ('name', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + open_mock.assert_called_with('filer', 'rb') + + # ImageManager.get(name) + self.images_mock.get.assert_called_with(image_fakes.image_name) + + # ImageManager.create(name=, **) + self.images_mock.create.assert_called_with( + name=image_fakes.image_name, + container_format=image.DEFAULT_CONTAINER_FORMAT, + disk_format=image.DEFAULT_DISK_FORMAT, + protected=False, + is_public=True, + properties={ + 'Alpha': '1', + 'Beta': '2', + }, + data=image_fakes.image_data, + ) + + # Verify update() was not called, if it was show the args + self.assertEqual(self.images_mock.update.call_args_list, []) + + self.assertEqual(image_fakes.IMAGE_columns, columns) + self.assertEqual(image_fakes.IMAGE_data, data) + + def test_image_create_volume(self): + # Set up VolumeManager Mock + volumes_mock = self.app.client_manager.volume.volumes + volumes_mock.reset_mock() + volumes_mock.get.return_value = fakes.FakeResource( None, copy.deepcopy({'id': 'vol1', 'name': 'volly'}), loaded=True, ) - volumes.get.return_value = volume_resource - results = self.cmd.take_action(parsed_args) - volumes.upload_to_image.assert_called_with( - volume_resource, + response = { + "id": 'volume_id', + "updated_at": 'updated_at', + "status": 'uploading', + "display_description": 'desc', + "size": 'size', + "volume_type": 'volume_type', + "image_id": 'image1', + "container_format": image.DEFAULT_CONTAINER_FORMAT, + "disk_format": image.DEFAULT_DISK_FORMAT, + "image_name": image_fakes.image_name, + } + full_response = {"os-volume_upload_image": response} + volumes_mock.upload_to_image.return_value = (201, full_response) + + arglist = [ + '--volume', 'volly', + image_fakes.image_name, + ] + verifylist = [ + ('private', False), + ('protected', False), + ('public', False), + ('unprotected', False), + ('volume', 'volly'), + ('force', False), + ('name', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # VolumeManager.upload_to_image(volume, force, image_name, + # container_format, disk_format) + volumes_mock.upload_to_image.assert_called_with( + 'vol1', False, image_fakes.image_name, 'bare', 'raw', ) - expects = [('container_format', - 'disk_format', - 'display_description', - 'id', - 'image_id', - 'image_name', - 'size', - 'status', - 'updated_at', - 'volume_type'), - ('bare', - 'raw', - 'desc', - 'volume_id', - 'image1', - 'graven', - 'size', - 'uploading', - 'updated_at', - 'volume_type')] - for expected, result in zip(expects, results): - self.assertEqual(expected, result) + + # ImageManager.update(image_id, remove_props=, **) + self.images_mock.update.assert_called_with( + image_fakes.image_id, + name=image_fakes.image_name, + container_format=image.DEFAULT_CONTAINER_FORMAT, + disk_format=image.DEFAULT_DISK_FORMAT, + properties=image_fakes.image_properties, + volume='volly', + ) + + self.assertEqual(image_fakes.IMAGE_columns, columns) + self.assertEqual(image_fakes.IMAGE_data, data) class TestImageDelete(TestImage): @@ -137,3 +291,158 @@ class TestImageDelete(TestImage): self.images_mock.delete.assert_called_with( image_fakes.image_id, ) + + +class TestImageSet(TestImage): + + def setUp(self): + super(TestImageSet, self).setUp() + + # This is the return value for utils.find_resource() + self.images_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(image_fakes.IMAGE), + loaded=True, + ) + self.images_mock.update.return_value = fakes.FakeResource( + None, + copy.deepcopy(image_fakes.IMAGE), + loaded=True, + ) + + # Get the command object to test + self.cmd = image.SetImage(self.app, None) + + def test_image_set_no_options(self): + arglist = [ + image_fakes.image_name, + ] + verifylist = [ + ('image', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + # Verify update() was not called, if it was show the args + self.assertEqual(self.images_mock.update.call_args_list, []) + + def test_image_set_options(self): + arglist = [ + '--name', 'new-name', + '--owner', 'new-owner', + '--min-disk', '2', + '--min-ram', '4', + image_fakes.image_name, + ] + verifylist = [ + ('name', 'new-name'), + ('owner', 'new-owner'), + ('min_disk', 2), + ('min_ram', 4), + ('image', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + kwargs = { + 'name': 'new-name', + 'owner': 'new-owner', + 'min_disk': 2, + 'min_ram': 4, + } + # ImageManager.update(image, **kwargs) + self.images_mock.update.assert_called_with( + image_fakes.image_id, + **kwargs + ) + + self.assertEqual(image_fakes.IMAGE_columns, columns) + self.assertEqual(image_fakes.IMAGE_data, data) + + def test_image_set_bools1(self): + arglist = [ + '--protected', + '--private', + image_fakes.image_name, + ] + verifylist = [ + ('protected', True), + ('unprotected', False), + ('public', False), + ('private', True), + ('image', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + kwargs = { + 'protected': True, + 'is_public': False, + } + # ImageManager.update(image, **kwargs) + self.images_mock.update.assert_called_with( + image_fakes.image_id, + **kwargs + ) + + def test_image_set_bools2(self): + arglist = [ + '--unprotected', + '--public', + image_fakes.image_name, + ] + verifylist = [ + ('protected', False), + ('unprotected', True), + ('public', True), + ('private', False), + ('image', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + kwargs = { + 'protected': False, + 'is_public': True, + } + # ImageManager.update(image, **kwargs) + self.images_mock.update.assert_called_with( + image_fakes.image_id, + **kwargs + ) + + def test_image_set_properties(self): + arglist = [ + '--property', 'Alpha=1', + '--property', 'Beta=2', + image_fakes.image_name, + ] + verifylist = [ + ('properties', {'Alpha': '1', 'Beta': '2'}), + ('image', image_fakes.image_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + kwargs = { + 'properties': { + 'Alpha': '1', + 'Beta': '2', + 'Gamma': 'g', + }, + } + # ImageManager.update(image, **kwargs) + self.images_mock.update.assert_called_with( + image_fakes.image_id, + **kwargs + ) diff --git a/openstackclient/tests/volume/test_find_resource.py b/openstackclient/tests/volume/test_find_resource.py new file mode 100644 index 00000000..8539070f --- /dev/null +++ b/openstackclient/tests/volume/test_find_resource.py @@ -0,0 +1,71 @@ +# Copyright 2013 Nebula Inc. +# +# 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 cinderclient.v1 import volume_snapshots +from cinderclient.v1 import volumes + +from openstackclient.common import exceptions +from openstackclient.common import utils +from openstackclient.tests import utils as test_utils + + +ID = '1after909' +NAME = 'PhilSpector' + + +class TestFindResourceVolumes(test_utils.TestCase): + + def setUp(self): + super(TestFindResourceVolumes, self).setUp() + api = mock.Mock() + api.client = mock.Mock() + api.client.get = mock.Mock() + resp = mock.Mock() + body = {"volumes": [{"id": ID, 'display_name': NAME}]} + api.client.get.side_effect = [Exception("Not found"), (resp, body)] + self.manager = volumes.VolumeManager(api) + + def test_find(self): + result = utils.find_resource(self.manager, NAME) + self.assertEqual(ID, result.id) + self.assertEqual(NAME, result.display_name) + + def test_not_find(self): + self.assertRaises(exceptions.CommandError, utils.find_resource, + self.manager, 'GeorgeMartin') + + +class TestFindResourceVolumeSnapshots(test_utils.TestCase): + + def setUp(self): + super(TestFindResourceVolumeSnapshots, self).setUp() + api = mock.Mock() + api.client = mock.Mock() + api.client.get = mock.Mock() + resp = mock.Mock() + body = {"snapshots": [{"id": ID, 'display_name': NAME}]} + api.client.get.side_effect = [Exception("Not found"), (resp, body)] + self.manager = volume_snapshots.SnapshotManager(api) + + def test_find(self): + result = utils.find_resource(self.manager, NAME) + self.assertEqual(ID, result.id) + self.assertEqual(NAME, result.display_name) + + def test_not_find(self): + self.assertRaises(exceptions.CommandError, utils.find_resource, + self.manager, 'GeorgeMartin') diff --git a/openstackclient/tests/volume/v1/fakes.py b/openstackclient/tests/volume/v1/fakes.py index 3567eca5..c0ffbd34 100644 --- a/openstackclient/tests/volume/v1/fakes.py +++ b/openstackclient/tests/volume/v1/fakes.py @@ -45,6 +45,26 @@ VOLUME = { 'metadata': volume_metadata, } +extension_name = 'SchedulerHints' +extension_namespace = 'http://docs.openstack.org/'\ + 'block-service/ext/scheduler-hints/api/v2' +extension_description = 'Pass arbitrary key/value'\ + 'pairs to the scheduler.' +extension_updated = '2014-02-07T12:00:0-00:00' +extension_alias = 'OS-SCH-HNT' +extension_links = '[{"href":'\ + '"https://github.com/openstack/block-api", "type":'\ + ' "text/html", "rel": "describedby"}]' + +EXTENSION = { + 'name': extension_name, + 'namespace': extension_namespace, + 'description': extension_description, + 'updated': extension_updated, + 'alias': extension_alias, + 'links': extension_links, +} + class FakeVolumev1Client(object): def __init__(self, **kwargs): @@ -52,6 +72,8 @@ class FakeVolumev1Client(object): self.volumes.resource_class = fakes.FakeResource(None, {}) self.services = mock.Mock() self.services.resource_class = fakes.FakeResource(None, {}) + self.extensions = mock.Mock() + self.extensions.resource_class = fakes.FakeResource(None, {}) self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py index 7cf828b4..9b37b8f5 100644 --- a/openstackclient/volume/client.py +++ b/openstackclient/volume/client.py @@ -15,8 +15,13 @@ import logging +from cinderclient.v1 import volume_snapshots +from cinderclient.v1 import volumes from openstackclient.common import utils +# Monkey patch for v1 cinderclient +volumes.Volume.NAME_ATTR = 'display_name' +volume_snapshots.Snapshot.NAME_ATTR = 'display_name' LOG = logging.getLogger(__name__) diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/backup.py index ac34749b..992fa7be 100644 --- a/openstackclient/volume/v1/backup.py +++ b/openstackclient/volume/v1/backup.py @@ -57,7 +57,7 @@ class CreateBackup(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume_id = utils.find_resource(volume_client.volumes, parsed_args.volume).id @@ -87,7 +87,7 @@ class DeleteBackup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume backup_id = utils.find_resource(volume_client.backups, parsed_args.backup).id @@ -101,7 +101,7 @@ class ListBackup(lister.Lister): log = logging.getLogger(__name__ + '.ListBackup') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ( 'ID', 'Display Name', @@ -135,7 +135,7 @@ class RestoreBackup(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume backup = utils.find_resource(volume_client.backups, parsed_args.backup) @@ -159,7 +159,7 @@ class ShowBackup(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume backup = utils.find_resource(volume_client.backups, parsed_args.backup) diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py index d3a56b75..9cc3c4c1 100644 --- a/openstackclient/volume/v1/snapshot.py +++ b/openstackclient/volume/v1/snapshot.py @@ -59,7 +59,7 @@ class CreateSnapshot(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume_id = utils.find_resource(volume_client.volumes, parsed_args.volume).id @@ -88,7 +88,7 @@ class DeleteSnapshot(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume snapshot_id = utils.find_resource(volume_client.volume_snapshots, parsed_args.snapshot).id @@ -102,7 +102,7 @@ class ListSnapshot(lister.Lister): log = logging.getLogger(__name__ + '.ListSnapshot') def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) columns = ( 'ID', 'Display Name', @@ -140,7 +140,7 @@ class SetSnapshot(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume snapshot = utils.find_resource(volume_client.volume_snapshots, parsed_args.snapshot) @@ -171,7 +171,7 @@ class ShowSnapshot(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume snapshot = utils.find_resource(volume_client.volume_snapshots, parsed_args.snapshot) diff --git a/openstackclient/volume/v1/type.py b/openstackclient/volume/v1/type.py index b199b7c3..71bfc9ea 100644 --- a/openstackclient/volume/v1/type.py +++ b/openstackclient/volume/v1/type.py @@ -48,7 +48,7 @@ class CreateVolumeType(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume_type = volume_client.volume_types.create(parsed_args.name) volume_type._info.pop('extra_specs') @@ -76,7 +76,7 @@ class DeleteVolumeType(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume_type_id = utils.find_resource( volume_client.volume_types, parsed_args.volume_type).id @@ -99,7 +99,7 @@ class ListVolumeType(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) if parsed_args.long: columns = ('ID', 'Name', 'Extra Specs') column_headers = ('ID', 'Name', 'Properties') @@ -136,7 +136,7 @@ class SetVolumeType(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume_type = utils.find_resource( volume_client.volume_types, parsed_args.volume_type) @@ -170,7 +170,7 @@ class UnsetVolumeType(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume_type = utils.find_resource( volume_client.volume_types, diff --git a/openstackclient/volume/v1/volume.py b/openstackclient/volume/v1/volume.py index cad53eb1..3e4af56c 100644 --- a/openstackclient/volume/v1/volume.py +++ b/openstackclient/volume/v1/volume.py @@ -96,7 +96,7 @@ class CreateVolume(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) identity_client = self.app.client_manager.identity volume_client = self.app.client_manager.volume @@ -164,7 +164,7 @@ class DeleteVolume(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume = utils.find_resource( volume_client.volumes, parsed_args.volume) @@ -207,7 +207,7 @@ class ListVolume(lister.Lister): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) if parsed_args.long: columns = ( @@ -293,7 +293,7 @@ class SetVolume(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume = utils.find_resource(volume_client.volumes, parsed_args.volume) @@ -329,7 +329,7 @@ class ShowVolume(show.ShowOne): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume = utils.find_resource(volume_client.volumes, parsed_args.volume) # Map 'metadata' column to 'properties' @@ -370,7 +370,7 @@ class UnsetVolume(command.Command): return parser def take_action(self, parsed_args): - self.log.debug('take_action(%s)' % parsed_args) + self.log.debug('take_action(%s)', parsed_args) volume_client = self.app.client_manager.volume volume = utils.find_resource( volume_client.volumes, parsed_args.volume) |
