Skip to content

Commit 554e628

Browse files
committed
add module jsonschema
1 parent 04c613c commit 554e628

6 files changed

Lines changed: 260 additions & 0 deletions

File tree

test_jsonschema/schemas/__init__.py

Whitespace-only changes.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
from zun.common.validation import parameter_types
14+
15+
_container_properties = {
16+
'name': parameter_types.container_name,
17+
'image': parameter_types.image_name,
18+
'command': parameter_types.command,
19+
'cpu': parameter_types.cpu,
20+
'memory': parameter_types.memory,
21+
'workdir': parameter_types.workdir,
22+
'image_pull_policy': parameter_types.image_pull_policy,
23+
'labels': parameter_types.labels,
24+
'environment': parameter_types.environment,
25+
}
26+
27+
container_create = {
28+
'type': 'object',
29+
'properties': _container_properties,
30+
'required': ['image'],
31+
'additionalProperties': False
32+
}

test_jsonschema/schemas/images.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
from zun.common.validation import parameter_types
14+
15+
_image_properties = {
16+
'image_id': parameter_types.image_id,
17+
'repo': parameter_types.repo,
18+
'tag': parameter_types.tag,
19+
'size': parameter_types.size
20+
}
21+
22+
image_create = {
23+
'type': 'object',
24+
'properties': _image_properties,
25+
'required': ['repo'],
26+
'additionalProperties': False
27+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import functools
14+
15+
from zun.common.validation import validators
16+
17+
18+
def validated(request_body_schema):
19+
"""Register a schema to validate a resource reference.
20+
21+
Registered schema will be used for validating a request body just before
22+
API method execution.
23+
24+
:param request_body_schema: a schema to validate the resource reference
25+
"""
26+
schema_validator = validators.SchemaValidator(request_body_schema)
27+
28+
def add_validator(func):
29+
@functools.wraps(func)
30+
def wrapper(*args, **kwargs):
31+
schema_validator.validate(kwargs)
32+
return func(*args, **kwargs)
33+
return wrapper
34+
return add_validator
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import copy
14+
15+
16+
boolean = {
17+
'type': 'boolean',
18+
'enum': [True, False]
19+
}
20+
21+
container_name = {
22+
'type': ['string', 'null'],
23+
'minLength': 2,
24+
'maxLength': 255,
25+
'pattern': '^[a-zA-Z0-9][a-zA-Z0-9_.-]+$'
26+
}
27+
28+
hex_uuid = {
29+
'type': 'string',
30+
'maxLength': 32,
31+
'minLength': 32,
32+
'pattern': '^[a-fA-F0-9]*$'
33+
}
34+
35+
image_name = {
36+
'type': 'string',
37+
'minLength': 2,
38+
'maxLength': 255,
39+
'pattern': '[a-zA-Z0-9][a-zA-Z0-9_.-]'
40+
}
41+
42+
command = {
43+
'type': ['string', 'null']
44+
}
45+
46+
cpu = {
47+
'type': ['number', 'string', 'null'],
48+
'pattern': '^[0-9]*(\.([0-9]+))?$',
49+
'minLength': 1
50+
}
51+
52+
# TODO(pksingh) Memory provided must be in MBs
53+
# Will find another way if people dont find it useful.
54+
memory = {
55+
'type': ['string', 'integer', 'null'],
56+
'minimum': 4,
57+
'pattern': '^[0-9]+$'
58+
}
59+
60+
workdir = {
61+
'type': ['string', 'null']
62+
}
63+
64+
image_pull_policy = {
65+
'type': ['string', 'null'],
66+
'enum': ['never', 'always', 'ifnotpresent', None]
67+
}
68+
69+
labels = {
70+
'type': ['object', 'null']
71+
}
72+
73+
environment = {
74+
'type': ['object', 'null']
75+
}
76+
77+
image_id = {
78+
'type': ['string', 'null'],
79+
'minLength': 2,
80+
'maxLength': 255,
81+
'pattern': '[a-zA-Z0-9][a-zA-Z0-9_.-]'
82+
}
83+
84+
repo = {
85+
'type': 'string',
86+
'minLength': 2,
87+
'maxLength': 255,
88+
'pattern': '[a-zA-Z0-9][a-zA-Z0-9_.-]'
89+
}
90+
91+
92+
tag = copy.deepcopy(image_id)
93+
94+
size = {
95+
'type': ['string', 'integer', 'null'],
96+
'pattern': '^[0-9]+[b|B|k|K|m|M|g|G]?$',
97+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import jsonschema
14+
15+
from zun.common import exception
16+
from zun.common.i18n import _
17+
18+
19+
class SchemaValidator(object):
20+
"""Resource reference validator class."""
21+
22+
validator_org = jsonschema.Draft4Validator
23+
24+
def __init__(self, schema):
25+
validators = {
26+
'minimum': self._validate_minimum,
27+
'maximum': self._validate_maximum
28+
}
29+
validator_cls = jsonschema.validators.extend(self.validator_org,
30+
validators)
31+
fc = jsonschema.FormatChecker()
32+
self.validator = validator_cls(schema, format_checker=fc)
33+
34+
def validate(self, *args, **kwargs):
35+
try:
36+
self.validator.validate(*args, **kwargs)
37+
except jsonschema.ValidationError as ex:
38+
if len(ex.path) > 0:
39+
detail = _("Invalid input for field '%(path)s'. Value: "
40+
"'%(value)s'. %(message)s") % {
41+
'path': ex.path.pop(),
42+
'value': ex.instance,
43+
'message': ex.message}
44+
else:
45+
detail = ex.message
46+
raise exception.SchemaValidationError(detail=detail)
47+
48+
def _number_from_str(self, instance):
49+
try:
50+
value = int(instance)
51+
except (ValueError, TypeError):
52+
try:
53+
value = float(instance)
54+
except (ValueError, TypeError):
55+
return None
56+
return value
57+
58+
def _validate_minimum(self, validator, minimum, instance, schema):
59+
instance = self._number_from_str(instance)
60+
if instance is None:
61+
return
62+
return self.validator_org.VALIDATORS['minimum'](validator, minimum,
63+
instance, schema)
64+
65+
def _validate_maximum(self, validator, maximum, instance, schema):
66+
instance = self._number_from_str(instance)
67+
if instance is None:
68+
return
69+
return self.validator_org.VALIDATORS['maximum'](validator, maximum,
70+
instance, schema)

0 commit comments

Comments
 (0)