diff --git a/cloudinit/net/networkd.py b/cloudinit/net/networkd.py index ee6fd2ade3a..c97c18f67b5 100644 --- a/cloudinit/net/networkd.py +++ b/cloudinit/net/networkd.py @@ -41,11 +41,11 @@ def update_section(self, sec, key, val): def get_final_conf(self): contents = '' - for k, v in self.conf_dict.items(): + for k, v in sorted(self.conf_dict.items()): if not v: continue contents += '['+k+']\n' - for e in v: + for e in sorted(v): contents += e + '\n' contents += '\n' @@ -242,6 +242,19 @@ def _render_content(self, ns): name = iface['name'] # network state doesn't give dhcp domain info # using ns.config as a workaround here + + # Check to see if this interface matches against an interface + # from the network state that specified a set-name directive. + # If there is a device with a set-name directive and it has + # set-name value that matches the current name, then update the + # current name to the device's name. That will be the value in + # the ns.config['ethernets'] dict below. + for dev_name, dev_cfg in ns.config['ethernets'].items(): + if 'set-name' in dev_cfg: + if dev_cfg.get('set-name') == name: + name = dev_name + break + self.dhcp_domain(ns.config['ethernets'][name], cfg) ret_dict.update({link: cfg.get_final_conf()}) diff --git a/cloudinit/net/tests/test_networkd.py b/cloudinit/net/tests/test_networkd.py new file mode 100644 index 00000000000..8dc90b48461 --- /dev/null +++ b/cloudinit/net/tests/test_networkd.py @@ -0,0 +1,64 @@ +# This file is part of cloud-init. See LICENSE file for license information. + +from cloudinit import safeyaml +from cloudinit.net import networkd, network_state + +V2_CONFIG_SET_NAME = """\ +network: + version: 2 + ethernets: + eth0: + match: + macaddress: '00:11:22:33:44:55' + nameservers: + search: [spam.local, eggs.local] + addresses: [8.8.8.8] + eth1: + match: + macaddress: '66:77:88:99:00:11' + set-name: "ens92" + nameservers: + search: [foo.local, bar.local] + addresses: [4.4.4.4] +""" + +V2_CONFIG_SET_NAME_RENDERED_ETH0 = """[Match] +MACAddress=00:11:22:33:44:55 +Name=eth0 + +[Network] +DHCP=no +DNS=8.8.8.8 +Domains=spam.local eggs.local + +""" + +V2_CONFIG_SET_NAME_RENDERED_ETH1 = """[Match] +MACAddress=66:77:88:99:00:11 +Name=ens92 + +[Network] +DHCP=no +DNS=4.4.4.4 +Domains=foo.local bar.local + +""" + + +class TestNetworkdRenderState: + def _parse_network_state_from_config(self, config): + yaml = safeyaml.load(config) + return network_state.parse_net_config_data(yaml["network"]) + + def test_networkd_render_with_set_name(self): + ns = self._parse_network_state_from_config(V2_CONFIG_SET_NAME) + renderer = networkd.Renderer() + rendered_content = renderer._render_content(ns) + + assert "eth0" in rendered_content + assert rendered_content["eth0"] == V2_CONFIG_SET_NAME_RENDERED_ETH0 + assert "ens92" in rendered_content + assert rendered_content["ens92"] == V2_CONFIG_SET_NAME_RENDERED_ETH1 + + +# vi: ts=4 expandtab