|
Server : Apache System : Linux server.mata-lashes.com 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64 User : matalashes ( 1004) PHP Version : 8.1.29 Disable Function : NONE Directory : /usr/src/cloud-init/tests/unittests/net/ |
Upload File : |
# This file is part of cloud-init. See LICENSE file for license information.
from string import Template
from unittest import mock
import pytest
from cloudinit import safeyaml
from cloudinit.net import network_state, networkd
V2_CONFIG_SET_NAME = """\
network:
version: 2
ethernets:
eth0:
match:
macaddress: '00:11:22:33:44:55'
addresses: [172.16.10.2/12, 172.16.10.3/12]
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 = """[Address]
Address=172.16.10.2/12
[Address]
Address=172.16.10.3/12
[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
"""
V2_CONFIG_DHCP_YES_OVERRIDES = """\
network:
version: 2
ethernets:
eth0:
dhcp4: true
dhcp4-overrides:
hostname: hal
route-metric: 1100
send-hostname: false
use-dns: false
use-domains: false
use-hostname: false
use-mtu: false
use-ntp: false
use-routes: false
dhcp6: true
dhcp6-overrides:
use-dns: false
use-domains: false
use-hostname: false
use-ntp: false
match:
macaddress: "00:11:22:33:44:55"
nameservers:
addresses: ["8.8.8.8", "2001:4860:4860::8888"]
"""
V2_CONFIG_DHCP_YES_OVERRIDES_RENDERED = """[DHCPv4]
Hostname=hal
RouteMetric=1100
SendHostname=False
UseDNS=False
UseDomains=False
UseHostname=False
UseMTU=False
UseNTP=False
UseRoutes=False
[DHCPv6]
UseDNS=False
UseDomains=False
UseHostname=False
UseNTP=False
[Match]
MACAddress=00:11:22:33:44:55
Name=eth0
[Network]
DHCP=yes
DNS=8.8.8.8 2001:4860:4860::8888
"""
V2_CONFIG_DHCP_DOMAIN_VS_OVERRIDE = Template(
"""\
network:
version: 2
ethernets:
eth0:
dhcp${dhcp_version}domain: true
dhcp${dhcp_version}: true
dhcp${dhcp_version}-overrides:
use-domains: route
"""
)
V2_CONFIG_DHCP_OVERRIDES = Template(
"""\
network:
version: 2
ethernets:
eth0:
dhcp${dhcp_version}: true
dhcp${dhcp_version}-overrides:
${key}: ${value}
match:
macaddress: "00:11:22:33:44:55"
nameservers:
addresses: ["8.8.8.8", "2001:4860:4860::8888"]
"""
)
V2_CONFIG_DHCP_OVERRIDES_RENDERED = Template(
"""[DHCPv${dhcp_version}]
${key}=${value}
[Match]
MACAddress=00:11:22:33:44:55
Name=eth0
[Network]
DHCP=ipv${dhcp_version}
DNS=8.8.8.8 2001:4860:4860::8888
"""
)
V1_CONFIG_MULTI_SUBNETS = """
network:
version: 1
config:
- type: physical
name: eth0
mac_address: 'ae:98:25:fa:36:9e'
subnets:
- type: static
address: '10.0.0.2'
netmask: '255.255.255.255'
gateway: '10.0.0.1'
- type: static6
address: '2a01:4f8:10a:19d2::4/64'
gateway: '2a01:4f8:10a:19d2::2'
- type: nameserver
address:
- '100.100.100.100'
search:
- 'rgrunbla.github.beta.tailscale.net'
"""
V1_CONFIG_MULTI_SUBNETS_RENDERED = """\
[Address]
Address=10.0.0.2/32
[Address]
Address=2a01:4f8:10a:19d2::4/64
[Match]
MACAddress=ae:98:25:fa:36:9e
Name=eth0
[Network]
DHCP=no
DNS=100.100.100.100
Domains=rgrunbla.github.beta.tailscale.net
[Route]
Gateway=10.0.0.1
[Route]
Gateway=2a01:4f8:10a:19d2::2
"""
V2_CONFIG_MULTI_SUBNETS = """
network:
version: 2
ethernets:
eth0:
addresses:
- 192.168.1.1/24
- fec0::1/64
gateway4: 192.168.254.254
gateway6: "fec0::ffff"
routes:
- to: 169.254.1.1/32
- to: "fe80::1/128"
"""
V2_CONFIG_MULTI_SUBNETS_RENDERED = """\
[Address]
Address=192.168.1.1/24
[Address]
Address=fec0::1/64
[Match]
Name=eth0
[Network]
DHCP=no
[Route]
Gateway=192.168.254.254
[Route]
Gateway=fec0::ffff
[Route]
Destination=169.254.1.1/32
[Route]
Destination=fe80::1/128
"""
class TestNetworkdRenderState:
def _parse_network_state_from_config(self, config):
with mock.patch("cloudinit.net.network_state.get_interfaces_by_mac"):
yaml = safeyaml.load(config)
return network_state.parse_net_config_data(yaml["network"])
def test_networkd_render_with_set_name(self):
with mock.patch("cloudinit.net.get_interfaces_by_mac"):
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
def test_networkd_render_dhcp_yes_with_dhcp_overrides(self):
with mock.patch("cloudinit.net.get_interfaces_by_mac"):
ns = self._parse_network_state_from_config(
V2_CONFIG_DHCP_YES_OVERRIDES
)
renderer = networkd.Renderer()
rendered_content = renderer._render_content(ns)
assert (
rendered_content["eth0"] == V2_CONFIG_DHCP_YES_OVERRIDES_RENDERED
)
@pytest.mark.parametrize("dhcp_version", [("4"), ("6")])
def test_networkd_render_dhcp_domains_vs_overrides(self, dhcp_version):
expected_exception = (
f"eth0 has both dhcp{dhcp_version}domain and"
f" dhcp{dhcp_version}-overrides.use-domains configured. Use one"
)
with pytest.raises(Exception, match=expected_exception):
with mock.patch("cloudinit.net.get_interfaces_by_mac"):
config = V2_CONFIG_DHCP_DOMAIN_VS_OVERRIDE.substitute(
dhcp_version=dhcp_version
)
ns = self._parse_network_state_from_config(config)
renderer = networkd.Renderer()
renderer._render_content(ns)
@pytest.mark.parametrize(
"dhcp_version,spec_key,spec_value,rendered_key,rendered_value",
[
("4", "use-dns", "false", "UseDNS", "False"),
("4", "use-dns", "true", "UseDNS", "True"),
("4", "use-ntp", "false", "UseNTP", "False"),
("4", "use-ntp", "true", "UseNTP", "True"),
("4", "send-hostname", "false", "SendHostname", "False"),
("4", "send-hostname", "true", "SendHostname", "True"),
("4", "use-hostname", "false", "UseHostname", "False"),
("4", "use-hostname", "true", "UseHostname", "True"),
("4", "hostname", "olivaw", "Hostname", "olivaw"),
("4", "route-metric", "12345", "RouteMetric", "12345"),
("4", "use-domains", "false", "UseDomains", "False"),
("4", "use-domains", "true", "UseDomains", "True"),
("4", "use-domains", "route", "UseDomains", "route"),
("4", "use-mtu", "false", "UseMTU", "False"),
("4", "use-mtu", "true", "UseMTU", "True"),
("4", "use-routes", "false", "UseRoutes", "False"),
("4", "use-routes", "true", "UseRoutes", "True"),
("6", "use-dns", "false", "UseDNS", "False"),
("6", "use-dns", "true", "UseDNS", "True"),
("6", "use-ntp", "false", "UseNTP", "False"),
("6", "use-ntp", "true", "UseNTP", "True"),
("6", "use-hostname", "false", "UseHostname", "False"),
("6", "use-hostname", "true", "UseHostname", "True"),
("6", "use-domains", "false", "UseDomains", "False"),
("6", "use-domains", "true", "UseDomains", "True"),
("6", "use-domains", "route", "UseDomains", "route"),
],
)
def test_networkd_render_dhcp_overrides(
self, dhcp_version, spec_key, spec_value, rendered_key, rendered_value
):
with mock.patch("cloudinit.net.get_interfaces_by_mac"):
ns = self._parse_network_state_from_config(
V2_CONFIG_DHCP_OVERRIDES.substitute(
dhcp_version=dhcp_version, key=spec_key, value=spec_value
)
)
renderer = networkd.Renderer()
rendered_content = renderer._render_content(ns)
assert rendered_content[
"eth0"
] == V2_CONFIG_DHCP_OVERRIDES_RENDERED.substitute(
dhcp_version=dhcp_version, key=rendered_key, value=rendered_value
)
def test_networkd_render_v1_multi_subnets(self):
"""
Ensure a device with multiple subnets gets correctly rendered.
Per systemd-networkd docs, [Address] can only contain a single instance
of Address.
"""
with mock.patch("cloudinit.net.get_interfaces_by_mac"):
ns = self._parse_network_state_from_config(V1_CONFIG_MULTI_SUBNETS)
renderer = networkd.Renderer()
rendered_content = renderer._render_content(ns)
assert rendered_content["eth0"] == V1_CONFIG_MULTI_SUBNETS_RENDERED
def test_networkd_render_v2_multi_subnets(self):
"""
Ensure a device with multiple subnets gets correctly rendered.
Per systemd-networkd docs, [Route] can only contain a single instance
of Gateway.
"""
with mock.patch("cloudinit.net.get_interfaces_by_mac"):
ns = self._parse_network_state_from_config(V2_CONFIG_MULTI_SUBNETS)
renderer = networkd.Renderer()
rendered_content = renderer._render_content(ns)
assert rendered_content["eth0"] == V2_CONFIG_MULTI_SUBNETS_RENDERED