Use common code instead of novaclient.utils
Module `novaclient.utils` contains a lot of functions which are presented in modules from common code. * service_type -> novaclient.openstack.common.cliutils.service_type * get_service_type -> novaclient.openstack.common.cliutils.get_service_type * pretty_choice_list -> novaclient.openstack.common.cliutils.pretty_choice_list * import_class -> oslo.utils.importutils.importclass * HookableMixin -> novaclient.openstack.common.apiclient.base.HookableMixin Change-Id: Ia6cac058da12c852d92f26875a66ae31cc4c63d4
This commit is contained in:
parent
87a1ebcd14
commit
d03014cdb0
@ -26,7 +26,6 @@ import six
|
|||||||
|
|
||||||
from novaclient import exceptions
|
from novaclient import exceptions
|
||||||
from novaclient.openstack.common.apiclient import base
|
from novaclient.openstack.common.apiclient import base
|
||||||
from novaclient import utils
|
|
||||||
|
|
||||||
Resource = base.Resource
|
Resource = base.Resource
|
||||||
|
|
||||||
@ -42,7 +41,7 @@ def getid(obj):
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class Manager(utils.HookableMixin):
|
class Manager(base.HookableMixin):
|
||||||
"""
|
"""
|
||||||
Managers interact with a particular type of API (servers, flavors, images,
|
Managers interact with a particular type of API (servers, flavors, images,
|
||||||
etc.) and provide CRUD operations for them.
|
etc.) and provide CRUD operations for them.
|
||||||
|
@ -31,6 +31,7 @@ import re
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from keystoneclient import adapter
|
from keystoneclient import adapter
|
||||||
|
from oslo.utils import importutils
|
||||||
from oslo.utils import netutils
|
from oslo.utils import netutils
|
||||||
import requests
|
import requests
|
||||||
from requests import adapters
|
from requests import adapters
|
||||||
@ -757,7 +758,7 @@ def get_client_class(version):
|
|||||||
'keys': ', '.join(version_map.keys())}
|
'keys': ', '.join(version_map.keys())}
|
||||||
raise exceptions.UnsupportedVersion(msg)
|
raise exceptions.UnsupportedVersion(msg)
|
||||||
|
|
||||||
return utils.import_class(client_path)
|
return importutils.import_class(client_path)
|
||||||
|
|
||||||
|
|
||||||
def Client(version, *args, **kwargs):
|
def Client(version, *args, **kwargs):
|
||||||
|
@ -14,10 +14,11 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from novaclient import base
|
from novaclient import base
|
||||||
|
from novaclient.openstack.common.apiclient import base as common_base
|
||||||
from novaclient import utils
|
from novaclient import utils
|
||||||
|
|
||||||
|
|
||||||
class Extension(utils.HookableMixin):
|
class Extension(common_base.HookableMixin):
|
||||||
"""Extension descriptor."""
|
"""Extension descriptor."""
|
||||||
|
|
||||||
SUPPORTED_HOOKS = ('__pre_parse_args__', '__post_parse_args__')
|
SUPPORTED_HOOKS = ('__pre_parse_args__', '__post_parse_args__')
|
||||||
|
@ -601,7 +601,7 @@ class OpenStackComputeShell(object):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
service_type = DEFAULT_NOVA_SERVICE_TYPE_MAP[
|
service_type = DEFAULT_NOVA_SERVICE_TYPE_MAP[
|
||||||
DEFAULT_OS_COMPUTE_API_VERSION]
|
DEFAULT_OS_COMPUTE_API_VERSION]
|
||||||
service_type = utils.get_service_type(args.func) or service_type
|
service_type = cliutils.get_service_type(args.func) or service_type
|
||||||
|
|
||||||
# If we have an auth token but no management_url, we must auth anyway.
|
# If we have an auth token but no management_url, we must auth anyway.
|
||||||
# Expired tokens are handled by client.py:_cs_request
|
# Expired tokens are handled by client.py:_cs_request
|
||||||
|
@ -267,15 +267,6 @@ class FlattenTestCase(test_utils.TestCase):
|
|||||||
'a3': ('t',)},
|
'a3': ('t',)},
|
||||||
squashed)
|
squashed)
|
||||||
|
|
||||||
def test_pretty_choice_list(self):
|
|
||||||
l = []
|
|
||||||
r = utils.pretty_choice_list(l)
|
|
||||||
self.assertEqual("", r)
|
|
||||||
|
|
||||||
l = ["v1", "v2", "v3"]
|
|
||||||
r = utils.pretty_choice_list(l)
|
|
||||||
self.assertEqual("'v1', 'v2', 'v3'", r)
|
|
||||||
|
|
||||||
def test_pretty_choice_dict(self):
|
def test_pretty_choice_dict(self):
|
||||||
d = {}
|
d = {}
|
||||||
r = utils.pretty_choice_dict(d)
|
r = utils.pretty_choice_dict(d)
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
import textwrap
|
import textwrap
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
@ -71,34 +70,10 @@ def get_resource_manager_extra_kwargs(f, args, allow_conflicts=False):
|
|||||||
return extra_kwargs
|
return extra_kwargs
|
||||||
|
|
||||||
|
|
||||||
def service_type(stype):
|
|
||||||
"""
|
|
||||||
Adds 'service_type' attribute to decorated function.
|
|
||||||
Usage:
|
|
||||||
@service_type('volume')
|
|
||||||
def mymethod(f):
|
|
||||||
...
|
|
||||||
"""
|
|
||||||
def inner(f):
|
|
||||||
f.service_type = stype
|
|
||||||
return f
|
|
||||||
return inner
|
|
||||||
|
|
||||||
|
|
||||||
def get_service_type(f):
|
|
||||||
"""
|
|
||||||
Retrieves service type from function
|
|
||||||
"""
|
|
||||||
return getattr(f, 'service_type', None)
|
|
||||||
|
|
||||||
|
|
||||||
def pretty_choice_list(l):
|
|
||||||
return ', '.join("'%s'" % i for i in l)
|
|
||||||
|
|
||||||
|
|
||||||
def pretty_choice_dict(d):
|
def pretty_choice_dict(d):
|
||||||
"""Returns a formatted dict as 'key=value'."""
|
"""Returns a formatted dict as 'key=value'."""
|
||||||
return pretty_choice_list(['%s=%s' % (k, d[k]) for k in sorted(d.keys())])
|
return cliutils.pretty_choice_list(
|
||||||
|
['%s=%s' % (k, d[k]) for k in sorted(d.keys())])
|
||||||
|
|
||||||
|
|
||||||
def print_list(objs, fields, formatters={}, sortby_index=None):
|
def print_list(objs, fields, formatters={}, sortby_index=None):
|
||||||
@ -313,24 +288,6 @@ def _make_field_formatter(attr, filters=None):
|
|||||||
return name, formatter
|
return name, formatter
|
||||||
|
|
||||||
|
|
||||||
class HookableMixin(object):
|
|
||||||
"""Mixin so classes can register and run hooks."""
|
|
||||||
_hooks_map = {}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def add_hook(cls, hook_type, hook_func):
|
|
||||||
if hook_type not in cls._hooks_map:
|
|
||||||
cls._hooks_map[hook_type] = []
|
|
||||||
|
|
||||||
cls._hooks_map[hook_type].append(hook_func)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def run_hooks(cls, hook_type, *args, **kwargs):
|
|
||||||
hook_funcs = cls._hooks_map.get(hook_type) or []
|
|
||||||
for hook_func in hook_funcs:
|
|
||||||
hook_func(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def safe_issubclass(*args):
|
def safe_issubclass(*args):
|
||||||
"""Like issubclass, but will just return False if not a class."""
|
"""Like issubclass, but will just return False if not a class."""
|
||||||
|
|
||||||
@ -343,13 +300,6 @@ def safe_issubclass(*args):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def import_class(import_str):
|
|
||||||
"""Returns a class from a string including module and class."""
|
|
||||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
|
||||||
__import__(mod_str)
|
|
||||||
return getattr(sys.modules[mod_str], class_str)
|
|
||||||
|
|
||||||
|
|
||||||
def _load_entry_point(ep_name, name=None):
|
def _load_entry_point(ep_name, name=None):
|
||||||
"""Try to load the entry point ep_name that matches name."""
|
"""Try to load the entry point ep_name that matches name."""
|
||||||
for ep in pkg_resources.iter_entry_points(ep_name, name=name):
|
for ep in pkg_resources.iter_entry_points(ep_name, name=name):
|
||||||
|
@ -34,6 +34,7 @@ from oslo.utils import timeutils
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from novaclient import exceptions
|
from novaclient import exceptions
|
||||||
|
from novaclient.openstack.common import cliutils
|
||||||
from novaclient.openstack.common.gettextutils import _
|
from novaclient.openstack.common.gettextutils import _
|
||||||
from novaclient.openstack.common import uuidutils
|
from novaclient.openstack.common import uuidutils
|
||||||
from novaclient import utils
|
from novaclient import utils
|
||||||
@ -1767,7 +1768,7 @@ def _translate_availability_zone_keys(collection):
|
|||||||
type=int,
|
type=int,
|
||||||
const=1,
|
const=1,
|
||||||
help=argparse.SUPPRESS)
|
help=argparse.SUPPRESS)
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_list(cs, args):
|
def do_volume_list(cs, args):
|
||||||
"""List all the volumes."""
|
"""List all the volumes."""
|
||||||
search_opts = {'all_tenants': args.all_tenants}
|
search_opts = {'all_tenants': args.all_tenants}
|
||||||
@ -1783,7 +1784,7 @@ def do_volume_list(cs, args):
|
|||||||
|
|
||||||
|
|
||||||
@utils.arg('volume', metavar='<volume>', help=_('Name or ID of the volume.'))
|
@utils.arg('volume', metavar='<volume>', help=_('Name or ID of the volume.'))
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_show(cs, args):
|
def do_volume_show(cs, args):
|
||||||
"""Show details about a volume."""
|
"""Show details about a volume."""
|
||||||
volume = _find_volume(cs, args.volume)
|
volume = _find_volume(cs, args.volume)
|
||||||
@ -1825,7 +1826,7 @@ def do_volume_show(cs, args):
|
|||||||
@utils.arg('--availability-zone', metavar='<availability-zone>',
|
@utils.arg('--availability-zone', metavar='<availability-zone>',
|
||||||
help=_('Optional Availability Zone for volume. (Default=None)'),
|
help=_('Optional Availability Zone for volume. (Default=None)'),
|
||||||
default=None)
|
default=None)
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_create(cs, args):
|
def do_volume_create(cs, args):
|
||||||
"""Add a new volume."""
|
"""Add a new volume."""
|
||||||
volume = cs.volumes.create(args.size,
|
volume = cs.volumes.create(args.size,
|
||||||
@ -1841,7 +1842,7 @@ def do_volume_create(cs, args):
|
|||||||
@utils.arg('volume',
|
@utils.arg('volume',
|
||||||
metavar='<volume>', nargs='+',
|
metavar='<volume>', nargs='+',
|
||||||
help=_('Name or ID of the volume(s) to delete.'))
|
help=_('Name or ID of the volume(s) to delete.'))
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_delete(cs, args):
|
def do_volume_delete(cs, args):
|
||||||
"""Remove volume(s)."""
|
"""Remove volume(s)."""
|
||||||
for volume in args.volume:
|
for volume in args.volume:
|
||||||
@ -1900,7 +1901,7 @@ def do_volume_detach(cs, args):
|
|||||||
args.attachment_id)
|
args.attachment_id)
|
||||||
|
|
||||||
|
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_snapshot_list(cs, _args):
|
def do_volume_snapshot_list(cs, _args):
|
||||||
"""List all the snapshots."""
|
"""List all the snapshots."""
|
||||||
snapshots = cs.volume_snapshots.list()
|
snapshots = cs.volume_snapshots.list()
|
||||||
@ -1912,7 +1913,7 @@ def do_volume_snapshot_list(cs, _args):
|
|||||||
@utils.arg('snapshot',
|
@utils.arg('snapshot',
|
||||||
metavar='<snapshot>',
|
metavar='<snapshot>',
|
||||||
help=_('Name or ID of the snapshot.'))
|
help=_('Name or ID of the snapshot.'))
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_snapshot_show(cs, args):
|
def do_volume_snapshot_show(cs, args):
|
||||||
"""Show details about a snapshot."""
|
"""Show details about a snapshot."""
|
||||||
snapshot = _find_volume_snapshot(cs, args.snapshot)
|
snapshot = _find_volume_snapshot(cs, args.snapshot)
|
||||||
@ -1939,7 +1940,7 @@ def do_volume_snapshot_show(cs, args):
|
|||||||
help=_('Optional snapshot description. (Default=None)'))
|
help=_('Optional snapshot description. (Default=None)'))
|
||||||
@utils.arg('--display_description',
|
@utils.arg('--display_description',
|
||||||
help=argparse.SUPPRESS)
|
help=argparse.SUPPRESS)
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_snapshot_create(cs, args):
|
def do_volume_snapshot_create(cs, args):
|
||||||
"""Add a new snapshot."""
|
"""Add a new snapshot."""
|
||||||
snapshot = cs.volume_snapshots.create(args.volume_id,
|
snapshot = cs.volume_snapshots.create(args.volume_id,
|
||||||
@ -1952,7 +1953,7 @@ def do_volume_snapshot_create(cs, args):
|
|||||||
@utils.arg('snapshot',
|
@utils.arg('snapshot',
|
||||||
metavar='<snapshot>',
|
metavar='<snapshot>',
|
||||||
help=_('Name or ID of the snapshot to delete.'))
|
help=_('Name or ID of the snapshot to delete.'))
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_snapshot_delete(cs, args):
|
def do_volume_snapshot_delete(cs, args):
|
||||||
"""Remove a snapshot."""
|
"""Remove a snapshot."""
|
||||||
snapshot = _find_volume_snapshot(cs, args.snapshot)
|
snapshot = _find_volume_snapshot(cs, args.snapshot)
|
||||||
@ -1963,7 +1964,7 @@ def _print_volume_type_list(vtypes):
|
|||||||
utils.print_list(vtypes, ['ID', 'Name'])
|
utils.print_list(vtypes, ['ID', 'Name'])
|
||||||
|
|
||||||
|
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_type_list(cs, args):
|
def do_volume_type_list(cs, args):
|
||||||
"""Print a list of available 'volume types'."""
|
"""Print a list of available 'volume types'."""
|
||||||
vtypes = cs.volume_types.list()
|
vtypes = cs.volume_types.list()
|
||||||
@ -1973,7 +1974,7 @@ def do_volume_type_list(cs, args):
|
|||||||
@utils.arg('name',
|
@utils.arg('name',
|
||||||
metavar='<name>',
|
metavar='<name>',
|
||||||
help=_("Name of the new volume type"))
|
help=_("Name of the new volume type"))
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_type_create(cs, args):
|
def do_volume_type_create(cs, args):
|
||||||
"""Create a new volume type."""
|
"""Create a new volume type."""
|
||||||
vtype = cs.volume_types.create(args.name)
|
vtype = cs.volume_types.create(args.name)
|
||||||
@ -1983,7 +1984,7 @@ def do_volume_type_create(cs, args):
|
|||||||
@utils.arg('id',
|
@utils.arg('id',
|
||||||
metavar='<id>',
|
metavar='<id>',
|
||||||
help=_("Unique ID of the volume type to delete"))
|
help=_("Unique ID of the volume type to delete"))
|
||||||
@utils.service_type('volume')
|
@cliutils.service_type('volume')
|
||||||
def do_volume_type_delete(cs, args):
|
def do_volume_type_delete(cs, args):
|
||||||
"""Delete a specific volume type."""
|
"""Delete a specific volume type."""
|
||||||
cs.volume_types.delete(args.id)
|
cs.volume_types.delete(args.id)
|
||||||
@ -2966,7 +2967,7 @@ def _print_aggregate_details(aggregate):
|
|||||||
return utils.pretty_choice_dict(getattr(fields, 'metadata', {}) or {})
|
return utils.pretty_choice_dict(getattr(fields, 'metadata', {}) or {})
|
||||||
|
|
||||||
def parser_hosts(fields):
|
def parser_hosts(fields):
|
||||||
return utils.pretty_choice_list(getattr(fields, 'hosts', []))
|
return cliutils.pretty_choice_list(getattr(fields, 'hosts', []))
|
||||||
|
|
||||||
formatters = {
|
formatters = {
|
||||||
'Metadata': parser_metadata,
|
'Metadata': parser_metadata,
|
||||||
@ -3783,7 +3784,7 @@ def _treeizeAvailabilityZone(zone):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@utils.service_type('compute')
|
@cliutils.service_type('compute')
|
||||||
def do_availability_zone_list(cs, _args):
|
def do_availability_zone_list(cs, _args):
|
||||||
"""List all the availability zones."""
|
"""List all the availability zones."""
|
||||||
try:
|
try:
|
||||||
|
@ -32,6 +32,7 @@ from oslo.utils import timeutils
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from novaclient import exceptions
|
from novaclient import exceptions
|
||||||
|
from novaclient.openstack.common import cliutils
|
||||||
from novaclient.openstack.common.gettextutils import _
|
from novaclient.openstack.common.gettextutils import _
|
||||||
from novaclient.openstack.common import uuidutils
|
from novaclient.openstack.common import uuidutils
|
||||||
from novaclient import utils
|
from novaclient import utils
|
||||||
@ -778,7 +779,7 @@ def do_network_create(cs, args):
|
|||||||
dest="limit",
|
dest="limit",
|
||||||
metavar="<limit>",
|
metavar="<limit>",
|
||||||
help='Number of images to return per request.')
|
help='Number of images to return per request.')
|
||||||
@utils.service_type('image')
|
@cliutils.service_type('image')
|
||||||
def do_image_list(cs, _args):
|
def do_image_list(cs, _args):
|
||||||
"""Print a list of available images to boot from."""
|
"""Print a list of available images to boot from."""
|
||||||
limit = _args.limit
|
limit = _args.limit
|
||||||
@ -867,7 +868,7 @@ def _print_flavor(flavor):
|
|||||||
@utils.arg('image',
|
@utils.arg('image',
|
||||||
metavar='<image>',
|
metavar='<image>',
|
||||||
help="Name or ID of image")
|
help="Name or ID of image")
|
||||||
@utils.service_type('image')
|
@cliutils.service_type('image')
|
||||||
def do_image_show(cs, args):
|
def do_image_show(cs, args):
|
||||||
"""Show details about the given image."""
|
"""Show details about the given image."""
|
||||||
image = _find_image(cs, args.image)
|
image = _find_image(cs, args.image)
|
||||||
@ -2363,7 +2364,7 @@ def _print_aggregate_details(aggregate):
|
|||||||
return utils.pretty_choice_dict(getattr(fields, 'metadata', {}) or {})
|
return utils.pretty_choice_dict(getattr(fields, 'metadata', {}) or {})
|
||||||
|
|
||||||
def parser_hosts(fields):
|
def parser_hosts(fields):
|
||||||
return utils.pretty_choice_list(getattr(fields, 'hosts', []))
|
return cliutils.pretty_choice_list(getattr(fields, 'hosts', []))
|
||||||
|
|
||||||
formatters = {
|
formatters = {
|
||||||
'Metadata': parser_metadata,
|
'Metadata': parser_metadata,
|
||||||
|
Loading…
Reference in New Issue
Block a user