Add label config validation, fixes #4904

Signed-off-by: Drew Romanyk <drewiswaycool@gmail.com>
This commit is contained in:
Drew Romanyk 2017-11-30 11:57:42 -06:00
parent d48002a09d
commit a1ac289943
12 changed files with 248 additions and 49 deletions

View File

@ -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",

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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):