Fix jsonschma input data validation (#50)
Fix jsonschma input data validation Reviewed-by: https://github.com/apps/ansible-zuulpull/55/head
parent
4c531bb418
commit
f5dd4b80e7
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- Fix jsonschema input data format checking (https://github.com/ansible-collections/ansible.utils/pull/50).
|
|
@ -33,8 +33,7 @@ DOCUMENTATION = """
|
||||||
vars:
|
vars:
|
||||||
- name: ansible_validate_jsonschema_draft
|
- name: ansible_validate_jsonschema_draft
|
||||||
notes:
|
notes:
|
||||||
- The value of I(data) option should be either of type B(dict) or B(strings) which should be
|
- The value of I(data) option should be either a valid B(JSON) object or a B(JSON) string.
|
||||||
a valid B(dict) when read in python.
|
|
||||||
- The value of I(criteria) should be B(list) of B(dict) or B(list) of B(strings) and each
|
- The value of I(criteria) should be B(list) of B(dict) or B(list) of B(strings) and each
|
||||||
B(string) within the B(list) entry should be a valid B(dict) when read in python.
|
B(string) within the B(list) entry should be a valid B(dict) when read in python.
|
||||||
"""
|
"""
|
||||||
|
@ -98,19 +97,14 @@ class Validate(ValidateBase):
|
||||||
:return: None: In case all arguments passed are valid
|
:return: None: In case all arguments passed are valid
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if isinstance(self._data, dict):
|
if isinstance(self._data, string_types):
|
||||||
self._data = json.loads(json.dumps(self._data))
|
|
||||||
elif isinstance(self._data, string_types):
|
|
||||||
self._data = json.loads(self._data)
|
self._data = json.loads(self._data)
|
||||||
else:
|
else:
|
||||||
msg = "Expected value of 'data' option is either dict or str, received type '{data_type}'".format(
|
self._data = json.loads(json.dumps(self._data))
|
||||||
data_type=type(self._data)
|
|
||||||
)
|
|
||||||
raise AnsibleError(msg)
|
|
||||||
|
|
||||||
except (TypeError, JSONDecodeError) as exe:
|
except (TypeError, JSONDecodeError) as exe:
|
||||||
msg = (
|
msg = (
|
||||||
"'data' option value is invalid, value should of type dict or str format of dict."
|
"'data' option value is invalid, value should a valid JSON."
|
||||||
" Failed to read with error '{err}'".format(
|
" Failed to read with error '{err}'".format(
|
||||||
err=to_text(exe, errors="surrogate_then_replace")
|
err=to_text(exe, errors="surrogate_then_replace")
|
||||||
)
|
)
|
||||||
|
@ -120,20 +114,15 @@ class Validate(ValidateBase):
|
||||||
try:
|
try:
|
||||||
criteria = []
|
criteria = []
|
||||||
for item in to_list(self._criteria):
|
for item in to_list(self._criteria):
|
||||||
if isinstance(item, dict):
|
if isinstance(self._criteria, string_types):
|
||||||
criteria.append(json.loads(json.dumps(item)))
|
|
||||||
elif isinstance(self._criteria, string_types):
|
|
||||||
criteria.append(json.loads(item))
|
criteria.append(json.loads(item))
|
||||||
else:
|
else:
|
||||||
msg = "Expected value of 'criteria' option is either list of dict/str or dict or str, received type '{criteria_type}'".format(
|
criteria.append(json.loads(json.dumps(item)))
|
||||||
criteria_type=type(criteria)
|
|
||||||
)
|
|
||||||
raise AnsibleError(msg)
|
|
||||||
|
|
||||||
self._criteria = criteria
|
self._criteria = criteria
|
||||||
except (TypeError, JSONDecodeError) as exe:
|
except (TypeError, JSONDecodeError) as exe:
|
||||||
msg = (
|
msg = (
|
||||||
"'criteria' option value is invalid, value should of type dict or str format of dict."
|
"'criteria' option value is invalid, value should a valid JSON."
|
||||||
" Failed to read with error '{err}'".format(
|
" Failed to read with error '{err}'".format(
|
||||||
err=to_text(exe, errors="surrogate_then_replace")
|
err=to_text(exe, errors="surrogate_then_replace")
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"definitions": {},
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://example.com/object1615264346.json",
|
||||||
|
"title": "Root",
|
||||||
|
"type": "array",
|
||||||
|
"default": [],
|
||||||
|
"items":{
|
||||||
|
"$id": "#root/items",
|
||||||
|
"title": "Items",
|
||||||
|
"type": "integer",
|
||||||
|
"examples": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"default": 0
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
[1]
|
|
@ -48,7 +48,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'data\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'data\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: invalid criteria value
|
- name: invalid criteria value
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'criteria\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'criteria\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: read data and criteria from file
|
- name: read data and criteria from file
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'data\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'data\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: invalid criteria value
|
- name: invalid criteria value
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'criteria\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'criteria\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: read data and criteria from file
|
- name: read data and criteria from file
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'data\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'data\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: invalid criteria value
|
- name: invalid criteria value
|
||||||
ansible.utils.validate:
|
ansible.utils.validate:
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'criteria\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'criteria\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: validate data using jsonschema engine (invalid data read from file)
|
- name: validate data using jsonschema engine (invalid data read from file)
|
||||||
ansible.utils.validate:
|
ansible.utils.validate:
|
||||||
|
@ -132,3 +132,14 @@
|
||||||
that:
|
that:
|
||||||
- "'errors' not in result"
|
- "'errors' not in result"
|
||||||
- "'all checks passed' in result.msg"
|
- "'all checks passed' in result.msg"
|
||||||
|
|
||||||
|
- name: validate list data using jsonschema
|
||||||
|
ansible.utils.validate:
|
||||||
|
data: "{{ lookup('ansible.builtin.file', 'data/test_list_data.json') }}"
|
||||||
|
criteria: "{{ lookup('ansible.builtin.file', 'criteria/check_list_data.json') }}"
|
||||||
|
engine: ansible.utils.jsonschema
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- "'errors' not in result"
|
||||||
|
- "'all checks passed' in result.msg"
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'data\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'data\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: invalid criteria value
|
- name: invalid criteria value
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "result['failed'] == true"
|
- "result['failed'] == true"
|
||||||
- "'\\'criteria\\' option value is invalid, value should of type dict or str format of dict' in result.msg"
|
- "'\\'criteria\\' option value is invalid' in result.msg"
|
||||||
|
|
||||||
- name: read data and criteria from file
|
- name: read data and criteria from file
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
|
|
|
@ -158,10 +158,7 @@ class TestValidate(unittest.TestCase):
|
||||||
|
|
||||||
with self.assertRaises(AnsibleActionFail) as error:
|
with self.assertRaises(AnsibleActionFail) as error:
|
||||||
self._plugin.run(task_vars=None)
|
self._plugin.run(task_vars=None)
|
||||||
self.assertIn(
|
self.assertIn("'data' option value is invalid", str(error.exception))
|
||||||
"'data' option value is invalid, value should of type dict or str format of dict",
|
|
||||||
str(error.exception),
|
|
||||||
)
|
|
||||||
|
|
||||||
# invalid criteria option value
|
# invalid criteria option value
|
||||||
self._plugin._task.args = {
|
self._plugin._task.args = {
|
||||||
|
@ -173,8 +170,7 @@ class TestValidate(unittest.TestCase):
|
||||||
with self.assertRaises(AnsibleActionFail) as error:
|
with self.assertRaises(AnsibleActionFail) as error:
|
||||||
self._plugin.run(task_vars=None)
|
self._plugin.run(task_vars=None)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"'criteria' option value is invalid, value should of type dict or str format of dict",
|
"'criteria' option value is invalid", str(error.exception)
|
||||||
str(error.exception),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_invalid_validate_plugin_config_options(self):
|
def test_invalid_validate_plugin_config_options(self):
|
||||||
|
|
|
@ -118,10 +118,9 @@ class TestValidate(unittest.TestCase):
|
||||||
|
|
||||||
# missing required arguments
|
# missing required arguments
|
||||||
with self.assertRaises(AnsibleFilterError) as error:
|
with self.assertRaises(AnsibleFilterError) as error:
|
||||||
validate([DATA], {})
|
validate([DATA])
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"Expected value of 'data' option is either dict or str, received type",
|
"Missing either 'data' or 'criteria' value", str(error.exception)
|
||||||
str(error.exception),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
args = [DATA, [CRITERIA_IN_RATE_CHECK]]
|
args = [DATA, [CRITERIA_IN_RATE_CHECK]]
|
||||||
|
|
Loading…
Reference in New Issue