Add NIC Mapping Reporting Feature
The -i or --interfaces flag will print out a dict of the NIC mappings if no interfaces are specified, or it will print a list of the real interface names that match the interfaces given. If a real interface name is given, it will be returned in the list without translation only if it is live. It has always been technically possible to map an interface using an alias that matches an inactive real interface. This change preserves that functionality, but will prevent mapping using the name of an active interface. A warning will be printed if an alias matches an inactive inteface. Also change _is_active_nic and _mapped_nics to public functions since they are called outside of utils. Change-Id: I74af5391165e10f04800ea05e4204a7d1f74f526 Closes-bug: 1713137
This commit is contained in:
parent
69fca4aa70
commit
ebc1c1bc80
|
@ -0,0 +1,5 @@
|
|||
interface_mapping:
|
||||
nic1: em1
|
||||
nic2: em2
|
||||
nic3: em4
|
||||
nic4: em3
|
|
@ -273,7 +273,7 @@ class NetConfig(object):
|
|||
msg = 'renaming %s to %s: ' % (oldname, newname)
|
||||
# ifdown isn't enough when renaming, we need the link down
|
||||
for name in (oldname, newname):
|
||||
if utils._is_active_nic(name):
|
||||
if utils.is_active_nic(name):
|
||||
self.execute(msg, '/sbin/ip',
|
||||
'link', 'set', 'dev', name, 'down')
|
||||
self.execute(msg, '/sbin/ip',
|
||||
|
|
|
@ -42,8 +42,14 @@ def parse_opts(argv):
|
|||
parser.add_argument('-m', '--mapping-file', metavar='MAPPING_FILE',
|
||||
help="""path to the interface mapping file.""",
|
||||
default='/etc/os-net-config/mapping.yaml')
|
||||
parser.add_argument('-i', '--interfaces', metavar='INTERFACES',
|
||||
help="""Identify the real interface for a nic name. """
|
||||
"""If a real name is given, it is returned if live. """
|
||||
"""If no value is given, display full NIC mapping. """
|
||||
"""Exit after printing, ignoring other parameters. """,
|
||||
nargs='*', default=None)
|
||||
parser.add_argument('-p', '--provider', metavar='PROVIDER',
|
||||
help="""The provider to use."""
|
||||
help="""The provider to use. """
|
||||
"""One of: ifcfg, eni, iproute.""",
|
||||
default=None)
|
||||
parser.add_argument('-r', '--root-dir', metavar='ROOT_DIR',
|
||||
|
@ -53,7 +59,7 @@ def parse_opts(argv):
|
|||
action='store_true',
|
||||
help="""Enable detailed exit codes. """
|
||||
"""If enabled an exit code of '2' means """
|
||||
"""that files were modified."""
|
||||
"""that files were modified. """
|
||||
"""Disabled by default.""",
|
||||
default=False)
|
||||
|
||||
|
@ -160,19 +166,6 @@ def main(argv=sys.argv):
|
|||
logger.error('Unable to set provider for this operating system.')
|
||||
return 1
|
||||
|
||||
# Read config file containing network configs to apply
|
||||
if os.path.exists(opts.config_file):
|
||||
with open(opts.config_file) as cf:
|
||||
iface_array = yaml.load(cf.read()).get("network_config")
|
||||
logger.debug('network_config JSON: %s' % str(iface_array))
|
||||
else:
|
||||
logger.error('No config file exists at: %s' % opts.config_file)
|
||||
return 1
|
||||
|
||||
if not isinstance(iface_array, list):
|
||||
logger.error('No interfaces defined in config: %s' % opts.config_file)
|
||||
return 1
|
||||
|
||||
# Read the interface mapping file, if it exists
|
||||
# This allows you to override the default network naming abstraction
|
||||
# mappings by specifying a specific nicN->name or nicN->MAC mapping
|
||||
|
@ -187,6 +180,59 @@ def main(argv=sys.argv):
|
|||
iface_mapping = None
|
||||
persist_mapping = False
|
||||
|
||||
# If --interfaces is specified, either return the real name of the
|
||||
# interfaces specified, or return the map of all nic abstractions/names.
|
||||
if opts.interfaces is not None:
|
||||
reported_nics = {}
|
||||
mapped_nics = objects.mapped_nics(iface_mapping)
|
||||
retval = 0
|
||||
if len(opts.interfaces) > 0:
|
||||
for requested_nic in opts.interfaces:
|
||||
found = False
|
||||
# Check to see if requested iface is a mapped NIC name.
|
||||
if requested_nic in mapped_nics:
|
||||
reported_nics[requested_nic] = mapped_nics[requested_nic]
|
||||
found = True
|
||||
# Check to see if the requested iface is a real NIC name
|
||||
if requested_nic in mapped_nics.values():
|
||||
if found is True: # Name matches alias and real NIC
|
||||
# (return the mapped NIC, but warn of overlap).
|
||||
logger.warning('"%s" overlaps with real NIC name.'
|
||||
% (requested_nic))
|
||||
else:
|
||||
reported_nics[requested_nic] = requested_nic
|
||||
found = True
|
||||
if not found:
|
||||
retval = 1
|
||||
if reported_nics:
|
||||
logger.debug("Interface mapping requested for interface: "
|
||||
"%s" % reported_nics.keys())
|
||||
else:
|
||||
logger.debug("Interface mapping requested for all interfaces")
|
||||
reported_nics = mapped_nics
|
||||
# Return the report on the mapped NICs. If all NICs were found, exit
|
||||
# cleanly, otherwise exit with status 1.
|
||||
logger.debug("Interface report requested, exiting after report.")
|
||||
print(reported_nics)
|
||||
return retval
|
||||
|
||||
# Read config file containing network configs to apply
|
||||
if os.path.exists(opts.config_file):
|
||||
try:
|
||||
with open(opts.config_file) as cf:
|
||||
iface_array = yaml.load(cf.read()).get("network_config")
|
||||
logger.debug('network_config JSON: %s' % str(iface_array))
|
||||
except IOError:
|
||||
logger.error("Error reading file: %s" % opts.config_file)
|
||||
return 1
|
||||
else:
|
||||
logger.error('No config file exists at: %s' % opts.config_file)
|
||||
return 1
|
||||
|
||||
if not isinstance(iface_array, list):
|
||||
logger.error('No interfaces defined in config: %s' % opts.config_file)
|
||||
return 1
|
||||
|
||||
for iface_json in iface_array:
|
||||
iface_json.update({'nic_mapping': iface_mapping})
|
||||
iface_json.update({'persist_mapping': persist_mapping})
|
||||
|
|
|
@ -112,7 +112,7 @@ def _update_members(json, nic_mapping, persist_mapping):
|
|||
return members
|
||||
|
||||
|
||||
def _mapped_nics(nic_mapping=None):
|
||||
def mapped_nics(nic_mapping=None):
|
||||
mapping = nic_mapping or {}
|
||||
global _MAPPED_NICS
|
||||
if _MAPPED_NICS:
|
||||
|
@ -155,6 +155,17 @@ def _mapped_nics(nic_mapping=None):
|
|||
% nic_mapped)
|
||||
raise InvalidConfigException(msg)
|
||||
|
||||
# Using a mapping name that overlaps with a real NIC is not allowed
|
||||
# (However using the name of an inactive NIC as an alias is
|
||||
# permitted).
|
||||
if utils.is_active_nic(nic_alias):
|
||||
msg = ('cannot map %s to alias %s, alias overlaps with active '
|
||||
'NIC.' % (nic_mapped, nic_alias))
|
||||
raise InvalidConfigException(msg)
|
||||
elif utils.is_real_nic(nic_alias):
|
||||
logger.warning("Mapped nic %s overlaps with name of inactive "
|
||||
"NIC." % (nic_alias))
|
||||
|
||||
_MAPPED_NICS[nic_alias] = nic_mapped
|
||||
logger.info("%s in mapping file mapped to: %s"
|
||||
% (nic_alias, nic_mapped))
|
||||
|
@ -230,7 +241,7 @@ class _BaseOpts(object):
|
|||
addresses = addresses or []
|
||||
routes = routes or []
|
||||
dns_servers = dns_servers or []
|
||||
mapped_nic_names = _mapped_nics(nic_mapping)
|
||||
mapped_nic_names = mapped_nics(nic_mapping)
|
||||
self.hwaddr = None
|
||||
self.hwname = None
|
||||
self.renamed = False
|
||||
|
@ -379,7 +390,7 @@ class Vlan(_BaseOpts):
|
|||
dns_servers, nm_controlled)
|
||||
self.vlan_id = int(vlan_id)
|
||||
|
||||
mapped_nic_names = _mapped_nics(nic_mapping)
|
||||
mapped_nic_names = mapped_nics(nic_mapping)
|
||||
if device in mapped_nic_names:
|
||||
self.device = mapped_nic_names[device]
|
||||
else:
|
||||
|
|
|
@ -41,7 +41,7 @@ class TestCase(testtools.TestCase):
|
|||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return self.stubbed_mapped_nics
|
||||
if self.stub_mapped_nics:
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
|
||||
try:
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
|
||||
import os.path
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
import os_net_config
|
||||
from os_net_config import cli
|
||||
from os_net_config import impl_ifcfg
|
||||
from os_net_config import objects
|
||||
from os_net_config.tests import base
|
||||
import six
|
||||
|
||||
|
@ -235,3 +237,39 @@ class TestCli(base.TestCase):
|
|||
for dev in sanity_devices:
|
||||
self.assertIn(dev, stdout_yaml)
|
||||
self.assertEqual(stdout_yaml, stdout_json)
|
||||
|
||||
def test_nic_mapping_report_output(self):
|
||||
mapping_report = os.path.join(SAMPLE_BASE, 'mapping_report.yaml')
|
||||
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return nic_mapping
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
stdout, stderr = self.run_cli('ARG0 --interfaces '
|
||||
'--exit-on-validation-errors '
|
||||
'-m %s' % mapping_report)
|
||||
self.assertEqual('', stderr)
|
||||
stdout_list = yaml.load(stdout)
|
||||
self.assertEqual(stdout_list['nic1'], 'em1')
|
||||
self.assertEqual(stdout_list['nic2'], 'em2')
|
||||
self.assertEqual(stdout_list['nic3'], 'em4')
|
||||
self.assertEqual(stdout_list['nic4'], 'em3')
|
||||
|
||||
def test_nic_mapping_report_with_explicit_interface_name(self):
|
||||
mapping_report = os.path.join(SAMPLE_BASE, 'mapping_report.yaml')
|
||||
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return nic_mapping
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
stdout, stderr = self.run_cli('ARG0 --interfaces em2 em3 '
|
||||
'--exit-on-validation-errors '
|
||||
'-m %s' % mapping_report)
|
||||
self.assertEqual('', stderr)
|
||||
stdout_list = yaml.load(stdout)
|
||||
self.assertNotIn('em1', stdout_list.keys())
|
||||
self.assertNotIn('em1', stdout_list.values())
|
||||
self.assertEqual(stdout_list['em2'], 'em2')
|
||||
self.assertEqual(stdout_list['em3'], 'em3')
|
||||
self.assertNotIn('em4', stdout_list.keys())
|
||||
self.assertNotIn('em4', stdout_list.values())
|
||||
|
|
|
@ -198,7 +198,7 @@ class TestInterface(base.TestCase):
|
|||
def test_from_json_dhcp_nic1(self):
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return {"nic1": "em3"}
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
data = '{"type": "interface", "name": "nic1", "use_dhcp": true}'
|
||||
interface = objects.object_from_json(json.loads(data))
|
||||
|
@ -250,7 +250,7 @@ class TestVlan(base.TestCase):
|
|||
def test_from_json_dhcp_nic1(self):
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return {"nic1": "em4"}
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
data = '{"type": "vlan", "device": "nic1", "vlan_id": 16,' \
|
||||
'"use_dhcp": true}'
|
||||
|
@ -284,7 +284,7 @@ class TestBridge(base.TestCase):
|
|||
def test_from_json_dhcp_with_nic1(self):
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return {"nic1": "em5"}
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
data = """{
|
||||
"type": "ovs_bridge",
|
||||
|
@ -388,7 +388,7 @@ class TestLinuxBridge(base.TestCase):
|
|||
def test_from_json_dhcp_with_nic1(self):
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return {"nic1": "em5"}
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
data = """{
|
||||
"type": "linux_bridge",
|
||||
|
@ -595,7 +595,7 @@ class TestBond(base.TestCase):
|
|||
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return {"nic1": "em1", "nic2": "em2"}
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
data = """{
|
||||
"type": "ovs_bond",
|
||||
|
@ -686,7 +686,7 @@ class TestLinuxBond(base.TestCase):
|
|||
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return {"nic1": "em1", "nic2": "em2"}
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
data = """{
|
||||
"type": "ovs_bond",
|
||||
|
@ -873,7 +873,7 @@ class TestIbInterface(base.TestCase):
|
|||
def test_from_json_dhcp_nic1(self):
|
||||
def dummy_mapped_nics(nic_mapping=None):
|
||||
return {"nic1": "ib0"}
|
||||
self.stubs.Set(objects, '_mapped_nics', dummy_mapped_nics)
|
||||
self.stubs.Set(objects, 'mapped_nics', dummy_mapped_nics)
|
||||
|
||||
data = '{"type": "ib_interface", "name": "nic1", "use_dhcp": true}'
|
||||
ib_interface = objects.object_from_json(json.loads(data))
|
||||
|
@ -933,28 +933,28 @@ class TestNicMapping(base.TestCase):
|
|||
def test_mapped_nics_default(self):
|
||||
self._stub_active_nics(['em1', 'em2'])
|
||||
expected = {'nic1': 'em1', 'nic2': 'em2'}
|
||||
self.assertEqual(expected, objects._mapped_nics())
|
||||
self.assertEqual(expected, objects.mapped_nics())
|
||||
|
||||
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))
|
||||
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))
|
||||
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))
|
||||
self.assertEqual(expected, objects.mapped_nics(nic_mapping=mapping))
|
||||
|
||||
def test_mapped_nics_mapped_unnumbered(self):
|
||||
self._stub_active_nics(['em1', 'em2', 'em3', 'em4'])
|
||||
|
@ -962,21 +962,21 @@ class TestNicMapping(base.TestCase):
|
|||
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))
|
||||
self.assertEqual(expected, objects.mapped_nics(nic_mapping=mapping))
|
||||
|
||||
def test_mapped_nics_map_error_notactive(self):
|
||||
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))
|
||||
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)
|
||||
objects.mapped_nics, nic_mapping=mapping)
|
||||
expected = 'em1 already mapped, check mapping file for duplicates'
|
||||
self.assertIn(expected, six.text_type(err))
|
||||
|
||||
|
@ -985,7 +985,7 @@ class TestNicMapping(base.TestCase):
|
|||
self._stub_available_nics(['em1', 'em2'])
|
||||
mapping = {'nic1': 'em1', 'nic2': 'foo'}
|
||||
expected = {'nic1': 'em1'}
|
||||
self.assertEqual(expected, objects._mapped_nics(nic_mapping=mapping))
|
||||
self.assertEqual(expected, objects.mapped_nics(nic_mapping=mapping))
|
||||
|
||||
def test_mapped_nics_map_mac(self):
|
||||
def dummy_interface_mac(name):
|
||||
|
@ -997,7 +997,7 @@ class TestNicMapping(base.TestCase):
|
|||
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))
|
||||
self.assertEqual(expected, objects.mapped_nics(nic_mapping=mapping))
|
||||
|
||||
def test_mapped_nics_map_invalid_mac(self):
|
||||
def dummy_interface_mac(name):
|
||||
|
@ -1010,13 +1010,43 @@ class TestNicMapping(base.TestCase):
|
|||
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))
|
||||
self.assertEqual(expected, objects.mapped_nics(nic_mapping=mapping))
|
||||
|
||||
def test_mapped_nics_no_active(self):
|
||||
self._stub_active_nics([])
|
||||
expected = {}
|
||||
# This only emits a warning, so it should still work
|
||||
self.assertEqual(expected, objects._mapped_nics())
|
||||
self.assertEqual(expected, objects.mapped_nics())
|
||||
|
||||
def test_mapped_nics_mapping_overlap_real_nic_name(self):
|
||||
def dummy_is_active_nic(nic):
|
||||
if nic == 'em1':
|
||||
return True
|
||||
elif nic == 'nic1':
|
||||
return False
|
||||
|
||||
self.stubs.Set(utils, 'is_active_nic', dummy_is_active_nic)
|
||||
self._stub_available_nics(['em1', 'em2'])
|
||||
mapping = {'nic1': 'em1', 'em1': 'em2'}
|
||||
err = self.assertRaises(objects.InvalidConfigException,
|
||||
objects.mapped_nics, nic_mapping=mapping)
|
||||
expected = 'cannot map em2 to alias em1, alias overlaps'
|
||||
self.assertIn(expected, six.text_type(err))
|
||||
|
||||
def test_mapped_nics_mapping_inactive_name_as_alias(self):
|
||||
def dummy_is_active_nic(nic):
|
||||
return False
|
||||
|
||||
def dummy_is_real_nic(nic):
|
||||
return True
|
||||
|
||||
self.stubs.Set(utils, 'is_active_nic', dummy_is_active_nic)
|
||||
self.stubs.Set(utils, 'is_real_nic', dummy_is_real_nic)
|
||||
self._stub_active_nics([])
|
||||
self._stub_available_nics(['em1', 'em2'])
|
||||
mapping = {'em2': 'em1', 'nic1': 'em2'}
|
||||
expected = {'em2': 'em1', 'nic1': 'em2'}
|
||||
self.assertEqual(expected, objects.mapped_nics(nic_mapping=mapping))
|
||||
|
||||
# Test that mapping file is passed to interface members from parent object
|
||||
def _test_mapped_nics_with_parent(self, type, name):
|
||||
|
|
|
@ -333,8 +333,8 @@ class TestUtils(base.TestCase):
|
|||
nic_path = os.path.join(tmpdir, 'enp129s2', 'device', 'physfn')
|
||||
os.makedirs(nic_path)
|
||||
|
||||
self.assertEqual(utils._is_active_nic('ens802f0'), True)
|
||||
self.assertEqual(utils._is_active_nic('enp129s2'), False)
|
||||
self.assertEqual(utils.is_active_nic('ens802f0'), True)
|
||||
self.assertEqual(utils.is_active_nic('enp129s2'), False)
|
||||
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
|
|
|
@ -99,18 +99,36 @@ def interface_mac(name):
|
|||
raise
|
||||
|
||||
|
||||
def _is_active_nic(interface_name):
|
||||
def is_active_nic(interface_name):
|
||||
return _is_available_nic(interface_name, True)
|
||||
|
||||
|
||||
def is_real_nic(interface_name):
|
||||
if interface_name == 'lo':
|
||||
return True
|
||||
|
||||
device_dir = _SYS_CLASS_NET + '/%s/device' % interface_name
|
||||
has_device_dir = os.path.isdir(device_dir)
|
||||
|
||||
address = None
|
||||
try:
|
||||
with open(_SYS_CLASS_NET + '/%s/address' % interface_name, 'r') as f:
|
||||
address = f.read().rstrip()
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
if has_device_dir and address:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
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:
|
||||
if not is_real_nic(interface_name):
|
||||
return False
|
||||
|
||||
operstate = None
|
||||
|
@ -119,12 +137,6 @@ def _is_available_nic(interface_name, check_active=True):
|
|||
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
|
||||
# the nic numbering. All the VFs will have a reference to the PF with
|
||||
|
|
Loading…
Reference in New Issue