|
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/cmd/devel/ |
Upload File : |
# This file is part of cloud-init. See LICENSE file for license information.
import itertools
import pytest
from cloudinit import safeyaml as yaml
from cloudinit.cmd.devel import net_convert
from cloudinit.distros.debian import NETWORK_FILE_HEADER
from tests.unittests.helpers import mock
M_PATH = "cloudinit.cmd.devel.net_convert."
required_args = [
"--directory",
"--network-data",
"--distro=ubuntu",
"--kind=eni",
"--output-kind=eni",
]
SAMPLE_NET_V1 = """\
network:
version: 1
config:
- type: physical
name: eth0
subnets:
- type: dhcp
"""
SAMPLE_NETPLAN_CONTENT = f"""\
{NETWORK_FILE_HEADER}network:
version: 2
ethernets:
eth0:
dhcp4: true
"""
SAMPLE_ENI_CONTENT = f"""\
{NETWORK_FILE_HEADER}auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
"""
SAMPLE_NETWORKD_CONTENT = """\
[Match]
Name=eth0
[Network]
DHCP=ipv4
"""
SAMPLE_SYSCONFIG_CONTENT = """\
# Created by cloud-init on instance boot automatically, do not edit.
#
BOOTPROTO=dhcp
DEVICE=eth0
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
"""
SAMPLE_NETWORK_MANAGER_CONTENT = """\
# Generated by cloud-init. Changes will be lost.
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
type=ethernet
interface-name=eth0
[user]
org.freedesktop.NetworkManager.origin=cloud-init
[ethernet]
[ipv4]
method=auto
may-fail=false
"""
class TestNetConvert:
missing_required_args = itertools.combinations(
required_args, len(required_args) - 1
)
def _replace_path_args(self, cmd, tmpdir):
"""Inject tmpdir replacements for parameterize args."""
updated_cmd = []
for arg in cmd:
if arg == "--network-data":
net_file = tmpdir.join("net")
net_file.write("")
updated_cmd.append(f"--network-data={net_file}")
elif arg == "--directory":
updated_cmd.append(f"--directory={tmpdir.strpath}")
else:
updated_cmd.append(arg)
return updated_cmd
@pytest.mark.parametrize("cmdargs", missing_required_args)
def test_argparse_error_on_missing_args(self, cmdargs, capsys, tmpdir):
"""Log the appropriate error when required args are missing."""
params = self._replace_path_args(cmdargs, tmpdir)
with mock.patch("sys.argv", ["net-convert"] + params):
with pytest.raises(SystemExit):
net_convert.get_parser().parse_args()
_out, err = capsys.readouterr()
assert "the following arguments are required" in err
@pytest.mark.parametrize("debug", (False, True))
@pytest.mark.parametrize(
"output_kind,outfile_content",
(
(
"netplan",
{"etc/netplan/50-cloud-init.yaml": SAMPLE_NETPLAN_CONTENT},
),
(
"eni",
{
"etc/network/interfaces.d/50-cloud-init.cfg": SAMPLE_ENI_CONTENT # noqa: E501
},
),
(
"networkd",
{
"etc/systemd/network/10-cloud-init-eth0.network": SAMPLE_NETWORKD_CONTENT # noqa: E501
},
),
(
"sysconfig",
{
"etc/sysconfig/network-scripts/ifcfg-eth0": SAMPLE_SYSCONFIG_CONTENT # noqa: E501
},
),
(
"network-manager",
{
"etc/NetworkManager/system-connections/cloud-init-eth0.nmconnection": SAMPLE_NETWORK_MANAGER_CONTENT # noqa: E501
},
),
),
)
def test_convert_output_kind_artifacts(
self, output_kind, outfile_content, debug, capsys, tmpdir
):
"""Assert proper output-kind artifacts are written."""
network_data = tmpdir.join("network_data")
network_data.write(SAMPLE_NET_V1)
distro = "centos" if output_kind == "sysconfig" else "ubuntu"
args = [
f"--directory={tmpdir.strpath}",
f"--network-data={network_data.strpath}",
f"--distro={distro}",
"--kind=yaml",
f"--output-kind={output_kind}",
]
if debug:
args.append("--debug")
params = self._replace_path_args(args, tmpdir)
with mock.patch("sys.argv", ["net-convert"] + params):
args = net_convert.get_parser().parse_args()
with mock.patch("cloudinit.util.chownbyname") as chown:
net_convert.handle_args("somename", args)
for path in outfile_content:
outfile = tmpdir.join(path)
assert outfile_content[path] == outfile.read()
if output_kind == "networkd":
assert [
mock.call(
outfile.strpath, "systemd-network", "systemd-network"
)
] == chown.call_args_list
@pytest.mark.parametrize("debug", (False, True))
def test_convert_netplan_passthrough(self, debug, tmpdir):
"""Assert that if the network config's version is 2 and the renderer is
Netplan, then the config is passed through as-is.
"""
network_data = tmpdir.join("network_data")
# `default` as a route supported by Netplan but not by cloud-init
content = """\
network:
version: 2
ethernets:
enp0s3:
dhcp4: false
addresses: [10.0.4.10/24]
nameservers:
addresses: [10.0.4.1]
routes:
- to: default
via: 10.0.4.1
metric: 100
"""
network_data.write(content)
args = [
"-m",
"enp0s3,AA",
f"--directory={tmpdir.strpath}",
f"--network-data={network_data.strpath}",
"--distro=ubuntu",
"--kind=yaml",
"--output-kind=netplan",
]
if debug:
args.append("--debug")
params = self._replace_path_args(args, tmpdir)
with mock.patch("sys.argv", ["net-convert"] + params):
args = net_convert.get_parser().parse_args()
with mock.patch("cloudinit.util.chownbyname"):
net_convert.handle_args("somename", args)
outfile = tmpdir.join("etc/netplan/50-cloud-init.yaml")
assert yaml.load(content) == yaml.load(outfile.read())
# vi: ts=4 expandtab