ansible-test validate-modules: don't allow arbitrary lists and dicts for 'default', 'sample' and 'example' (#69287)

* Don't allow arbitrary lists and dicts for 'default', 'sample' and 'example'.

* Add changelog.

* Make compile with Python 2.
This commit is contained in:
Felix Fontein 2020-05-05 18:38:10 +02:00 committed by GitHub
parent 049800c063
commit 947fa3bad3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 6 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- "ansible-test - improve module validation so that ``default``, ``sample`` and ``example`` contain JSON values and not arbitrary YAML values, like ``datetime`` objects or dictionaries with non-string keys."

View file

@ -147,6 +147,15 @@ def ansible_module_kwargs_schema():
return Schema(schema) return Schema(schema)
json_value = Schema(Any(
None,
int,
float,
[Self],
*(list({str_type: Self} for str_type in string_types) + list(string_types))
))
suboption_schema = Schema( suboption_schema = Schema(
{ {
Required('description'): Any(list_string_types, *string_types), Required('description'): Any(list_string_types, *string_types),
@ -154,7 +163,7 @@ suboption_schema = Schema(
'choices': list, 'choices': list,
'aliases': Any(list_string_types), 'aliases': Any(list_string_types),
'version_added': Any(float, *string_types), 'version_added': Any(float, *string_types),
'default': Any(None, float, int, bool, list, dict, *string_types), 'default': json_value,
# Note: Types are strings, not literal bools, such as True or False # Note: Types are strings, not literal bools, such as True or False
'type': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'), 'type': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'),
# in case of type='list' elements define type of individual item in list # in case of type='list' elements define type of individual item in list
@ -176,7 +185,7 @@ option_schema = Schema(
'choices': list, 'choices': list,
'aliases': Any(list_string_types), 'aliases': Any(list_string_types),
'version_added': Any(float, *string_types), 'version_added': Any(float, *string_types),
'default': Any(None, float, int, bool, list, dict, *string_types), 'default': json_value,
'suboptions': Any(None, *list_dict_suboption_schema), 'suboptions': Any(None, *list_dict_suboption_schema),
# Note: Types are strings, not literal bools, such as True or False # Note: Types are strings, not literal bools, such as True or False
'type': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'), 'type': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'),
@ -211,8 +220,8 @@ return_contains_schema = Any(
'returned': Any(*string_types), # only returned on top level 'returned': Any(*string_types), # only returned on top level
Required('type'): Any('bool', 'complex', 'dict', 'float', 'int', 'list', 'str'), Required('type'): Any('bool', 'complex', 'dict', 'float', 'int', 'list', 'str'),
'version_added': Any(float, *string_types), 'version_added': Any(float, *string_types),
'sample': Any(None, list, dict, int, float, *string_types), 'sample': json_value,
'example': Any(None, list, dict, int, float, *string_types), 'example': json_value,
'contains': Any(None, *list({str_type: Self} for str_type in string_types)), 'contains': Any(None, *list({str_type: Self} for str_type in string_types)),
# in case of type='list' elements define type of individual item in list # in case of type='list' elements define type of individual item in list
'elements': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'), 'elements': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'),
@ -236,8 +245,8 @@ return_schema = Any(
Required('returned'): Any(*string_types), Required('returned'): Any(*string_types),
Required('type'): Any('bool', 'complex', 'dict', 'float', 'int', 'list', 'str'), Required('type'): Any('bool', 'complex', 'dict', 'float', 'int', 'list', 'str'),
'version_added': Any(float, *string_types), 'version_added': Any(float, *string_types),
'sample': Any(None, list, dict, int, float, *string_types), 'sample': json_value,
'example': Any(None, list, dict, int, float, *string_types), 'example': json_value,
'contains': Any(None, *list_dict_return_contains_schema), 'contains': Any(None, *list_dict_return_contains_schema),
# in case of type='list' elements define type of individual item in list # in case of type='list' elements define type of individual item in list
'elements': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'), 'elements': Any(None, 'bits', 'bool', 'bytes', 'dict', 'float', 'int', 'json', 'jsonarg', 'list', 'path', 'raw', 'sid', 'str'),