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'