diff --git a/releasenotes/notes/ironic-ucs-driver-node-uniqueness-fix-c74110a9728d1023.yaml b/releasenotes/notes/ironic-ucs-driver-node-uniqueness-fix-c74110a9728d1023.yaml new file mode 100644 index 000000000..bcf1ac8a4 --- /dev/null +++ b/releasenotes/notes/ironic-ucs-driver-node-uniqueness-fix-c74110a9728d1023.yaml @@ -0,0 +1,11 @@ +--- +deprecations: + - | + Un-deprecated `pm_service_profile` option support at the UCS ironic + driver. +fixes: + - | + Previously, ironic nodes that only differ in `pm_service_profile` + or `ucs_service_profile` would override one another ultimately leaving + just one of them in ironic configuration. This fix un-deprecates + `pm_service_profile` option support at the UCS ironic driver. diff --git a/tripleo_common/tests/utils/test_nodes.py b/tripleo_common/tests/utils/test_nodes.py index 53b2ee872..3f09bb562 100644 --- a/tripleo_common/tests/utils/test_nodes.py +++ b/tripleo_common/tests/utils/test_nodes.py @@ -227,6 +227,44 @@ class iBootDriverInfoTest(base.TestCase): self.driver_info.unique_id_from_node(node)) +class UcsDriverInfoTest(base.TestCase): + driver_info = nodes.UcsDriverInfo() + + def test_convert_key(self): + keys = { + 'pm_addr': 'ucs_address', + 'pm_user': 'ucs_username', + 'pm_password': 'ucs_password', + 'pm_service_profile': 'ucs_service_profile' + } + for key, expected in keys.items(): + self.assertEqual(expected, self.driver_info.convert_key(key)) + + self.assertIsNone(self.driver_info.convert_key('unknown')) + + def test_unique_id_from_fields(self): + fields = { + 'pm_addr': '127.0.0.1', + 'pm_user': 'user', + 'pm_password': '123456', + "pm_service_profile": 'org-root/org-CPC/ls-CPC-test' + } + self.assertEqual('127.0.0.1:org-root/org-CPC/ls-CPC-test', + self.driver_info.unique_id_from_fields(fields)) + + def test_unique_id_from_node(self): + node = mock.Mock( + driver_info={ + 'ucs_address': '127.0.0.1', + 'ucs_username': 'user', + 'ucs_password': '123456', + "ucs_service_profile": 'org-root/org-CPC/ls-CPC-test' + } + ) + self.assertEqual('127.0.0.1:org-root/org-CPC/ls-CPC-test', + self.driver_info.unique_id_from_node(node)) + + class FindNodeHandlerTest(base.TestCase): def test_found(self): test = [('fake', 'fake'), diff --git a/tripleo_common/utils/nodes.py b/tripleo_common/utils/nodes.py index 83d3a8d44..4502e1cd0 100644 --- a/tripleo_common/utils/nodes.py +++ b/tripleo_common/utils/nodes.py @@ -264,13 +264,43 @@ class iBootDriverInfo(PrefixedDriverInfo): return result +class UcsDriverInfo(DriverInfo): + def __init__(self): + mapping = { + 'pm_addr': 'ucs_address', + 'pm_user': 'ucs_username', + 'pm_password': 'ucs_password', + 'pm_service_profile': 'ucs_service_profile' + } + mandatory_fields = list(mapping) + + super(UcsDriverInfo, self).__init__( + 'ucs', mapping, + mandatory_fields=mandatory_fields + ) + + def unique_id_from_fields(self, fields): + try: + return '%s:%s' % (fields['pm_addr'], fields['pm_service_profile']) + + except KeyError: + return + + def unique_id_from_node(self, node): + try: + return '%s:%s' % (node.driver_info['ucs_address'], + node.driver_info['ucs_service_profile']) + except KeyError: + return + + 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'), + '(cisco\-ucs\-managed|.*_ucs)': UcsDriverInfo(), '(irmc|.*_irmc)': PrefixedDriverInfo('irmc', has_port=True), 'redfish': RedfishDriverInfo(), # test drivers