From cea85025271b5aa5dfd271adc4a2ae6d61d31d08 Mon Sep 17 00:00:00 2001 From: James Slagle Date: Tue, 6 Oct 2015 13:25:03 -0400 Subject: [PATCH] Remove requirement of specifying hardware stats With introspection in place, there is no longer a hard requirement of knowing the hardware statistics (cpu, memory, disk, arch) of nodes when initially registering them with Ironic. The requirement was never on the Ironic side, it was only enforced here in os-cloud-config. Previously, to get around the requirement, one could just specify an empty string value for these statistics in the nodes json file. This change makes it such that these keys do not even have to exist in the json anymore. Add a unit test as well that verifies this change. Change-Id: Idcc5a9a4ac043c88fe0102626eefb327476819fd --- doc/source/usage.rst | 4 ++++ os_cloud_config/nodes.py | 11 +++++++---- os_cloud_config/tests/test_nodes.py | 30 +++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/doc/source/usage.rst b/doc/source/usage.rst index 5628ba6..4cc7f2c 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -79,6 +79,10 @@ Where ``/tmp/one-node`` contains:: } ] + .. note:: + + The memory, disk, arch, and cpu fields are optional and can be omitted. + ---------------------------------------------------------- Generating keys and certificates for use with Keystone PKI ---------------------------------------------------------- diff --git a/os_cloud_config/nodes.py b/os_cloud_config/nodes.py index 6281ba1..25b5980 100644 --- a/os_cloud_config/nodes.py +++ b/os_cloud_config/nodes.py @@ -80,10 +80,13 @@ def _extract_driver_info(node): def register_ironic_node(service_host, node, client=None, blocking=True): - properties = {"cpus": six.text_type(node["cpu"]), - "memory_mb": six.text_type(node["memory"]), - "local_gb": six.text_type(node["disk"]), - "cpu_arch": node["arch"]} + mapping = {'cpus': 'cpu', + 'memory_mb': 'memory', + 'local_gb': 'disk', + 'cpu_arch': 'arch'} + properties = {k: six.text_type(node.get(v)) + for k, v in mapping.items() + if node.get(v) is not None} driver_info = _extract_driver_info(node) if 'capabilities' in node: diff --git a/os_cloud_config/tests/test_nodes.py b/os_cloud_config/tests/test_nodes.py index 2c7a0cd..e0480b9 100644 --- a/os_cloud_config/tests/test_nodes.py +++ b/os_cloud_config/tests/test_nodes.py @@ -152,6 +152,36 @@ class NodesTest(base.TestCase): node["pm_type"] = "unknown_type" self.assertRaises(ValueError, nodes._extract_driver_info, node) + def test_register_all_nodes_ironic_no_hw_stats(self): + node_list = [self._get_node()] + + # Remove the hardware stats from the node dictionary + node_list[0].pop("cpu") + node_list[0].pop("memory") + node_list[0].pop("disk") + node_list[0].pop("arch") + + # Node properties should be created with empty string values for the + # hardware statistics + node_properties = {"capabilities": "num_nics:6"} + + ironic = mock.MagicMock() + nodes.register_all_nodes('servicehost', node_list, client=ironic) + pxe_node_driver_info = {"ssh_address": "foo.bar", + "ssh_username": "test", + "ssh_key_contents": "random", + "ssh_virt_type": "virsh"} + pxe_node = mock.call(driver="pxe_ssh", + name='node1', + driver_info=pxe_node_driver_info, + properties=node_properties) + port_call = mock.call(node_uuid=ironic.node.create.return_value.uuid, + address='aaa') + power_off_call = mock.call(ironic.node.create.return_value.uuid, 'off') + ironic.node.create.assert_has_calls([pxe_node, mock.ANY]) + ironic.port.create.assert_has_calls([port_call]) + ironic.node.set_power_state.assert_has_calls([power_off_call]) + def test_register_all_nodes_ironic(self): node_list = [self._get_node()] node_properties = {"cpus": "1",