Extends driver-list, driver-show supporting new hardware types
- Extend the driver-list command with --type argument, which, if supplied, limits the driver list to only classic drivers (classic value) or hardware types (dynamic value), and --detail to show detailed info of drivers. - Extend the output of the driver-show command with more info of driver. Change-Id: I5f72c47805ae9f761250f500098bfef4d502e419 Partial-Bug: #1524745
This commit is contained in:
@@ -27,6 +27,7 @@ import tempfile
|
|||||||
|
|
||||||
from oslo_serialization import base64
|
from oslo_serialization import base64
|
||||||
from oslo_utils import strutils
|
from oslo_utils import strutils
|
||||||
|
import six
|
||||||
|
|
||||||
from ironicclient.common.i18n import _
|
from ironicclient.common.i18n import _
|
||||||
from ironicclient import exc
|
from ironicclient import exc
|
||||||
@@ -145,6 +146,27 @@ def args_array_to_patch(op, attributes):
|
|||||||
return patch
|
return patch
|
||||||
|
|
||||||
|
|
||||||
|
def convert_list_props_to_comma_separated(data, props=None):
|
||||||
|
"""Convert the list-type properties to comma-separated strings
|
||||||
|
|
||||||
|
:param data: the input dict object.
|
||||||
|
:param props: the properties whose values will be converted.
|
||||||
|
Default to None to convert all list-type properties of the input.
|
||||||
|
:returns: the result dict instance.
|
||||||
|
"""
|
||||||
|
result = dict(data)
|
||||||
|
|
||||||
|
if props is None:
|
||||||
|
props = data.keys()
|
||||||
|
|
||||||
|
for prop in props:
|
||||||
|
val = data.get(prop, None)
|
||||||
|
if isinstance(val, list):
|
||||||
|
result[prop] = ', '.join(map(six.text_type, val))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def common_params_for_list(args, fields, field_labels):
|
def common_params_for_list(args, fields, field_labels):
|
||||||
"""Generate 'params' dict that is common for every 'list' command.
|
"""Generate 'params' dict that is common for every 'list' command.
|
||||||
|
|
||||||
|
@@ -32,22 +32,43 @@ class ListBaremetalDriver(command.Lister):
|
|||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(ListBaremetalDriver, self).get_parser(prog_name)
|
parser = super(ListBaremetalDriver, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'--type',
|
||||||
|
metavar='<type>',
|
||||||
|
choices=["classic", "dynamic"],
|
||||||
|
help='Type of driver ("classic" or "dynamic"). '
|
||||||
|
'The default is to list all of them.'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--long',
|
||||||
|
action='store_true',
|
||||||
|
default=None,
|
||||||
|
help="Show detailed information about the drivers.")
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
self.log.debug("take_action(%s)", parsed_args)
|
self.log.debug("take_action(%s)", parsed_args)
|
||||||
client = self.app.client_manager.baremetal
|
client = self.app.client_manager.baremetal
|
||||||
|
|
||||||
labels = res_fields.DRIVER_RESOURCE.labels
|
params = {'driver_type': parsed_args.type,
|
||||||
columns = res_fields.DRIVER_RESOURCE.fields
|
'detail': parsed_args.long}
|
||||||
|
if parsed_args.long:
|
||||||
|
labels = res_fields.DRIVER_DETAILED_RESOURCE.labels
|
||||||
|
columns = res_fields.DRIVER_DETAILED_RESOURCE.fields
|
||||||
|
else:
|
||||||
|
labels = res_fields.DRIVER_RESOURCE.labels
|
||||||
|
columns = res_fields.DRIVER_RESOURCE.fields
|
||||||
|
|
||||||
drivers = client.driver.list()
|
drivers = client.driver.list(**params)
|
||||||
drivers = oscutils.sort_items(drivers, 'name')
|
drivers = oscutils.sort_items(drivers, 'name')
|
||||||
for d in drivers:
|
|
||||||
d.hosts = ', '.join(d.hosts)
|
# For list-type properties, show the values as comma separated
|
||||||
|
# strings. It's easier to read.
|
||||||
|
data = [utils.convert_list_props_to_comma_separated(d._info)
|
||||||
|
for d in drivers]
|
||||||
|
|
||||||
return (labels,
|
return (labels,
|
||||||
(oscutils.get_item_properties(s, columns) for s in drivers))
|
(oscutils.get_dict_properties(s, columns) for s in data))
|
||||||
|
|
||||||
|
|
||||||
class PassthruCallBaremetalDriver(command.ShowOne):
|
class PassthruCallBaremetalDriver(command.ShowOne):
|
||||||
@@ -154,8 +175,7 @@ class ShowBaremetalDriver(command.ShowOne):
|
|||||||
driver = baremetal_client.driver.get(parsed_args.driver)._info
|
driver = baremetal_client.driver.get(parsed_args.driver)._info
|
||||||
driver.pop("links", None)
|
driver.pop("links", None)
|
||||||
driver.pop("properties", None)
|
driver.pop("properties", None)
|
||||||
# NOTE(rloo): this will show the hosts as a comma-separated string
|
# For list-type properties, show the values as comma separated
|
||||||
# whereas 'ironic driver show' displays this as a list
|
# strings. It's easier to read.
|
||||||
# of hosts (eg "host1, host2" vs "[u'host1', u'host2']"
|
driver = utils.convert_list_props_to_comma_separated(driver)
|
||||||
driver['hosts'] = ', '.join(driver.get('hosts', ()))
|
|
||||||
return zip(*sorted(driver.items()))
|
return zip(*sorted(driver.items()))
|
||||||
|
@@ -139,6 +139,28 @@ class UtilsTest(test_utils.BaseTestCase):
|
|||||||
self.assertRaises(exc.CommandError, utils.check_for_invalid_fields,
|
self.assertRaises(exc.CommandError, utils.check_for_invalid_fields,
|
||||||
['a', 'd'], ['a', 'b', 'c'])
|
['a', 'd'], ['a', 'b', 'c'])
|
||||||
|
|
||||||
|
def test_convert_list_props_to_comma_separated_strings(self):
|
||||||
|
data = {'prop1': 'val1',
|
||||||
|
'prop2': ['item1', 'item2', 'item3']}
|
||||||
|
result = utils.convert_list_props_to_comma_separated(data)
|
||||||
|
self.assertEqual('val1', result['prop1'])
|
||||||
|
self.assertEqual('item1, item2, item3', result['prop2'])
|
||||||
|
|
||||||
|
def test_convert_list_props_to_comma_separated_mix(self):
|
||||||
|
data = {'prop1': 'val1',
|
||||||
|
'prop2': [1, 2.5, 'item3']}
|
||||||
|
result = utils.convert_list_props_to_comma_separated(data)
|
||||||
|
self.assertEqual('val1', result['prop1'])
|
||||||
|
self.assertEqual('1, 2.5, item3', result['prop2'])
|
||||||
|
|
||||||
|
def test_convert_list_props_to_comma_separated_partial(self):
|
||||||
|
data = {'prop1': [1, 2, 3],
|
||||||
|
'prop2': [1, 2.5, 'item3']}
|
||||||
|
result = utils.convert_list_props_to_comma_separated(
|
||||||
|
data, props=['prop2'])
|
||||||
|
self.assertEqual([1, 2, 3], result['prop1'])
|
||||||
|
self.assertEqual('1, 2.5, item3', result['prop2'])
|
||||||
|
|
||||||
|
|
||||||
class CommonParamsForListTest(test_utils.BaseTestCase):
|
class CommonParamsForListTest(test_utils.BaseTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@@ -61,10 +61,48 @@ BAREMETAL_PORT = {
|
|||||||
|
|
||||||
baremetal_driver_hosts = ['fake-host1', 'fake-host2']
|
baremetal_driver_hosts = ['fake-host1', 'fake-host2']
|
||||||
baremetal_driver_name = 'fakedrivername'
|
baremetal_driver_name = 'fakedrivername'
|
||||||
|
baremetal_driver_type = 'classic'
|
||||||
|
baremetal_driver_default_boot_if = 'boot'
|
||||||
|
baremetal_driver_default_console_if = 'console'
|
||||||
|
baremetal_driver_default_deploy_if = 'deploy'
|
||||||
|
baremetal_driver_default_inspect_if = 'inspect'
|
||||||
|
baremetal_driver_default_management_if = 'management'
|
||||||
|
baremetal_driver_default_network_if = 'network'
|
||||||
|
baremetal_driver_default_power_if = 'power'
|
||||||
|
baremetal_driver_default_raid_if = 'raid'
|
||||||
|
baremetal_driver_default_vendor_if = 'vendor'
|
||||||
|
baremetal_driver_enabled_boot_ifs = ['boot', 'boot2']
|
||||||
|
baremetal_driver_enabled_console_ifs = ['console', 'console2']
|
||||||
|
baremetal_driver_enabled_deploy_ifs = ['deploy', 'deploy2']
|
||||||
|
baremetal_driver_enabled_inspect_ifs = ['inspect', 'inspect2']
|
||||||
|
baremetal_driver_enabled_management_ifs = ['management', 'management2']
|
||||||
|
baremetal_driver_enabled_network_ifs = ['network', 'network2']
|
||||||
|
baremetal_driver_enabled_power_ifs = ['power', 'power2']
|
||||||
|
baremetal_driver_enabled_raid_ifs = ['raid', 'raid2']
|
||||||
|
baremetal_driver_enabled_vendor_ifs = ['vendor', 'vendor2']
|
||||||
|
|
||||||
BAREMETAL_DRIVER = {
|
BAREMETAL_DRIVER = {
|
||||||
'hosts': baremetal_driver_hosts,
|
'hosts': baremetal_driver_hosts,
|
||||||
'name': baremetal_driver_name,
|
'name': baremetal_driver_name,
|
||||||
|
'type': baremetal_driver_type,
|
||||||
|
'default_boot_interface': baremetal_driver_default_boot_if,
|
||||||
|
'default_console_interface': baremetal_driver_default_console_if,
|
||||||
|
'default_deploy_interface': baremetal_driver_default_deploy_if,
|
||||||
|
'default_inspect_interface': baremetal_driver_default_inspect_if,
|
||||||
|
'default_management_interface': baremetal_driver_default_management_if,
|
||||||
|
'default_network_interface': baremetal_driver_default_network_if,
|
||||||
|
'default_power_interface': baremetal_driver_default_power_if,
|
||||||
|
'default_raid_interface': baremetal_driver_default_raid_if,
|
||||||
|
'default_vendor_interface': baremetal_driver_default_vendor_if,
|
||||||
|
'enabled_boot_interfaces': baremetal_driver_enabled_boot_ifs,
|
||||||
|
'enabled_console_interfaces': baremetal_driver_enabled_console_ifs,
|
||||||
|
'enabled_deploy_interfaces': baremetal_driver_enabled_deploy_ifs,
|
||||||
|
'enabled_inspect_interfaces': baremetal_driver_enabled_inspect_ifs,
|
||||||
|
'enabled_management_interfaces': baremetal_driver_enabled_management_ifs,
|
||||||
|
'enabled_network_interfaces': baremetal_driver_enabled_network_ifs,
|
||||||
|
'enabled_power_interfaces': baremetal_driver_enabled_power_ifs,
|
||||||
|
'enabled_raid_interfaces': baremetal_driver_enabled_raid_ifs,
|
||||||
|
'enabled_vendor_interfaces': baremetal_driver_enabled_vendor_ifs,
|
||||||
}
|
}
|
||||||
|
|
||||||
baremetal_driver_passthru_method = 'lookup'
|
baremetal_driver_passthru_method = 'lookup'
|
||||||
|
@@ -60,6 +60,80 @@ class TestListBaremetalDriver(TestBaremetalDriver):
|
|||||||
', '.join(baremetal_fakes.baremetal_driver_hosts)), )
|
', '.join(baremetal_fakes.baremetal_driver_hosts)), )
|
||||||
self.assertEqual(datalist, tuple(data))
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
def test_baremetal_driver_list_with_type(self):
|
||||||
|
arglist = ['--type', baremetal_fakes.baremetal_driver_type]
|
||||||
|
verifylist = [('type', baremetal_fakes.baremetal_driver_type)]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
collist = (
|
||||||
|
"Supported driver(s)",
|
||||||
|
"Active host(s)")
|
||||||
|
self.assertEqual(collist, tuple(columns))
|
||||||
|
|
||||||
|
datalist = ((
|
||||||
|
baremetal_fakes.baremetal_driver_name,
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_hosts)),)
|
||||||
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
def test_baremetal_driver_list_with_detail(self):
|
||||||
|
arglist = ['--long']
|
||||||
|
verifylist = [('long', True)]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
collist = (
|
||||||
|
"Supported driver(s)",
|
||||||
|
"Type",
|
||||||
|
"Active host(s)",
|
||||||
|
'Default Boot Interface',
|
||||||
|
'Default Console Interface',
|
||||||
|
'Default Deploy Interface',
|
||||||
|
'Default Inspect Interface',
|
||||||
|
'Default Management Interface',
|
||||||
|
'Default Network Interface',
|
||||||
|
'Default Power Interface',
|
||||||
|
'Default RAID Interface',
|
||||||
|
'Default Vendor Interface',
|
||||||
|
'Enabled Boot Interfaces',
|
||||||
|
'Enabled Console Interfaces',
|
||||||
|
'Enabled Deploy Interfaces',
|
||||||
|
'Enabled Inspect Interfaces',
|
||||||
|
'Enabled Management Interfaces',
|
||||||
|
'Enabled Network Interfaces',
|
||||||
|
'Enabled Power Interfaces',
|
||||||
|
'Enabled RAID Interfaces',
|
||||||
|
'Enabled Vendor Interfaces'
|
||||||
|
)
|
||||||
|
self.assertEqual(collist, tuple(columns))
|
||||||
|
|
||||||
|
datalist = ((
|
||||||
|
baremetal_fakes.baremetal_driver_name,
|
||||||
|
baremetal_fakes.baremetal_driver_type,
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_hosts),
|
||||||
|
baremetal_fakes.baremetal_driver_default_boot_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_console_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_deploy_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_inspect_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_management_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_network_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_power_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_raid_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_vendor_if,
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_boot_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_console_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_deploy_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_inspect_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_management_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_network_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_power_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_raid_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_vendor_ifs),
|
||||||
|
),)
|
||||||
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
|
||||||
class TestPassthruCallBaremetalDriver(TestBaremetalDriver):
|
class TestPassthruCallBaremetalDriver(TestBaremetalDriver):
|
||||||
|
|
||||||
@@ -205,12 +279,41 @@ class TestShowBaremetalDriver(TestBaremetalDriver):
|
|||||||
self.baremetal_mock.driver.get.assert_called_with(*args)
|
self.baremetal_mock.driver.get.assert_called_with(*args)
|
||||||
self.assertFalse(self.baremetal_mock.driver.properties.called)
|
self.assertFalse(self.baremetal_mock.driver.properties.called)
|
||||||
|
|
||||||
collist = ('hosts', 'name')
|
collist = ('default_boot_interface', 'default_console_interface',
|
||||||
|
'default_deploy_interface', 'default_inspect_interface',
|
||||||
|
'default_management_interface', 'default_network_interface',
|
||||||
|
'default_power_interface', 'default_raid_interface',
|
||||||
|
'default_vendor_interface', 'enabled_boot_interfaces',
|
||||||
|
'enabled_console_interfaces', 'enabled_deploy_interfaces',
|
||||||
|
'enabled_inspect_interfaces',
|
||||||
|
'enabled_management_interfaces',
|
||||||
|
'enabled_network_interfaces', 'enabled_power_interfaces',
|
||||||
|
'enabled_raid_interfaces', 'enabled_vendor_interfaces',
|
||||||
|
'hosts', 'name', 'type')
|
||||||
self.assertEqual(collist, columns)
|
self.assertEqual(collist, columns)
|
||||||
|
|
||||||
datalist = (
|
datalist = (
|
||||||
|
baremetal_fakes.baremetal_driver_default_boot_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_console_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_deploy_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_inspect_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_management_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_network_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_power_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_raid_if,
|
||||||
|
baremetal_fakes.baremetal_driver_default_vendor_if,
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_boot_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_console_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_deploy_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_inspect_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_management_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_network_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_power_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_raid_ifs),
|
||||||
|
', '.join(baremetal_fakes.baremetal_driver_enabled_vendor_ifs),
|
||||||
', '.join(baremetal_fakes.baremetal_driver_hosts),
|
', '.join(baremetal_fakes.baremetal_driver_hosts),
|
||||||
baremetal_fakes.baremetal_driver_name)
|
baremetal_fakes.baremetal_driver_name,
|
||||||
|
baremetal_fakes.baremetal_driver_type)
|
||||||
|
|
||||||
self.assertEqual(datalist, tuple(data))
|
self.assertEqual(datalist, tuple(data))
|
||||||
|
|
||||||
|
@@ -22,8 +22,34 @@ from ironicclient.tests.unit import utils
|
|||||||
from ironicclient.v1 import driver
|
from ironicclient.v1 import driver
|
||||||
|
|
||||||
|
|
||||||
DRIVER1 = {'name': 'fake', 'hosts': ['fake-host1', 'fake-host2']}
|
DRIVER1 = {
|
||||||
DRIVER2 = {'name': 'pxe_ipminative', 'hosts': ['fake-host1', 'fake-host2']}
|
'name': 'fake',
|
||||||
|
'type': 'dynamic',
|
||||||
|
'hosts': ['fake-host1', 'fake-host2'],
|
||||||
|
'default_boot_interface': 'boot',
|
||||||
|
'default_console_interface': 'console',
|
||||||
|
'default_deploy_interface': 'deploy',
|
||||||
|
'default_inspect_interface': 'inspect',
|
||||||
|
'default_management_interface': 'management',
|
||||||
|
'default_network_interface': 'network',
|
||||||
|
'default_power_interface': 'power',
|
||||||
|
'default_raid_interface': 'raid',
|
||||||
|
'default_vendor_interface': 'vendor',
|
||||||
|
'enabled_boot_interfaces': ['boot', 'boot2'],
|
||||||
|
'enabled_console_interfaces': ['console', 'console2'],
|
||||||
|
'enabled_deploy_interfaces': ['deploy', 'deploy2'],
|
||||||
|
'enabled_inspect_interfaces': ['inspect', 'inspect2'],
|
||||||
|
'enabled_management_interfaces': ['management', 'management2'],
|
||||||
|
'enabled_network_interfaces': ['network', 'network2'],
|
||||||
|
'enabled_power_interfaces': ['power', 'power2'],
|
||||||
|
'enabled_raid_interfaces': ['raid', 'raid2'],
|
||||||
|
'enabled_vendor_interfaces': ['vendor', 'vendor2'],
|
||||||
|
}
|
||||||
|
DRIVER2 = {
|
||||||
|
'name': 'pxe_ipminative',
|
||||||
|
'type': 'classic',
|
||||||
|
'hosts': ['fake-host1', 'fake-host2'],
|
||||||
|
}
|
||||||
|
|
||||||
DRIVER2_PROPERTIES = {
|
DRIVER2_PROPERTIES = {
|
||||||
"username": "username. Required.",
|
"username": "username. Required.",
|
||||||
@@ -100,8 +126,12 @@ class DriverManagerTest(testtools.TestCase):
|
|||||||
('GET', '/v1/drivers/%s' % DRIVER1['name'], {}, None)
|
('GET', '/v1/drivers/%s' % DRIVER1['name'], {}, None)
|
||||||
]
|
]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(DRIVER1['name'], driver_.name)
|
|
||||||
self.assertEqual(DRIVER1['hosts'], driver_.hosts)
|
driver_attr = {}
|
||||||
|
for attr in DRIVER1.keys():
|
||||||
|
driver_attr[attr] = getattr(driver_, attr)
|
||||||
|
|
||||||
|
self.assertEqual(DRIVER1, driver_attr)
|
||||||
|
|
||||||
def test_driver_properties(self):
|
def test_driver_properties(self):
|
||||||
properties = self.mgr.properties(DRIVER2['name'])
|
properties = self.mgr.properties(DRIVER2['name'])
|
||||||
|
@@ -34,7 +34,17 @@ class DriverShellTest(utils.BaseTestCase):
|
|||||||
with mock.patch.object(cliutils, 'print_dict', fake_print_dict):
|
with mock.patch.object(cliutils, 'print_dict', fake_print_dict):
|
||||||
driver = object()
|
driver = object()
|
||||||
d_shell._print_driver_show(driver)
|
d_shell._print_driver_show(driver)
|
||||||
exp = ['hosts', 'name']
|
exp = ['hosts', 'name', 'type',
|
||||||
|
'default_boot_interface', 'default_console_interface',
|
||||||
|
'default_deploy_interface', 'default_inspect_interface',
|
||||||
|
'default_management_interface', 'default_network_interface',
|
||||||
|
'default_power_interface', 'default_raid_interface',
|
||||||
|
'default_vendor_interface',
|
||||||
|
'enabled_boot_interfaces', 'enabled_console_interfaces',
|
||||||
|
'enabled_deploy_interfaces', 'enabled_inspect_interfaces',
|
||||||
|
'enabled_management_interfaces', 'enabled_network_interfaces',
|
||||||
|
'enabled_power_interfaces', 'enabled_raid_interfaces',
|
||||||
|
'enabled_vendor_interfaces']
|
||||||
act = actual.keys()
|
act = actual.keys()
|
||||||
self.assertEqual(sorted(exp), sorted(act))
|
self.assertEqual(sorted(exp), sorted(act))
|
||||||
|
|
||||||
@@ -145,9 +155,35 @@ class DriverShellTest(utils.BaseTestCase):
|
|||||||
def test_do_driver_list(self):
|
def test_do_driver_list(self):
|
||||||
client_mock = self.client_mock
|
client_mock = self.client_mock
|
||||||
args = mock.MagicMock()
|
args = mock.MagicMock()
|
||||||
|
args.type = None
|
||||||
|
args.detail = None
|
||||||
|
args.json = False
|
||||||
|
|
||||||
d_shell.do_driver_list(client_mock, args)
|
d_shell.do_driver_list(client_mock, args)
|
||||||
client_mock.driver.list.assert_called_once_with()
|
client_mock.driver.list.assert_called_once_with(driver_type=None,
|
||||||
|
detail=None)
|
||||||
|
|
||||||
|
def test_do_driver_list_with_type_and_no_detail(self):
|
||||||
|
client_mock = self.client_mock
|
||||||
|
args = mock.MagicMock()
|
||||||
|
args.type = 'classic'
|
||||||
|
args.detail = False
|
||||||
|
args.json = False
|
||||||
|
|
||||||
|
d_shell.do_driver_list(client_mock, args)
|
||||||
|
client_mock.driver.list.assert_called_once_with(driver_type='classic',
|
||||||
|
detail=False)
|
||||||
|
|
||||||
|
def test_do_driver_list_with_detail(self):
|
||||||
|
client_mock = self.client_mock
|
||||||
|
args = mock.MagicMock()
|
||||||
|
args.type = None
|
||||||
|
args.detail = True
|
||||||
|
args.json = False
|
||||||
|
|
||||||
|
d_shell.do_driver_list(client_mock, args)
|
||||||
|
client_mock.driver.list.assert_called_once_with(driver_type=None,
|
||||||
|
detail=True)
|
||||||
|
|
||||||
def test_do_driver_get_vendor_passthru_methods(self):
|
def test_do_driver_get_vendor_passthru_methods(self):
|
||||||
client_mock = mock.MagicMock()
|
client_mock = mock.MagicMock()
|
||||||
|
@@ -27,8 +27,28 @@ class DriverManager(base.Manager):
|
|||||||
resource_class = Driver
|
resource_class = Driver
|
||||||
_resource_name = 'drivers'
|
_resource_name = 'drivers'
|
||||||
|
|
||||||
def list(self):
|
def list(self, driver_type=None, detail=None):
|
||||||
return self._list('/v1/drivers', self._resource_name)
|
"""Retrieve a list of drivers.
|
||||||
|
|
||||||
|
:param driver_type: Optional, string to filter the drivers by type.
|
||||||
|
Value should be 'classic' or 'dynamic'.
|
||||||
|
:param detail: Optional, flag whether to return detailed information
|
||||||
|
about drivers. Default is None means not to send the arg
|
||||||
|
to the server due to older versions of the server cannot
|
||||||
|
handle filtering on detail.
|
||||||
|
:returns: A list of drivers.
|
||||||
|
"""
|
||||||
|
filters = []
|
||||||
|
if driver_type is not None:
|
||||||
|
filters.append('type=%s' % driver_type)
|
||||||
|
if detail is not None:
|
||||||
|
filters.append('detail=%s' % detail)
|
||||||
|
|
||||||
|
path = ''
|
||||||
|
if filters:
|
||||||
|
path = '?' + '&'.join(filters)
|
||||||
|
|
||||||
|
return self._list(self._path(path), self._resource_name)
|
||||||
|
|
||||||
def get(self, driver_name):
|
def get(self, driver_name):
|
||||||
return self._get(resource_id=driver_name)
|
return self._get(resource_id=driver_name)
|
||||||
|
@@ -22,21 +22,37 @@ from ironicclient.v1 import utils as v1_utils
|
|||||||
|
|
||||||
|
|
||||||
def _print_driver_show(driver, json=False):
|
def _print_driver_show(driver, json=False):
|
||||||
fields = res_fields.DRIVER_RESOURCE.fields
|
fields = res_fields.DRIVER_DETAILED_RESOURCE.fields
|
||||||
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, json_flag=json)
|
cliutils.print_dict(data, wrap=72, json_flag=json)
|
||||||
|
|
||||||
|
|
||||||
|
@cliutils.arg('-t', '--type',
|
||||||
|
metavar='<type>',
|
||||||
|
choices=["classic", "dynamic"],
|
||||||
|
help='Type of driver ("classic" or "dynamic"). '
|
||||||
|
'The default is to list all of them.')
|
||||||
|
@cliutils.arg('--detail',
|
||||||
|
dest='detail',
|
||||||
|
action='store_true',
|
||||||
|
default=None,
|
||||||
|
help="Show detailed information about the drivers.")
|
||||||
def do_driver_list(cc, args):
|
def do_driver_list(cc, args):
|
||||||
"""List the enabled drivers."""
|
"""List the enabled drivers."""
|
||||||
drivers = cc.driver.list()
|
drivers = cc.driver.list(driver_type=args.type, detail=args.detail)
|
||||||
# NOTE(lucasagomes): Separate each host by a comma.
|
# NOTE(lucasagomes): For list-type properties, show the values as
|
||||||
# It's easier to read.
|
# comma separated strings. It's easier to read.
|
||||||
for d in drivers:
|
data = [utils.convert_list_props_to_comma_separated(d._info)
|
||||||
d.hosts = ', '.join(d.hosts)
|
for d in drivers]
|
||||||
field_labels = res_fields.DRIVER_RESOURCE.labels
|
|
||||||
fields = res_fields.DRIVER_RESOURCE.fields
|
if args.detail:
|
||||||
cliutils.print_list(drivers, fields, field_labels=field_labels,
|
field_labels = res_fields.DRIVER_DETAILED_RESOURCE.labels
|
||||||
|
fields = res_fields.DRIVER_DETAILED_RESOURCE.fields
|
||||||
|
else:
|
||||||
|
field_labels = res_fields.DRIVER_RESOURCE.labels
|
||||||
|
fields = res_fields.DRIVER_RESOURCE.fields
|
||||||
|
|
||||||
|
cliutils.print_list(data, fields, field_labels=field_labels,
|
||||||
json_flag=args.json)
|
json_flag=args.json)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -38,10 +38,28 @@ class Resource(object):
|
|||||||
'clean_step': 'Clean Step',
|
'clean_step': 'Clean Step',
|
||||||
'console_enabled': 'Console Enabled',
|
'console_enabled': 'Console Enabled',
|
||||||
'created_at': 'Created At',
|
'created_at': 'Created At',
|
||||||
|
'default_boot_interface': 'Default Boot Interface',
|
||||||
|
'default_console_interface': 'Default Console Interface',
|
||||||
|
'default_deploy_interface': 'Default Deploy Interface',
|
||||||
|
'default_inspect_interface': 'Default Inspect Interface',
|
||||||
|
'default_management_interface': 'Default Management Interface',
|
||||||
|
'default_network_interface': 'Default Network Interface',
|
||||||
|
'default_power_interface': 'Default Power Interface',
|
||||||
|
'default_raid_interface': 'Default RAID Interface',
|
||||||
|
'default_vendor_interface': 'Default Vendor Interface',
|
||||||
'description': 'Description',
|
'description': 'Description',
|
||||||
'driver': 'Driver',
|
'driver': 'Driver',
|
||||||
'driver_info': 'Driver Info',
|
'driver_info': 'Driver Info',
|
||||||
'driver_internal_info': 'Driver Internal Info',
|
'driver_internal_info': 'Driver Internal Info',
|
||||||
|
'enabled_boot_interfaces': 'Enabled Boot Interfaces',
|
||||||
|
'enabled_console_interfaces': 'Enabled Console Interfaces',
|
||||||
|
'enabled_deploy_interfaces': 'Enabled Deploy Interfaces',
|
||||||
|
'enabled_inspect_interfaces': 'Enabled Inspect Interfaces',
|
||||||
|
'enabled_management_interfaces': 'Enabled Management Interfaces',
|
||||||
|
'enabled_network_interfaces': 'Enabled Network Interfaces',
|
||||||
|
'enabled_power_interfaces': 'Enabled Power Interfaces',
|
||||||
|
'enabled_raid_interfaces': 'Enabled RAID Interfaces',
|
||||||
|
'enabled_vendor_interfaces': 'Enabled Vendor Interfaces',
|
||||||
'extra': 'Extra',
|
'extra': 'Extra',
|
||||||
'hosts': 'Active host(s)',
|
'hosts': 'Active host(s)',
|
||||||
'http_methods': 'Supported HTTP methods',
|
'http_methods': 'Supported HTTP methods',
|
||||||
@@ -66,6 +84,7 @@ class Resource(object):
|
|||||||
'target_power_state': 'Target Power State',
|
'target_power_state': 'Target Power State',
|
||||||
'target_provision_state': 'Target Provision State',
|
'target_provision_state': 'Target Provision State',
|
||||||
'target_raid_config': 'Target RAID configuration',
|
'target_raid_config': 'Target RAID configuration',
|
||||||
|
'type': 'Type',
|
||||||
'updated_at': 'Updated At',
|
'updated_at': 'Updated At',
|
||||||
'uuid': 'UUID',
|
'uuid': 'UUID',
|
||||||
'local_link_connection': 'Local Link Connection',
|
'local_link_connection': 'Local Link Connection',
|
||||||
@@ -158,7 +177,6 @@ CHASSIS_RESOURCE = Resource(
|
|||||||
'description',
|
'description',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
# Nodes
|
# Nodes
|
||||||
NODE_DETAILED_RESOURCE = Resource(
|
NODE_DETAILED_RESOURCE = Resource(
|
||||||
['chassis_uuid',
|
['chassis_uuid',
|
||||||
@@ -292,6 +310,31 @@ VIF_RESOURCE = Resource(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Drivers
|
# Drivers
|
||||||
|
DRIVER_DETAILED_RESOURCE = Resource(
|
||||||
|
['name',
|
||||||
|
'type',
|
||||||
|
'hosts',
|
||||||
|
'default_boot_interface',
|
||||||
|
'default_console_interface',
|
||||||
|
'default_deploy_interface',
|
||||||
|
'default_inspect_interface',
|
||||||
|
'default_management_interface',
|
||||||
|
'default_network_interface',
|
||||||
|
'default_power_interface',
|
||||||
|
'default_raid_interface',
|
||||||
|
'default_vendor_interface',
|
||||||
|
'enabled_boot_interfaces',
|
||||||
|
'enabled_console_interfaces',
|
||||||
|
'enabled_deploy_interfaces',
|
||||||
|
'enabled_inspect_interfaces',
|
||||||
|
'enabled_management_interfaces',
|
||||||
|
'enabled_network_interfaces',
|
||||||
|
'enabled_power_interfaces',
|
||||||
|
'enabled_raid_interfaces',
|
||||||
|
'enabled_vendor_interfaces'
|
||||||
|
],
|
||||||
|
override_labels={'name': 'Supported driver(s)'}
|
||||||
|
)
|
||||||
DRIVER_RESOURCE = Resource(
|
DRIVER_RESOURCE = Resource(
|
||||||
['name',
|
['name',
|
||||||
'hosts',
|
'hosts',
|
||||||
|
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
To support dynamic drivers (available starting with ironic API
|
||||||
|
microversion 1.30):
|
||||||
|
|
||||||
|
* ironic driver-list has two new optional arguments, ``--type <type>``
|
||||||
|
for the type of driver ('classic' or 'dynamic') to list, and
|
||||||
|
``--detail`` to show detailed information about the drivers.
|
||||||
|
* ironic driver-show returns a lot more information, including the type
|
||||||
|
of driver and the default and enabled interfaces.
|
||||||
|
* openstack baremetal driver list has two new optional arguments,
|
||||||
|
``--type <type>`` for the type of driver ('classic' or 'dynamic')
|
||||||
|
to list, and ``--long`` to show detailed information about the drivers.
|
||||||
|
* openstack baremetal driver show returns a lot more information,
|
||||||
|
including the type of driver and the default and enabled interfaces.
|
Reference in New Issue
Block a user