[2.11] Improve handling of AnsibleModule arguments in validate-modules (#75360)

* Improve handling of AnsibleModule arguments in validate-modules (#75332)

* Make sure AnsibleModule positional arguments are validated.

* Extract ANSIBLE_MODULE_CONSTURCTOR_ARGS with inspection.

* Remove no longer necessary return value.

* Fix PR #.

* argument_spec might not have been specified, as in community.general.xenserver_facts.

* Fix typo.

(cherry picked from commit 7726b70d9a)

* Make sure self doesn't end up in fake.args (#75403)

(cherry picked from commit 2455d82c14)

Co-authored-by: Matt Martz <matt@sivel.net>
pull/75409/head
Felix Fontein 3 years ago committed by GitHub
parent 54119d71f8
commit e2f14d94b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- "ansible-test validate-modules - correctly validate positional parameters to ``AnsibleModules`` (https://github.com/ansible/ansible/pull/75332)."

@ -1221,7 +1221,7 @@ class ModuleValidator(Validator):
def _validate_ansible_module_call(self, docs):
try:
spec, args, kwargs = get_argument_spec(self.path, self.collection)
spec, kwargs = get_argument_spec(self.path, self.collection)
except AnsibleModuleNotInitialized:
self.reporter.error(
path=self.object_path,

@ -19,6 +19,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import runpy
import inspect
import json
import os
import subprocess
@ -27,13 +28,16 @@ import sys
from contextlib import contextmanager
from ansible.executor.powershell.module_manifest import PSModuleDepFinder
from ansible.module_utils.basic import FILE_COMMON_ARGUMENTS
from ansible.module_utils.basic import FILE_COMMON_ARGUMENTS, AnsibleModule
from ansible.module_utils.six import reraise
from ansible.module_utils._text import to_bytes, to_text
from .utils import CaptureStd, find_executable, get_module_name_from_filename
ANSIBLE_MODULE_CONSTRUCTOR_ARGS = tuple(list(inspect.signature(AnsibleModule.__init__).parameters)[1:])
class AnsibleModuleCallError(RuntimeError):
pass
@ -53,6 +57,11 @@ class _FakeAnsibleModuleInit:
self.called = False
def __call__(self, *args, **kwargs):
if args and isinstance(args[0], AnsibleModule):
# Make sure, due to creative calling, that we didn't end up with
# ``self`` in ``args``
self.args = args[1:]
else:
self.args = args
self.kwargs = kwargs
self.called = True
@ -126,7 +135,7 @@ def get_ps_argument_spec(filename, collection):
# the validate-modules code expects the options spec to be under the argument_spec key not options as set in PS
kwargs['argument_spec'] = kwargs.pop('options', {})
return kwargs['argument_spec'], (), kwargs
return kwargs['argument_spec'], kwargs
def get_py_argument_spec(filename, collection):
@ -146,11 +155,11 @@ def get_py_argument_spec(filename, collection):
raise AnsibleModuleNotInitialized()
try:
# Convert positional arguments to kwargs to make sure that all parameters are actually checked
for arg, arg_name in zip(fake.args, ANSIBLE_MODULE_CONSTRUCTOR_ARGS):
fake.kwargs[arg_name] = arg
# for ping kwargs == {'argument_spec':{'data':{'type':'str','default':'pong'}}, 'supports_check_mode':True}
if 'argument_spec' in fake.kwargs:
argument_spec = fake.kwargs['argument_spec']
else:
argument_spec = fake.args[0]
argument_spec = fake.kwargs.get('argument_spec') or {}
# If add_file_common_args is truish, add options from FILE_COMMON_ARGUMENTS when not present.
# This is the only modification to argument_spec done by AnsibleModule itself, and which is
# not caught by setup_env's AnsibleModule replacement
@ -158,9 +167,9 @@ def get_py_argument_spec(filename, collection):
for k, v in FILE_COMMON_ARGUMENTS.items():
if k not in argument_spec:
argument_spec[k] = v
return argument_spec, fake.args, fake.kwargs
return argument_spec, fake.kwargs
except (TypeError, IndexError):
return {}, (), {}
return {}, {}
def get_argument_spec(filename, collection):

Loading…
Cancel
Save