1
0
Эх сурвалжийг харах

Support for host address in port bindings (Closes #267)

Mark Steve Samson 11 жил өмнө
parent
commit
4f7cbc3812

+ 19 - 6
fig/service.py

@@ -214,12 +214,7 @@ class Service(object):
 
         if options.get('ports', None) is not None:
             for port in options['ports']:
-                port = str(port)
-                if ':' in port:
-                    external_port, internal_port = port.split(':', 1)
-                else:
-                    external_port, internal_port = (None, port)
-
+                internal_port, external_port = split_port(port)
                 port_bindings[internal_port] = external_port
 
         volume_bindings = {}
@@ -407,3 +402,21 @@ def split_volume(v):
         return v.split(':', 1)
     else:
         return (None, v)
+
+
+def split_port(port):
+    port = str(port)
+    external_ip = None
+    if ':' in port:
+        external_port, internal_port = port.rsplit(':', 1)
+        if ':' in external_port:
+            external_ip, external_port = external_port.split(':', 1)
+    else:
+        external_port, internal_port = (None, port)
+    if external_ip:
+        if external_port:
+            external_port = (external_ip, external_port)
+        else:
+            external_port = (external_ip,)
+    return internal_port, external_port
+

+ 21 - 0
tests/integration/service_test.py

@@ -231,6 +231,27 @@ class ServiceTest(DockerClientTestCase):
         self.assertIn('8000/tcp', container['NetworkSettings']['Ports'])
         self.assertEqual(container['NetworkSettings']['Ports']['8000/tcp'][0]['HostPort'], '8001')
 
+    def test_port_with_explicit_interface(self):
+        service = self.create_service('web', ports=[
+            '127.0.0.1:8001:8000',
+            '0.0.0.0:9001:9000',
+        ])
+        container = service.start_container().inspect()
+        self.assertEqual(container['NetworkSettings']['Ports'], {
+            '8000/tcp': [
+                {
+                    'HostIp': '127.0.0.1',
+                    'HostPort': '8001',
+                },
+            ],
+            '9000/tcp': [
+                {
+                    'HostIp': '0.0.0.0',
+                    'HostPort': '9001',
+                },
+            ],
+        })
+
     def test_scale(self):
         service = self.create_service('web')
         service.scale(1)

+ 16 - 1
tests/unit/service_test.py

@@ -2,7 +2,7 @@ from __future__ import unicode_literals
 from __future__ import absolute_import
 from .. import unittest
 from fig import Service
-from fig.service import ConfigError
+from fig.service import ConfigError, split_port
 
 class ServiceTest(unittest.TestCase):
     def test_name_validations(self):
@@ -27,3 +27,18 @@ class ServiceTest(unittest.TestCase):
     def test_config_validation(self):
         self.assertRaises(ConfigError, lambda: Service(name='foo', port=['8000']))
         Service(name='foo', ports=['8000'])
+
+    def test_split_port(self):
+        internal_port, external_port = split_port("127.0.0.1:1000:2000")
+        self.assertEqual(internal_port, "2000")
+        self.assertEqual(external_port, ("127.0.0.1", "1000"))
+
+        internal_port, external_port = split_port("127.0.0.1::2000")
+        self.assertEqual(internal_port, "2000")
+        self.assertEqual(external_port, ("127.0.0.1",))
+
+        internal_port, external_port = split_port("1000:2000")
+        self.assertEqual(internal_port, "2000")
+        self.assertEqual(external_port, "1000")
+
+