diff options
Diffstat (limited to 'cloudinit/net')
-rw-r--r-- | cloudinit/net/__init__.py | 19 | ||||
-rw-r--r-- | cloudinit/net/tests/test_init.py | 33 |
2 files changed, 47 insertions, 5 deletions
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py index 67e3d578..08eaf0a3 100644 --- a/cloudinit/net/__init__.py +++ b/cloudinit/net/__init__.py @@ -6,13 +6,14 @@ # This file is part of cloud-init. See LICENSE file for license information. import errno +import ipaddress import logging import os import re from functools import partial -from cloudinit.net.network_state import mask_to_net_prefix from cloudinit import util +from cloudinit.net.network_state import mask_to_net_prefix from cloudinit.url_helper import UrlError, readurl LOG = logging.getLogger(__name__) @@ -961,6 +962,22 @@ def has_url_connectivity(url): return True +def is_ip_address(s: str) -> bool: + """Returns a bool indicating if ``s`` is an IP address. + + :param s: + The string to test. + + :return: + A bool indicating if the string contains an IP address or not. + """ + try: + ipaddress.ip_address(s) + except ValueError: + return False + return True + + class EphemeralIPv4Network(object): """Context manager which sets up temporary static network configuration. diff --git a/cloudinit/net/tests/test_init.py b/cloudinit/net/tests/test_init.py index a965699a..909f43c8 100644 --- a/cloudinit/net/tests/test_init.py +++ b/cloudinit/net/tests/test_init.py @@ -2,16 +2,19 @@ import copy import errno -import httpretty +import ipaddress import os -import requests import textwrap from unittest import mock +import httpretty +import pytest +import requests + import cloudinit.net as net -from cloudinit.util import ensure_file, write_file, ProcessExecutionError -from cloudinit.tests.helpers import CiTestCase, HttprettyTestCase from cloudinit import safeyaml as yaml +from cloudinit.tests.helpers import CiTestCase, HttprettyTestCase +from cloudinit.util import ProcessExecutionError, ensure_file, write_file class TestSysDevPath(CiTestCase): @@ -1291,4 +1294,26 @@ class TestNetFailOver(CiTestCase): m_standby.return_value = False self.assertFalse(net.is_netfailover(devname, driver)) + +class TestIsIpAddress: + """Tests for net.is_ip_address. + + Instead of testing with values we rely on the ipaddress stdlib module to + handle all values correctly, so simply test that is_ip_address defers to + the ipaddress module correctly. + """ + + @pytest.mark.parametrize('ip_address_side_effect,expected_return', ( + (ValueError, False), + (lambda _: ipaddress.IPv4Address('192.168.0.1'), True), + (lambda _: ipaddress.IPv6Address('2001:db8::'), True), + )) + def test_is_ip_address(self, ip_address_side_effect, expected_return): + with mock.patch('cloudinit.net.ipaddress.ip_address', + side_effect=ip_address_side_effect) as m_ip_address: + ret = net.is_ip_address(mock.sentinel.ip_address_in) + assert expected_return == ret + expected_call = mock.call(mock.sentinel.ip_address_in) + assert [expected_call] == m_ip_address.call_args_list + # vi: ts=4 expandtab |