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:
Dao Cong Tien
2017-01-12 12:04:17 +07:00
parent 3d2389ed1a
commit 9fbcadfff3
11 changed files with 396 additions and 30 deletions

View File

@@ -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.

View File

@@ -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()))

View File

@@ -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):

View File

@@ -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'

View File

@@ -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))

View File

@@ -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'])

View File

@@ -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()

View File

@@ -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)

View File

@@ -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)

View File

@@ -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',

View File

@@ -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.