2237 lines
82 KiB
Python
Executable File
2237 lines
82 KiB
Python
Executable File
#!/usr/bin/env python
|
|
""" Tests for network_connections Ansible module """
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
import itertools
|
|
import os
|
|
import pprint as pprint_
|
|
import socket
|
|
import sys
|
|
import unittest
|
|
|
|
TESTS_BASEDIR = os.path.dirname(os.path.abspath(__file__))
|
|
sys.path.insert(1, os.path.join(TESTS_BASEDIR, "../..", "library"))
|
|
sys.path.insert(1, os.path.join(TESTS_BASEDIR, "../..", "module_utils"))
|
|
|
|
try:
|
|
from unittest import mock
|
|
except ImportError: # py2
|
|
import mock
|
|
|
|
sys.modules["ansible"] = mock.Mock()
|
|
sys.modules["ansible.module_utils.basic"] = mock.Mock()
|
|
sys.modules["ansible.module_utils"] = mock.Mock()
|
|
sys.modules["ansible.module_utils.network_lsr"] = __import__("network_lsr")
|
|
|
|
# pylint: disable=import-error, wrong-import-position
|
|
import network_lsr
|
|
import network_connections as n
|
|
|
|
from network_connections import SysUtil
|
|
from network_connections import Util
|
|
|
|
|
|
try:
|
|
my_test_skipIf = unittest.skipIf
|
|
except AttributeError:
|
|
# python 2.6 workaround
|
|
def my_test_skipIf(condition, reason):
|
|
if condition:
|
|
return lambda x: None
|
|
else:
|
|
return lambda x: x
|
|
|
|
|
|
try:
|
|
nmutil = n.NMUtil()
|
|
assert nmutil
|
|
except Exception:
|
|
# NMUtil is not supported, for example on RHEL 6 or without
|
|
# pygobject.
|
|
nmutil = None
|
|
|
|
if nmutil:
|
|
NM = n.Util.NM()
|
|
GObject = n.Util.GObject()
|
|
|
|
|
|
def pprint(msg, obj):
|
|
print("PRINT: %s\n" % (msg))
|
|
|
|
p = pprint_.PrettyPrinter(indent=4)
|
|
p.pprint(obj)
|
|
if nmutil is not None and isinstance(obj, NM.Connection):
|
|
obj.dump()
|
|
|
|
|
|
ARGS_CONNECTIONS = network_lsr.argument_validator.ArgValidator_ListConnections()
|
|
VALIDATE_ONE_MODE_INITSCRIPTS = ARGS_CONNECTIONS.VALIDATE_ONE_MODE_INITSCRIPTS
|
|
|
|
ETHTOOL_FEATURES_DEFAULTS = {
|
|
"esp-hw-offload": None,
|
|
"esp-tx-csum-hw-offload": None,
|
|
"fcoe-mtu": None,
|
|
"gro": None,
|
|
"gso": None,
|
|
"highdma": None,
|
|
"hw-tc-offload": None,
|
|
"l2-fwd-offload": None,
|
|
"loopback": None,
|
|
"lro": None,
|
|
"ntuple": None,
|
|
"rx": None,
|
|
"rx-all": None,
|
|
"rx-fcs": None,
|
|
"rx-gro-hw": None,
|
|
"rx-udp_tunnel-port-offload": None,
|
|
"rx-vlan-filter": None,
|
|
"rx-vlan-stag-filter": None,
|
|
"rx-vlan-stag-hw-parse": None,
|
|
"rxhash": None,
|
|
"rxvlan": None,
|
|
"sg": None,
|
|
"tls-hw-record": None,
|
|
"tls-hw-tx-offload": None,
|
|
"tso": None,
|
|
"tx": None,
|
|
"tx-checksum-fcoe-crc": None,
|
|
"tx-checksum-ip-generic": None,
|
|
"tx-checksum-ipv4": None,
|
|
"tx-checksum-ipv6": None,
|
|
"tx-checksum-sctp": None,
|
|
"tx-esp-segmentation": None,
|
|
"tx-fcoe-segmentation": None,
|
|
"tx-gre-csum-segmentation": None,
|
|
"tx-gre-segmentation": None,
|
|
"tx-gso-partial": None,
|
|
"tx-gso-robust": None,
|
|
"tx-ipxip4-segmentation": None,
|
|
"tx-ipxip6-segmentation": None,
|
|
"tx-nocache-copy": None,
|
|
"tx-scatter-gather": None,
|
|
"tx-scatter-gather-fraglist": None,
|
|
"tx-sctp-segmentation": None,
|
|
"tx-tcp-ecn-segmentation": None,
|
|
"tx-tcp-mangleid-segmentation": None,
|
|
"tx-tcp-segmentation": None,
|
|
"tx-tcp6-segmentation": None,
|
|
"tx-udp-segmentation": None,
|
|
"tx-udp_tnl-csum-segmentation": None,
|
|
"tx-udp_tnl-segmentation": None,
|
|
"tx-vlan-stag-hw-insert": None,
|
|
"txvlan": None,
|
|
}
|
|
|
|
ETHTOOL_DEFAULTS = {"features": ETHTOOL_FEATURES_DEFAULTS}
|
|
|
|
ETHERNET_DEFAULTS = {"autoneg": None, "duplex": None, "speed": 0}
|
|
|
|
|
|
class TestValidator(unittest.TestCase):
|
|
def setUp(self):
|
|
# default values when "type" is specified and state is not
|
|
self.default_connection_settings = {
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"ignore_errors": None,
|
|
"ip": {
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"route_metric4": None,
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"route_metric6": None,
|
|
"dhcp4_send_hostname": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "5",
|
|
"parent": None,
|
|
"slave_type": None,
|
|
"zone": None,
|
|
}
|
|
|
|
def assertValidationError(self, v, value):
|
|
self.assertRaises(n.ValidationError, v.validate, value)
|
|
|
|
def assert_nm_connection_routes_expected(self, connection, route_list_expected):
|
|
parser = network_lsr.argument_validator.ArgValidatorIPRoute("route[?]")
|
|
route_list_exp = [parser.validate(r) for r in route_list_expected]
|
|
route_list_new = itertools.chain(
|
|
nmutil.setting_ip_config_get_routes(
|
|
connection.get_setting(NM.SettingIP4Config)
|
|
),
|
|
nmutil.setting_ip_config_get_routes(
|
|
connection.get_setting(NM.SettingIP6Config)
|
|
),
|
|
)
|
|
route_list_new = [
|
|
{
|
|
"family": r.get_family(),
|
|
"network": r.get_dest(),
|
|
"prefix": int(r.get_prefix()),
|
|
"gateway": r.get_next_hop(),
|
|
"metric": int(r.get_metric()),
|
|
}
|
|
for r in route_list_new
|
|
]
|
|
self.assertEqual(route_list_exp, route_list_new)
|
|
|
|
def do_connections_check_invalid(self, input_connections):
|
|
self.assertValidationError(ARGS_CONNECTIONS, input_connections)
|
|
|
|
def do_connections_validate_nm(self, input_connections, **kwargs):
|
|
if not nmutil:
|
|
return
|
|
connections = ARGS_CONNECTIONS.validate(input_connections)
|
|
for connection in connections:
|
|
if "type" in connection:
|
|
connection["nm.exists"] = False
|
|
connection["nm.uuid"] = n.Util.create_uuid()
|
|
mode = VALIDATE_ONE_MODE_INITSCRIPTS
|
|
for idx, connection in enumerate(connections):
|
|
try:
|
|
ARGS_CONNECTIONS.validate_connection_one(mode, connections, idx)
|
|
except n.ValidationError:
|
|
continue
|
|
if "type" in connection:
|
|
con_new = nmutil.connection_create(connections, idx)
|
|
self.assertTrue(con_new)
|
|
self.assertTrue(con_new.verify())
|
|
if "nm_route_list_current" in kwargs:
|
|
parser = network_lsr.argument_validator.ArgValidatorIPRoute(
|
|
"route[?]"
|
|
)
|
|
s4 = con_new.get_setting(NM.SettingIP4Config)
|
|
s6 = con_new.get_setting(NM.SettingIP6Config)
|
|
s4.clear_routes()
|
|
s6.clear_routes()
|
|
for r in kwargs["nm_route_list_current"][idx]:
|
|
r = parser.validate(r)
|
|
r = NM.IPRoute.new(
|
|
r["family"],
|
|
r["network"],
|
|
r["prefix"],
|
|
r["gateway"],
|
|
r["metric"],
|
|
)
|
|
if r.get_family() == socket.AF_INET:
|
|
s4.add_route(r)
|
|
else:
|
|
s6.add_route(r)
|
|
con_new = nmutil.connection_create(
|
|
connections, idx, connection_current=con_new
|
|
)
|
|
self.assertTrue(con_new)
|
|
self.assertTrue(con_new.verify())
|
|
if "nm_route_list_expected" in kwargs:
|
|
self.assert_nm_connection_routes_expected(
|
|
con_new, kwargs["nm_route_list_expected"][idx]
|
|
)
|
|
|
|
def do_connections_validate_ifcfg(self, input_connections, **kwargs):
|
|
mode = VALIDATE_ONE_MODE_INITSCRIPTS
|
|
connections = ARGS_CONNECTIONS.validate(input_connections)
|
|
for idx, connection in enumerate(connections):
|
|
try:
|
|
ARGS_CONNECTIONS.validate_connection_one(mode, connections, idx)
|
|
except n.ValidationError:
|
|
continue
|
|
if "type" not in connection:
|
|
continue
|
|
if connection["type"] in ["macvlan"]:
|
|
# initscripts do not support this type. Skip the test.
|
|
continue
|
|
content_current = kwargs.get("initscripts_content_current", None)
|
|
if content_current:
|
|
content_current = content_current[idx]
|
|
c = n.IfcfgUtil.ifcfg_create(
|
|
connections, idx, content_current=content_current
|
|
)
|
|
# pprint("con[%s] = \"%s\"" % (idx, connections[idx]['name']), c)
|
|
exp = kwargs.get("initscripts_dict_expected", None)
|
|
if exp is not None:
|
|
self.assertEqual(exp[idx], c)
|
|
|
|
def do_connections_validate(
|
|
self, expected_connections, input_connections, **kwargs
|
|
):
|
|
connections = ARGS_CONNECTIONS.validate(input_connections)
|
|
self.assertEqual(expected_connections, connections)
|
|
self.do_connections_validate_nm(input_connections, **kwargs)
|
|
self.do_connections_validate_ifcfg(input_connections, **kwargs)
|
|
|
|
def test_validate_str(self):
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorStr("state")
|
|
self.assertEqual("a", v.validate("a"))
|
|
self.assertValidationError(v, 1)
|
|
self.assertValidationError(v, None)
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorStr("state", required=True)
|
|
self.assertValidationError(v, None)
|
|
|
|
def test_validate_int(self):
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorNum(
|
|
"state", default_value=None, numeric_type=float
|
|
)
|
|
self.assertEqual(1, v.validate(1))
|
|
self.assertEqual(1.5, v.validate(1.5))
|
|
self.assertEqual(1.5, v.validate("1.5"))
|
|
self.assertValidationError(v, None)
|
|
self.assertValidationError(v, "1a")
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorNum("state", default_value=None)
|
|
self.assertEqual(1, v.validate(1))
|
|
self.assertEqual(1, v.validate(1.0))
|
|
self.assertEqual(1, v.validate("1"))
|
|
self.assertValidationError(v, None)
|
|
self.assertValidationError(v, None)
|
|
self.assertValidationError(v, 1.5)
|
|
self.assertValidationError(v, "1.5")
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorNum("state", required=True)
|
|
self.assertValidationError(v, None)
|
|
|
|
def test_validate_bool(self):
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorBool("state")
|
|
self.assertEqual(True, v.validate("yes"))
|
|
self.assertEqual(True, v.validate("yeS"))
|
|
self.assertEqual(True, v.validate("Y"))
|
|
self.assertEqual(True, v.validate(True))
|
|
self.assertEqual(True, v.validate("True"))
|
|
self.assertEqual(True, v.validate("1"))
|
|
self.assertEqual(True, v.validate(1))
|
|
|
|
self.assertEqual(False, v.validate("no"))
|
|
self.assertEqual(False, v.validate("nO"))
|
|
self.assertEqual(False, v.validate("N"))
|
|
self.assertEqual(False, v.validate(False))
|
|
self.assertEqual(False, v.validate("False"))
|
|
self.assertEqual(False, v.validate("0"))
|
|
self.assertEqual(False, v.validate(0))
|
|
|
|
self.assertValidationError(v, 2)
|
|
self.assertValidationError(v, -1)
|
|
self.assertValidationError(v, "Ye")
|
|
self.assertValidationError(v, "")
|
|
self.assertValidationError(v, None)
|
|
v = network_lsr.argument_validator.ArgValidatorBool("state", required=True)
|
|
self.assertValidationError(v, None)
|
|
|
|
def test_validate_dict(self):
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorDict(
|
|
"dict",
|
|
nested=[
|
|
network_lsr.argument_validator.ArgValidatorNum("i", required=True),
|
|
network_lsr.argument_validator.ArgValidatorStr(
|
|
"s", required=False, default_value="s_default"
|
|
),
|
|
network_lsr.argument_validator.ArgValidatorStr(
|
|
"l",
|
|
required=False,
|
|
default_value=network_lsr.argument_validator.ArgValidator.MISSING,
|
|
),
|
|
],
|
|
)
|
|
|
|
self.assertEqual({"i": 5, "s": "s_default"}, v.validate({"i": "5"}))
|
|
self.assertEqual(
|
|
{"i": 5, "s": "s_default", "l": "6"}, v.validate({"i": "5", "l": "6"})
|
|
)
|
|
self.assertValidationError(v, {"k": 1})
|
|
|
|
def test_validate_list(self):
|
|
|
|
v = network_lsr.argument_validator.ArgValidatorList(
|
|
"list", nested=network_lsr.argument_validator.ArgValidatorNum("i")
|
|
)
|
|
self.assertEqual([1, 5], v.validate(["1", 5]))
|
|
self.assertValidationError(v, [1, "s"])
|
|
|
|
def test_empty(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate([], [])
|
|
|
|
def test_ethernet_two_defaults(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"ignore_errors": None,
|
|
"interface_name": "5",
|
|
"ip": {
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"route_metric4": None,
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"route_metric6": None,
|
|
"dhcp4_send_hostname": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "5",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": None,
|
|
"type": "ethernet",
|
|
"zone": None,
|
|
},
|
|
{
|
|
"actions": ["present"],
|
|
"ignore_errors": None,
|
|
"name": "5",
|
|
"persistent_state": "present",
|
|
"state": None,
|
|
},
|
|
],
|
|
[{"name": "5", "type": "ethernet"}, {"name": "5"}],
|
|
)
|
|
|
|
def test_up_ethernet(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "5",
|
|
"ip": {
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"route_metric4": None,
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"route_metric6": None,
|
|
"dhcp4_send_hostname": None,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "5",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[{"name": "5", "state": "up", "type": "ethernet"}],
|
|
)
|
|
|
|
def test_up_ethernet_no_autoconnect(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": False,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "5",
|
|
"ip": {
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"route_metric4": None,
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"route_metric6": None,
|
|
"dhcp4_send_hostname": None,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "5",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[{"name": "5", "state": "up", "type": "ethernet", "autoconnect": "no"}],
|
|
initscripts_dict_expected=[
|
|
{
|
|
"ifcfg": {
|
|
"BOOTPROTO": "dhcp",
|
|
"IPV6INIT": "yes",
|
|
"IPV6_AUTOCONF": "yes",
|
|
"NM_CONTROLLED": "no",
|
|
"ONBOOT": "no",
|
|
"TYPE": "Ethernet",
|
|
"DEVICE": "5",
|
|
},
|
|
"keys": None,
|
|
"route": None,
|
|
"route6": None,
|
|
"rule": None,
|
|
"rule6": None,
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_invalid_autoconnect(self):
|
|
self.maxDiff = None
|
|
self.do_connections_check_invalid([{"name": "a", "autoconnect": True}])
|
|
|
|
def test_absent(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["absent"],
|
|
"ignore_errors": None,
|
|
"name": "5",
|
|
"persistent_state": "absent",
|
|
"state": None,
|
|
}
|
|
],
|
|
[{"name": "5", "persistent_state": "absent"}],
|
|
)
|
|
|
|
def test_up_ethernet_mac_mtu_static_ip(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": None,
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": True,
|
|
"dns": [],
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.174.5",
|
|
}
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
},
|
|
"mac": "52:54:00:44:9f:ba",
|
|
"master": None,
|
|
"mtu": 1450,
|
|
"name": "prod1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "prod1",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"autoconnect": "yes",
|
|
"mac": "52:54:00:44:9f:ba",
|
|
"mtu": 1450,
|
|
"ip": {"address": "192.168.174.5/24"},
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_up_single_v4_dns(self):
|
|
self.maxDiff = None
|
|
# set single IPv4 DNS server
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "prod1",
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": True,
|
|
"dns": [{"address": "192.168.174.1", "family": socket.AF_INET}],
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.174.5",
|
|
}
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "prod1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "prod1",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"autoconnect": "yes",
|
|
"ip": {"address": "192.168.174.5/24", "dns": "192.168.174.1"},
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_routes(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": None,
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"auto6": True,
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.176.5",
|
|
},
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.177.5",
|
|
},
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"dns": [],
|
|
},
|
|
"mac": "52:54:00:44:9f:ba",
|
|
"master": None,
|
|
"mtu": 1450,
|
|
"name": "prod1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "prod.100",
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": False,
|
|
"dns": [],
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.174.5",
|
|
},
|
|
{
|
|
"prefix": 65,
|
|
"family": socket.AF_INET6,
|
|
"address": "a:b:c::6",
|
|
},
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.5.0",
|
|
"prefix": 24,
|
|
"gateway": None,
|
|
"metric": -1,
|
|
}
|
|
],
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "prod.100",
|
|
"parent": "prod1",
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "vlan",
|
|
"vlan": {"id": 100},
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
],
|
|
[
|
|
{
|
|
"name": "prod1",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"autoconnect": "yes",
|
|
"mac": "52:54:00:44:9f:ba",
|
|
"mtu": 1450,
|
|
"ip": {"address": "192.168.176.5/24 192.168.177.5/24"},
|
|
},
|
|
{
|
|
"name": "prod.100",
|
|
"state": "up",
|
|
"type": "vlan",
|
|
"parent": "prod1",
|
|
"vlan": {"id": "100"},
|
|
"ip": {
|
|
"address": [
|
|
"192.168.174.5/24",
|
|
{"address": "a:b:c::6", "prefix": 65},
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [{"network": "192.168.5.0"}],
|
|
},
|
|
},
|
|
],
|
|
)
|
|
|
|
def test_vlan(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": None,
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"auto6": True,
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.176.5",
|
|
},
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.177.5",
|
|
},
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"dns": [],
|
|
},
|
|
"mac": "52:54:00:44:9f:ba",
|
|
"master": None,
|
|
"mtu": 1450,
|
|
"name": "prod1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "prod.100",
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": False,
|
|
"dns": [],
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.174.5",
|
|
},
|
|
{
|
|
"prefix": 65,
|
|
"family": socket.AF_INET6,
|
|
"address": "a:b:c::6",
|
|
},
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.5.0",
|
|
"prefix": 24,
|
|
"gateway": None,
|
|
"metric": -1,
|
|
}
|
|
],
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "prod.100",
|
|
"parent": "prod1",
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "vlan",
|
|
"vlan": {"id": 101},
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
],
|
|
[
|
|
{
|
|
"name": "prod1",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"autoconnect": "yes",
|
|
"mac": "52:54:00:44:9f:ba",
|
|
"mtu": 1450,
|
|
"ip": {"address": "192.168.176.5/24 192.168.177.5/24"},
|
|
},
|
|
{
|
|
"name": "prod.100",
|
|
"state": "up",
|
|
"type": "vlan",
|
|
"parent": "prod1",
|
|
"vlan_id": 101,
|
|
"ip": {
|
|
"address": [
|
|
"192.168.174.5/24",
|
|
{"address": "a:b:c::6", "prefix": 65},
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [{"network": "192.168.5.0"}],
|
|
},
|
|
},
|
|
],
|
|
)
|
|
|
|
def test_macvlan(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "eth0",
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"auto6": False,
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.122.3",
|
|
}
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"dns": [],
|
|
},
|
|
"mac": "33:24:10:24:2f:b9",
|
|
"master": None,
|
|
"mtu": 1450,
|
|
"name": "eth0-parent",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "veth0",
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": False,
|
|
"dns": [],
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.244.1",
|
|
}
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.244.0",
|
|
"prefix": 24,
|
|
"gateway": None,
|
|
"metric": -1,
|
|
}
|
|
],
|
|
},
|
|
"mac": None,
|
|
"macvlan": {"mode": "bridge", "promiscuous": True, "tap": False},
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "veth0.0",
|
|
"parent": "eth0-parent",
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "macvlan",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "veth1",
|
|
"ip": {
|
|
"dhcp4": False,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": False,
|
|
"dns": [],
|
|
"address": [
|
|
{
|
|
"prefix": 24,
|
|
"family": socket.AF_INET,
|
|
"address": "192.168.245.7",
|
|
}
|
|
],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.245.0",
|
|
"prefix": 24,
|
|
"gateway": None,
|
|
"metric": -1,
|
|
}
|
|
],
|
|
},
|
|
"mac": None,
|
|
"macvlan": {"mode": "passthru", "promiscuous": False, "tap": True},
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "veth0.1",
|
|
"parent": "eth0-parent",
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "macvlan",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
],
|
|
[
|
|
{
|
|
"name": "eth0-parent",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"autoconnect": "yes",
|
|
"interface_name": "eth0",
|
|
"mac": "33:24:10:24:2f:b9",
|
|
"mtu": 1450,
|
|
"ip": {"address": "192.168.122.3/24", "auto6": False},
|
|
},
|
|
{
|
|
"name": "veth0.0",
|
|
"state": "up",
|
|
"type": "macvlan",
|
|
"parent": "eth0-parent",
|
|
"interface_name": "veth0",
|
|
"macvlan": {"mode": "bridge", "promiscuous": True, "tap": False},
|
|
"ip": {
|
|
"address": "192.168.244.1/24",
|
|
"auto6": False,
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [{"network": "192.168.244.0"}],
|
|
},
|
|
},
|
|
{
|
|
"name": "veth0.1",
|
|
"state": "up",
|
|
"type": "macvlan",
|
|
"parent": "eth0-parent",
|
|
"interface_name": "veth1",
|
|
"macvlan": {"mode": "passthru", "promiscuous": False, "tap": True},
|
|
"ip": {
|
|
"address": "192.168.245.7/24",
|
|
"auto6": False,
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [{"network": "192.168.245.0"}],
|
|
},
|
|
},
|
|
],
|
|
)
|
|
|
|
def test_bridge_no_dhcp4_auto6(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "bridge2",
|
|
"ip": {
|
|
"address": [],
|
|
"auto6": False,
|
|
"dhcp4": False,
|
|
"dhcp4_send_hostname": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"gateway4": None,
|
|
"gateway6": None,
|
|
"route": [],
|
|
"route_append_only": False,
|
|
"route_metric4": None,
|
|
"route_metric6": None,
|
|
"rule_append_only": False,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "prod2",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "bridge",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "eth1",
|
|
"ip": {
|
|
"address": [],
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"dhcp4_send_hostname": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"gateway4": None,
|
|
"gateway6": None,
|
|
"route": [],
|
|
"route_append_only": False,
|
|
"route_metric4": None,
|
|
"route_metric6": None,
|
|
"rule_append_only": False,
|
|
},
|
|
"mac": None,
|
|
"master": "prod2",
|
|
"mtu": None,
|
|
"name": "prod2-slave1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": "bridge",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
],
|
|
[
|
|
{
|
|
"name": "prod2",
|
|
"state": "up",
|
|
"type": "bridge",
|
|
"interface_name": "bridge2",
|
|
"ip": {"dhcp4": False, "auto6": False},
|
|
},
|
|
{
|
|
"name": "prod2-slave1",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"interface_name": "eth1",
|
|
"master": "prod2",
|
|
},
|
|
],
|
|
)
|
|
|
|
def test_bond(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"bond": {"mode": "balance-rr", "miimon": None},
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "bond1",
|
|
"ip": {
|
|
"dhcp4": True,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": True,
|
|
"dns": [],
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "bond1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "bond",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[{"name": "bond1", "state": "up", "type": "bond"}],
|
|
)
|
|
|
|
def test_bond_active_backup(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"bond": {"mode": "active-backup", "miimon": None},
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "bond1",
|
|
"ip": {
|
|
"dhcp4": True,
|
|
"route_metric6": None,
|
|
"route_metric4": None,
|
|
"dns_search": [],
|
|
"dhcp4_send_hostname": None,
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"auto6": True,
|
|
"dns": [],
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "bond1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "bond",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "bond1",
|
|
"state": "up",
|
|
"type": "bond",
|
|
"bond": {"mode": "active-backup"},
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_invalid_values(self):
|
|
self.maxDiff = None
|
|
self.do_connections_check_invalid([{}])
|
|
self.do_connections_check_invalid([{"name": "b", "xxx": 5}])
|
|
|
|
def test_ethernet_mac_address(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"ignore_errors": None,
|
|
"interface_name": None,
|
|
"ip": {
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"dhcp4_send_hostname": None,
|
|
"gateway4": None,
|
|
"gateway6": None,
|
|
"route_metric4": None,
|
|
"route_metric6": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
},
|
|
"mac": "aa:bb:cc:dd:ee:ff",
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "5",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": None,
|
|
"type": "ethernet",
|
|
"zone": None,
|
|
}
|
|
],
|
|
[{"name": "5", "type": "ethernet", "mac": "AA:bb:cC:DD:ee:FF"}],
|
|
)
|
|
|
|
def test_ethernet_speed_settings(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": {"autoneg": False, "duplex": "half", "speed": 400},
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "5",
|
|
"ip": {
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"route_metric4": None,
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [],
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"route_metric6": None,
|
|
"dhcp4_send_hostname": None,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "5",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "5",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"ip": {},
|
|
"ethernet": {"duplex": "half", "speed": 400},
|
|
}
|
|
],
|
|
initscripts_dict_expected=[
|
|
{
|
|
"ifcfg": {
|
|
"BOOTPROTO": "dhcp",
|
|
"ETHTOOL_OPTS": "autoneg off speed 400 duplex half",
|
|
"IPV6INIT": "yes",
|
|
"IPV6_AUTOCONF": "yes",
|
|
"NM_CONTROLLED": "no",
|
|
"ONBOOT": "yes",
|
|
"TYPE": "Ethernet",
|
|
"DEVICE": "5",
|
|
},
|
|
"keys": None,
|
|
"route": None,
|
|
"route6": None,
|
|
"rule": None,
|
|
"rule6": None,
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_bridge2(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "6643-master",
|
|
"ip": {
|
|
"address": [],
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"dhcp4_send_hostname": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"gateway4": None,
|
|
"gateway6": None,
|
|
"route": [],
|
|
"route_append_only": False,
|
|
"route_metric4": None,
|
|
"route_metric6": None,
|
|
"rule_append_only": False,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "6643-master",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "bridge",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "6643",
|
|
"ip": {
|
|
"address": [],
|
|
"auto6": True,
|
|
"dhcp4_send_hostname": None,
|
|
"dhcp4": True,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"gateway4": None,
|
|
"gateway6": None,
|
|
"route": [],
|
|
"route_append_only": False,
|
|
"route_metric4": None,
|
|
"route_metric6": None,
|
|
"rule_append_only": False,
|
|
},
|
|
"mac": None,
|
|
"master": "6643-master",
|
|
"mtu": None,
|
|
"name": "6643",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": "bridge",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
},
|
|
],
|
|
[
|
|
{"name": "6643-master", "state": "up", "type": "bridge"},
|
|
{
|
|
"name": "6643",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"master": "6643-master",
|
|
},
|
|
],
|
|
)
|
|
|
|
def test_infiniband(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"infiniband": {"p_key": -1, "transport_mode": "datagram"},
|
|
"interface_name": None,
|
|
"ip": {
|
|
"address": [],
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"dhcp4_send_hostname": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"gateway4": None,
|
|
"gateway6": None,
|
|
"route": [],
|
|
"route_append_only": False,
|
|
"route_metric4": None,
|
|
"route_metric6": None,
|
|
"rule_append_only": False,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "infiniband.1",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "infiniband",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "infiniband.1",
|
|
"interface_name": "",
|
|
"state": "up",
|
|
"type": "infiniband",
|
|
}
|
|
],
|
|
initscripts_dict_expected=[
|
|
{
|
|
"ifcfg": {
|
|
"BOOTPROTO": "dhcp",
|
|
"CONNECTED_MODE": "no",
|
|
"IPV6INIT": "yes",
|
|
"IPV6_AUTOCONF": "yes",
|
|
"NM_CONTROLLED": "no",
|
|
"ONBOOT": "yes",
|
|
"TYPE": "InfiniBand",
|
|
},
|
|
"keys": None,
|
|
"route": None,
|
|
"route6": None,
|
|
"rule": None,
|
|
"rule6": None,
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_infiniband2(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"infiniband": {"p_key": 5, "transport_mode": "datagram"},
|
|
"interface_name": None,
|
|
"ip": {
|
|
"address": [],
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"dhcp4_send_hostname": None,
|
|
"dns": [],
|
|
"dns_search": [],
|
|
"gateway4": None,
|
|
"gateway6": None,
|
|
"route": [],
|
|
"route_append_only": False,
|
|
"route_metric4": None,
|
|
"route_metric6": None,
|
|
"rule_append_only": False,
|
|
},
|
|
"mac": "11:22:33:44:55:66:77:88:99:00:"
|
|
"11:22:33:44:55:66:77:88:99:00",
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "infiniband.2",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "infiniband",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "infiniband.2",
|
|
"state": "up",
|
|
"type": "infiniband",
|
|
"mac": "11:22:33:44:55:66:77:88:99:00:"
|
|
"11:22:33:44:55:66:77:88:99:00",
|
|
"infiniband_p_key": 5,
|
|
}
|
|
],
|
|
initscripts_dict_expected=[
|
|
{
|
|
"ifcfg": {
|
|
"BOOTPROTO": "dhcp",
|
|
"CONNECTED_MODE": "no",
|
|
"HWADDR": "11:22:33:44:55:66:77:88:99:00:"
|
|
"11:22:33:44:55:66:77:88:99:00",
|
|
"IPV6INIT": "yes",
|
|
"IPV6_AUTOCONF": "yes",
|
|
"NM_CONTROLLED": "no",
|
|
"ONBOOT": "yes",
|
|
"PKEY": "yes",
|
|
"PKEY_ID": "5",
|
|
"TYPE": "InfiniBand",
|
|
},
|
|
"keys": None,
|
|
"route": None,
|
|
"route6": None,
|
|
"rule": None,
|
|
"rule6": None,
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_route_metric_prefix(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "555",
|
|
"ip": {
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"route_metric4": None,
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"address": [],
|
|
"route_append_only": False,
|
|
"rule_append_only": False,
|
|
"route": [
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.45.0",
|
|
"prefix": 24,
|
|
"gateway": None,
|
|
"metric": 545,
|
|
},
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.46.0",
|
|
"prefix": 30,
|
|
"gateway": None,
|
|
"metric": -1,
|
|
},
|
|
],
|
|
"dns": [],
|
|
"dns_search": ["aa", "bb"],
|
|
"route_metric6": None,
|
|
"dhcp4_send_hostname": None,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "555",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": None,
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "555",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"ip": {
|
|
"dns_search": ["aa", "bb"],
|
|
"route": [
|
|
{"network": "192.168.45.0", "metric": 545},
|
|
{"network": "192.168.46.0", "prefix": 30},
|
|
],
|
|
},
|
|
}
|
|
],
|
|
initscripts_dict_expected=[
|
|
{
|
|
"ifcfg": {
|
|
"BOOTPROTO": "dhcp",
|
|
"DOMAIN": "aa bb",
|
|
"IPV6INIT": "yes",
|
|
"IPV6_AUTOCONF": "yes",
|
|
"NM_CONTROLLED": "no",
|
|
"ONBOOT": "yes",
|
|
"TYPE": "Ethernet",
|
|
"DEVICE": "555",
|
|
},
|
|
"keys": None,
|
|
"route": "192.168.45.0/24 metric 545\n192.168.46.0/30\n",
|
|
"route6": None,
|
|
"rule": None,
|
|
"rule6": None,
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_route_v6(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present", "up"],
|
|
"autoconnect": True,
|
|
"check_iface_exists": True,
|
|
"ethernet": ETHERNET_DEFAULTS,
|
|
"ethtool": ETHTOOL_DEFAULTS,
|
|
"force_state_change": None,
|
|
"ignore_errors": None,
|
|
"interface_name": "e556",
|
|
"ip": {
|
|
"gateway6": None,
|
|
"gateway4": None,
|
|
"route_metric4": None,
|
|
"auto6": True,
|
|
"dhcp4": True,
|
|
"address": [],
|
|
"route_append_only": True,
|
|
"rule_append_only": False,
|
|
"route": [
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.45.0",
|
|
"prefix": 24,
|
|
"gateway": None,
|
|
"metric": 545,
|
|
},
|
|
{
|
|
"family": socket.AF_INET,
|
|
"network": "192.168.46.0",
|
|
"prefix": 30,
|
|
"gateway": None,
|
|
"metric": -1,
|
|
},
|
|
{
|
|
"family": socket.AF_INET6,
|
|
"network": "a:b:c:d::",
|
|
"prefix": 64,
|
|
"gateway": None,
|
|
"metric": -1,
|
|
},
|
|
],
|
|
"dns": [],
|
|
"dns_search": ["aa", "bb"],
|
|
"route_metric6": None,
|
|
"dhcp4_send_hostname": None,
|
|
},
|
|
"mac": None,
|
|
"master": None,
|
|
"mtu": None,
|
|
"name": "e556",
|
|
"parent": None,
|
|
"persistent_state": "present",
|
|
"slave_type": None,
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"wait": None,
|
|
"zone": "external",
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"name": "e556",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
"zone": "external",
|
|
"ip": {
|
|
"dns_search": ["aa", "bb"],
|
|
"route_append_only": True,
|
|
"rule_append_only": False,
|
|
"route": [
|
|
{"network": "192.168.45.0", "metric": 545},
|
|
{"network": "192.168.46.0", "prefix": 30},
|
|
{"network": "a:b:c:d::"},
|
|
],
|
|
},
|
|
}
|
|
],
|
|
nm_route_list_current=[
|
|
[
|
|
{"network": "192.168.40.0", "prefix": 24, "metric": 545},
|
|
{"network": "192.168.46.0", "prefix": 30},
|
|
{"network": "a:b:c:f::"},
|
|
]
|
|
],
|
|
nm_route_list_expected=[
|
|
[
|
|
{"network": "192.168.40.0", "prefix": 24, "metric": 545},
|
|
{"network": "192.168.46.0", "prefix": 30},
|
|
{"network": "192.168.45.0", "prefix": 24, "metric": 545},
|
|
{"network": "a:b:c:f::"},
|
|
{"network": "a:b:c:d::"},
|
|
]
|
|
],
|
|
initscripts_content_current=[
|
|
{
|
|
"ifcfg": "",
|
|
"keys": None,
|
|
"route": "192.168.40.0/24 metric 545\n192.168.46.0/30",
|
|
"route6": "a:b:c:f::/64",
|
|
"rule": None,
|
|
"rule6": None,
|
|
}
|
|
],
|
|
initscripts_dict_expected=[
|
|
{
|
|
"ifcfg": {
|
|
"BOOTPROTO": "dhcp",
|
|
"DOMAIN": "aa bb",
|
|
"IPV6INIT": "yes",
|
|
"IPV6_AUTOCONF": "yes",
|
|
"NM_CONTROLLED": "no",
|
|
"ONBOOT": "yes",
|
|
"TYPE": "Ethernet",
|
|
"ZONE": "external",
|
|
"DEVICE": "e556",
|
|
},
|
|
"keys": None,
|
|
"route": "192.168.40.0/24 metric 545\n192.168.46.0/30\n"
|
|
"192.168.45.0/24 metric 545\n",
|
|
"route6": "a:b:c:f::/64\na:b:c:d::/64\n",
|
|
"rule": None,
|
|
"rule6": None,
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_invalid_mac(self):
|
|
self.maxDiff = None
|
|
self.do_connections_check_invalid(
|
|
[{"name": "b", "type": "ethernet", "mac": "aa:b"}]
|
|
)
|
|
|
|
def test_interface_name_ethernet_default(self):
|
|
""" Use the profile name as interface_name for ethernet profiles """
|
|
cons_without_interface_name = [{"name": "eth0", "type": "ethernet"}]
|
|
connections = ARGS_CONNECTIONS.validate(cons_without_interface_name)
|
|
self.assertTrue(connections[0]["interface_name"] == "eth0")
|
|
|
|
def test_interface_name_ethernet_mac(self):
|
|
""" Do not set interface_name when mac is specified """
|
|
cons_without_interface_name = [
|
|
{"name": "eth0", "type": "ethernet", "mac": "3b:0b:88:16:6d:1a"}
|
|
]
|
|
connections = ARGS_CONNECTIONS.validate(cons_without_interface_name)
|
|
self.assertTrue(connections[0]["interface_name"] is None)
|
|
|
|
def test_interface_name_ethernet_empty(self):
|
|
""" Allow not to restrict the profile to an interface """
|
|
network_connections = [
|
|
{"name": "internal_network", "type": "ethernet", "interface_name": ""}
|
|
]
|
|
connections = ARGS_CONNECTIONS.validate(network_connections)
|
|
|
|
self.assertTrue(connections[0]["interface_name"] is None)
|
|
|
|
def test_interface_name_ethernet_None(self):
|
|
""" Check that interface_name cannot be None """
|
|
network_connections = [
|
|
{"name": "internal_network", "type": "ethernet", "interface_name": None}
|
|
]
|
|
self.assertRaises(
|
|
n.ValidationError, ARGS_CONNECTIONS.validate, network_connections
|
|
)
|
|
|
|
def test_interface_name_ethernet_explicit(self):
|
|
""" Use the explicitly provided interface name """
|
|
network_connections = [
|
|
{"name": "internal", "type": "ethernet", "interface_name": "eth0"}
|
|
]
|
|
connections = ARGS_CONNECTIONS.validate(network_connections)
|
|
self.assertEqual(connections[0]["interface_name"], "eth0")
|
|
|
|
def test_interface_name_ethernet_invalid_profile(self):
|
|
""" Require explicit interface_name when the profile name is not a
|
|
valid interface_name """
|
|
network_connections = [{"name": "internal:main", "type": "ethernet"}]
|
|
self.assertRaises(
|
|
n.ValidationError, ARGS_CONNECTIONS.validate, network_connections
|
|
)
|
|
network_connections = [
|
|
{"name": "internal:main", "type": "ethernet", "interface_name": "eth0"}
|
|
]
|
|
connections = ARGS_CONNECTIONS.validate(network_connections)
|
|
self.assertTrue(connections[0]["interface_name"] == "eth0")
|
|
|
|
def test_interface_name_ethernet_invalid_interface_name(self):
|
|
network_connections = [
|
|
{"name": "internal", "type": "ethernet", "interface_name": "invalid:name"}
|
|
]
|
|
self.assertRaises(
|
|
n.ValidationError, ARGS_CONNECTIONS.validate, network_connections
|
|
)
|
|
|
|
def test_interface_name_bond_empty_interface_name(self):
|
|
network_connections = [
|
|
{"name": "internal", "type": "bond", "interface_name": "invalid:name"}
|
|
]
|
|
self.assertRaises(
|
|
n.ValidationError, ARGS_CONNECTIONS.validate, network_connections
|
|
)
|
|
|
|
def test_interface_name_bond_profile_as_interface_name(self):
|
|
network_connections = [{"name": "internal", "type": "bond"}]
|
|
connections = ARGS_CONNECTIONS.validate(network_connections)
|
|
self.assertEqual(connections[0]["interface_name"], "internal")
|
|
|
|
def check_connection(self, connection, expected):
|
|
reduced_connection = {}
|
|
for setting in expected:
|
|
reduced_connection[setting] = connection[setting]
|
|
self.assertEqual(reduced_connection, expected)
|
|
|
|
def check_partial_connection_zero(self, network_config, expected):
|
|
connections = ARGS_CONNECTIONS.validate([network_config])
|
|
self.check_connection(connections[0], expected)
|
|
|
|
def check_one_connection_with_defaults(
|
|
self, network_config, expected_changed_settings
|
|
):
|
|
self.maxDiff = None
|
|
expected = self.default_connection_settings
|
|
expected.update(expected_changed_settings)
|
|
|
|
self.do_connections_validate([expected], [network_config])
|
|
|
|
def test_default_states(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0"},
|
|
{"actions": ["present"], "persistent_state": "present", "state": None},
|
|
)
|
|
|
|
def test_invalid_persistent_state_up(self):
|
|
network_connections = [{"name": "internal", "persistent_state": "up"}]
|
|
self.assertRaises(
|
|
n.ValidationError, ARGS_CONNECTIONS.validate, network_connections
|
|
)
|
|
|
|
def test_invalid_persistent_state_down(self):
|
|
network_connections = [{"name": "internal", "persistent_state": "down"}]
|
|
self.assertRaises(
|
|
n.ValidationError, ARGS_CONNECTIONS.validate, network_connections
|
|
)
|
|
|
|
def test_invalid_state_test(self):
|
|
network_connections = [{"name": "internal", "state": "test"}]
|
|
self.assertRaises(
|
|
n.ValidationError, ARGS_CONNECTIONS.validate, network_connections
|
|
)
|
|
|
|
def test_default_states_type(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "type": "ethernet"},
|
|
{"actions": ["present"], "persistent_state": "present", "state": None},
|
|
)
|
|
|
|
def test_persistent_state_present(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "persistent_state": "present", "type": "ethernet"},
|
|
{"actions": ["present"], "persistent_state": "present", "state": None},
|
|
)
|
|
|
|
def test_state_present(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "state": "present", "type": "ethernet"},
|
|
{"actions": ["present"], "persistent_state": "present", "state": None},
|
|
)
|
|
|
|
def test_state_absent(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "state": "absent"},
|
|
{"actions": ["absent"], "persistent_state": "absent", "state": None},
|
|
)
|
|
|
|
def test_persistent_state_absent(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "persistent_state": "absent"},
|
|
{"actions": ["absent"], "persistent_state": "absent", "state": None},
|
|
)
|
|
|
|
def test_state_present_up(self):
|
|
self.check_partial_connection_zero(
|
|
{
|
|
"name": "eth0",
|
|
"persistent_state": "present",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"persistent_state": "present",
|
|
"state": "up",
|
|
},
|
|
)
|
|
|
|
def test_state_present_down(self):
|
|
self.check_partial_connection_zero(
|
|
{
|
|
"name": "eth0",
|
|
"persistent_state": "present",
|
|
"state": "down",
|
|
"type": "ethernet",
|
|
},
|
|
{
|
|
"actions": ["present", "down"],
|
|
"persistent_state": "present",
|
|
"state": "down",
|
|
},
|
|
)
|
|
|
|
def test_state_absent_up_no_type(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "persistent_state": "absent", "state": "up"},
|
|
{
|
|
"actions": ["present", "up", "absent"],
|
|
"persistent_state": "absent",
|
|
"state": "up",
|
|
},
|
|
)
|
|
|
|
def test_state_absent_up_type(self):
|
|
# if type is specified, present should happen, too
|
|
self.check_partial_connection_zero(
|
|
{
|
|
"name": "eth0",
|
|
"persistent_state": "absent",
|
|
"state": "up",
|
|
"type": "ethernet",
|
|
},
|
|
{
|
|
"actions": ["present", "up", "absent"],
|
|
"persistent_state": "absent",
|
|
"state": "up",
|
|
},
|
|
)
|
|
|
|
def test_state_absent_down(self):
|
|
# if type is specified, present should happen, too
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "persistent_state": "absent", "state": "down"},
|
|
{
|
|
"actions": ["present", "down", "absent"],
|
|
"persistent_state": "absent",
|
|
"state": "down",
|
|
},
|
|
)
|
|
|
|
def test_state_up_no_type(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "state": "up"},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"persistent_state": "present",
|
|
"state": "up",
|
|
},
|
|
)
|
|
|
|
def test_state_up_type(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "state": "up", "type": "ethernet"},
|
|
{
|
|
"actions": ["present", "up"],
|
|
"persistent_state": "present",
|
|
"state": "up",
|
|
},
|
|
)
|
|
|
|
def test_state_down_no_type(self):
|
|
self.check_partial_connection_zero(
|
|
{"name": "eth0", "state": "down"},
|
|
{
|
|
"actions": ["present", "down"],
|
|
"persistent_state": "present",
|
|
"state": "down",
|
|
},
|
|
)
|
|
|
|
def test_full_state_present_no_type(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["present"],
|
|
"ignore_errors": None,
|
|
"name": "eth0",
|
|
"state": None,
|
|
"persistent_state": "present",
|
|
}
|
|
],
|
|
[{"name": "eth0", "persistent_state": "present"}],
|
|
)
|
|
|
|
def test_full_state_present_type_defaults(self):
|
|
self.check_one_connection_with_defaults(
|
|
{"name": "eth0", "type": "ethernet", "persistent_state": "present"},
|
|
{
|
|
"actions": ["present"],
|
|
"interface_name": "eth0",
|
|
"name": "eth0",
|
|
"persistent_state": "present",
|
|
"state": None,
|
|
"type": "ethernet",
|
|
},
|
|
)
|
|
|
|
def test_full_state_absent_no_type(self):
|
|
self.maxDiff = None
|
|
self.do_connections_validate(
|
|
[
|
|
{
|
|
"actions": ["absent"],
|
|
"ignore_errors": None,
|
|
"name": "eth0",
|
|
"state": None,
|
|
"persistent_state": "absent",
|
|
}
|
|
],
|
|
[{"name": "eth0", "persistent_state": "absent"}],
|
|
)
|
|
|
|
def test_full_state_absent_defaults(self):
|
|
self.maxDiff = None
|
|
self.check_one_connection_with_defaults(
|
|
{"name": "eth0", "persistent_state": "absent", "type": "ethernet"},
|
|
{
|
|
"actions": ["absent"],
|
|
"ignore_errors": None,
|
|
"name": "eth0",
|
|
"state": None,
|
|
"persistent_state": "absent",
|
|
"type": "ethernet",
|
|
"interface_name": "eth0",
|
|
},
|
|
)
|
|
|
|
|
|
@my_test_skipIf(nmutil is None, "no support for NM (libnm via pygobject)")
|
|
class TestNM(unittest.TestCase):
|
|
def test_connection_ensure_setting(self):
|
|
con = NM.SimpleConnection.new()
|
|
self.assertIsNotNone(con)
|
|
self.assertTrue(GObject.type_is_a(con, NM.Connection))
|
|
|
|
s = nmutil.connection_ensure_setting(con, NM.SettingWired)
|
|
self.assertIsNotNone(s)
|
|
self.assertTrue(GObject.type_is_a(s, NM.SettingWired))
|
|
|
|
s2 = nmutil.connection_ensure_setting(con, NM.SettingWired)
|
|
self.assertIsNotNone(s2)
|
|
self.assertIs(s, s2)
|
|
self.assertTrue(GObject.type_is_a(s, NM.SettingWired))
|
|
|
|
def test_connection_list(self):
|
|
connections = nmutil.connection_list()
|
|
self.assertIsNotNone(connections)
|
|
|
|
|
|
class TestUtils(unittest.TestCase):
|
|
def test_check_output(self):
|
|
res = Util.check_output(["echo", "test"])
|
|
self.assertEqual(res, "test\n")
|
|
self.assertRaises(n.MyError, Util.check_output, ["false"])
|
|
|
|
|
|
class TestSysUtils(unittest.TestCase):
|
|
def test_link_read_permaddress(self):
|
|
# Manipulate PATH to use ethtool mock script to avoid hard dependency on
|
|
# ethtool
|
|
os.environ["PATH"] = TESTS_BASEDIR + "/helpers:" + os.environ["PATH"]
|
|
self.assertEqual(SysUtil._link_read_permaddress("lo"), "23:00:00:00:00:00")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|