Update validate to use 2.11 ArgumentSpecValidator if available (#86)

Update validate to use 2.11 ArgumentSpecValidator if available

SUMMARY

fixes: #85

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Bradley A. Thornton <bthornto@redhat.com>
Reviewed-by: Ashwini Mhatre <mashu97@gmail.com>
Reviewed-by: None <None>
pull/91/head
Ashwini Mhatre 2021-08-03 13:34:33 +05:30 committed by GitHub
parent b95847245d
commit 61a826c997
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 85 additions and 22 deletions

View File

@ -0,0 +1,3 @@
---
bugfixes:
- Update validate to use 2.11 ArgumentSpecValidator if available.

View File

@ -46,9 +46,7 @@ except ImportError:
# ansible-base 2.11 should expose argspec validation outside of the # ansible-base 2.11 should expose argspec validation outside of the
# ansiblemodule class # ansiblemodule class
try: try:
from ansible.module_utils.somefile import ( # noqa: F401 from ansible.module_utils.common.arg_spec import ArgumentSpecValidator
FutureBaseArgspecValidator,
)
HAS_ANSIBLE_ARG_SPEC_VALIDATOR = True HAS_ANSIBLE_ARG_SPEC_VALIDATOR = True
except ImportError: except ImportError:
@ -238,7 +236,35 @@ class AnsibleArgSpecValidator:
that is coming in 2.11, change the check according above that is coming in 2.11, change the check according above
""" """
if HAS_ANSIBLE_ARG_SPEC_VALIDATOR: if HAS_ANSIBLE_ARG_SPEC_VALIDATOR:
return self._validate() if self._schema_format == "doc":
self._convert_doc_to_schema()
if self._schema_conditionals is not None:
self._schema = dict_merge(
self._schema, self._schema_conditionals
)
invalid_keys = [
k
for k in self._schema.keys()
if k not in VALID_ANSIBLEMODULE_ARGS
]
if invalid_keys:
valid = False
errors = [
"Invalid schema. Invalid keys found: {ikeys}".format(
ikeys=",".join(invalid_keys)
)
]
updated_data = {}
return valid, errors, updated_data
else:
validator = ArgumentSpecValidator(**self._schema)
result = validator.validate(self._data)
valid = not bool(result.error_messages)
return (
valid,
result.error_messages,
result.validated_parameters,
)
else: else:
return self._validate() return self._validate()

View File

@ -11,7 +11,9 @@
- name: "{{ parser }} Check argspec fail" - name: "{{ parser }} Check argspec fail"
assert: assert:
that: "argfail['errors'] == 'parameters are mutually exclusive: command|template_path found in parser'" that: "{{ msg in argfail.errors }}"
vars:
msg: "parameters are mutually exclusive: command|template_path found in parser"
- name: "{{ parser }} validate argspec" - name: "{{ parser }} validate argspec"
ansible.utils.cli_parse: ansible.utils.cli_parse:
@ -25,7 +27,9 @@
- name: "{{ parser }} Check argspec fail" - name: "{{ parser }} Check argspec fail"
assert: assert:
that: "argfail['errors'] == 'parameters are mutually exclusive: command|text'" that: "{{ msg in argfail.errors }}"
vars:
msg: "parameters are mutually exclusive: command|text"
- name: "{{ parser }} validate argspec" - name: "{{ parser }} validate argspec"
ansible.utils.cli_parse: ansible.utils.cli_parse:
@ -37,7 +41,9 @@
- name: "{{ parser }} Check argspec fail" - name: "{{ parser }} Check argspec fail"
assert: assert:
that: "argfail['errors'] == 'one of the following is required: command, text'" that: "{{ msg in argfail.errors }}"
vars:
msg: "one of the following is required: command, text"
- name: "{{ parser }} validate argspec" - name: "{{ parser }} validate argspec"
@ -51,4 +57,6 @@
- name: "{{ parser }} Check arspec fail" - name: "{{ parser }} Check arspec fail"
assert: assert:
that: "argfail['msg'] == 'Parser name should be provided as a full name including collection'" that: "{{ msg in argfail.msg }}"
vars:
msg: "Parser name should be provided as a full name including collection"

View File

@ -12,6 +12,13 @@
- after - after
loop_control: loop_control:
loop_var: string loop_var: string
when: "{{result.msg|type_debug != 'list'}}"
- assert:
that: "{{ msg in result.msg }}"
vars:
msg: "missing required arguments: after, before"
when: "{{result.msg|type_debug == 'list'}}"
- name: Check argspec validation, skip_lines must be a dict - name: Check argspec validation, skip_lines must be a dict
ansible.utils.fact_diff: ansible.utils.fact_diff:
@ -26,3 +33,8 @@
- assert: - assert:
that: "{{ 'unable to convert to list' in result.msg }}" that: "{{ 'unable to convert to list' in result.msg }}"
when: "{{result.msg|type_debug != 'list'}}"
- assert:
that: "{{ 'unable to convert to list' in result.msg[0] }}"
when: "{{result.msg|type_debug == 'list'}}"

View File

@ -14,7 +14,7 @@
register: result register: result
- assert: - assert:
that: "{{ result.msg == msg }}" that: "{{ msg in result.msg }}"
vars: vars:
msg: "missing required arguments: path" msg: "missing required arguments: path"

View File

@ -27,6 +27,8 @@ class TestSortList(unittest.TestCase):
) )
valid, errors, _updated_data = aav.validate() valid, errors, _updated_data = aav.validate()
self.assertTrue(valid) self.assertTrue(valid)
if not errors:
errors = None
self.assertEqual(errors, None) self.assertEqual(errors, None)
def test_simple_defaults(self): def test_simple_defaults(self):
@ -46,6 +48,8 @@ class TestSortList(unittest.TestCase):
} }
valid, errors, updated_data = aav.validate() valid, errors, updated_data = aav.validate()
self.assertTrue(valid) self.assertTrue(valid)
if not errors:
errors = None
self.assertEqual(errors, None) self.assertEqual(errors, None)
self.assertEqual(expected, updated_data) self.assertEqual(expected, updated_data)
@ -84,6 +88,8 @@ class TestSortList(unittest.TestCase):
) )
valid, errors, _updated_data = aav.validate() valid, errors, _updated_data = aav.validate()
self.assertTrue(valid) self.assertTrue(valid)
if not errors:
errors = None
self.assertEqual(errors, None) self.assertEqual(errors, None)
def test_schema_conditional(self): def test_schema_conditional(self):
@ -114,10 +120,16 @@ class TestSortList(unittest.TestCase):
) )
valid, errors, _updated_data = aav.validate() valid, errors, _updated_data = aav.validate()
self.assertFalse(valid) self.assertFalse(valid)
self.assertIn( if isinstance(errors, list):
"Unsupported parameters for 'test_action' module: not_valid", # for ansibleargspecvalidator 2.11 its returning errors as list
errors, self.assertIn(
) "not_valid. Supported parameters include:", errors[0]
)
else:
self.assertIn(
"Unsupported parameters for 'test_action' module: not_valid",
errors,
)
def test_other_args(self): def test_other_args(self):
data = {"param_str": "string"} data = {"param_str": "string"}
@ -130,6 +142,8 @@ class TestSortList(unittest.TestCase):
) )
valid, errors, _updated_data = aav.validate() valid, errors, _updated_data = aav.validate()
self.assertTrue(valid) self.assertTrue(valid)
if not errors:
errors = None
self.assertIsNone(errors) self.assertIsNone(errors)
def test_invalid_spec(self): def test_invalid_spec(self):
@ -143,4 +157,4 @@ class TestSortList(unittest.TestCase):
) )
valid, errors, _updated_data = aav.validate() valid, errors, _updated_data = aav.validate()
self.assertFalse(valid) self.assertFalse(valid)
self.assertIn("Invalid keys found: not_valid", errors) self.assertIn("Invalid schema. Invalid keys found: not_valid", errors)

