summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToshio Kuratomi <a.badger@gmail.com>2015-08-23 10:24:03 -0700
committerToshio Kuratomi <a.badger@gmail.com>2015-08-23 10:24:03 -0700
commite11d56c06baa7aebd4148e99ddad23ff4ee6f67b (patch)
treec6372eccd8eb5eb648822ab115830b9c01df8067
parent47d9e7ca93808383568c3019ac32de7e7ba05ac5 (diff)
parent09e4eac2e5fa055e117c47ec53eebb08e895db30 (diff)
downloadansible-e11d56c06baa7aebd4148e99ddad23ff4ee6f67b.tar.gz
Merge pull request #11747 from amenonsen/8682-rebase
Fix a parsing bug that prevents IPv6 addresses from being used with add_host
-rw-r--r--lib/ansible/plugins/action/add_host.py28
-rw-r--r--test/units/plugins/action/test_add_host.py47
2 files changed, 73 insertions, 2 deletions
diff --git a/lib/ansible/plugins/action/add_host.py b/lib/ansible/plugins/action/add_host.py
index 12c9febe95..cf2dab1737 100644
--- a/lib/ansible/plugins/action/add_host.py
+++ b/lib/ansible/plugins/action/add_host.py
@@ -20,6 +20,8 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
+import re
+
from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
@@ -38,8 +40,8 @@ class ActionModule(ActionBase):
new_name = self._task.args.get('name', self._task.args.get('hostname', None))
#vv("creating host via 'add_host': hostname=%s" % new_name)
- if ":" in new_name:
- new_name, new_port = new_name.split(":")
+ new_name, new_port = _parse_ip_host_and_port(new_name)
+ if new_port:
self._task.args['ansible_ssh_port'] = new_port
groups = self._task.args.get('groupname', self._task.args.get('groups', self._task.args.get('group', '')))
@@ -58,4 +60,26 @@ class ActionModule(ActionBase):
return dict(changed=True, add_host=dict(host_name=new_name, groups=new_groups, host_vars=host_vars))
+def _parse_ip_host_and_port(hostname):
+ """
+ Attempt to parse the hostname and port from a hostname, e.g.,
+ some-host-name
+ some-host-name:80
+ 8.8.8.8
+ 8.8.8.8:80
+ 2001:db8:0:1
+ [2001:db8:0:1]:80
+ """
+ if hostname.count(':') > 1:
+ match = re.match(
+ '\[(?P<ip>[^\]]+)\](:(?P<port>[0-9]+))?',
+ hostname
+ )
+ if match:
+ return match.group('ip'), match.group('port')
+ else:
+ return hostname, None
+ elif ':' in hostname:
+ return hostname.rsplit(':', 1)
+ return hostname, None
diff --git a/test/units/plugins/action/test_add_host.py b/test/units/plugins/action/test_add_host.py
new file mode 100644
index 0000000000..c694d387a3
--- /dev/null
+++ b/test/units/plugins/action/test_add_host.py
@@ -0,0 +1,47 @@
+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'