Browse Source

Add label config validation, fixes #4904

Signed-off-by: Drew Romanyk <[email protected]>
Drew Romanyk 8 years ago
parent
commit
a1ac289943

+ 16 - 1
compose/config/config_schema_v1.json

@@ -78,7 +78,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
         "log_driver": {"type": "string"},
         "log_opt": {"type": "object"},
@@ -166,6 +166,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "constraints": {
       "service": {
         "id": "#/definitions/constraints/service",

+ 16 - 1
compose/config/config_schema_v2.0.json

@@ -158,7 +158,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -354,6 +354,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "blkio_limit": {
       "type": "object",
       "properties": {

+ 19 - 4
compose/config/config_schema_v2.1.json

@@ -88,7 +88,7 @@
                 "context": {"type": "string"},
                 "dockerfile": {"type": "string"},
                 "args": {"$ref": "#/definitions/list_or_dict"},
-                "labels": {"$ref": "#/definitions/list_or_dict"}
+                "labels": {"$ref": "#/definitions/labels"}
               },
               "additionalProperties": false
             }
@@ -183,7 +183,7 @@
         "image": {"type": "string"},
         "ipc": {"type": "string"},
         "isolation": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -350,7 +350,7 @@
         },
         "internal": {"type": "boolean"},
         "enable_ipv6": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -373,7 +373,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "name": {"type": "string"}
       },
       "additionalProperties": false
@@ -407,6 +407,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "blkio_limit": {
       "type": "object",
       "properties": {

+ 19 - 4
compose/config/config_schema_v2.2.json

@@ -88,7 +88,7 @@
                 "context": {"type": "string"},
                 "dockerfile": {"type": "string"},
                 "args": {"$ref": "#/definitions/list_or_dict"},
-                "labels": {"$ref": "#/definitions/list_or_dict"},
+                "labels": {"$ref": "#/definitions/labels"},
                 "cache_from": {"$ref": "#/definitions/list_of_strings"},
                 "network": {"type": "string"}
               },
@@ -189,7 +189,7 @@
         "init": {"type": ["boolean", "string"]},
         "ipc": {"type": "string"},
         "isolation": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -357,7 +357,7 @@
         },
         "internal": {"type": "boolean"},
         "enable_ipv6": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -380,7 +380,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "name": {"type": "string"}
       },
       "additionalProperties": false
@@ -414,6 +414,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "blkio_limit": {
       "type": "object",
       "properties": {

+ 19 - 4
compose/config/config_schema_v2.3.json

@@ -88,7 +88,7 @@
                 "context": {"type": "string"},
                 "dockerfile": {"type": "string"},
                 "args": {"$ref": "#/definitions/list_or_dict"},
-                "labels": {"$ref": "#/definitions/list_or_dict"},
+                "labels": {"$ref": "#/definitions/labels"},
                 "cache_from": {"$ref": "#/definitions/list_of_strings"},
                 "network": {"type": "string"},
                 "target": {"type": "string"},
@@ -192,7 +192,7 @@
         "init": {"type": ["boolean", "string"]},
         "ipc": {"type": "string"},
         "isolation": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -361,7 +361,7 @@
         },
         "internal": {"type": "boolean"},
         "enable_ipv6": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -384,7 +384,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "name": {"type": "string"}
       },
       "additionalProperties": false
