diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 75a8a0766a0..1265f79efe9 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -253,6 +253,26 @@ class Runner(object): # ensure we are using unique tmp paths random.seed() + # ***************************************************** + + def _complex_args_hack(self, complex_args, module_args): + """ + ansible-playbook both allows specifying key=value string arguments and complex arguments + however not all modules use our python common module system and cannot + access these. An example might be a Bash module. This hack allows users to still pass "args" + as a hash of simple scalars to those arguments and is short term. We could technically + just feed JSON to the module, but that makes it hard on Bash consumers. The way this is implemented + it does mean values in 'args' have LOWER priority than those on the key=value line, allowing + args to provide yet another way to have pluggable defaults. + """ + if complex_args is None: + return module_args + if not isinstance(complex_args, dict): + raise errors.AnsibleError("complex arguments are not a dictionary: %s" % complex_args) + for (k,v) in complex_args.iteritems(): + if isinstance(v, basestring): + module_args = "%s=%s %s" % (k, pipes.quote(v), module_args) + return module_args # ***************************************************** diff --git a/lib/ansible/runner/action_plugins/normal.py b/lib/ansible/runner/action_plugins/normal.py index d845fa886f1..8500c6641c3 100644 --- a/lib/ansible/runner/action_plugins/normal.py +++ b/lib/ansible/runner/action_plugins/normal.py @@ -36,6 +36,8 @@ class ActionModule(object): def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): ''' transfer & execute a module that is not 'copy' or 'template' ''' + module_args = self.runner._complex_args_hack(complex_args, module_args) + if self.runner.noop_on_check(inject): if module_name in [ 'shell', 'command' ]: return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for %s' % module_name))