Browse Source

Network fields schema validation

Signed-off-by: Dimitar Bonev <[email protected]>
Dimitar Bonev 9 years ago
parent
commit
3a72edb906
3 changed files with 70 additions and 2 deletions
  1. 28 1
      compose/config/fields_schema_v2.json
  2. 1 1
      docs/networking.md
  3. 41 0
      tests/unit/config/config_test.py

+ 28 - 1
compose/config/fields_schema_v2.json

@@ -41,7 +41,34 @@
   "definitions": {
     "network": {
       "id": "#/definitions/network",
-      "type": "object"
+      "type": "object",
+      "properties": {
+        "driver": {"type": "string"},
+        "driver_opts": {
+          "type": "object",
+          "patternProperties": {
+            "^.+$": {"type": ["string", "number"]}
+          }
+        },
+        "ipam": {
+            "type": "object",
+            "properties": {
+                "driver": {"type": "string"},
+                "config": {
+                    "type": "array"
+                }
+            },
+            "additionalProperties": false
+        },
+        "external": {
+          "type": ["boolean", "object"],
+          "properties": {
+            "name": {"type": "string"}
+          },
+          "additionalProperties": false
+        }
+      },
+      "additionalProperties": false
     },
     "volume": {
       "id": "#/definitions/volume",

+ 1 - 1
docs/networking.md

@@ -106,7 +106,7 @@ Here's an example Compose file defining two custom networks. The `proxy` service
       back:
         # Use a custom driver which takes special options
         driver: my-custom-driver
-        options:
+        driver_opts:
           foo: "1"
           bar: "2"
 

+ 41 - 0
tests/unit/config/config_test.py

@@ -88,11 +88,26 @@ class ConfigTest(unittest.TestCase):
                         'driver': 'default',
                         'driver_opts': {'beep': 'boop'}
                     }
+                },
+                'networks': {
+                    'default': {
+                        'driver': 'bridge',
+                        'driver_opts': {'beep': 'boop'}
+                    },
+                    'with_ipam': {
+                        'ipam': {
+                            'driver': 'default',
+                            'config': [
+                                {'subnet': '172.28.0.0/16'}
+                            ]
+                        }
+                    }
                 }
             }, 'working_dir', 'filename.yml')
         )
         service_dicts = config_data.services
         volume_dict = config_data.volumes
+        networks_dict = config_data.networks
         self.assertEqual(
             service_sort(service_dicts),
             service_sort([
@@ -113,6 +128,20 @@ class ConfigTest(unittest.TestCase):
                 'driver_opts': {'beep': 'boop'}
             }
         })
+        self.assertEqual(networks_dict, {
+            'default': {
+                'driver': 'bridge',
+                'driver_opts': {'beep': 'boop'}
+            },
+            'with_ipam': {
+                'ipam': {
+                    'driver': 'default',
+                    'config': [
+                        {'subnet': '172.28.0.0/16'}
+                    ]
+                }
+            }
+        })
 
     def test_named_volume_config_empty(self):
         config_details = build_config_details({
@@ -191,6 +220,18 @@ class ConfigTest(unittest.TestCase):
                 )
             )
 
+    def test_load_throws_error_with_invalid_network_fields(self):
+        with self.assertRaises(ConfigurationError):
+            config.load(
+                build_config_details({
+                    'version': 2,
+                    'services': {'web': 'busybox:latest'},
+                    'networks': {
+                        'invalid': {'foo', 'bar'}
+                    }
+                }, 'working_dir', 'filename.yml')
+            )
+
     def test_load_config_invalid_service_names(self):
         for invalid_name in ['?not?allowed', ' ', '', '!', '/', '\xe2']:
             with pytest.raises(ConfigurationError) as exc: