mirror of
https://github.com/linux-system-roles/network.git
synced 2026-01-23 10:25:28 +00:00
Use profile name for interface name by default
* by default ```name``` is used as ```interface_name``` * if ```interface_name``` is set to the empty string, it will not be set * if ```mac``` is specified, ```interface_name``` defaults to not being set This fixes #41
This commit is contained in:
parent
64879e74d9
commit
6bf70bcf60
3 changed files with 130 additions and 26 deletions
16
README.md
16
README.md
|
|
@ -151,18 +151,22 @@ to match a non-virtual device with the profile.
|
|||
|
||||
### `interface_name`
|
||||
|
||||
For type `ethernet`, this option restricts the profile to the
|
||||
given interface by name. This argument is optional and by default
|
||||
a profile is not restricted to any interface by name.
|
||||
Note that with [persistent interface naming](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/ch-Consistent_Network_Device_Naming.html),
|
||||
For type `ethernet`, this option restricts the profile to the given interface
|
||||
by name. This argument is optional and by default the profile name is used
|
||||
unless a mac address is specified using the `mac` key. Specifying an empty
|
||||
string (`""`) allows to specify that the profile is not restricted to a network
|
||||
interface.
|
||||
|
||||
|
||||
**Note:** With [persistent interface naming](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/ch-Consistent_Network_Device_Naming.html),
|
||||
the interface is predictable based on the hardware configuration.
|
||||
Otherwise, the `mac` address might be an option.
|
||||
|
||||
For virtual interface types like bridges, this argument is the name of the created
|
||||
interface. In case of a missing `interface_name`, the profile name `name` is used.
|
||||
|
||||
Note the destinction between the profile name `name` and the device
|
||||
name `interface_name`, which may or may not be the same.
|
||||
**Note:** The profile name `name` and the device name `interface_name` may be
|
||||
different or the profile may not be tied to an interface at all.
|
||||
|
||||
### `zone`
|
||||
|
||||
|
|
|
|||
|
|
@ -1080,7 +1080,7 @@ class ArgValidator_DictConnection(ArgValidatorDict):
|
|||
enum_values=ArgValidator_DictConnection.VALID_SLAVE_TYPES,
|
||||
),
|
||||
ArgValidatorStr("master"),
|
||||
ArgValidatorStr("interface_name"),
|
||||
ArgValidatorStr("interface_name", allow_empty=True),
|
||||
ArgValidatorMac("mac"),
|
||||
ArgValidatorNum(
|
||||
"mtu", val_min=0, val_max=0xFFFFFFFF, default_value=None
|
||||
|
|
@ -1291,21 +1291,36 @@ class ArgValidator_DictConnection(ArgValidatorDict):
|
|||
)
|
||||
|
||||
if "interface_name" in result:
|
||||
if not Util.ifname_valid(result["interface_name"]):
|
||||
# Ignore empty interface_name
|
||||
if result["interface_name"] == "":
|
||||
del result["interface_name"]
|
||||
elif not Util.ifname_valid(result["interface_name"]):
|
||||
raise ValidationError(
|
||||
name + ".interface_name",
|
||||
"invalid 'interface_name' '%s'" % (result["interface_name"]),
|
||||
)
|
||||
else:
|
||||
if result["type"] in ["bridge", "bond", "team", "vlan", "macvlan"]:
|
||||
if not result.get("mac"):
|
||||
if not Util.ifname_valid(result["name"]):
|
||||
raise ValidationError(
|
||||
name + ".interface_name",
|
||||
'requires \'interface_name\' as "name" "%s" is not valid'
|
||||
'\'interface_name\' as "name" "%s" is not valid'
|
||||
% (result["name"]),
|
||||
)
|
||||
result["interface_name"] = result["name"]
|
||||
|
||||
if "interface_name" not in result and result["type"] in [
|
||||
"bond",
|
||||
"bridge",
|
||||
"macvlan",
|
||||
"team",
|
||||
"vlan",
|
||||
]:
|
||||
raise ValidationError(
|
||||
name + ".interface_name",
|
||||
"type '%s' requires 'interface_name'" % (result["type"]),
|
||||
)
|
||||
|
||||
if result["type"] == "vlan":
|
||||
if "vlan" not in result:
|
||||
if "vlan_id" not in result:
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
""" Tests for network_connections Ansible module """
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import sys
|
||||
import os
|
||||
import unittest
|
||||
import socket
|
||||
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"))
|
||||
|
|
@ -43,9 +44,8 @@ if nmutil:
|
|||
|
||||
def pprint(msg, obj):
|
||||
print("PRINT: %s\n" % (msg))
|
||||
import pprint
|
||||
|
||||
p = pprint.PrettyPrinter(indent=4)
|
||||
p = pprint_.PrettyPrinter(indent=4)
|
||||
p.pprint(obj)
|
||||
if nmutil is not None and isinstance(obj, NM.Connection):
|
||||
obj.dump()
|
||||
|
|
@ -281,7 +281,7 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": None,
|
||||
"master": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "5",
|
||||
"check_iface_exists": True,
|
||||
"slave_type": None,
|
||||
},
|
||||
|
|
@ -324,7 +324,7 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": None,
|
||||
"master": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "5",
|
||||
"check_iface_exists": True,
|
||||
"force_state_change": None,
|
||||
"slave_type": None,
|
||||
|
|
@ -362,7 +362,7 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": None,
|
||||
"master": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "5",
|
||||
"check_iface_exists": True,
|
||||
"force_state_change": None,
|
||||
"slave_type": None,
|
||||
|
|
@ -379,6 +379,7 @@ class TestValidator(unittest.TestCase):
|
|||
"NM_CONTROLLED": "no",
|
||||
"ONBOOT": "no",
|
||||
"TYPE": "Ethernet",
|
||||
"DEVICE": "5",
|
||||
},
|
||||
"keys": None,
|
||||
"route": None,
|
||||
|
|
@ -488,7 +489,7 @@ class TestValidator(unittest.TestCase):
|
|||
"master": None,
|
||||
"mtu": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "prod1",
|
||||
"type": "ethernet",
|
||||
"slave_type": None,
|
||||
"wait": None,
|
||||
|
|
@ -1185,7 +1186,7 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": None,
|
||||
"master": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "5",
|
||||
"check_iface_exists": True,
|
||||
"force_state_change": None,
|
||||
"slave_type": None,
|
||||
|
|
@ -1224,7 +1225,7 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": None,
|
||||
"master": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "5",
|
||||
"check_iface_exists": True,
|
||||
"force_state_change": None,
|
||||
"slave_type": None,
|
||||
|
|
@ -1250,6 +1251,7 @@ class TestValidator(unittest.TestCase):
|
|||
"NM_CONTROLLED": "no",
|
||||
"ONBOOT": "yes",
|
||||
"TYPE": "Ethernet",
|
||||
"DEVICE": "5",
|
||||
},
|
||||
"keys": None,
|
||||
"route": None,
|
||||
|
|
@ -1301,7 +1303,7 @@ class TestValidator(unittest.TestCase):
|
|||
"ethernet": {"autoneg": None, "duplex": None, "speed": 0},
|
||||
"force_state_change": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "6643",
|
||||
"ip": {
|
||||
"address": [],
|
||||
"auto6": True,
|
||||
|
|
@ -1376,7 +1378,14 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": None,
|
||||
}
|
||||
],
|
||||
[{"name": "infiniband.1", "state": "up", "type": "infiniband"}],
|
||||
[
|
||||
{
|
||||
"name": "infiniband.1",
|
||||
"interface_name": "",
|
||||
"state": "up",
|
||||
"type": "infiniband",
|
||||
}
|
||||
],
|
||||
initscripts_dict_expected=[
|
||||
{
|
||||
"ifcfg": {
|
||||
|
|
@ -1512,7 +1521,7 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": None,
|
||||
"master": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "555",
|
||||
"check_iface_exists": True,
|
||||
"force_state_change": None,
|
||||
"slave_type": None,
|
||||
|
|
@ -1543,6 +1552,7 @@ class TestValidator(unittest.TestCase):
|
|||
"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",
|
||||
|
|
@ -1604,7 +1614,7 @@ class TestValidator(unittest.TestCase):
|
|||
"zone": "external",
|
||||
"master": None,
|
||||
"ignore_errors": None,
|
||||
"interface_name": None,
|
||||
"interface_name": "e556",
|
||||
"check_iface_exists": True,
|
||||
"force_state_change": None,
|
||||
"slave_type": None,
|
||||
|
|
@ -1666,6 +1676,7 @@ class TestValidator(unittest.TestCase):
|
|||
"ONBOOT": "yes",
|
||||
"TYPE": "Ethernet",
|
||||
"ZONE": "external",
|
||||
"DEVICE": "e556",
|
||||
},
|
||||
"keys": None,
|
||||
"route": "192.168.40.0/24 metric 545\n192.168.46.0/30\n"
|
||||
|
|
@ -1681,6 +1692,80 @@ class TestValidator(unittest.TestCase):
|
|||
[{"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 inerface_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.assertEquals(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.assertEquals(connections[0]["interface_name"], "internal")
|
||||
|
||||
|
||||
@my_test_skipIf(nmutil is None, "no support for NM (libnm via pygobject)")
|
||||
class TestNM(unittest.TestCase):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue