From bfc7ac4995851097503d78d5af80610adcad3aa6 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 5 Jun 2017 14:33:20 -0700 Subject: [PATCH] Always convert port values in ServicePort to integer Signed-off-by: Joffrey F --- compose/config/types.py | 16 ++++++++++++++++ tests/unit/config/types_test.py | 21 +++++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/compose/config/types.py b/compose/config/types.py index d853d84f4..85daa70b0 100644 --- a/compose/config/types.py +++ b/compose/config/types.py @@ -263,6 +263,22 @@ class ServiceSecret(namedtuple('_ServiceSecret', 'source target uid gid mode')): class ServicePort(namedtuple('_ServicePort', 'target published protocol mode external_ip')): + def __new__(cls, target, published, *args, **kwargs): + try: + if target: + target = int(target) + except ValueError: + raise ConfigurationError('Invalid target port: {}'.format(target)) + + try: + if published: + published = int(published) + except ValueError: + raise ConfigurationError('Invalid published port: {}'.format(published)) + + return super(ServicePort, cls).__new__( + cls, target, published, *args, **kwargs + ) @classmethod def parse(cls, spec): diff --git a/tests/unit/config/types_test.py b/tests/unit/config/types_test.py index 83d6270d2..10b698fe3 100644 --- a/tests/unit/config/types_test.py +++ b/tests/unit/config/types_test.py @@ -57,15 +57,15 @@ class TestServicePort(object): def test_parse_simple_target_port(self): ports = ServicePort.parse(8000) assert len(ports) == 1 - assert ports[0].target == '8000' + assert ports[0].target == 8000 def test_parse_complete_port_definition(self): port_def = '1.1.1.1:3000:3000/udp' ports = ServicePort.parse(port_def) assert len(ports) == 1 assert ports[0].repr() == { - 'target': '3000', - 'published': '3000', + 'target': 3000, + 'published': 3000, 'external_ip': '1.1.1.1', 'protocol': 'udp', } @@ -77,7 +77,7 @@ class TestServicePort(object): assert len(ports) == 1 assert ports[0].legacy_repr() == port_def + '/tcp' assert ports[0].repr() == { - 'target': '3000', + 'target': 3000, 'external_ip': '1.1.1.1', } @@ -86,14 +86,19 @@ class TestServicePort(object): assert len(ports) == 2 reprs = [p.repr() for p in ports] assert { - 'target': '4000', - 'published': '25000' + 'target': 4000, + 'published': 25000 } in reprs assert { - 'target': '4001', - 'published': '25001' + 'target': 4001, + 'published': 25001 } in reprs + def test_parse_invalid_port(self): + port_def = '4000p' + with pytest.raises(ConfigurationError): + ServicePort.parse(port_def) + class TestVolumeSpec(object):