summaryrefslogtreecommitdiff
path: root/cloudinit/distros
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/distros')
-rw-r--r--cloudinit/distros/networking.py16
-rw-r--r--cloudinit/distros/tests/test_networking.py42
2 files changed, 56 insertions, 2 deletions
diff --git a/cloudinit/distros/networking.py b/cloudinit/distros/networking.py
index eecdccc6..e421a2ce 100644
--- a/cloudinit/distros/networking.py
+++ b/cloudinit/distros/networking.py
@@ -1,4 +1,5 @@
import abc
+import os
from cloudinit import net
@@ -79,8 +80,15 @@ class Networking(metaclass=abc.ABCMeta):
def is_bridge(self, devname: DeviceName) -> bool:
return net.is_bridge(devname)
+ @abc.abstractmethod
def is_physical(self, devname: DeviceName) -> bool:
- return net.is_physical(devname)
+ """
+ Is ``devname`` a physical network device?
+
+ Examples of non-physical network devices: bonds, bridges, tunnels,
+ loopback devices.
+ """
+ pass
def is_renamed(self, devname: DeviceName) -> bool:
return net.is_renamed(devname)
@@ -103,7 +111,8 @@ class Networking(metaclass=abc.ABCMeta):
class BSDNetworking(Networking):
"""Implementation of networking functionality shared across BSDs."""
- pass
+ def is_physical(self, devname: DeviceName) -> bool:
+ raise NotImplementedError()
class LinuxNetworking(Networking):
@@ -126,3 +135,6 @@ class LinuxNetworking(Networking):
def is_netfail_standby(self, devname: DeviceName) -> bool:
return net.is_netfail_standby(devname)
+
+ def is_physical(self, devname: DeviceName) -> bool:
+ return os.path.exists(net.sys_dev_path(devname, "device"))
diff --git a/cloudinit/distros/tests/test_networking.py b/cloudinit/distros/tests/test_networking.py
new file mode 100644
index 00000000..2acb12f4
--- /dev/null
+++ b/cloudinit/distros/tests/test_networking.py
@@ -0,0 +1,42 @@
+from unittest import mock
+
+import pytest
+
+from cloudinit.distros.networking import BSDNetworking, LinuxNetworking
+
+
+@pytest.yield_fixture
+def sys_class_net(tmpdir):
+ sys_class_net_path = tmpdir.join("sys/class/net")
+ sys_class_net_path.ensure_dir()
+ with mock.patch(
+ "cloudinit.net.get_sys_class_path",
+ return_value=sys_class_net_path.strpath + "/",
+ ):
+ yield sys_class_net_path
+
+
+class TestBSDNetworkingIsPhysical:
+ def test_raises_notimplementederror(self):
+ with pytest.raises(NotImplementedError):
+ BSDNetworking().is_physical("eth0")
+
+
+class TestLinuxNetworkingIsPhysical:
+ def test_returns_false_by_default(self, sys_class_net):
+ assert not LinuxNetworking().is_physical("eth0")
+
+ def test_returns_false_if_devname_exists_but_not_physical(
+ self, sys_class_net
+ ):
+ devname = "eth0"
+ sys_class_net.join(devname).mkdir()
+ assert not LinuxNetworking().is_physical(devname)
+
+ def test_returns_true_if_device_is_physical(self, sys_class_net):
+ devname = "eth0"
+ device_dir = sys_class_net.join(devname)
+ device_dir.mkdir()
+ device_dir.join("device").write("")
+
+ assert LinuxNetworking().is_physical(devname)