From 4967b8650c1d054bce117f58675db985bf7e5ebc Mon Sep 17 00:00:00 2001 From: Sloane Hertel <19572925+s-hertel@users.noreply.github.com> Date: Wed, 29 Sep 2021 16:19:52 -0400 Subject: [PATCH] Fix unexpected exception when a role has an empty argument_specs.yml (#75604) (#75684) * Fix role with empty argument_specs.yml * Use try/except and add changelog fragment * Always return a dict * Add test for empty argument_specs key (cherry picked from commit 3e7a6222047aae29db4ce0005c0bdf320c7f7918) Co-authored-by: devon-mar --- .../fragments/75604-empty-argument-specs.yml | 3 +++ lib/ansible/playbook/role/__init__.py | 5 ++++- .../roles/empty_argspec/meta/argument_specs.yml | 2 ++ .../roles/empty_argspec/tasks/main.yml | 3 +++ .../roles/empty_file/meta/argument_specs.yml | 1 + .../roles/empty_file/tasks/main.yml | 3 +++ test/integration/targets/roles_arg_spec/test.yml | 16 ++++++++++++++++ 7 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/75604-empty-argument-specs.yml create mode 100644 test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml create mode 100644 test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml create mode 100644 test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml create mode 100644 test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml diff --git a/changelogs/fragments/75604-empty-argument-specs.yml b/changelogs/fragments/75604-empty-argument-specs.yml new file mode 100644 index 00000000000..49db731ad2a --- /dev/null +++ b/changelogs/fragments/75604-empty-argument-specs.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - roles - fix unexpected ``AttributeError`` when an empty ``argument_specs.yml`` is present (https://github.com/ansible/ansible/pull/75604). diff --git a/lib/ansible/playbook/role/__init__.py b/lib/ansible/playbook/role/__init__.py index 25c3b1679ba..8ee812a6a5d 100644 --- a/lib/ansible/playbook/role/__init__.py +++ b/lib/ansible/playbook/role/__init__.py @@ -294,7 +294,10 @@ class Role(Base, Conditional, Taggable, CollectionSearch): if self._loader.path_exists(full_path): # Note: _load_role_yaml() takes care of rebuilding the path. argument_specs = self._load_role_yaml('meta', main='argument_specs') - return argument_specs.get('argument_specs', {}) + try: + return argument_specs.get('argument_specs') or {} + except AttributeError: + return {} # We did not find the meta/argument_specs.[yml|yaml] file, so use the spec # dict from the role meta data, if it exists. Ansible 2.11 and later will diff --git a/test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml b/test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml new file mode 100644 index 00000000000..b592aa05b3a --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml @@ -0,0 +1,2 @@ +--- +argument_specs: diff --git a/test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml b/test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml new file mode 100644 index 00000000000..90aab0e0a89 --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- debug: + msg: "Role with empty argument_specs key" diff --git a/test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml b/test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml new file mode 100644 index 00000000000..ed97d539c09 --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml @@ -0,0 +1 @@ +--- diff --git a/test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml b/test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml new file mode 100644 index 00000000000..b77b835730a --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- debug: + msg: "Role with empty argument_specs.yml" diff --git a/test/integration/targets/roles_arg_spec/test.yml b/test/integration/targets/roles_arg_spec/test.yml index 06268c6a527..5eca7c73f9c 100644 --- a/test/integration/targets/roles_arg_spec/test.yml +++ b/test/integration/targets/roles_arg_spec/test.yml @@ -338,3 +338,19 @@ - debug: var=ansible_failed_result - fail: msg: "Should not get here" + +- name: "New play to reset vars: Test empty argument_specs.yml" + hosts: localhost + gather_facts: false + tasks: + - name: Import role with an empty argument_specs.yml + import_role: + name: empty_file + +- name: "New play to reset vars: Test empty argument_specs key" + hosts: localhost + gather_facts: false + tasks: + - name: Import role with an empty argument_specs key + import_role: + name: empty_argspec