From 734a0a0cb9188c4d686b749b6b809240a4bae8c0 Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Fri, 11 Oct 2019 23:10:48 +0200 Subject: [PATCH] Add `get_node_network_data` to non-Neutron NetworkInterface Implements `get_node_network_data` network interface method for non-Neutron networks providing network configuration for the node taken from the `network_data` field of the ironic node object. Change-Id: I4c5722b5e515f6edfa6a1bac0a443c71312c34d8 Story: 2006691 Task: 37070 --- ironic/drivers/modules/network/common.py | 24 ++++ .../network/json_samples/network_data.json | 113 ++++++++++++++++++ .../drivers/modules/network/test_common.py | 14 +++ 3 files changed, 151 insertions(+) create mode 100644 ironic/tests/unit/drivers/modules/network/json_samples/network_data.json diff --git a/ironic/drivers/modules/network/common.py b/ironic/drivers/modules/network/common.py index 736249b69c..14a8f74657 100644 --- a/ironic/drivers/modules/network/common.py +++ b/ironic/drivers/modules/network/common.py @@ -393,6 +393,30 @@ class VIFPortIDMixin(object): or p_obj.internal_info.get('inspection_vif_port_id') or self._get_vif_id_by_port_like_obj(p_obj) or None) + def get_node_network_data(self, task): + """Return network configuration for node NICs. + + Gather L2 and L3 network settings from ironic node `network_data` + field. Ironic would eventually pass network configuration to the node + being managed out-of-band. + + :param task: A TaskManager instance. + :raises: InvalidParameterValue, if the network interface configuration + is invalid. + :raises: MissingParameterValue, if some parameters are missing. + :returns: a dict holding network configuration information adhearing + Nova network metadata layout (`network_data.json`). + """ + node = task.node + + network_data = node.network_data + + # TODO(etingof): remove or truncate `network_data` logging + LOG.debug('Collected network data for node %(node)s: %(data)s', + {'node': node.uuid, 'data': network_data}) + + return network_data + class NeutronVIFPortIDMixin(VIFPortIDMixin): """VIF port ID mixin class for neutron network interfaces. diff --git a/ironic/tests/unit/drivers/modules/network/json_samples/network_data.json b/ironic/tests/unit/drivers/modules/network/json_samples/network_data.json new file mode 100644 index 0000000000..efce35ddde --- /dev/null +++ b/ironic/tests/unit/drivers/modules/network/json_samples/network_data.json @@ -0,0 +1,113 @@ +{ + "links": [ + { + "id": "interface2", + "type": "vif", + "ethernet_mac_address": "a0:36:9f:2c:e8:70", + "vif_id": "e1c90e9f-eafc-4e2d-8ec9-58b91cebb53d", + "mtu": 1500 + }, + { + "id": "interface0", + "type": "phy", + "ethernet_mac_address": "a0:36:9f:2c:e8:80", + "mtu": 9000 + }, + { + "id": "interface1", + "type": "phy", + "ethernet_mac_address": "a0:36:9f:2c:e8:81", + "mtu": 9000 + }, + { + "id": "bond0", + "type": "bond", + "bond_links": [ + "interface0", + "interface1" + ], + "ethernet_mac_address": "a0:36:9f:2c:e8:82", + "bond_mode": "802.1ad", + "bond_xmit_hash_policy": "layer3+4", + "bond_miimon": 100 + }, + { + "id": "vlan0", + "type": "vlan", + "vlan_link": "bond0", + "vlan_id": 101, + "vlan_mac_address": "a0:36:9f:2c:e8:80", + "vif_id": "e1c90e9f-eafc-4e2d-8ec9-58b91cebb53f" + } + ], + "networks": [ + { + "id": "private-ipv4", + "type": "ipv4", + "link": "interface0", + "ip_address": "10.184.0.244", + "netmask": "255.255.240.0", + "routes": [ + { + "network": "10.0.0.0", + "netmask": "255.0.0.0", + "gateway": "11.0.0.1" + }, + { + "network": "0.0.0.0", + "netmask": "0.0.0.0", + "gateway": "23.253.157.1" + } + ], + "network_id": "da5bb487-5193-4a65-a3df-4a0055a8c0d7" + }, + { + "id": "private-ipv4", + "type": "ipv6", + "link": "interface0", + "ip_address": "2001:cdba::3257:9652/24", + "routes": [ + { + "network": "::", + "netmask": "::", + "gateway": "fd00::1" + }, + { + "network": "::", + "netmask": "ffff:ffff:ffff::", + "gateway": "fd00::1:1" + } + ], + "network_id": "da5bb487-5193-4a65-a3df-4a0055a8c0d8" + }, + { + "id": "publicnet-ipv4", + "type": "ipv4", + "link": "vlan0", + "ip_address": "23.253.157.244", + "netmask": "255.255.255.0", + "dns_nameservers": [ + "69.20.0.164", + "69.20.0.196" + ], + "routes": [ + { + "network": "0.0.0.0", + "netmask": "0.0.0.0", + "gateway": "23.253.157.1" + } + ], + "network_id": "62611d6f-66cb-4270-8b1f-503ef0dd4736" + } + ], + "services": [ + { + "type": "dns", + "address": "8.8.8.8" + }, + { + "type": "dns", + "address": "8.8.4.4" + } + ] +} \ No newline at end of file diff --git a/ironic/tests/unit/drivers/modules/network/test_common.py b/ironic/tests/unit/drivers/modules/network/test_common.py index d2d4b6bb3d..d2833f2bee 100644 --- a/ironic/tests/unit/drivers/modules/network/test_common.py +++ b/ironic/tests/unit/drivers/modules/network/test_common.py @@ -10,6 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. +import json +import os from unittest import mock from oslo_config import cfg @@ -470,6 +472,10 @@ class TestVifPortIDMixin(db_base.DbTestCase): address='52:54:00:cf:2d:32', extra={'vif_port_id': uuidutils.generate_uuid(), 'client-id': 'fake1'}) + network_data_file = os.path.join( + os.path.dirname(__file__), 'json_samples', 'network_data.json') + with open(network_data_file, 'rb') as fl: + self.network_data = json.load(fl) def test__save_vif_to_port_like_obj_port(self): self.port.extra = {} @@ -680,6 +686,14 @@ class TestVifPortIDMixin(db_base.DbTestCase): vif = self.interface.get_current_vif(task, self.port) self.assertIsNone(vif) + def test_get_node_network_data_complete(self): + self.node.network_data = self.network_data + self.node.save() + with task_manager.acquire(self.context, self.node.id) as task: + network_data = self.interface.get_node_network_data(task) + + self.assertEqual(self.network_data, network_data) + class TestNeutronVifPortIDMixin(db_base.DbTestCase):