@@ -418,6 +418,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "blkio_limit": {
       "type": "object",
       "properties": {

+ 19 - 4
compose/config/config_schema_v3.0.json

@@ -105,7 +105,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -223,7 +223,7 @@
       "properties": {
         "mode": {"type": "string"},
         "replicas": {"type": "integer"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "update_config": {
           "type": "object",
           "properties": {
@@ -310,7 +310,7 @@
           "additionalProperties": false
         },
         "internal": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -333,7 +333,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -366,6 +366,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "constraints": {
       "service": {
         "id": "#/definitions/constraints/service",

+ 20 - 5
compose/config/config_schema_v3.1.json

@@ -116,7 +116,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -252,7 +252,7 @@
       "properties": {
         "mode": {"type": "string"},
         "replicas": {"type": "integer"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "update_config": {
           "type": "object",
           "properties": {
@@ -339,7 +339,7 @@
           "additionalProperties": false
         },
         "internal": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -362,7 +362,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -378,7 +378,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -411,6 +411,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "constraints": {
       "service": {
         "id": "#/definitions/constraints/service",

+ 20 - 5
compose/config/config_schema_v3.2.json

@@ -117,7 +117,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -297,7 +297,7 @@
         "mode": {"type": "string"},
         "endpoint_mode": {"type": "string"},
         "replicas": {"type": "integer"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "update_config": {
           "type": "object",
           "properties": {
@@ -385,7 +385,7 @@
         },
         "internal": {"type": "boolean"},
         "attachable": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -408,7 +408,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -424,7 +424,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -457,6 +457,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "constraints": {
       "service": {
         "id": "#/definitions/constraints/service",

+ 22 - 7
compose/config/config_schema_v3.3.json

@@ -83,7 +83,7 @@
                 "context": {"type": "string"},
                 "dockerfile": {"type": "string"},
                 "args": {"$ref": "#/definitions/list_or_dict"},
-                "labels": {"$ref": "#/definitions/list_or_dict"},
+                "labels": {"$ref": "#/definitions/labels"},
                 "cache_from": {"$ref": "#/definitions/list_of_strings"}
               },
               "additionalProperties": false
@@ -151,7 +151,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -331,7 +331,7 @@
         "mode": {"type": "string"},
         "endpoint_mode": {"type": "string"},
         "replicas": {"type": "integer"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "update_config": {
           "type": "object",
           "properties": {
@@ -429,7 +429,7 @@
         },
         "internal": {"type": "boolean"},
         "attachable": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -452,7 +452,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -468,7 +468,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -484,7 +484,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -517,6 +517,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "constraints": {
       "service": {
         "id": "#/definitions/constraints/service",

+ 22 - 7
compose/config/config_schema_v3.4.json

@@ -85,7 +85,7 @@
                 "context": {"type": "string"},
                 "dockerfile": {"type": "string"},
                 "args": {"$ref": "#/definitions/list_or_dict"},
-                "labels": {"$ref": "#/definitions/list_or_dict"},
+                "labels": {"$ref": "#/definitions/labels"},
                 "cache_from": {"$ref": "#/definitions/list_of_strings"},
                 "network": {"type": "string"},
                 "target": {"type": "string"}
@@ -155,7 +155,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -336,7 +336,7 @@
         "mode": {"type": "string"},
         "endpoint_mode": {"type": "string"},
         "replicas": {"type": "integer"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "update_config": {
           "type": "object",
           "properties": {
@@ -437,7 +437,7 @@
         },
         "internal": {"type": "boolean"},
         "attachable": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -461,7 +461,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -477,7 +477,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -493,7 +493,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -526,6 +526,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "constraints": {
       "service": {
         "id": "#/definitions/constraints/service",

+ 22 - 7
compose/config/config_schema_v3.5.json

@@ -83,7 +83,7 @@
                 "context": {"type": "string"},
                 "dockerfile": {"type": "string"},
                 "args": {"$ref": "#/definitions/list_or_dict"},
-                "labels": {"$ref": "#/definitions/list_or_dict"},
+                "labels": {"$ref": "#/definitions/labels"},
                 "cache_from": {"$ref": "#/definitions/list_of_strings"},
                 "network": {"type": "string"},
                 "target": {"type": "string"},
@@ -154,7 +154,7 @@
         "hostname": {"type": "string"},
         "image": {"type": "string"},
         "ipc": {"type": "string"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 
         "logging": {
@@ -334,7 +334,7 @@
         "mode": {"type": "string"},
         "endpoint_mode": {"type": "string"},
         "replicas": {"type": "integer"},
-        "labels": {"$ref": "#/definitions/list_or_dict"},
+        "labels": {"$ref": "#/definitions/labels"},
         "update_config": {
           "type": "object",
           "properties": {
@@ -435,7 +435,7 @@
         },
         "internal": {"type": "boolean"},
         "attachable": {"type": "boolean"},
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -459,7 +459,7 @@
           },
           "additionalProperties": false
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -475,7 +475,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -491,7 +491,7 @@
             "name": {"type": "string"}
           }
         },
-        "labels": {"$ref": "#/definitions/list_or_dict"}
+        "labels": {"$ref": "#/definitions/labels"}
       },
       "additionalProperties": false
     },
@@ -524,6 +524,21 @@
       ]
     },
 
+    "labels": {
+      "oneOf": [
+        {
+          "type": "object",
+          "patternProperties": {
+            ".+": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
+      ]
+    },
+
     "constraints": {
       "service": {
         "id": "#/definitions/constraints/service",

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

@@ -2631,6 +2631,40 @@ class ConfigTest(unittest.TestCase):
         ]
         assert service_sort(service_dicts) == service_sort(expected)
 
+    def test_config_invalid_service_label_validation(self):
+        config_details = build_config_details(
+            {
+                'version': '3.5',
+                'services': {
+                    'web': {
+                        'image': 'busybox',
+                        'labels': {
+                            "key": 12345
+                        }
+                    },
+                },
+            }
+        )
+        with pytest.raises(ConfigurationError) as exc:
+            config.load(config_details)
+        assert "which is an invalid type, it should be a string" in exc.exconly()
+
+    def test_config_valid_service_label_validation(self):
+        config_details = build_config_details(
+            {
+                'version': '3.5',
+                'services': {
+                    'web': {
+                        'image': 'busybox',
+                        'labels': {
+                            "key": "string"
+                        }
+                    },
+                },
+            }
+        )
+        config.load(config_details)
+
 
 class NetworkModeTest(unittest.TestCase):