From bc6cd138740bd927b5c52c3b9c18c7812179835e Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Fri, 4 Jan 2019 10:33:37 +0530 Subject: [PATCH] Handle exception raised in recursive_finder API (#49590) User module can contain Indentation errors or syntax errors. Handle AST exceptions rather than showing traceback while importing such module. Fixes: #21707 Signed-off-by: Abhijeet Kasurde --- lib/ansible/executor/module_common.py | 5 ++++- .../module_common/test_recursive_finder.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/ansible/executor/module_common.py b/lib/ansible/executor/module_common.py index 65525ae3b4..bae447c7df 100644 --- a/lib/ansible/executor/module_common.py +++ b/lib/ansible/executor/module_common.py @@ -462,7 +462,10 @@ def recursive_finder(name, data, py_module_names, py_module_cache, zf): the module its module_utils files needs. """ # Parse the module and find the imports of ansible.module_utils - tree = ast.parse(data) + try: + tree = ast.parse(data) + except (SyntaxError, IndentationError) as e: + raise AnsibleError("Unable to import %s due to %s" % (name, e.msg)) finder = ModuleDepFinder() finder.visit(tree) diff --git a/test/units/executor/module_common/test_recursive_finder.py b/test/units/executor/module_common/test_recursive_finder.py index 2dc74fd40e..0b919f6987 100644 --- a/test/units/executor/module_common/test_recursive_finder.py +++ b/test/units/executor/module_common/test_recursive_finder.py @@ -112,6 +112,20 @@ class TestRecursiveFinder(object): assert finder_containers.py_module_cache == {} assert frozenset(finder_containers.zf.namelist()) == MODULE_UTILS_BASIC_FILES + def test_module_utils_with_syntax_error(self, finder_containers): + name = 'fake_module' + data = b'#!/usr/bin/python\ndef something(:\n pass\n' + with pytest.raises(ansible.errors.AnsibleError) as exec_info: + recursive_finder(name, data, *finder_containers) + assert 'Unable to import fake_module due to invalid syntax' in str(exec_info) + + def test_module_utils_with_identation_error(self, finder_containers): + name = 'fake_module' + data = b'#!/usr/bin/python\n def something():\n pass\n' + with pytest.raises(ansible.errors.AnsibleError) as exec_info: + recursive_finder(name, data, *finder_containers) + assert 'Unable to import fake_module due to unexpected indent' in str(exec_info) + def test_from_import_toplevel_package(self, finder_containers, mocker): if PY2: module_utils_data = BytesIO(b'# License\ndef do_something():\n pass\n')