aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os_net_config/objects.py66
-rw-r--r--os_net_config/tests/test_objects.py39
-rw-r--r--os_net_config/tests/test_utils.py8
-rw-r--r--os_net_config/utils.py30
4 files changed, 103 insertions, 40 deletions
diff --git a/os_net_config/objects.py b/os_net_config/objects.py
index a469914..5bdbb9c 100644
--- a/os_net_config/objects.py
+++ b/os_net_config/objects.py
@@ -87,37 +87,49 @@ def _mapped_nics(nic_mapping=None):
if _MAPPED_NICS:
return _MAPPED_NICS
_MAPPED_NICS = {}
- active_nics = utils.ordered_active_nics()
- for nic_alias, nic_mapped in mapping.items():
- if nic_mapped not in active_nics:
- # The mapping is either invalid, or specifies a mac
- is_mapping_valid = False
- for active in active_nics:
- try:
- active_mac = utils.interface_mac(active)
- except IOError:
+
+ if mapping:
+ # If mapping file provided, nics need not be active
+ available_nics = utils.ordered_available_nics()
+ for nic_alias, nic_mapped in mapping.items():
+
+ if netaddr.valid_mac(nic_mapped):
+ # If 'nic' is actually a mac address, retrieve actual nic name
+ for nic in available_nics:
+ try:
+ mac = utils.interface_mac(nic)
+ except IOError:
+ continue
+ if nic_mapped == mac:
+ logger.debug("%s matches device %s" %
+ (nic_mapped, nic))
+ nic_mapped = nic
+ break
+ else:
+ # The mac could not be found on this system
+ logger.error('mac %s not found in available nics (%s)'
+ % (nic_mapped, ', '.join(available_nics)))
continue
- if nic_mapped == active_mac:
- logger.debug("%s matches device %s" % (nic_mapped, active))
- nic_mapped = active
- is_mapping_valid = True
- break
-
- if not is_mapping_valid:
- # The mapping can't specify a non-active or non-existent nic
- logger.warning('interface %s is not an active nic (%s)'
- % (nic_mapped, ', '.join(active_nics)))
+
+ elif nic_mapped not in available_nics:
+ # nic doesn't exist on this system
+ logger.error('nic %s not found in available nics (%s)'
+ % (nic_mapped, ', '.join(available_nics)))
continue
- # Duplicate mappings are not allowed
- if nic_mapped in _MAPPED_NICS.values():
- msg = ('interface %s already mapped, '
- 'check mapping file for duplicates'
- % nic_mapped)
- raise InvalidConfigException(msg)
+ # Duplicate mappings are not allowed
+ if nic_mapped in _MAPPED_NICS.values():
+ msg = ('interface %s already mapped, '
+ 'check mapping file for duplicates'
+ % nic_mapped)
+ raise InvalidConfigException(msg)
+
+ _MAPPED_NICS[nic_alias] = nic_mapped
+ logger.info("%s in mapping file mapped to: %s"
+ % (nic_alias, nic_mapped))
- _MAPPED_NICS[nic_alias] = nic_mapped
- logger.info("%s mapped to: %s" % (nic_alias, nic_mapped))
+ # nics not in mapping file must be active in order to be mapped
+ active_nics = utils.ordered_active_nics()
# Add default numbered mappings, but do not overwrite existing entries
for nic_mapped in set(active_nics).difference(set(_MAPPED_NICS.values())):
diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py
index afe63b5..1199bb2 100644
--- a/os_net_config/tests/test_objects.py
+++ b/os_net_config/tests/test_objects.py
@@ -913,6 +913,12 @@ class TestNicMapping(base.TestCase):
return nics
self.stubs.Set(utils, 'ordered_active_nics', dummy_ordered_active_nics)
+ def _stub_available_nics(self, nics):
+ def dummy_ordered_available_nics():
+ return nics
+ self.stubs.Set(utils, 'ordered_available_nics',
+ dummy_ordered_available_nics)
+
def test_mapped_nics_default(self):
self._stub_active_nics(['em1', 'em2'])
expected = {'nic1': 'em1', 'nic2': 'em2'}
@@ -920,43 +926,56 @@ class TestNicMapping(base.TestCase):
def test_mapped_nics_mapped(self):
self._stub_active_nics(['em1', 'em2'])
+ self._stub_available_nics(['em1', 'em2'])
mapping = {'nic1': 'em2', 'nic2': 'em1'}
expected = {'nic1': 'em2', 'nic2': 'em1'}
self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
def test_mapped_nics_mapped_partial(self):
self._stub_active_nics(['em1', 'em2', 'em3', 'em4'])
+ self._stub_available_nics(['em1', 'em2', 'em3', 'em4'])
mapping = {'nic1': 'em2', 'nic2': 'em1'}
expected = {'nic1': 'em2', 'nic2': 'em1', 'nic3': 'em3', 'nic4': 'em4'}
self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
def test_mapped_nics_mapped_partial_reordered(self):
self._stub_active_nics(['em1', 'em2', 'em3', 'em4'])
+ self._stub_available_nics(['em1', 'em2', 'em3', 'em4'])
mapping = {'nic1': 'em1', 'nic2': 'em3'}
expected = {'nic1': 'em1', 'nic2': 'em3', 'nic4': 'em4'}
self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
def test_mapped_nics_mapped_unnumbered(self):
self._stub_active_nics(['em1', 'em2', 'em3', 'em4'])
+ self._stub_available_nics(['em1', 'em2', 'em3', 'em4'])
mapping = {'John': 'em1', 'Paul': 'em2', 'George': 'em3'}
expected = {'John': 'em1', 'Paul': 'em2', 'George': 'em3',
'nic4': 'em4'}
self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
def test_mapped_nics_map_error_notactive(self):
- self._stub_active_nics(['em1', 'em2'])
- mapping = {'nic1': 'em3', 'nic2': 'em1'}
- expected = {'nic2': 'em1'}
+ self._stub_active_nics(['em2'])
+ self._stub_available_nics(['em1', 'em2', 'em3'])
+ mapping = {'nic2': 'em1'}
+ expected = {'nic1': 'em2', 'nic2': 'em1'}
self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
def test_mapped_nics_map_error_duplicate(self):
self._stub_active_nics(['em1', 'em2'])
+ self._stub_available_nics(['em1', 'em2'])
mapping = {'nic1': 'em1', 'nic2': 'em1'}
err = self.assertRaises(objects.InvalidConfigException,
objects._mapped_nics, nic_mapping=mapping)
expected = 'em1 already mapped, check mapping file for duplicates'
self.assertIn(expected, six.text_type(err))
+ def test_mapped_nics_map_invalid_nic(self):
+ self._stub_active_nics(['em1'])
+ self._stub_available_nics(['em1', 'em2'])
+ mapping = {'nic1': 'em1', 'nic2': 'foo'}
+ expected = {'nic1': 'em1'}
+ self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
+
def test_mapped_nics_map_mac(self):
def dummy_interface_mac(name):
mac_map = {'em1': '12:34:56:78:9a:bc',
@@ -964,10 +983,24 @@ class TestNicMapping(base.TestCase):
return mac_map[name]
self.stubs.Set(utils, 'interface_mac', dummy_interface_mac)
self._stub_active_nics(['em1', 'em2'])
+ self._stub_available_nics(['em1', 'em2'])
mapping = {'nic1': '12:34:56:de:f0:12', 'nic2': '12:34:56:78:9a:bc'}
expected = {'nic1': 'em2', 'nic2': 'em1'}
self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
+ def test_mapped_nics_map_invalid_mac(self):
+ def dummy_interface_mac(name):
+ mac_map = {'em1': '12:34:56:78:9a:bc',
+ 'em2': '12:34:56:de:f0:12'}
+ return mac_map[name]
+
+ self.stubs.Set(utils, 'interface_mac', dummy_interface_mac)
+ self._stub_active_nics(['em1', 'em2'])
+ self._stub_available_nics(['em1', 'em2'])
+ mapping = {'nic1': '12:34:56:de:f0:12', 'nic2': 'aa:bb:cc:dd:ee:ff'}
+ expected = {'nic1': 'em2'}
+ self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
+
def test_mapped_nics_no_active(self):
self._stub_active_nics([])
expected = {}
diff --git a/os_net_config/tests/test_utils.py b/os_net_config/tests/test_utils.py
index 5a8b6af..dcd6045 100644
--- a/os_net_config/tests/test_utils.py
+++ b/os_net_config/tests/test_utils.py
@@ -84,9 +84,9 @@ class TestUtils(base.TestCase):
tmpdir = tempfile.mkdtemp()
self.stubs.Set(utils, '_SYS_CLASS_NET', tmpdir)
- def test_is_active_nic(interface_name):
+ def test_is_available_nic(interface_name, check_active):
return True
- self.stubs.Set(utils, '_is_active_nic', test_is_active_nic)
+ self.stubs.Set(utils, '_is_available_nic', test_is_available_nic)
for nic in ['a1', 'em1', 'em2', 'eth2', 'z1',
'enp8s0', 'enp10s0', 'enp1s0f0']:
@@ -214,9 +214,9 @@ class TestUtils(base.TestCase):
tmpdir = tempfile.mkdtemp()
self.stubs.Set(utils, '_SYS_CLASS_NET', tmpdir)
- def test_is_active_nic(interface_name):
+ def test_is_available_nic(interface_name, check_active):
return True
- self.stubs.Set(utils, '_is_active_nic', test_is_active_nic)
+ self.stubs.Set(utils, '_is_available_nic', test_is_available_nic)
for nic in ['a1', 'em1', 'em2', 'eth2', 'z1',
'enp8s0', 'enp10s0', 'enp1s0f0']:
diff --git a/os_net_config/utils.py b/os_net_config/utils.py
index a4dfa4b..b7a54bf 100644
--- a/os_net_config/utils.py
+++ b/os_net_config/utils.py
@@ -100,20 +100,30 @@ def interface_mac(name):
def _is_active_nic(interface_name):
+ return _is_available_nic(interface_name, True)
+
+
+def _is_available_nic(interface_name, check_active=True):
try:
if interface_name == 'lo':
return False
device_dir = _SYS_CLASS_NET + '/%s/device' % interface_name
has_device_dir = os.path.isdir(device_dir)
+ if not has_device_dir:
+ return False
operstate = None
with open(_SYS_CLASS_NET + '/%s/operstate' % interface_name, 'r') as f:
operstate = f.read().rstrip().lower()
+ if check_active and operstate != 'up':
+ return False
address = None
with open(_SYS_CLASS_NET + '/%s/address' % interface_name, 'r') as f:
address = f.read().rstrip()
+ if not address:
+ return False
# If SR-IOV Virtual Functions (VF) are enabled in an interface, there
# will be additional nics created for each VF. It has to be ignored in
@@ -122,12 +132,12 @@ def _is_active_nic(interface_name):
# ignored.
vf_path_check = _SYS_CLASS_NET + '/%s/device/physfn' % interface_name
is_sriov_vf = os.path.isdir(vf_path_check)
-
- if (has_device_dir and operstate == 'up' and address and
- not is_sriov_vf):
- return True
- else:
+ if is_sriov_vf:
return False
+
+ # nic is available
+ return True
+
except IOError:
return False
@@ -144,13 +154,21 @@ def _is_embedded_nic(nic):
return False
+def ordered_available_nics():
+ return _ordered_nics(False)
+
+
def ordered_active_nics():
+ return _ordered_nics(True)
+
+
+def _ordered_nics(check_active):
embedded_nics = []
nics = []
logger.debug("Finding active nics")
for name in glob.iglob(_SYS_CLASS_NET + '/*'):
nic = name[(len(_SYS_CLASS_NET) + 1):]
- if _is_active_nic(nic):
+ if _is_available_nic(nic, check_active):
if _is_embedded_nic(nic):
logger.debug("%s is an embedded active nic" % nic)
embedded_nics.append(nic)