aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Hardy <shardy@redhat.com>2015-01-21 17:24:08 +0000
committerSteven Hardy <shardy@redhat.com>2015-02-24 09:20:41 +0000
commita4ad189558a414c6029b4dfbc8e459339ebe534d (patch)
tree0c39889bc89c461803f03b4cb9ae89e8bd4c0033
parent6945fe5afdc12574fe00ad440319b7873f818e84 (diff)
Add a persist_mapping option to the mapping file
This adds the option to permanently rewrite the configuration so the aliases are used instead of the system name. This is useful where you have a variety of hardware and you want to have consistent device naming accross all platforms - this allows you to essentially rename the interfaces permanently so they match the abstracted nicN names. Note, this needs to be run with --cleanup or the old (now conflicting) configs will still be in place, and it may require a reboot before the changes are fully applied. Change-Id: I5af146e764b72c4beaa41c549fabff0af8802152
-rw-r--r--etc/os-net-config/samples/mapping.yaml4
-rw-r--r--os_net_config/cli.py15
-rw-r--r--os_net_config/impl_eni.py3
-rw-r--r--os_net_config/impl_ifcfg.py2
-rw-r--r--os_net_config/objects.py55
-rw-r--r--os_net_config/tests/base.py3
-rw-r--r--os_net_config/tests/test_impl_ifcfg.py19
7 files changed, 81 insertions, 20 deletions
diff --git a/etc/os-net-config/samples/mapping.yaml b/etc/os-net-config/samples/mapping.yaml
index 5faec22..a832dc9 100644
--- a/etc/os-net-config/samples/mapping.yaml
+++ b/etc/os-net-config/samples/mapping.yaml
@@ -1,6 +1,10 @@
# This can be used with the -m option to override the
# default mapping of the nicN aliases in configs
# The mapping can specify either a device name or a mac address
+# If --persist-mapping is specified, we write the device aliases
+# config instead of the system names, e.g we actually configure
+# nic1 intead of em3. This is probably best used with --cleanup
+# to remove the stale configs e.g for em3
interface_mapping:
nic1: em3
nic2: em1
diff --git a/os_net_config/cli.py b/os_net_config/cli.py
index d22573d..939eeaa 100644
--- a/os_net_config/cli.py
+++ b/os_net_config/cli.py
@@ -74,6 +74,14 @@ def parse_opts(argv):
help="Cleanup unconfigured interfaces.",
required=False)
+ parser.add_argument(
+ '--persist-mapping',
+ dest="persist_mapping",
+ action='store_true',
+ help="Make aliases defined in the mapping file permanent "
+ "(WARNING, permanently renames nics).",
+ required=False)
+
opts = parser.parse_args(argv[1:])
return opts
@@ -139,13 +147,18 @@ def main(argv=sys.argv):
# mappings by specifying a specific nicN->name or nicN->MAC mapping
if os.path.exists(opts.mapping_file):
with open(opts.mapping_file) as cf:
- iface_mapping = yaml.load(cf.read()).get("interface_mapping")
+ iface_map = yaml.load(cf.read())
+ iface_mapping = iface_map.get("interface_mapping")
logger.debug('interface_mapping JSON: %s' % str(iface_mapping))
+ persist_mapping = opts.persist_mapping
+ logger.debug('persist_mapping: %s' % persist_mapping)
else:
iface_mapping = None
+ persist_mapping = False
for iface_json in iface_array:
iface_json.update({'nic_mapping': iface_mapping})
+ iface_json.update({'persist_mapping': persist_mapping})
obj = objects.object_from_json(iface_json)
provider.add_object(obj)
files_changed = provider.apply(noop=opts.noop, cleanup=opts.cleanup)
diff --git a/os_net_config/impl_eni.py b/os_net_config/impl_eni.py
index 5f4f727..ce4ffe9 100644
--- a/os_net_config/impl_eni.py
+++ b/os_net_config/impl_eni.py
@@ -129,6 +129,9 @@ class ENINetConfig(os_net_config.NetConfig):
if interface.mtu != 1500:
data += " mtu %i\n" % interface.mtu
+ if interface.hwaddr:
+ raise NotImplemented("hwaddr is not implemented.")
+
if ovs_extra:
data += " ovs_extra %s\n" % " -- ".join(ovs_extra)
diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py
index c871296..a728f53 100644
--- a/os_net_config/impl_ifcfg.py
+++ b/os_net_config/impl_ifcfg.py
@@ -142,6 +142,8 @@ class IfcfgNetConfig(os_net_config.NetConfig):
first_v6 = v6_addresses[0]
data += "IPV6_AUTOCONF=no\n"
data += "IPV6ADDR=%s\n" % first_v6.ip
+ if base_opt.hwaddr:
+ data += "HWADDR=%s\n" % base_opt.hwaddr
if ovs_extra:
data += "OVS_EXTRA=\"%s\"\n" % " -- ".join(ovs_extra)
return data
diff --git a/os_net_config/objects.py b/os_net_config/objects.py
index 929bcab..79d83e7 100644
--- a/os_net_config/objects.py
+++ b/os_net_config/objects.py
@@ -129,12 +129,20 @@ class _BaseOpts(object):
"""Base abstraction for logical port options."""
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=[],
- routes=[], mtu=1500, primary=False, nic_mapping=None):
+ routes=[], mtu=1500, primary=False, nic_mapping=None,
+ persist_mapping=False):
numbered_nic_names = _numbered_nics(nic_mapping)
+ self.hwaddr = None
if name in numbered_nic_names:
- self.name = numbered_nic_names[name]
+ if persist_mapping:
+ self.name = name
+ hwname = numbered_nic_names[name]
+ self.hwaddr = utils.interface_mac(hwname)
+ else:
+ self.name = numbered_nic_names[name]
else:
self.name = name
+
self.mtu = mtu
self.use_dhcp = use_dhcp
self.use_dhcpv6 = use_dhcpv6
@@ -192,22 +200,25 @@ class _BaseOpts(object):
raise InvalidConfigException(msg)
nic_mapping = json.get('nic_mapping')
+ persist_mapping = json.get('persist_mapping')
if include_primary:
return (use_dhcp, use_dhcpv6, addresses, routes, mtu, primary,
- nic_mapping)
+ nic_mapping, persist_mapping)
else:
return (use_dhcp, use_dhcpv6, addresses, routes, mtu,
- nic_mapping)
+ nic_mapping, persist_mapping)
class Interface(_BaseOpts):
"""Base class for network interfaces."""
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=[],
- routes=[], mtu=1500, primary=False, nic_mapping=None):
+ routes=[], mtu=1500, primary=False, nic_mapping=None,
+ persist_mapping=False):
super(Interface, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
- routes, mtu, primary, nic_mapping)
+ routes, mtu, primary, nic_mapping,
+ persist_mapping)
@staticmethod
def from_json(json):
@@ -225,10 +236,11 @@ class Vlan(_BaseOpts):
def __init__(self, device, vlan_id, use_dhcp=False, use_dhcpv6=False,
addresses=[], routes=[], mtu=1500, primary=False,
- nic_mapping=None):
+ nic_mapping=None, persist_mapping=False):
name = 'vlan%i' % vlan_id
super(Vlan, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
- routes, mtu, primary, nic_mapping)
+ routes, mtu, primary, nic_mapping,
+ persist_mapping)
self.vlan_id = int(vlan_id)
numbered_nic_names = _numbered_nics(nic_mapping)
@@ -251,9 +263,10 @@ class OvsBridge(_BaseOpts):
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=[],
routes=[], mtu=1500, members=[], ovs_options=None,
- ovs_extra=[], nic_mapping=None):
+ ovs_extra=[], nic_mapping=None, persist_mapping=False):
super(OvsBridge, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
- routes, mtu, False, nic_mapping)
+ routes, mtu, False, nic_mapping,
+ persist_mapping)
self.members = members
self.ovs_options = ovs_options
self.ovs_extra = ovs_extra
@@ -272,8 +285,9 @@ class OvsBridge(_BaseOpts):
@staticmethod
def from_json(json):
name = _get_required_field(json, 'name', 'OvsBridge')
- (use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping
- ) = _BaseOpts.base_opts_from_json(json, include_primary=False)
+ (use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
+ persist_mapping) = _BaseOpts.base_opts_from_json(
+ json, include_primary=False)
ovs_options = json.get('ovs_options')
ovs_extra = json.get('ovs_extra', [])
members = []
@@ -291,7 +305,8 @@ class OvsBridge(_BaseOpts):
return OvsBridge(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
addresses=addresses, routes=routes, mtu=mtu,
members=members, ovs_options=ovs_options,
- ovs_extra=ovs_extra, nic_mapping=nic_mapping)
+ ovs_extra=ovs_extra, nic_mapping=nic_mapping,
+ persist_mapping=persist_mapping)
class OvsBond(_BaseOpts):
@@ -299,9 +314,11 @@ class OvsBond(_BaseOpts):
def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=[],
routes=[], mtu=1500, primary=False, members=[],
- ovs_options=None, ovs_extra=[], nic_mapping=None):
+ ovs_options=None, ovs_extra=[], nic_mapping=None,
+ persist_mapping=False):
super(OvsBond, self).__init__(name, use_dhcp, use_dhcpv6, addresses,
- routes, mtu, primary, nic_mapping)
+ routes, mtu, primary, nic_mapping,
+ persist_mapping)
self.members = members
self.ovs_options = ovs_options
self.ovs_extra = ovs_extra
@@ -318,8 +335,9 @@ class OvsBond(_BaseOpts):
@staticmethod
def from_json(json):
name = _get_required_field(json, 'name', 'OvsBond')
- (use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping
- ) = _BaseOpts.base_opts_from_json(json, include_primary=False)
+ (use_dhcp, use_dhcpv6, addresses, routes, mtu, nic_mapping,
+ persist_mapping) = _BaseOpts.base_opts_from_json(
+ json, include_primary=False)
ovs_options = json.get('ovs_options')
ovs_extra = json.get('ovs_extra', [])
members = []
@@ -337,4 +355,5 @@ class OvsBond(_BaseOpts):
return OvsBond(name, use_dhcp=use_dhcp, use_dhcpv6=use_dhcpv6,
addresses=addresses, routes=routes, mtu=mtu,
members=members, ovs_options=ovs_options,
- ovs_extra=ovs_extra, nic_mapping=nic_mapping)
+ ovs_extra=ovs_extra, nic_mapping=nic_mapping,
+ persist_mapping=persist_mapping)
diff --git a/os_net_config/tests/base.py b/os_net_config/tests/base.py
index 30f9d97..d5adc66 100644
--- a/os_net_config/tests/base.py
+++ b/os_net_config/tests/base.py
@@ -36,9 +36,10 @@ class TestCase(testtools.TestCase):
super(TestCase, self).setUp()
self.stubs = stubout.StubOutForTesting()
+ self.stubbed_numbered_nics = {}
def dummy_numbered_nics(nic_mapping=None):
- return {}
+ return self.stubbed_numbered_nics
if self.stub_numbered_nics:
self.stubs.Set(objects, '_numbered_nics', dummy_numbered_nics)
diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py
index c1026d9..46371db 100644
--- a/os_net_config/tests/test_impl_ifcfg.py
+++ b/os_net_config/tests/test_impl_ifcfg.py
@@ -36,6 +36,8 @@ IPADDR=192.168.1.2
NETMASK=255.255.255.0
"""
+_V4_IFCFG_MAPPED = _V4_IFCFG.replace('em1', 'nic1') + "HWADDR=a1:b2:c3:d4:e5\n"
+
_V6_IFCFG = _BASE_IFCFG + """IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6ADDR=2001:abc:a::
@@ -141,6 +143,23 @@ class TestIfcfgNetConfig(base.TestCase):
self.assertEqual(_V4_IFCFG, self.get_interface_config())
self.assertEqual('', self.get_route_config())
+ def test_add_interface_map_persisted(self):
+ def test_interface_mac(name):
+ macs = {'em1': 'a1:b2:c3:d4:e5'}
+ return macs[name]
+ self.stubs.Set(utils, 'interface_mac', test_interface_mac)
+
+ nic_mapping = {'nic1': 'em1'}
+ self.stubbed_numbered_nics = nic_mapping
+ v4_addr = objects.Address('192.168.1.2/24')
+ interface = objects.Interface('nic1', addresses=[v4_addr],
+ nic_mapping=nic_mapping,
+ persist_mapping=True)
+ self.assertEqual('a1:b2:c3:d4:e5', interface.hwaddr)
+ self.provider.add_interface(interface)
+ self.assertEqual(_V4_IFCFG_MAPPED, self.get_interface_config('nic1'))
+ self.assertEqual('', self.get_route_config('nic1'))
+
def test_add_interface_with_v6(self):
v6_addr = objects.Address('2001:abc:a::/64')
interface = objects.Interface('em1', addresses=[v6_addr])