diff --git a/changelogs/fragments/367-docker_container-ports-validation.yml b/changelogs/fragments/367-docker_container-ports-validation.yml new file mode 100644 index 000000000..8c9dd1cb7 --- /dev/null +++ b/changelogs/fragments/367-docker_container-ports-validation.yml @@ -0,0 +1,2 @@ +bugfixes: + - "docker_container - fail with a meaningful message instead of crashing if a port is specified with more than three colon-separated parts (https://github.com/ansible-collections/community.docker/pull/367, https://github.com/ansible-collections/community.docker/issues/365)." diff --git a/plugins/modules/docker_container.py b/plugins/modules/docker_container.py index 6f3104776..4d36d5a25 100644 --- a/plugins/modules/docker_container.py +++ b/plugins/modules/docker_container.py @@ -1855,6 +1855,9 @@ def _parse_publish_ports(self): port_binds = [(ipaddr, port) for port in parse_port_range(parts[1], self.client)] else: port_binds = len(container_ports) * [(ipaddr,)] + else: + self.fail(('Invalid port description "%s" - expected 1 to 3 colon-separated parts, but got %d. ' + 'Maybe you forgot to use square brackets ([...]) around an IPv6 address?') % (port, p_len)) for bind, container_port in zip(port_binds, container_ports): idx = '{0}/{1}'.format(container_port, protocol) if protocol else container_port diff --git a/tests/integration/targets/docker_container/tasks/tests/ports.yml b/tests/integration/targets/docker_container/tasks/tests/ports.yml index 370d038ea..919878844 100644 --- a/tests/integration/targets/docker_container/tasks/tests/ports.yml +++ b/tests/integration/targets/docker_container/tasks/tests/ports.yml @@ -7,6 +7,52 @@ set_fact: cnames: "{{ cnames + [cname, cname2] }}" +#################################################################### +## published_ports: error handling ################################# +#################################################################### + +- name: published_ports -- non-closing square bracket + docker_container: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + name: "{{ cname }}" + state: started + published_ports: + - "[::1:2000:3000" + register: published_ports_1 + ignore_errors: true + +- name: published_ports -- forgot square brackets for IPv6 + docker_container: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + name: "{{ cname }}" + state: started + published_ports: + - "::1:2000:3000" + register: published_ports_2 + ignore_errors: true + +- name: published_ports -- disallow hostnames + docker_container: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + name: "{{ cname }}" + state: started + published_ports: + - "foo:2000:3000" + register: published_ports_3 + ignore_errors: true + +- assert: + that: + - published_ports_1 is failed + - published_ports_1.msg == 'Cannot find closing "]" in input "[::1:2000:3000" for opening "[" at index 1!' + - published_ports_2 is failed + - published_ports_2.msg == 'Invalid port description "::1:2000:3000" - expected 1 to 3 colon-separated parts, but got 5. Maybe you forgot to use square brackets ([...]) around an IPv6 address?' + - published_ports_3 is failed + - "published_ports_3.msg == 'Bind addresses for published ports must be IPv4 or IPv6 addresses, not hostnames. Use the dig lookup to resolve hostnames. (Found hostname: foo)'" + #################################################################### ## published_ports: all ############################################ ####################################################################