Add a JSON option to the client

Add a json option to list and show commands to return the JSON
response body from the Ironic API without formatting it.

Change-Id: Ic21c8ce1cc211816e309b4a00b6e89a0a8bf6a9d
Closes-Bug: #1436440
This commit is contained in:
Aline Bousquet 2016-02-18 07:23:15 +00:00
parent 8c38ce448e
commit fda1854865
11 changed files with 146 additions and 37 deletions

View File

@ -20,6 +20,7 @@ from __future__ import print_function
import getpass import getpass
import inspect import inspect
import json
import os import os
import sys import sys
import textwrap import textwrap
@ -139,7 +140,7 @@ def isunauthenticated(func):
def print_list(objs, fields, formatters=None, sortby_index=0, def print_list(objs, fields, formatters=None, sortby_index=0,
mixed_case_fields=None, field_labels=None): mixed_case_fields=None, field_labels=None, json_flag=False):
"""Print a list of objects or dict as a table, one row per object or dict. """Print a list of objects or dict as a table, one row per object or dict.
:param objs: iterable of :class:`Resource` :param objs: iterable of :class:`Resource`
@ -150,7 +151,11 @@ def print_list(objs, fields, formatters=None, sortby_index=0,
have mixed case names (e.g., 'serverId') have mixed case names (e.g., 'serverId')
:param field_labels: Labels to use in the heading of the table, default to :param field_labels: Labels to use in the heading of the table, default to
fields. fields.
:param json_flag: print the list as JSON instead of table
""" """
if json_flag:
print(json.dumps([o._info for o in objs]))
return
formatters = formatters or {} formatters = formatters or {}
mixed_case_fields = mixed_case_fields or [] mixed_case_fields = mixed_case_fields or []
field_labels = field_labels or fields field_labels = field_labels or fields
@ -189,14 +194,19 @@ def print_list(objs, fields, formatters=None, sortby_index=0,
print(encodeutils.safe_encode(pt.get_string(**kwargs))) print(encodeutils.safe_encode(pt.get_string(**kwargs)))
def print_dict(dct, dict_property="Property", wrap=0, dict_value='Value'): def print_dict(dct, dict_property="Property", wrap=0, dict_value='Value',
json_flag=False):
"""Print a `dict` as a table of two columns. """Print a `dict` as a table of two columns.
:param dct: `dict` to print :param dct: `dict` to print
:param dict_property: name of the first column :param dict_property: name of the first column
:param wrap: wrapping for the second column :param wrap: wrapping for the second column
:param dict_value: header label for the value (second) column :param dict_value: header label for the value (second) column
:param json_flag: print `dict` as JSON instead of table
""" """
if json_flag:
print(json.dumps(dct))
return
pt = prettytable.PrettyTable([dict_property, dict_value]) pt = prettytable.PrettyTable([dict_property, dict_value])
pt.align = 'l' pt.align = 'l'
for k, v in sorted(dct.items()): for k, v in sorted(dct.items()):

View File

@ -119,6 +119,11 @@ class IronicShell(object):
action='store_true', action='store_true',
help='Defaults to env[IRONICCLIENT_DEBUG]') help='Defaults to env[IRONICCLIENT_DEBUG]')
parser.add_argument('--json',
default=False,
action='store_true',
help='Print JSON response without formatting.')
parser.add_argument('-v', '--verbose', parser.add_argument('-v', '--verbose',
default=False, action="store_true", default=False, action="store_true",
help="Print more verbose output") help="Print more verbose output")

View File

@ -434,6 +434,7 @@ class _FakeResult(object):
def __init__(self, name, value): def __init__(self, name, value):
self.name = name self.name = name
self.value = value self.value = value
self._info = {"name": name, "value": value}
class PrintResultTestCase(test_base.BaseTestCase): class PrintResultTestCase(test_base.BaseTestCase):
@ -585,6 +586,24 @@ class PrintResultStringTestCase(test_base.BaseTestCase):
''' '''
self.assertEqual(expected, out) self.assertEqual(expected, out)
def test_print_list_string_json(self):
objs = [_FakeResult("k1", 1)]
field_labels = ["Another Name", "Another Value"]
orig = sys.stdout
sys.stdout = six.StringIO()
cliutils.print_list(objs, ["Name", "Value"], sortby_index=0,
field_labels=field_labels, json_flag=True)
out = sys.stdout.getvalue()
sys.stdout.close()
sys.stdout = orig
expected = ['''\
[{"name": "k1", "value": 1}]
''', '''\
[{"value": 1, "name": "k1"}]
''']
self.assertIn(out, expected)
def test_print_dict_string(self): def test_print_dict_string(self):
orig = sys.stdout orig = sys.stdout
sys.stdout = six.StringIO() sys.stdout = six.StringIO()
@ -602,6 +621,20 @@ class PrintResultStringTestCase(test_base.BaseTestCase):
''' '''
self.assertEqual(expected, out) self.assertEqual(expected, out)
def test_print_dict_string_json(self):
orig = sys.stdout
sys.stdout = six.StringIO()
cliutils.print_dict({"K": "k", "Key": "Value"}, json_flag=True)
out = sys.stdout.getvalue()
sys.stdout.close()
sys.stdout = orig
expected = ['''\
{"K": "k", "Key": "Value"}
''', '''\
{"Key": "Value", "K": "k"}
''']
self.assertIn(out, expected)
def test_print_dict_string_custom_headers(self): def test_print_dict_string_custom_headers(self):
orig = sys.stdout orig = sys.stdout
sys.stdout = six.StringIO() sys.stdout = six.StringIO()

