validate-modules¶
Python program to help test or validate Ansible modules.
validate-modules is one of the ansible-test Sanity Tests, see Sanity Tests for more information.
Originally developed by Matt Martz (@sivel)
Usage¶
cd /path/to/ansible/source
source hacking/env-setup
ansible-test sanity --test validate-modules
Help¶
usage: validate-modules [-h] [-w] [--exclude EXCLUDE] [--arg-spec]
                        [--base-branch BASE_BRANCH] [--format {json,plain}]
                        [--output OUTPUT]
                        modules [modules ...]
positional arguments:
  modules               Path to module or module directory
optional arguments:
  -h, --help            show this help message and exit
  -w, --warnings        Show warnings
  --exclude EXCLUDE     RegEx exclusion pattern
  --arg-spec            Analyze module argument spec
  --base-branch BASE_BRANCH
                        Used in determining if new options were added
  --format {json,plain}
                        Output format. Default: "plain"
  --output OUTPUT       Output location, use "-" for stdout. Default "-"
Extending validate-modules¶
The validate-modules tool has a schema.py that is used to validate the YAML blocks, such as DOCUMENTATION and RETURNS.
Codes¶
| Error Code | Type | Level | Sample Message | 
| ansible-module-not-initialized | Syntax | Error | Execution of the module did not result in initialization of AnsibleModule | 
| deprecation-mismatch | Documentation | Error | Module marked as deprecated or removed in at least one of the filename, its metadata, or in DOCUMENTATION (setting DOCUMENTATION.deprecated for deprecation or removing all Documentation for removed) but not in all three places. | 
| doc-choices-do-not-match-spec | Documentation | Error | Value for “choices” from the argument_spec does not match the documentation | 
| doc-choices-incompatible-type | Documentation | Error | Choices value from the documentation is not compatible with type defined in the argument_spec | 
| doc-default-does-not-match-spec | Documentation | Error | Value for “default” from the argument_spec does not match the documentation | 
| doc-default-incompatible-type | Documentation | Error | Default value from the documentation is not compatible with type defined in the argument_spec | 
| doc-missing-type | Documentation | Error | Documentation doesn’t specify a type but argument in argument_specuse default type (str) | 
| doc-type-does-not-match-spec | Documentation | Error | Argument_spec defines type different than documentation does | 
| documentation-error | Documentation | Error | Unknown DOCUMENTATIONerror | 
| documentation-syntax-error | Documentation | Error | Invalid DOCUMENTATIONschema | 
| illegal-future-imports | Imports | Error | Only the following from __future__imports are allowed:absolute_import,division, andprint_function. | 
| import-before-documentation | Imports | Error | Import found before documentation variables. All imports must appear below DOCUMENTATION/EXAMPLES/RETURN/ANSIBLE_METADATA | 
| import-error | Documentation | Error | Exceptionattempting to import module forargument_specintrospection | 
| import-placement | Locations | Warning | Imports should be directly below DOCUMENTATION/EXAMPLES/RETURN/ANSIBLE_METADATAfor legacy modules | 
| imports-improper-location | Imports | Error | Imports should be directly below DOCUMENTATION/EXAMPLES/RETURN/ANSIBLE_METADATA | 
| incompatible-choices | Documentation | Error | Choices value from the argument_spec is not compatible with type defined in the argument_spec | 
| incompatible-default-type | Documentation | Error | Default value from the argument_spec is not compatible with type defined in the argument_spec | 
| invalid-argument-spec | Documentation | Error | Argument in argument_spec must be a dictionary/hash when used | 
| invalid-argument-spec-options | Documentation | Error | Suboptions in argument_spec are invalid | 
| invalid-documentation | Documentation | Error | DOCUMENTATIONis not valid YAML | 
| invalid-documentation-options | Documentation | Error | DOCUMENTATION.optionsmust be a dictionary/hash when used | 
| invalid-examples | Documentation | Error | EXAMPLESis not valid YAML | 
| invalid-extension | Naming | Error | Official Ansible modules must have a .pyextension for python modules or a.ps1for powershell modules | 
| invalid-metadata-status | Documentation | Error | ANSIBLE_METADATA.statusof deprecated or removed can’t include other statuses | 
| invalid-metadata-type | Documentation | Error | ANSIBLE_METADATAwas not provided as a dict, YAML not supported, InvalidANSIBLE_METADATAschema | 
| invalid-module-schema | Documentation | Error | AnsibleModuleschema validation error | 
| invalid-requires-extension | Naming | Error | Module #AnsibleRequires -CSharpUtilshould not end in .cs, Module#Requiresshould not end in .psm1 | 
| last-line-main-call | Syntax | Error | Call to main()not the last line (orremoved_module()in the case of deprecated & docs only modules) | 
| metadata-changed | Documentation | Error | ANSIBLE_METADATAcannot be changed in a point release for a stable branch | 
| missing-doc-fragment | Documentation | Error | DOCUMENTATIONfragment missing | 
| missing-existing-doc-fragment | Documentation | Warning | Pre-existing DOCUMENTATIONfragment missing | 
| missing-documentation | Documentation | Error | No DOCUMENTATIONprovided | 
| missing-examples | Documentation | Error | No EXAMPLESprovided | 
| missing-gplv3-license | Documentation | Error | GPLv3 license header not found | 
| missing-if-name-main | Syntax | Error | Next to last line is not if __name__ == "__main__": | 
| missing-main-call | Syntax | Error | Did not find a call to main()(orremoved_module()in the case of deprecated & docs only modules) | 
| missing-metadata | Documentation | Error | No ANSIBLE_METADATAprovided | 
| missing-module-utils-basic-import | Imports | Warning | Did not find ansible.module_utils.basicimport | 
| missing-module-utils-import-csharp-requirements | Imports | Error | No Ansible.ModuleUtilsor C# Ansible util requirements/imports found | 
| missing-powershell-interpreter | Syntax | Error | Interpreter line is not #!powershell | 
| missing-python-doc | Naming | Error | Missing python documentation file | 
| missing-python-interpreter | Syntax | Error | Interpreter line is not #!/usr/bin/python | 
| missing-return | Documentation | Error | No RETURNdocumentation provided | 
| missing-return-legacy | Documentation | Warning | No RETURNdocumentation provided for legacy module | 
| missing-suboption-docs | Documentation | Error | Argument in argument_spec has sub-options but documentation does not define sub-options | 
| module-incorrect-version-added | Documentation | Error | Module level version_addedis incorrect | 
| module-invalid-version-added | Documentation | Error | Module level version_addedis not a valid version number | 
| module-utils-specific-import | Imports | Error | module_utilsimports should import specific components, not* | 
| multiple-utils-per-requires | Imports | Error | Ansible.ModuleUtilsrequirements do not support multiple modules per statement | 
| multiple-csharp-utils-per-requires | Imports | Error | Ansible C# util requirements do not support multiple utils per statement | 
| no-default-for-required-parameter | Documentation | Error | Option is marked as required but specifies a default. Arguments with a default should not be marked as required | 
| nonexistent-parameter-documented | Documentation | Error | Argument is listed in DOCUMENTATION.options, but not accepted by the module | 
| option-incorrect-version-added | Documentation | Error | version_addedfor new option is incorrect | 
| option-invalid-version-added | Documentation | Error | version_addedfor new option is not a valid version number | 
| parameter-invalid | Documentation | Error | Argument in argument_spec is not a valid python identifier | 
| parameter-invalid-elements | Documentation | Error | Value for “elements” is valid only when value of “type” is list | 
| implied-parameter-type-mismatch | Documentation | Error | Argument_spec implies type="str"but documentation defines it as different data type | 
| parameter-type-not-in-doc | Documentation | Error | Type value is defined in argument_specbut documentation doesn’t specify a type | 
| python-syntax-error | Syntax | Error | Python SyntaxErrorwhile parsing module | 
| return-syntax-error | Documentation | Error | RETURNis not valid YAML,RETURNfragments missing  or invalid | 
| subdirectory-missing-init | Naming | Error | Ansible module subdirectories must contain an __init__.py | 
| try-except-missing-has | Imports | Warning | Try/Except HAS_expression missing | 
| undocumented-parameter | Documentation | Error | Argument is listed in the argument_spec, but not documented in the module | 
| unidiomatic-typecheck | Syntax | Error | Type comparison using type()found. Useisinstance()instead | 
| unknown-doc-fragment | Documentation | Warning | Unknown pre-existing DOCUMENTATIONerror | 
| use-boto3 | Imports | Error | botoimport found, new modules should useboto3 | 
| use-fail-json-not-sys-exit | Imports | Error | sys.exit()call found. Should beexit_json/fail_json | 
| use-module-utils-urls | Imports | Error | requestsimport found, should useansible.module_utils.urlsinstead | 
| use-run-command-not-os-call | Imports | Error | os.callused instead ofmodule.run_command | 
| use-run-command-not-popen | Imports | Error | subprocess.Popenused instead ofmodule.run_command | 
| use-short-gplv3-license | Documentation | Error | GPLv3 license header should be the short form for new modules | 
