Merge "Convert classic drivers to hardware types on enrollment"

This commit is contained in:
Zuul 2018-05-31 14:26:12 +00:00 committed by Gerrit Code Review
commit c453658043
3 changed files with 95 additions and 25 deletions

View File

@ -0,0 +1,7 @@
---
features:
- |
On enrollment, all classic drivers are replaced with their hardware type
equivalents (e.g. ``pxe_ipmitool`` is replaced with ``ipmi``).
The ``fake_pxe`` classic driver is replaced with the ``manual-management``
hardware type (which must be enabled in the undercloud).

View File

@ -667,12 +667,29 @@ class NodesTest(base.TestCase):
node['pm_type'] = 'fake_pxe'
client = mock.MagicMock()
nodes.register_ironic_node(node, client=client)
client.node.create.assert_called_once_with(driver='fake_pxe',
client.node.create.assert_called_once_with(driver='manual-management',
name='node1',
properties=node_properties,
resource_class='baremetal',
driver_info={})
def test_register_ironic_node_ucs(self):
node_properties = {"cpus": "1",
"memory_mb": "2048",
"local_gb": "30",
"cpu_arch": "amd64",
"capabilities": "num_nics:6"}
node = self._get_node()
node['pm_type'] = 'cisco-ucs-managed'
client = mock.MagicMock()
nodes.register_ironic_node(node, client=client)
client.node.create.assert_called_once_with(
driver='cisco-ucs-managed', name='node1',
properties=node_properties,
resource_class='baremetal',
driver_info={'ucs_password': 'random', 'ucs_address': 'foo.bar',
'ucs_username': 'test'})
def test_register_ironic_node_pxe_ucs(self):
node_properties = {"cpus": "1",
"memory_mb": "2048",
@ -684,7 +701,8 @@ class NodesTest(base.TestCase):
client = mock.MagicMock()
nodes.register_ironic_node(node, client=client)
client.node.create.assert_called_once_with(
driver='pxe_ucs', name='node1', properties=node_properties,
driver='cisco-ucs-managed', name='node1',
properties=node_properties,
resource_class='baremetal',
driver_info={'ucs_password': 'random', 'ucs_address': 'foo.bar',
'ucs_username': 'test'})
@ -718,7 +736,7 @@ class NodesTest(base.TestCase):
client = mock.MagicMock()
nodes.register_ironic_node(node, client=client)
client.node.create.assert_called_once_with(
driver='pxe_ipmitool', name='node1', properties=node_properties,
driver='ipmi', name='node1', properties=node_properties,
resource_class='baremetal',
driver_info={'ipmi_password': 'random', 'ipmi_address': 'foo.bar',
'ipmi_username': 'test', 'ipmi_port': '6230'})
@ -769,11 +787,28 @@ class NodesTest(base.TestCase):
client = mock.MagicMock()
nodes.register_ironic_node(node, client=client)
client.node.create.assert_called_once_with(
driver='pxe_drac', name='node1', properties=node_properties,
driver='idrac', name='node1', properties=node_properties,
resource_class='baremetal',
driver_info={'drac_password': 'random', 'drac_address': 'foo.bar',
'drac_username': 'test', 'drac_port': '6230'})
def test_register_ironic_node_pxe_ilo(self):
node_properties = {"cpus": "1",
"memory_mb": "2048",
"local_gb": "30",
"cpu_arch": "amd64",
"capabilities": "num_nics:6"}
node = self._get_node()
node['pm_type'] = 'pxe_ilo'
node['pm_port'] = '1234'
client = mock.MagicMock()
nodes.register_ironic_node(node, client=client)
client.node.create.assert_called_once_with(
driver='ilo', name='node1', properties=node_properties,
resource_class='baremetal',
driver_info={'ilo_password': 'random', 'ilo_address': 'foo.bar',
'ilo_username': 'test', 'ilo_port': '1234'})
def test_register_ironic_node_redfish(self):
node_properties = {"cpus": "1",
"memory_mb": "2048",
@ -833,16 +868,16 @@ class NodesTest(base.TestCase):
nodes._clean_up_extra_nodes(seen, client, remove=True)
client.node.delete.assert_called_once_with('foobar')
def test__get_node_id_fake_pxe(self):
def test__get_node_id_manual_management(self):
node = self._get_node()
node['pm_type'] = 'fake_pxe'
handler = nodes.find_driver_handler('fake_pxe')
node['pm_type'] = 'manual-management'
handler = nodes.find_driver_handler('manual-management')
node_map = {'mac': {'aaa': 'abcdef'}, 'pm_addr': {}}
self.assertEqual('abcdef', nodes._get_node_id(node, handler, node_map))
def test__get_node_id_conflict(self):
node = self._get_node()
handler = nodes.find_driver_handler('pxe_ipmitool')
handler = nodes.find_driver_handler('ipmi')
node_map = {'mac': {'aaa': 'abcdef'},
'pm_addr': {'foo.bar': 'defabc'}}
self.assertRaises(exception.InvalidNode,
@ -851,7 +886,7 @@ class NodesTest(base.TestCase):
def test_get_node_id_valid_duplicate(self):
node = self._get_node()
handler = nodes.find_driver_handler('pxe_ipmitool')
handler = nodes.find_driver_handler('ipmi')
node_map = {'mac': {'aaa': 'id'},
'pm_addr': {'foo.bar': 'id'}}
self.assertEqual('id', nodes._get_node_id(node, handler, node_map))
@ -874,12 +909,12 @@ class TestPopulateNodeMapping(base.TestCase):
'uuids': {'abcdef', 'fedcba', 'xyz'}}
self.assertEqual(expected, nodes._populate_node_mapping(client))
def test_populate_node_mapping_ironic_fake_pxe(self):
def test_populate_node_mapping_ironic_manual_management(self):
client = mock.MagicMock()
ironic_node = collections.namedtuple('node', ['uuid', 'driver',
'driver_info'])
ironic_port = collections.namedtuple('port', ['address'])
node = ironic_node('abcdef', 'fake_pxe', None)
node = ironic_node('abcdef', 'manual-management', None)
client.node.list_ports.return_value = [ironic_port('aaa')]
client.node.list.return_value = [node]
expected = {'mac': {'aaa': 'abcdef'}, 'pm_addr': {},

View File

@ -54,17 +54,22 @@ class DriverInfo(object):
DEFAULTS = {}
def __init__(self, prefix, mapping, deprecated_mapping=None,
mandatory_fields=(), default_port=None):
mandatory_fields=(), default_port=None, hardware_type=None):
self._prefix = prefix
self._mapping = mapping
self._deprecated_mapping = deprecated_mapping or {}
self._mandatory_fields = mandatory_fields
self._default_port = default_port
self._hardware_type = hardware_type
@property
def default_port(self):
return self._default_port
@property
def hardware_type(self):
return self._hardware_type
def convert_key(self, key):
if key in self._mapping:
return self._mapping[key]
@ -116,7 +121,7 @@ class DriverInfo(object):
class PrefixedDriverInfo(DriverInfo):
def __init__(self, prefix, deprecated_mapping=None,
has_port=False, address_field='address',
default_port=None):
default_port=None, hardware_type=None):
mapping = {
'pm_addr': '%s_%s' % (prefix, address_field),
'pm_user': '%s_username' % prefix,
@ -133,6 +138,7 @@ class PrefixedDriverInfo(DriverInfo):
deprecated_mapping=deprecated_mapping,
mandatory_fields=mandatory_fields,
default_port=default_port,
hardware_type=hardware_type,
)
def unique_id_from_fields(self, fields):
@ -179,6 +185,7 @@ class RedfishDriverInfo(DriverInfo):
'redfish', mapping,
deprecated_mapping=None,
mandatory_fields=mandatory_fields,
hardware_type='redfish',
)
def _build_id(self, address, system):
@ -211,6 +218,7 @@ class oVirtDriverInfo(DriverInfo):
super(oVirtDriverInfo, self).__init__(
'ovirt', mapping,
mandatory_fields=list(mapping),
hardware_type='staging-ovirt',
)
def unique_id_from_fields(self, fields):
@ -233,7 +241,8 @@ class iBootDriverInfo(PrefixedDriverInfo):
'iboot', has_port=True,
deprecated_mapping={
'pm_relay_id': 'iboot_relay_id',
}
},
hardware_type='staging-iboot',
)
def unique_id_from_fields(self, fields):
@ -257,23 +266,35 @@ class iBootDriverInfo(PrefixedDriverInfo):
DRIVER_INFO = {
# production drivers
'(ipmi|.*_ipmitool)': PrefixedDriverInfo('ipmi', has_port=True,
default_port=623),
'(idrac|.*_drac)': PrefixedDriverInfo('drac', has_port=True),
'(ilo|.*_ilo)': PrefixedDriverInfo('ilo', has_port=True),
'(cisco\-ucs\-managed|.*_ucs)': PrefixedDriverInfo('ucs'),
'(irmc|.*_irmc)': PrefixedDriverInfo('irmc', has_port=True),
default_port=623,
hardware_type='ipmi'),
'(idrac|.*_drac)': PrefixedDriverInfo('drac', has_port=True,
hardware_type='idrac'),
'(ilo|.*_ilo)': PrefixedDriverInfo('ilo', has_port=True,
hardware_type='ilo'),
'(cisco\-ucs\-managed|.*_ucs)': PrefixedDriverInfo(
'ucs', hardware_type='cisco-ucs-managed'),
'(irmc|.*_irmc)': PrefixedDriverInfo('irmc', has_port=True,
hardware_type='irmc'),
'redfish': RedfishDriverInfo(),
# test drivers
'staging\-ovirt': oVirtDriverInfo(),
'.*_iboot': iBootDriverInfo(),
'.*_wol': DriverInfo(
'(staging\-iboot|.*_iboot)': iBootDriverInfo(),
'(staging\-wol|.*wol)': DriverInfo(
'wol',
mapping={
'pm_addr': 'wol_host',
'pm_port': 'wol_port',
}),
'.*_amt': PrefixedDriverInfo('amt'),
'fake(|_pxe|_agent)': DriverInfo('fake', mapping={}),
},
hardware_type='staging-wol'),
'(staging\-amt|.*_amt)': PrefixedDriverInfo('amt',
hardware_type='staging-amt'),
# fake_pxe was used when no management interface was supported, now
# manual-management is used for the same purpose
'(manual\-management|fake_pxe|fake_agent)': DriverInfo(
'fake', mapping={}, hardware_type='manual-management'),
'^fake(|\-hardware)$': DriverInfo('fake', mapping={},
hardware_type='fake-hardware'),
}
@ -334,7 +355,14 @@ def register_ironic_node(node, client):
caps = dict_to_capabilities(caps)
properties.update({"capabilities": six.text_type(caps)})
create_map = {"driver": node["pm_type"],
driver = node['pm_type']
if handler.hardware_type and handler.hardware_type != driver:
LOG.warning('Replacing deprecated driver %(old)s with the '
'hardware type %(new)s, please update your inventory',
{'old': driver, 'new': handler.hardware_type})
driver = handler.hardware_type
create_map = {"driver": driver,
"properties": properties,
"driver_info": driver_info,
"resource_class": resource_class}