View File

@ -27,7 +27,7 @@ class ChassisShellTest(utils.BaseTestCase):
def _get_client_mock_args(self, chassis=None, marker=None, limit=None, def _get_client_mock_args(self, chassis=None, marker=None, limit=None,
sort_dir=None, sort_key=None, detail=False, sort_dir=None, sort_key=None, detail=False,
fields=None, associated=None, maintenance=None, fields=None, associated=None, maintenance=None,
provision_state=None): provision_state=None, json=False):
args = mock.MagicMock(spec=True) args = mock.MagicMock(spec=True)
args.chassis = chassis args.chassis = chassis
args.marker = marker args.marker = marker
@ -39,6 +39,7 @@ class ChassisShellTest(utils.BaseTestCase):
args.associated = associated args.associated = associated
args.maintenance = maintenance args.maintenance = maintenance
args.provision_state = provision_state args.provision_state = provision_state
args.json = json
return args return args
@ -73,6 +74,7 @@ class ChassisShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.chassis = 'chassis_uuid' args.chassis = 'chassis_uuid'
args.fields = [['uuid', 'description']] args.fields = [['uuid', 'description']]
args.json = False
c_shell.do_chassis_show(client_mock, args) c_shell.do_chassis_show(client_mock, args)
client_mock.chassis.get.assert_called_once_with( client_mock.chassis.get.assert_called_once_with(
'chassis_uuid', fields=['uuid', 'description']) 'chassis_uuid', fields=['uuid', 'description'])
@ -82,6 +84,7 @@ class ChassisShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.chassis = 'chassis_uuid' args.chassis = 'chassis_uuid'
args.fields = [['foo', 'bar']] args.fields = [['foo', 'bar']]
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
c_shell.do_chassis_show, c_shell.do_chassis_show,
client_mock, args) client_mock, args)
@ -315,6 +318,7 @@ class ChassisShellTest(utils.BaseTestCase):
def test_do_chassis_create(self): def test_do_chassis_create(self):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.json = False
c_shell.do_chassis_create(client_mock, args) c_shell.do_chassis_create(client_mock, args)
client_mock.chassis.create.assert_called_once_with() client_mock.chassis.create.assert_called_once_with()
@ -322,6 +326,7 @@ class ChassisShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.uuid = uuidutils.generate_uuid() args.uuid = uuidutils.generate_uuid()
args.json = False
c_shell.do_chassis_create(client_mock, args) c_shell.do_chassis_create(client_mock, args)
client_mock.chassis.create.assert_called_once_with(uuid=args.uuid) client_mock.chassis.create.assert_called_once_with(uuid=args.uuid)
@ -331,6 +336,7 @@ class ChassisShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.extra = ["key1=val1", "key2=val2"] args.extra = ["key1=val1", "key2=val2"]
args.description = 'desc' args.description = 'desc'
args.json = False
c_shell.do_chassis_create(client_mock, args) c_shell.do_chassis_create(client_mock, args)
client_mock.chassis.create.assert_called_once_with(extra={ client_mock.chassis.create.assert_called_once_with(extra={
'key1': 'val1', 'key1': 'val1',
@ -342,6 +348,7 @@ class ChassisShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.extra = ["foo"] args.extra = ["foo"]
args.description = 'desc' args.description = 'desc'
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
c_shell.do_chassis_create, client_mock, args) c_shell.do_chassis_create, client_mock, args)
@ -366,6 +373,7 @@ class ChassisShellTest(utils.BaseTestCase):
args.chassis = 'chassis_uuid' args.chassis = 'chassis_uuid'
args.op = 'add' args.op = 'add'
args.attributes = [['arg1=val1', 'arg2=val2']] args.attributes = [['arg1=val1', 'arg2=val2']]
args.json = False
c_shell.do_chassis_update(client_mock, args) c_shell.do_chassis_update(client_mock, args)
patch = commonutils.args_array_to_patch(args.op, args.attributes[0]) patch = commonutils.args_array_to_patch(args.op, args.attributes[0])
client_mock.chassis.update.assert_called_once_with('chassis_uuid', client_mock.chassis.update.assert_called_once_with('chassis_uuid',

View File

@ -68,6 +68,7 @@ class DriverShellTest(utils.BaseTestCase):
client_mock = self.client_mock client_mock = self.client_mock
args = mock.MagicMock() args = mock.MagicMock()
args.driver_name = 'driver_name' args.driver_name = 'driver_name'
args.json = False
d_shell.do_driver_properties(client_mock, args) d_shell.do_driver_properties(client_mock, args)
client_mock.driver.properties.assert_called_once_with("driver_name") client_mock.driver.properties.assert_called_once_with("driver_name")
@ -81,11 +82,13 @@ class DriverShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.driver_name = 'driver_name' args.driver_name = 'driver_name'
args.wrap = 0 args.wrap = 0
args.json = False
d_shell.do_driver_properties(client_mock, args) d_shell.do_driver_properties(client_mock, args)
mock_print_dict.assert_called_with( mock_print_dict.assert_called_with(
{'foo': 'bar', 'baz': 'qux'}, {'foo': 'bar', 'baz': 'qux'},
dict_value='Description', dict_value='Description',
json_flag=False,
wrap=0) wrap=0)
@mock.patch('ironicclient.common.cliutils.print_dict') @mock.patch('ironicclient.common.cliutils.print_dict')
@ -97,17 +100,20 @@ class DriverShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.driver_name = 'driver_name' args.driver_name = 'driver_name'
args.wrap = 80 args.wrap = 80
args.json = False
d_shell.do_driver_properties(client_mock, args) d_shell.do_driver_properties(client_mock, args)
mock_print_dict.assert_called_with( mock_print_dict.assert_called_with(
{'foo': 'bar', 'baz': 'qux'}, {'foo': 'bar', 'baz': 'qux'},
dict_value='Description', dict_value='Description',
json_flag=False,
wrap=80) wrap=80)
def test_do_driver_show(self): def test_do_driver_show(self):
client_mock = self.client_mock client_mock = self.client_mock
args = mock.MagicMock() args = mock.MagicMock()
args.driver_name = 'fake' args.driver_name = 'fake'
args.json = False
d_shell.do_driver_show(client_mock, args) d_shell.do_driver_show(client_mock, args)
client_mock.driver.get.assert_called_once_with('fake') client_mock.driver.get.assert_called_once_with('fake')

View File

@ -97,6 +97,7 @@ class NodeShellTest(utils.BaseTestCase):
args.node = 'node_uuid' args.node = 'node_uuid'
args.op = 'add' args.op = 'add'
args.attributes = [['arg1=val1', 'arg2=val2']] args.attributes = [['arg1=val1', 'arg2=val2']]
args.json = False
n_shell.do_node_update(client_mock, args) n_shell.do_node_update(client_mock, args)
patch = commonutils.args_array_to_patch(args.op, args.attributes[0]) patch = commonutils.args_array_to_patch(args.op, args.attributes[0])
@ -108,6 +109,7 @@ class NodeShellTest(utils.BaseTestCase):
args.node = 'node_uuid' args.node = 'node_uuid'
args.op = 'foo' args.op = 'foo'
args.attributes = [['arg1=val1', 'arg2=val2']] args.attributes = [['arg1=val1', 'arg2=val2']]
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
n_shell.do_node_update, n_shell.do_node_update,
client_mock, args) client_mock, args)
@ -116,6 +118,7 @@ class NodeShellTest(utils.BaseTestCase):
def test_do_node_create(self): def test_do_node_create(self):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
client_mock.node.create.assert_called_once_with() client_mock.node.create.assert_called_once_with()
@ -124,6 +127,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.driver = 'driver' args.driver = 'driver'
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
client_mock.node.create.assert_called_once_with( client_mock.node.create.assert_called_once_with(
@ -133,6 +137,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.chassis_uuid = 'chassis_uuid' args.chassis_uuid = 'chassis_uuid'
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
client_mock.node.create.assert_called_once_with( client_mock.node.create.assert_called_once_with(
@ -142,6 +147,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.driver_info = ['arg1=val1', 'arg2=val2'] args.driver_info = ['arg1=val1', 'arg2=val2']
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
kwargs = {'driver_info': {'arg1': 'val1', 'arg2': 'val2'}} kwargs = {'driver_info': {'arg1': 'val1', 'arg2': 'val2'}}
@ -151,6 +157,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.properties = ['arg1=val1', 'arg2=val2'] args.properties = ['arg1=val1', 'arg2=val2']
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
kwargs = {'properties': {'arg1': 'val1', 'arg2': 'val2'}} kwargs = {'properties': {'arg1': 'val1', 'arg2': 'val2'}}
@ -161,6 +168,7 @@ class NodeShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.driver = 'driver_name' args.driver = 'driver_name'
args.extra = ['arg1=val1', 'arg2=val2'] args.extra = ['arg1=val1', 'arg2=val2']
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
kwargs = { kwargs = {
@ -173,6 +181,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.uuid = 'fef99cb8-a0d1-43df-b084-17b3b42b3cbd' args.uuid = 'fef99cb8-a0d1-43df-b084-17b3b42b3cbd'
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
client_mock.node.create.assert_called_once_with(uuid=args.uuid) client_mock.node.create.assert_called_once_with(uuid=args.uuid)
@ -181,6 +190,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.name = 'node_name' args.name = 'node_name'
args.json = False
n_shell.do_node_create(client_mock, args) n_shell.do_node_create(client_mock, args)
client_mock.node.create.assert_called_once_with(name=args.name) client_mock.node.create.assert_called_once_with(name=args.name)
@ -191,6 +201,7 @@ class NodeShellTest(utils.BaseTestCase):
args.node = 'node_uuid' args.node = 'node_uuid'
args.instance_uuid = False args.instance_uuid = False
args.fields = None args.fields = None
args.json = False
n_shell.do_node_show(client_mock, args) n_shell.do_node_show(client_mock, args)
client_mock.node.get.assert_called_once_with('node_uuid', fields=None) client_mock.node.get.assert_called_once_with('node_uuid', fields=None)
@ -203,6 +214,7 @@ class NodeShellTest(utils.BaseTestCase):
args.node = 'instance_uuid' args.node = 'instance_uuid'
args.instance_uuid = True args.instance_uuid = True
args.fields = None args.fields = None
args.json = False
n_shell.do_node_show(client_mock, args) n_shell.do_node_show(client_mock, args)
client_mock.node.get_by_instance_uuid.assert_called_once_with( client_mock.node.get_by_instance_uuid.assert_called_once_with(
@ -215,6 +227,7 @@ class NodeShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.node = ' ' args.node = ' '
args.instance_uuid = False args.instance_uuid = False
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
n_shell.do_node_show, n_shell.do_node_show,
client_mock, args) client_mock, args)
@ -224,6 +237,7 @@ class NodeShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.node = ' ' args.node = ' '
args.instance_uuid = True args.instance_uuid = True
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
n_shell.do_node_show, n_shell.do_node_show,
client_mock, args) client_mock, args)
@ -233,6 +247,7 @@ class NodeShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.node = '' args.node = ''
args.instance_uuid = False args.instance_uuid = False
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
n_shell.do_node_show, n_shell.do_node_show,
client_mock, args) client_mock, args)
@ -242,6 +257,7 @@ class NodeShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.node = '' args.node = ''
args.instance_uuid = True args.instance_uuid = True
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
n_shell.do_node_show, n_shell.do_node_show,
client_mock, args) client_mock, args)
@ -252,6 +268,7 @@ class NodeShellTest(utils.BaseTestCase):
args.node = 'node_uuid' args.node = 'node_uuid'
args.instance_uuid = False args.instance_uuid = False
args.fields = [['uuid', 'power_state']] args.fields = [['uuid', 'power_state']]
args.json = False
n_shell.do_node_show(client_mock, args) n_shell.do_node_show(client_mock, args)
client_mock.node.get.assert_called_once_with( client_mock.node.get.assert_called_once_with(
'node_uuid', fields=['uuid', 'power_state']) 'node_uuid', fields=['uuid', 'power_state'])
@ -262,6 +279,7 @@ class NodeShellTest(utils.BaseTestCase):
args.node = 'node_uuid' args.node = 'node_uuid'
args.instance_uuid = False args.instance_uuid = False
args.fields = [['foo', 'bar']] args.fields = [['foo', 'bar']]
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
n_shell.do_node_show, client_mock, args) n_shell.do_node_show, client_mock, args)
@ -637,6 +655,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.node = 'node_uuid' args.node = 'node_uuid'
args.json = False
n_shell.do_node_get_boot_device(client_mock, args) n_shell.do_node_get_boot_device(client_mock, args)
client_mock.node.get_boot_device.assert_called_once_with('node_uuid') client_mock.node.get_boot_device.assert_called_once_with('node_uuid')
@ -645,6 +664,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.node = 'node_uuid' args.node = 'node_uuid'
args.json = False
n_shell.do_node_get_supported_boot_devices(client_mock, args) n_shell.do_node_get_supported_boot_devices(client_mock, args)
client_mock.node.get_supported_boot_devices.assert_called_once_with( client_mock.node.get_supported_boot_devices.assert_called_once_with(
@ -653,7 +673,8 @@ class NodeShellTest(utils.BaseTestCase):
def _get_client_mock_args(self, node=None, associated=None, def _get_client_mock_args(self, node=None, associated=None,
maintenance=None, marker=None, limit=None, maintenance=None, marker=None, limit=None,
sort_dir=None, sort_key=None, detail=False, sort_dir=None, sort_key=None, detail=False,
fields=None, provision_state=None, driver=None): fields=None, provision_state=None, driver=None,
json=False):
args = mock.MagicMock() args = mock.MagicMock()
args.node = node args.node = node
args.associated = associated args.associated = associated
@ -666,6 +687,7 @@ class NodeShellTest(utils.BaseTestCase):
args.detail = detail args.detail = detail
args.fields = fields args.fields = fields
args.driver = driver args.driver = driver
args.json = json
return args return args
@ -839,6 +861,7 @@ class NodeShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.node = 'node_uuid' args.node = 'node_uuid'
args.json = False
n_shell.do_node_show_states(client_mock, args) n_shell.do_node_show_states(client_mock, args)
client_mock.node.states.assert_called_once_with('node_uuid') client_mock.node.states.assert_called_once_with('node_uuid')

View File

@ -42,6 +42,7 @@ class PortShellTest(utils.BaseTestCase):
args.port = 'port_uuid' args.port = 'port_uuid'
args.address = False args.address = False
args.fields = None args.fields = None
args.json = False
p_shell.do_port_show(client_mock, args) p_shell.do_port_show(client_mock, args)
client_mock.port.get.assert_called_once_with('port_uuid', fields=None) client_mock.port.get.assert_called_once_with('port_uuid', fields=None)
@ -53,6 +54,7 @@ class PortShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.port = ' ' args.port = ' '
args.address = False args.address = False
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
p_shell.do_port_show, p_shell.do_port_show,
client_mock, args) client_mock, args)
@ -62,6 +64,7 @@ class PortShellTest(utils.BaseTestCase):
args = mock.MagicMock() args = mock.MagicMock()
args.port = '' args.port = ''
args.address = False args.address = False
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
p_shell.do_port_show, p_shell.do_port_show,
client_mock, args) client_mock, args)
@ -72,6 +75,7 @@ class PortShellTest(utils.BaseTestCase):
args.port = 'port_address' args.port = 'port_address'
args.address = True args.address = True
args.fields = None args.fields = None
args.json = False
p_shell.do_port_show(client_mock, args) p_shell.do_port_show(client_mock, args)
client_mock.port.get_by_address.assert_called_once_with('port_address', client_mock.port.get_by_address.assert_called_once_with('port_address',
@ -85,6 +89,7 @@ class PortShellTest(utils.BaseTestCase):
args.port = 'port_uuid' args.port = 'port_uuid'
args.address = False args.address = False
args.fields = [['uuid', 'address']] args.fields = [['uuid', 'address']]
args.json = False
p_shell.do_port_show(client_mock, args) p_shell.do_port_show(client_mock, args)
client_mock.port.get.assert_called_once_with( client_mock.port.get.assert_called_once_with(
'port_uuid', fields=['uuid', 'address']) 'port_uuid', fields=['uuid', 'address'])
@ -95,6 +100,7 @@ class PortShellTest(utils.BaseTestCase):
args.port = 'port_uuid' args.port = 'port_uuid'
args.address = False args.address = False
args.fields = [['foo', 'bar']] args.fields = [['foo', 'bar']]
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
p_shell.do_port_show, p_shell.do_port_show,
client_mock, args) client_mock, args)
@ -105,6 +111,7 @@ class PortShellTest(utils.BaseTestCase):
args.port = 'port_uuid' args.port = 'port_uuid'
args.op = 'add' args.op = 'add'
args.attributes = [['arg1=val1', 'arg2=val2']] args.attributes = [['arg1=val1', 'arg2=val2']]
args.json = False
p_shell.do_port_update(client_mock, args) p_shell.do_port_update(client_mock, args)
patch = commonutils.args_array_to_patch(args.op, args.attributes[0]) patch = commonutils.args_array_to_patch(args.op, args.attributes[0])
@ -116,6 +123,7 @@ class PortShellTest(utils.BaseTestCase):
args.port = 'port_uuid' args.port = 'port_uuid'
args.op = 'foo' args.op = 'foo'
args.attributes = [['arg1=val1', 'arg2=val2']] args.attributes = [['arg1=val1', 'arg2=val2']]
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
p_shell.do_port_update, p_shell.do_port_update,
client_mock, args) client_mock, args)
@ -123,7 +131,7 @@ class PortShellTest(utils.BaseTestCase):
def _get_client_mock_args(self, address=None, marker=None, limit=None, def _get_client_mock_args(self, address=None, marker=None, limit=None,
sort_dir=None, sort_key=None, detail=False, sort_dir=None, sort_key=None, detail=False,
fields=None): fields=None, json=False):
args = mock.MagicMock(spec=True) args = mock.MagicMock(spec=True)
args.address = address args.address = address
args.marker = marker args.marker = marker
@ -132,6 +140,7 @@ class PortShellTest(utils.BaseTestCase):
args.sort_key = sort_key args.sort_key = sort_key
args.detail = detail args.detail = detail
args.fields = fields args.fields = fields
args.json = json
return args return args
@ -231,6 +240,7 @@ class PortShellTest(utils.BaseTestCase):
def test_do_port_create(self): def test_do_port_create(self):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.json = False
p_shell.do_port_create(client_mock, args) p_shell.do_port_create(client_mock, args)
client_mock.port.create.assert_called_once_with() client_mock.port.create.assert_called_once_with()
@ -238,6 +248,7 @@ class PortShellTest(utils.BaseTestCase):
client_mock = mock.MagicMock() client_mock = mock.MagicMock()
args = mock.MagicMock() args = mock.MagicMock()
args.uuid = uuidutils.generate_uuid() args.uuid = uuidutils.generate_uuid()
args.json = False
p_shell.do_port_create(client_mock, args) p_shell.do_port_create(client_mock, args)
client_mock.port.create.assert_called_once_with(uuid=args.uuid) client_mock.port.create.assert_called_once_with(uuid=args.uuid)
@ -248,6 +259,7 @@ class PortShellTest(utils.BaseTestCase):
args.address = 'address' args.address = 'address'
args.node_uuid = 'uuid' args.node_uuid = 'uuid'
args.extra = ["key1=val1", "key2=val2"] args.extra = ["key1=val1", "key2=val2"]
args.json = False
p_shell.do_port_create(client_mock, args) p_shell.do_port_create(client_mock, args)
client_mock.port.create.assert_called_once_with( client_mock.port.create.assert_called_once_with(
address='address', node_uuid='uuid', extra={'key1': 'val1', address='address', node_uuid='uuid', extra={'key1': 'val1',
@ -259,6 +271,7 @@ class PortShellTest(utils.BaseTestCase):
args.address = 'address' args.address = 'address'
args.node_uuid = 'uuid' args.node_uuid = 'uuid'
args.extra = ["foo"] args.extra = ["foo"]
args.json = False
self.assertRaises(exceptions.CommandError, self.assertRaises(exceptions.CommandError,
p_shell.do_port_create, client_mock, args) p_shell.do_port_create, client_mock, args)

View File

@ -18,12 +18,12 @@ from ironicclient.common import utils
from ironicclient.v1 import resource_fields as res_fields from ironicclient.v1 import resource_fields as res_fields
def _print_chassis_show(chassis, fields=None): def _print_chassis_show(chassis, fields=None, json=False):
if fields is None: if fields is None:
fields = res_fields.CHASSIS_DETAILED_RESOURCE.fields fields = res_fields.CHASSIS_DETAILED_RESOURCE.fields
data = dict([(f, getattr(chassis, f, '')) for f in fields]) data = dict([(f, getattr(chassis, f, '')) for f in fields])
cliutils.print_dict(data, wrap=72) cliutils.print_dict(data, wrap=72, json_flag=json)
@cliutils.arg('chassis', metavar='<chassis>', help="UUID of the chassis.") @cliutils.arg('chassis', metavar='<chassis>', help="UUID of the chassis.")
@ -43,7 +43,7 @@ def do_chassis_show(cc, args):
utils.check_for_invalid_fields( utils.check_for_invalid_fields(
fields, res_fields.CHASSIS_DETAILED_RESOURCE.fields) fields, res_fields.CHASSIS_DETAILED_RESOURCE.fields)
chassis = cc.chassis.get(args.chassis, fields=fields) chassis = cc.chassis.get(args.chassis, fields=fields)
_print_chassis_show(chassis, fields=fields) _print_chassis_show(chassis, fields=fields, json=args.json)
@cliutils.arg( @cliutils.arg(
@ -107,7 +107,8 @@ def do_chassis_list(cc, args):
chassis = cc.chassis.list(**params) chassis = cc.chassis.list(**params)
cliutils.print_list(chassis, fields, cliutils.print_list(chassis, fields,
field_labels=field_labels, field_labels=field_labels,
sortby_index=None) sortby_index=None,
json_flag=args.json)
@cliutils.arg( @cliutils.arg(
@ -133,7 +134,7 @@ def do_chassis_create(cc, args):
chassis = cc.chassis.create(**fields) chassis = cc.chassis.create(**fields)
data = dict([(f, getattr(chassis, f, '')) for f in field_list]) data = dict([(f, getattr(chassis, f, '')) for f in field_list])
cliutils.print_dict(data, wrap=72) cliutils.print_dict(data, wrap=72, json_flag=args.json)
@cliutils.arg( @cliutils.arg(
@ -166,7 +167,7 @@ def do_chassis_update(cc, args):
"""Update information about a chassis.""" """Update information about a chassis."""
patch = utils.args_array_to_patch(args.op, args.attributes[0]) patch = utils.args_array_to_patch(args.op, args.attributes[0])
chassis = cc.chassis.update(args.chassis, patch) chassis = cc.chassis.update(args.chassis, patch)
_print_chassis_show(chassis) _print_chassis_show(chassis, json=args.json)
@cliutils.arg( @cliutils.arg(
@ -253,4 +254,5 @@ def do_chassis_node_list(cc, args):
nodes = cc.chassis.list_nodes(args.chassis, **params) nodes = cc.chassis.list_nodes(args.chassis, **params)
cliutils.print_list(nodes, fields, cliutils.print_list(nodes, fields,
field_labels=field_labels, field_labels=field_labels,
sortby_index=None) sortby_index=None,
json_flag=args.json)

View File

@ -20,10 +20,10 @@ from ironicclient.common import utils
from ironicclient.v1 import resource_fields as res_fields from ironicclient.v1 import resource_fields as res_fields
def _print_driver_show(driver): def _print_driver_show(driver, json=False):
fields = ['name', 'hosts'] fields = ['name', 'hosts']
data = dict([(f, getattr(driver, f, '')) for f in fields]) data = dict([(f, getattr(driver, f, '')) for f in fields])
cliutils.print_dict(data, wrap=72) cliutils.print_dict(data, wrap=72, json_flag=json)
def do_driver_list(cc, args): def do_driver_list(cc, args):
@ -35,7 +35,8 @@ def do_driver_list(cc, args):
d.hosts = ', '.join(d.hosts) d.hosts = ', '.join(d.hosts)
field_labels = ['Supported driver(s)', 'Active host(s)'] field_labels = ['Supported driver(s)', 'Active host(s)']
fields = ['name', 'hosts'] fields = ['name', 'hosts']
cliutils.print_list(drivers, fields, field_labels=field_labels) cliutils.print_list(drivers, fields, field_labels=field_labels,
json_flag=args.json)
@cliutils.arg('driver_name', metavar='<driver>', @cliutils.arg('driver_name', metavar='<driver>',
@ -43,7 +44,7 @@ def do_driver_list(cc, args):
def do_driver_show(cc, args): def do_driver_show(cc, args):
"""Show information about a driver.""" """Show information about a driver."""
driver = cc.driver.get(args.driver_name) driver = cc.driver.get(args.driver_name)
_print_driver_show(driver) _print_driver_show(driver, json=args.json)
@cliutils.arg('driver_name', metavar='<driver>', @cliutils.arg('driver_name', metavar='<driver>',
@ -59,7 +60,8 @@ def do_driver_properties(cc, args):
cliutils.print_dict( cliutils.print_dict(
properties, properties,
wrap=args.wrap, wrap=args.wrap,
dict_value='Description') dict_value='Description',
json_flag=args.json)
@cliutils.arg('driver_name', @cliutils.arg('driver_name',
@ -117,4 +119,5 @@ def do_driver_get_vendor_passthru_methods(cc, args):
field_labels = res_fields.VENDOR_PASSTHRU_METHOD_RESOURCE.labels field_labels = res_fields.VENDOR_PASSTHRU_METHOD_RESOURCE.labels
cliutils.print_list(data, fields, cliutils.print_list(data, fields,
field_labels=field_labels, field_labels=field_labels,
sortby_index=None) sortby_index=None,
json_flag=args.json)

View File

@ -26,13 +26,13 @@ from ironicclient import exc
from ironicclient.v1 import resource_fields as res_fields from ironicclient.v1 import resource_fields as res_fields
def _print_node_show(node, fields=None): def _print_node_show(node, fields=None, json=False):
if fields is None: if fields is None:
fields = res_fields.NODE_DETAILED_RESOURCE.fields fields = res_fields.NODE_DETAILED_RESOURCE.fields
data = dict( data = dict(
[(f, getattr(node, f, '')) for f in fields]) [(f, getattr(node, f, '')) for f in fields])
cliutils.print_dict(data, wrap=72) cliutils.print_dict(data, wrap=72, json_flag=json)
def _get_from_stdin(info_desc): def _get_from_stdin(info_desc):
@ -107,7 +107,7 @@ def do_node_show(cc, args):
node = cc.node.get_by_instance_uuid(args.node, fields=fields) node = cc.node.get_by_instance_uuid(args.node, fields=fields)
else: else:
node = cc.node.get(args.node, fields=fields) node = cc.node.get(args.node, fields=fields)
_print_node_show(node, fields=fields) _print_node_show(node, fields=fields, json=args.json)
@cliutils.arg( @cliutils.arg(
@ -199,7 +199,8 @@ def do_node_list(cc, args):
nodes = cc.node.list(**params) nodes = cc.node.list(**params)
cliutils.print_list(nodes, fields, cliutils.print_list(nodes, fields,
field_labels=field_labels, field_labels=field_labels,
sortby_index=None) sortby_index=None,
json_flag=args.json)
@cliutils.arg( @cliutils.arg(
@ -258,7 +259,7 @@ def do_node_create(cc, args):
node = cc.node.create(**fields) node = cc.node.create(**fields)
data = dict([(f, getattr(node, f, '')) for f in field_list]) data = dict([(f, getattr(node, f, '')) for f in field_list])
cliutils.print_dict(data, wrap=72) cliutils.print_dict(data, wrap=72, json_flag=args.json)
@cliutils.arg('node', @cliutils.arg('node',
@ -301,7 +302,7 @@ def do_node_update(cc, args):
"""Update information about a registered node.""" """Update information about a registered node."""
patch = utils.args_array_to_patch(args.op, args.attributes[0]) patch = utils.args_array_to_patch(args.op, args.attributes[0])
node = cc.node.update(args.node, patch) node = cc.node.update(args.node, patch)
_print_node_show(node) _print_node_show(node, json=args.json)
@cliutils.arg('node', @cliutils.arg('node',
@ -402,9 +403,11 @@ def do_node_port_list(cc, args):
sort_field_labels) sort_field_labels)
ports = cc.node.list_ports(args.node, **params) ports = cc.node.list_ports(args.node, **params)
cliutils.print_list(ports, fields, cliutils.print_list(ports, fields,
field_labels=field_labels, field_labels=field_labels,
sortby_index=None) sortby_index=None,
json_flag=args.json)
@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.")
@ -501,14 +504,15 @@ def do_node_validate(cc, args):
obj_list.append(type('iface', (object,), data)) obj_list.append(type('iface', (object,), data))
field_labels = ['Interface', 'Result', 'Reason'] field_labels = ['Interface', 'Result', 'Reason']
fields = ['interface', 'result', 'reason'] fields = ['interface', 'result', 'reason']
cliutils.print_list(obj_list, fields, field_labels=field_labels) cliutils.print_list(obj_list, fields, field_labels=field_labels,
json_flag=args.json)
@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.")
def do_node_get_console(cc, args): def do_node_get_console(cc, args):
"""Get the connection information for a node's console, if enabled.""" """Get the connection information for a node's console, if enabled."""
info = cc.node.get_console(args.node) info = cc.node.get_console(args.node)
cliutils.print_dict(info, wrap=72) cliutils.print_dict(info, wrap=72, json_flag=args.json)
@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.")
@ -543,7 +547,7 @@ def do_node_set_boot_device(cc, args):
def do_node_get_boot_device(cc, args): def do_node_get_boot_device(cc, args):
"""Get the current boot device for a node.""" """Get the current boot device for a node."""
boot_device = cc.node.get_boot_device(args.node) boot_device = cc.node.get_boot_device(args.node)
cliutils.print_dict(boot_device, wrap=72) cliutils.print_dict(boot_device, wrap=72, json_flag=args.json)
@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.")
@ -552,14 +556,14 @@ def do_node_get_supported_boot_devices(cc, args):
boot_devices = cc.node.get_supported_boot_devices(args.node) boot_devices = cc.node.get_supported_boot_devices(args.node)
boot_device_list = boot_devices.get('supported_boot_devices', []) boot_device_list = boot_devices.get('supported_boot_devices', [])
boot_devices['supported_boot_devices'] = ', '.join(boot_device_list) boot_devices['supported_boot_devices'] = ', '.join(boot_device_list)
cliutils.print_dict(boot_devices, wrap=72) cliutils.print_dict(boot_devices, wrap=72, json_flag=args.json)
@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.")
def do_node_show_states(cc, args): def do_node_show_states(cc, args):
"""Show information about the node's states.""" """Show information about the node's states."""
states = cc.node.states(args.node) states = cc.node.states(args.node)
cliutils.print_dict(states.to_dict(), wrap=72) cliutils.print_dict(states.to_dict(), wrap=72, json_flag=args.json)
@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.")
@ -576,4 +580,5 @@ def do_node_get_vendor_passthru_methods(cc, args):
field_labels = res_fields.VENDOR_PASSTHRU_METHOD_RESOURCE.labels field_labels = res_fields.VENDOR_PASSTHRU_METHOD_RESOURCE.labels
cliutils.print_list(data, fields, cliutils.print_list(data, fields,
field_labels=field_labels, field_labels=field_labels,
sortby_index=None) sortby_index=None,
json_flag=args.json)

View File

@ -18,12 +18,12 @@ from ironicclient.common import utils
from ironicclient.v1 import resource_fields as res_fields from ironicclient.v1 import resource_fields as res_fields
def _print_port_show(port, fields=None): def _print_port_show(port, fields=None, json=False):
if fields is None: if fields is None:
fields = res_fields.PORT_DETAILED_RESOURCE.fields fields = res_fields.PORT_DETAILED_RESOURCE.fields
data = dict([(f, getattr(port, f, '')) for f in fields]) data = dict([(f, getattr(port, f, '')) for f in fields])
cliutils.print_dict(data, wrap=72) cliutils.print_dict(data, wrap=72, json_flag=json)
@cliutils.arg( @cliutils.arg(
@ -55,7 +55,7 @@ def do_port_show(cc, args):
else: else:
utils.check_empty_arg(args.port, '<id>') utils.check_empty_arg(args.port, '<id>')
port = cc.port.get(args.port, fields=fields) port = cc.port.get(args.port, fields=fields)
_print_port_show(port, fields=fields) _print_port_show(port, fields=fields, json=args.json)
@cliutils.arg( @cliutils.arg(
@ -128,7 +128,8 @@ def do_port_list(cc, args):
port = cc.port.list(**params) port = cc.port.list(**params)
cliutils.print_list(port, fields, cliutils.print_list(port, fields,
field_labels=field_labels, field_labels=field_labels,
sortby_index=None) sortby_index=None,
json_flag=args.json)
@cliutils.arg( @cliutils.arg(
@ -161,7 +162,7 @@ def do_port_create(cc, args):
port = cc.port.create(**fields) port = cc.port.create(**fields)
data = dict([(f, getattr(port, f, '')) for f in field_list]) data = dict([(f, getattr(port, f, '')) for f in field_list])
cliutils.print_dict(data, wrap=72) cliutils.print_dict(data, wrap=72, json_flag=args.json)
@cliutils.arg('port', metavar='<port>', nargs='+', help="UUID of the port.") @cliutils.arg('port', metavar='<port>', nargs='+', help="UUID of the port.")
@ -190,4 +191,4 @@ def do_port_update(cc, args):
"""Update information about a port.""" """Update information about a port."""
patch = utils.args_array_to_patch(args.op, args.attributes[0]) patch = utils.args_array_to_patch(args.op, args.attributes[0])
port = cc.port.update(args.port, patch) port = cc.port.update(args.port, patch)
_print_port_show(port) _print_port_show(port, json=args.json)