docker: Allow publishing of ports with the same number but different protocol (#38412)

* Don't deduplicate docker container ports with different protocols

* Test _parse_exposed_ports
This commit is contained in:
Sharp Hall 2018-06-15 12:36:20 -04:00 committed by Ryan Brown
parent f21307da91
commit 3935cce394
3 changed files with 29 additions and 3 deletions

View file

@ -1038,6 +1038,8 @@ class TaskParameters(DockerBaseClass):
protocol = 'tcp' protocol = 'tcp'
port = int(publish_port) port = int(publish_port)
for exposed_port in exposed: for exposed_port in exposed:
if exposed_port[1] != protocol:
continue
if isinstance(exposed_port[0], string_types) and '-' in exposed_port[0]: if isinstance(exposed_port[0], string_types) and '-' in exposed_port[0]:
start_port, end_port = exposed_port[0].split('-') start_port, end_port = exposed_port[0].split('-')
if int(start_port) <= port <= int(end_port): if int(start_port) <= port <= int(end_port):
@ -1229,7 +1231,7 @@ class Container(DockerBaseClass):
# "ExposedPorts": null returns None type & causes AttributeError - PR #5517 # "ExposedPorts": null returns None type & causes AttributeError - PR #5517
if config.get('ExposedPorts') is not None: if config.get('ExposedPorts') is not None:
expected_exposed = [re.sub(r'/.+$', '', p) for p in config.get('ExposedPorts', dict()).keys()] expected_exposed = [self._normalize_port(p) for p in config.get('ExposedPorts', dict()).keys()]
else: else:
expected_exposed = [] expected_exposed = []
@ -1644,10 +1646,10 @@ class Container(DockerBaseClass):
self.log('_get_expected_exposed') self.log('_get_expected_exposed')
image_ports = [] image_ports = []
if image: if image:
image_ports = [re.sub(r'/.+$', '', p) for p in (image['ContainerConfig'].get('ExposedPorts') or {}).keys()] image_ports = [self._normalize_port(p) for p in (image['ContainerConfig'].get('ExposedPorts') or {}).keys()]
param_ports = [] param_ports = []
if self.parameters.ports: if self.parameters.ports:
param_ports = [str(p[0]) for p in self.parameters.ports] param_ports = [str(p[0]) + '/' + p[1] for p in self.parameters.ports]
result = list(set(image_ports + param_ports)) result = list(set(image_ports + param_ports))
self.log(result, pretty_print=True) self.log(result, pretty_print=True)
return result return result
@ -1688,6 +1690,11 @@ class Container(DockerBaseClass):
results.append("%s%s%s" % (key, join_with, value)) results.append("%s%s%s" % (key, join_with, value))
return results return results
def _normalize_port(self, port):
if '/' not in port:
return port + '/tcp'
return port
class ContainerManager(DockerBaseClass): class ContainerManager(DockerBaseClass):
''' '''

View file

@ -0,0 +1,19 @@
import unittest
from ansible.modules.cloud.docker.docker_container import TaskParameters
class TestTaskParameters(unittest.TestCase):
"""Unit tests for TaskParameters."""
def test_parse_exposed_ports_tcp_udp(self):
"""
Ensure _parse_exposed_ports does not cancel ports with the same
number but different protocol.
"""
task_params = TaskParameters.__new__(TaskParameters)
task_params.exposed_ports = None
result = task_params._parse_exposed_ports([80, '443', '443/udp'])
self.assertTrue((80, 'tcp') in result)
self.assertTrue((443, 'tcp') in result)
self.assertTrue((443, 'udp') in result)