diff --git a/os_vif/internal/command/ip/api.py b/os_vif/internal/command/ip/api.py index 537307ad..e442d394 100644 --- a/os_vif/internal/command/ip/api.py +++ b/os_vif/internal/command/ip/api.py @@ -23,6 +23,6 @@ LOG = logging.getLogger(__name__) def _get_impl(): if os.name == 'nt': - return win_ip_lib + return win_ip_lib.Netifaces() else: - return linux_ip_lib + return linux_ip_lib.PyRoute2() diff --git a/os_vif/internal/command/ip/ip_command.py b/os_vif/internal/command/ip/ip_command.py index a5c8c34a..70605622 100644 --- a/os_vif/internal/command/ip/ip_command.py +++ b/os_vif/internal/command/ip/ip_command.py @@ -59,3 +59,11 @@ class IpCommand(object): :param dev_type: String network device type (TYPE_VETH, TYPE_VLAN) :return: status of the command execution """ + + @abc.abstractmethod + def exists(self, device): + """Method to dectect if a device exists. + + :param device: A network device (string) + :return: True if device exists else False + """ diff --git a/os_vif/internal/command/ip/windows/impl_netifaces.py b/os_vif/internal/command/ip/windows/impl_netifaces.py index eda20962..a17c1755 100644 --- a/os_vif/internal/command/ip/windows/impl_netifaces.py +++ b/os_vif/internal/command/ip/windows/impl_netifaces.py @@ -17,29 +17,30 @@ import netifaces from oslo_log import log as logging from os_vif import exception - +from os_vif.internal.command.ip import ip_command LOG = logging.getLogger(__name__) -def exists(device): - """Return True if the device exists in the namespace.""" - try: - return bool(netifaces.ifaddresses(device)) - except ValueError: - LOG.warning("The device does not exist on the system: %s", device) - except OSError: - LOG.error("Failed to get interface addresses: %s", device) - return False +class Netifaces(ip_command.IpCommand): + def exists(self, device): + """Return True if the device exists in the namespace.""" + try: + return bool(netifaces.ifaddresses(device)) + except ValueError: + LOG.warning("The device does not exist on the system: %s", device) + except OSError: + LOG.error("Failed to get interface addresses: %s", device) + return False -def set(*args): - exception.NotImplementedForOS(function='ip.set', os='Windows') + def set(self, device, check_exit_code=None, state=None, mtu=None, + address=None, promisc=None): + exception.NotImplementedForOS(function='ip.set', os='Windows') + def add(self, device, dev_type, check_exit_code=None, peer=None, link=None, + vlan_id=None): + exception.NotImplementedForOS(function='ip.add', os='Windows') -def add(*args): - exception.NotImplementedForOS(function='ip.add', os='Windows') - - -def delete(*args): - exception.NotImplementedForOS(function='ip.delete', os='Windows') + def delete(self, device, check_exit_code=None): + exception.NotImplementedForOS(function='ip.delete', os='Windows') diff --git a/os_vif/tests/unit/internal/command/ip/test_api.py b/os_vif/tests/unit/internal/command/ip/test_api.py new file mode 100644 index 00000000..cabaa688 --- /dev/null +++ b/os_vif/tests/unit/internal/command/ip/test_api.py @@ -0,0 +1,32 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from os_vif.tests.unit import base + +from os_vif.internal.command.ip import api +from os_vif.internal.command.ip.linux import impl_pyroute2 as linux_ip_lib +from os_vif.internal.command.ip.windows import impl_netifaces as win_ip_lib + + +class TestIpApi(base.TestCase): + + @mock.patch("os.name", "nt") + def test_get_impl_windows(self): + ip_lib = api._get_impl() + self.assertIsInstance(ip_lib, win_ip_lib.Netifaces) + + @mock.patch("os.name", "posix") + def test_get_impl_linux(self): + ip_lib = api._get_impl() + self.assertIsInstance(ip_lib, linux_ip_lib.PyRoute2) diff --git a/os_vif/tests/unit/internal/command/ip/windows/test_impl_netifaces.py b/os_vif/tests/unit/internal/command/ip/windows/test_impl_netifaces.py index 71ddbec7..f2c094e1 100644 --- a/os_vif/tests/unit/internal/command/ip/windows/test_impl_netifaces.py +++ b/os_vif/tests/unit/internal/command/ip/windows/test_impl_netifaces.py @@ -23,22 +23,23 @@ class TestIPDevice(base.TestCase): super(TestIPDevice, self).setUp() self.device_name = 'test_device' self.mock_log = mock.patch.object(ip_lib, "LOG").start() + self.ip_lib = ip_lib.Netifaces() @mock.patch.object(netifaces, 'ifaddresses', return_value=True) def test_exists(self, mock_ifaddresses): - self.assertTrue(ip_lib.exists(self.device_name)) + self.assertTrue(self.ip_lib.exists(self.device_name)) mock_ifaddresses.assert_called_once_with(self.device_name) @mock.patch.object(netifaces, 'ifaddresses', side_effect=ValueError()) def test_exists_not_found(self, mock_ifaddresses): - self.assertFalse(ip_lib.exists(self.device_name)) + self.assertFalse(self.ip_lib.exists(self.device_name)) mock_ifaddresses.assert_called_once_with(self.device_name) self.mock_log.warning.assert_called_once_with( "The device does not exist on the system: %s", self.device_name) @mock.patch.object(netifaces, 'ifaddresses', side_effect=OSError()) def test_exists_os_error_exception(self, mock_ifaddresses): - self.assertFalse(ip_lib.exists(self.device_name)) + self.assertFalse(self.ip_lib.exists(self.device_name)) mock_ifaddresses.assert_called_once_with(self.device_name) self.mock_log.error.assert_called_once_with( "Failed to get interface addresses: %s", self.device_name)