diff --git a/senlinclient/common/sdk.py b/senlinclient/common/sdk.py index 0882cf9e..ef1c5901 100644 --- a/senlinclient/common/sdk.py +++ b/senlinclient/common/sdk.py @@ -13,10 +13,13 @@ import argparse import os +from six.moves.urllib import parse as url_parse + from openstack import connection from openstack import exceptions from openstack import resource as base from openstack import user_preference +from openstack import utils from senlinclient.common import exc # Alias here for consistency @@ -118,6 +121,31 @@ class Resource(base.Resource): for attr in resp: self._attrs[attr] = resp[attr] self._reset_dirty() + + return self + + @classmethod + def get_data_with_args(cls, session, resource_id, args=None): + if not cls.allow_retrieve: + raise exceptions.MethodNotSupported('list') + + url = utils.urljoin(cls.base_path, resource_id) + if args: + args.pop('id') + url = '%s?%s' % (url, url_parse.urlencode(args)) + resp = session.get(url, service=cls.service) + body = resp.body + if cls.resource_key: + body = body[cls.resource_key] + + return body + + def get_with_args(self, session, args=None): + body = self.get_data_with_args(session, self.id, args=args) + + self._attrs.update(body) + self._loaded = True + return self diff --git a/senlinclient/v1/client.py b/senlinclient/v1/client.py index 5dffd7de..ca561709 100644 --- a/senlinclient/v1/client.py +++ b/senlinclient/v1/client.py @@ -71,6 +71,15 @@ class Client(object): except Exception as ex: client_exc.parse_exception(ex) + def get_with_args(self, cls, options=None): + if options is None: + options = {} + try: + obj = cls.new(**options) + return obj.get_with_args(self.session, options) + except Exception as ex: + client_exc.parse_exception(ex) + def get(self, cls, options=None): if options is None: options = {} diff --git a/senlinclient/v1/models.py b/senlinclient/v1/models.py index 131a4f3d..2e7b4540 100644 --- a/senlinclient/v1/models.py +++ b/senlinclient/v1/models.py @@ -517,6 +517,7 @@ class Node(resource.Resource): status_reason = resource.prop('status_reason') tags = resource.prop('tags', type=dict) data = resource.prop('data', type=dict) + details = resource.prop('details', type=dict) def action(self, session, body): url = utils.urljoin(self.base_path, self.id, 'action') @@ -556,6 +557,7 @@ class Node(resource.Resource): 'status_reason': self.status_reason, 'tags': self.tags, 'data': self.data, + 'details': self.details, } diff --git a/senlinclient/v1/shell.py b/senlinclient/v1/shell.py index c06534e1..cb3c4fc5 100644 --- a/senlinclient/v1/shell.py +++ b/senlinclient/v1/shell.py @@ -177,6 +177,8 @@ def do_profile_show(sc, args): 'This can be specified multiple times, or once with tags ' 'separated by a semicolon.'), action='append') +@utils.arg('-t', '--profile-type', metavar='', required=True, + help=_('Profile type used for this profile.')) @utils.arg('id', metavar='', help=_('Name or ID of the profile to update.')) def do_profile_update(sc, args): @@ -1011,11 +1013,14 @@ def do_node_list(sc, args): utils.print_list(nodes, fields, formatters=formatters, sortby_index=6) -def _show_node(sc, node_id): +def _show_node(sc, node_id, show_details=False): '''Show detailed info about the specified node.''' try: - query = {'id': node_id} - node = sc.get(models.Node, query) + query = { + 'id': node_id, + 'show_details': show_details, + } + node = sc.get_with_args(models.Node, query) except exc.HTTPNotFound: msg = _('Node %s is not found') % node_id raise exc.CommandError(msg) @@ -1024,8 +1029,12 @@ def _show_node(sc, node_id): 'tags': utils.json_formatter, 'data': utils.json_formatter, } + data = node.to_dict() + if show_details: + formatters['details'] = utils.nested_dict_formatter( + list(node['details'].keys()), ['property', 'value']) - utils.print_dict(node.to_dict(), formatters=formatters) + utils.print_dict(data, formatters=formatters) @utils.arg('-p', '--profile', metavar='', required=True, @@ -1055,11 +1064,13 @@ def do_node_create(sc, args): _show_node(sc, node.id) +@utils.arg('-D', '--details', default=False, action="store_true", + help=_('Include physical object details.')) @utils.arg('id', metavar='', help=_('Name or ID of the node to show the details for.')) def do_node_show(sc, args): '''Show detailed info about the specified node.''' - _show_node(sc, args.id) + _show_node(sc, args.id, args.details) @utils.arg('id', metavar='', nargs='+',