From 1fc57be0f7df6ba6b9faea4a7e082517287394b2 Mon Sep 17 00:00:00 2001 From: Alessandro Pilotti Date: Tue, 4 Sep 2018 14:30:19 +0300 Subject: [PATCH] Add get_network_adapter_name_by_mac_address A simple way to get an adapter name given the MAC address. This is needed since the MAC address is used to uniquely identify NICs based on information provided by metadata services. get_network_adapter_name_by_mac_address raises in case no adapters or multiple adapters with the same MAC are found. Change-Id: Ie17ee65445dc55a5946653ece1fef68ad7b87aba Partially-Implements: blueprint json-network-config --- cloudbaseinit/osutils/base.py | 3 ++ cloudbaseinit/osutils/windows.py | 19 ++++++++ cloudbaseinit/tests/osutils/test_windows.py | 52 +++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/cloudbaseinit/osutils/base.py b/cloudbaseinit/osutils/base.py index cdabde5e..ca26c5eb 100644 --- a/cloudbaseinit/osutils/base.py +++ b/cloudbaseinit/osutils/base.py @@ -78,6 +78,9 @@ class BaseOSUtils(object): def get_network_adapters(self): raise NotImplementedError() + def get_network_adapter_name_by_mac_address(self, mac_address): + raise NotImplementedError() + def set_network_adapter_mtu(self, name, mtu): raise NotImplementedError() diff --git a/cloudbaseinit/osutils/windows.py b/cloudbaseinit/osutils/windows.py index d0ec005b..ce2f6074 100644 --- a/cloudbaseinit/osutils/windows.py +++ b/cloudbaseinit/osutils/windows.py @@ -738,6 +738,25 @@ class WindowsUtils(base.BaseOSUtils): 'w32tm failed to configure NTP.\nOutput: %(out)s\nError:' ' %(err)s' % {'out': out, 'err': err}) + def get_network_adapter_name_by_mac_address(self, mac_address): + iface_index_list = [ + net_addr for net_addr + in network.get_adapter_addresses() + if net_addr["mac_address"] is not None and + net_addr["mac_address"].lower() == mac_address.lower()] + + if not iface_index_list: + raise exception.ItemNotFoundException( + 'Network interface with MAC address "%s" not found' % + mac_address) + + if len(iface_index_list) > 1: + raise exception.CloudbaseInitException( + 'Multiple network interfaces with MAC address "%s" exist' % + mac_address) + + return iface_index_list[0]["friendly_name"] + def set_network_adapter_mtu(self, name, mtu): if not self.check_os_version(6, 0): raise exception.CloudbaseInitException( diff --git a/cloudbaseinit/tests/osutils/test_windows.py b/cloudbaseinit/tests/osutils/test_windows.py index 4bea901b..cbc86696 100644 --- a/cloudbaseinit/tests/osutils/test_windows.py +++ b/cloudbaseinit/tests/osutils/test_windows.py @@ -1991,6 +1991,58 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase): self._test_set_ntp_client_config(sysnative=False, ret_val='fake return value') + @mock.patch("cloudbaseinit.utils.windows.network." + "get_adapter_addresses") + def _test_get_network_adapter_name_by_mac_address( + self, mock_get_adapter_addresses, + no_adapters_found=False, + multiple_adapters_found=False): + + mock.sentinel.mac_address = "aa:bb:cc:dd:ee:ff" + + if no_adapters_found: + mock_get_adapter_addresses.return_value = [] + elif multiple_adapters_found: + mock_get_adapter_addresses.return_value = [{ + "mac_address": mock.sentinel.mac_address, + "friendly_name": mock.sentinel.friendly_name, + }, { + "mac_address": mock.sentinel.mac_address, + "friendly_name": mock.sentinel.friendly_name2, + }] + else: + mock_get_adapter_addresses.return_value = [{ + "mac_address": mock.sentinel.mac_address.upper(), + "friendly_name": mock.sentinel.friendly_name, + }] + + if no_adapters_found: + with self.assertRaises(exception.ItemNotFoundException): + self._winutils.get_network_adapter_name_by_mac_address( + mock.sentinel.mac_address) + elif multiple_adapters_found: + with self.assertRaises(exception.CloudbaseInitException): + self._winutils.get_network_adapter_name_by_mac_address( + mock.sentinel.mac_address) + else: + self.assertEqual( + mock.sentinel.friendly_name, + self._winutils.get_network_adapter_name_by_mac_address( + mock.sentinel.mac_address)) + + mock_get_adapter_addresses.assert_called_once_with() + + def test_get_network_adapter_name_by_mac_address(self): + self._test_get_network_adapter_name_by_mac_address() + + def test_get_network_adapter_name_by_mac_address_no_adapters(self): + self._test_get_network_adapter_name_by_mac_address( + no_adapters_found=True) + + def test_get_network_adapter_name_by_mac_address_multiple_adapters(self): + self._test_get_network_adapter_name_by_mac_address( + multiple_adapters_found=True) + @mock.patch('cloudbaseinit.osutils.windows.WindowsUtils' '.execute_process') @mock.patch('cloudbaseinit.osutils.windows.WindowsUtils'