Be systematic about parsing and validating hostnames and addresses

This adds a parse_address(pattern) utility function that returns
(host,port), and uses it wherever where we accept IPv4 and IPv6
addresses and hostnames (or host patterns): the inventory parser
the the add_host action plugin.

It also introduces a more extensive set of unit tests that supersedes
the old add_host unit tests (which didn't actually test add_host, but
only the parsing function).
This commit is contained in:
Abhijit Menon-Sen
2015-08-31 10:37:09 +05:30
parent 49803509b4
commit 065bb52109
7 changed files with 283 additions and 139 deletions

View File

@@ -0,0 +1,56 @@
import unittest
from ansible.parsing.utils.addresses import parse_address
class TestParseAddress(unittest.TestCase):
tests = {
# IPv4 addresses
'192.0.2.3': ['192.0.2.3', None],
'192.0.2.3:23': ['192.0.2.3', 23],
# IPv6 addresses
'::': ['::', None],
'::1': ['::1', None],
'[::1]:442': ['::1', 442],
'abcd:ef98:7654:3210:abcd:ef98:7654:3210': ['abcd:ef98:7654:3210:abcd:ef98:7654:3210', None],
'[abcd:ef98:7654:3210:abcd:ef98:7654:3210]:42': ['abcd:ef98:7654:3210:abcd:ef98:7654:3210', 42],
# Hostnames
'some-host': ['some-host', None],
'some-host:80': ['some-host', 80],
'some.host.com:492': ['some.host.com', 492],
'[some.host.com]:493': ['some.host.com', 493],
# Various errors
'': [None, None],
'some..host': [None, None],
'some.': [None, None],
'[example.com]': [None, None],
}
range_tests = {
'192.0.2.[3:10]': ['192.0.2.[3:10]', None],
'192.0.2.[3:10]:23': ['192.0.2.[3:10]', 23],
'abcd:ef98::7654:[1:9]': ['abcd:ef98::7654:[1:9]', None],
'[abcd:ef98::7654:[6:32]]:2222': ['abcd:ef98::7654:[6:32]', 2222],
'foo[a:b]:42': ['foo[a:b]', 42],
'foo[a-b]:32': [None, None],
'foo[x-y]': [None, None],
}
def test_without_ranges(self):
for t in self.tests:
test = self.tests[t]
(host, port) = parse_address(t)
assert host == test[0]
assert port == test[1]
def test_with_ranges(self):
for t in self.range_tests:
test = self.range_tests[t]
(host, port) = parse_address(t, allow_ranges=True)
assert host == test[0]
assert port == test[1]

View File

@@ -1,47 +0,0 @@
import unittest
from ansible.plugins.action import add_host
class TestAddHost(unittest.TestCase):
def test_hostname(self):
host, port = add_host._parse_ip_host_and_port('some-remote-host')
assert host == 'some-remote-host'
assert port is None
def test_hostname_with_port(self):
host, port = add_host._parse_ip_host_and_port('some-remote-host:80')
assert host == 'some-remote-host'
assert port == '80'
def test_parse_ip_host_and_port_v4(self):
host, port = add_host._parse_ip_host_and_port('8.8.8.8')
assert host == '8.8.8.8'
assert port is None
def test_parse_ip_host_and_port_v4_and_port(self):
host, port = add_host._parse_ip_host_and_port('8.8.8.8:80')
assert host == '8.8.8.8'
assert port == '80'
def test_parse_ip_host_and_port_v6(self):
host, port = add_host._parse_ip_host_and_port(
'dead:beef:dead:beef:dead:beef:dead:beef'
)
assert host == 'dead:beef:dead:beef:dead:beef:dead:beef'
assert port is None
def test_parse_ip_host_and_port_v6_with_brackets(self):
host, port = add_host._parse_ip_host_and_port(
'[dead:beef:dead:beef:dead:beef:dead:beef]'
)
assert host == 'dead:beef:dead:beef:dead:beef:dead:beef'
assert port is None
def test_parse_ip_host_and_port_v6_with_brackets_and_port(self):
host, port = add_host._parse_ip_host_and_port(
'[dead:beef:dead:beef:dead:beef:dead:beef]:80'
)
assert host == 'dead:beef:dead:beef:dead:beef:dead:beef'
assert port == '80'