View File

@ -117,7 +117,7 @@ class TestCli_Parse(unittest.TestCase):
**kwargs **kwargs
) )
self.assertEqual( self.assertIn(
"one of the following is required: command, text", result["errors"] "one of the following is required: command, text", result["errors"]
) )
@ -131,7 +131,7 @@ class TestCli_Parse(unittest.TestCase):
schema_conditionals=ARGSPEC_CONDITIONALS, schema_conditionals=ARGSPEC_CONDITIONALS,
**kwargs **kwargs
) )
self.assertEqual( self.assertIn(
"missing required arguments: name found in parser", "missing required arguments: name found in parser",
result["errors"], result["errors"],
) )

View File

@ -144,9 +144,11 @@ class TestValidate(unittest.TestCase):
# missing required arguments # missing required arguments
self._plugin._task.args = {"engine": "ansible.utils.jsonschema"} self._plugin._task.args = {"engine": "ansible.utils.jsonschema"}
result = self._plugin.run(task_vars=None) result = self._plugin.run(task_vars=None)
msg = "missing required arguments criteria data" msg = "missing required arguments:"
for word in msg.split(): if isinstance(result["errors"], list):
self.assertIn(word, result["errors"]) self.assertIn(msg, result["errors"][0])
else:
self.assertIn(msg, result["errors"])
# invalid engine option value # invalid engine option value
self._plugin._task.args = { self._plugin._task.args = {

View File

@ -112,9 +112,7 @@ class TestValidate(unittest.TestCase):
with self.assertRaises(AnsibleError) as error: with self.assertRaises(AnsibleError) as error:
validate(*args, **kwargs) validate(*args, **kwargs)
msg = "missing required arguments: criteria" msg = "missing required arguments: criteria"
self.assertTrue( self.assertIn(msg, str(error.exception))
set(str(error.exception).split()).issuperset(set(msg.split()))
)
kwargs = { kwargs = {
"criteria": CRITERIA_IN_RATE_CHECK, "criteria": CRITERIA_IN_RATE_CHECK,