From 3fa377387e0289fad7163375f812d30ecf689704 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 10 Jun 2022 12:55:43 -0400 Subject: [PATCH] shell plugins give out user friendly type error (#77983) shell plugins give out user friendly type error # TODO: this should really have been taken care of via config or fieldattribute validation --- changelogs/fragments/shell_env_typeerror.yml | 2 ++ lib/ansible/plugins/shell/__init__.py | 17 +++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/shell_env_typeerror.yml diff --git a/changelogs/fragments/shell_env_typeerror.yml b/changelogs/fragments/shell_env_typeerror.yml new file mode 100644 index 00000000000..105eefeb72b --- /dev/null +++ b/changelogs/fragments/shell_env_typeerror.yml @@ -0,0 +1,2 @@ +bugfixes: + - shell plugins now give a more user friendly error when fed the wrong type of data. diff --git a/lib/ansible/plugins/shell/__init__.py b/lib/ansible/plugins/shell/__init__.py index 513ddb6fe8d..d5db261f680 100644 --- a/lib/ansible/plugins/shell/__init__.py +++ b/lib/ansible/plugins/shell/__init__.py @@ -25,8 +25,9 @@ import shlex import time from ansible.errors import AnsibleError -from ansible.module_utils.six import text_type from ansible.module_utils._text import to_native +from ansible.module_utils.six import text_type, string_types +from ansible.module_utils.common._collections_compat import Mapping, Sequence from ansible.plugins import AnsiblePlugin _USER_HOME_PATH_RE = re.compile(r'^~[_.A-Za-z0-9][-_.A-Za-z0-9]*$') @@ -60,12 +61,16 @@ class ShellBase(AnsiblePlugin): super(ShellBase, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct) # set env if needed, deal with environment's 'dual nature' list of dicts or dict + # TODO: config system should already resolve this so we should be able to just iterate over dicts env = self.get_option('environment') - if isinstance(env, list): - for env_dict in env: - self.env.update(env_dict) - else: - self.env.update(env) + if isinstance(env, string_types): + raise AnsibleError('The "envirionment" keyword takes a list of dictionaries or a dictionary, not a string') + if not isinstance(env, Sequence): + env = [env] + for env_dict in env: + if not isinstance(env_dict, Mapping): + raise AnsibleError('The "envirionment" keyword takes a list of dictionaries (or single dictionary), but got a "%s" instead' % type(env_dict)) + self.env.update(env_dict) # We can remove the try: except in the future when we make ShellBase a proper subset of # *all* shells. Right now powershell and third party shells which do not use the