Merge "os_net_config should map nics that are down if nic is in mapping file"
This commit is contained in:
commit
52c59fbb55
|
@ -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:
|
||||
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)))
|
||||
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
|
||||
|
||||
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 mapped to: %s" % (nic_alias, nic_mapped))
|
||||
_MAPPED_NICS[nic_alias] = nic_mapped
|
||||
logger.info("%s in mapping file 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())):
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -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']:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue