diff --git a/CHANGELOG.md b/CHANGELOG.md index 65e3c020e0..31f4ac12c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Major features/changes: * localhost/127.0.0.1 is not required to be in inventory if referenced, if not in inventory, it does not implicitly appear in the 'all' group. * git module has new parameters (accept_hostkey, key_file, ssh_opts) to ease the usage of git and ssh protocols. * when using accelerate mode, the daemon will now be restarted when specifying a different remote_user between plays. +* added no_log: option for tasks. When used, no logging information will be sent to syslog during the module execution. New modules: diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 29766efb3c..0cfe5bbf4e 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -175,6 +175,7 @@ class AnsibleModule(object): self.argument_spec = argument_spec self.supports_check_mode = supports_check_mode self.check_mode = False + self.no_log = no_log self.aliases = {} @@ -186,13 +187,14 @@ class AnsibleModule(object): os.environ['LANG'] = MODULE_LANG (self.params, self.args) = self._load_params() - self._legal_inputs = [ 'CHECKMODE' ] + self._legal_inputs = [ 'CHECKMODE', 'NO_LOG' ] self.aliases = self._handle_aliases() if check_invalid_arguments: self._check_invalid_arguments() self._check_for_check_mode() + self._check_for_no_log() self._set_defaults(pre=True) @@ -205,7 +207,7 @@ class AnsibleModule(object): self._check_required_one_of(required_one_of) self._set_defaults(pre=False) - if not no_log: + if not self.no_log: self._log_invocation() def load_file_common_arguments(self, params): @@ -558,9 +560,14 @@ class AnsibleModule(object): if self.supports_check_mode: self.check_mode = True + def _check_for_no_log(self): + for (k,v) in self.params.iteritems(): + if k == 'NO_LOG': + self.no_log = self.boolean(v) + def _check_invalid_arguments(self): for (k,v) in self.params.iteritems(): - if k == 'CHECKMODE': + if k in ('CHECKMODE', 'NO_LOG'): continue if k not in self._legal_inputs: self.fail_json(msg="unsupported parameter for module: %s" % k) diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py index 61db0512fe..0d72548582 100644 --- a/lib/ansible/playbook/__init__.py +++ b/lib/ansible/playbook/__init__.py @@ -343,7 +343,8 @@ class PlayBook(object): su=task.su, su_user=task.su_user, su_pass=task.su_pass, - run_hosts=hosts + run_hosts=hosts, + no_log=task.no_log, ) if task.async_seconds == 0: diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py index a2d5c8880d..94f4dc074a 100644 --- a/lib/ansible/playbook/play.py +++ b/lib/ansible/playbook/play.py @@ -504,7 +504,7 @@ class Play(object): elif type(x[k]) is list: for i in x[k]: included_additional_conditions.insert(0, i) - elif k in ("include", "vars", "default_vars", "sudo", "sudo_user", "role_name"): + elif k in ("include", "vars", "default_vars", "sudo", "sudo_user", "role_name", "no_log"): continue else: include_vars[k] = x[k] diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index 8b358486b9..99e99d4ba1 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -31,7 +31,7 @@ class Task(object): 'local_action', 'transport', 'sudo', 'remote_user', 'sudo_user', 'sudo_pass', 'items_lookup_plugin', 'items_lookup_terms', 'environment', 'args', 'any_errors_fatal', 'changed_when', 'failed_when', 'always_run', 'delay', 'retries', 'until', - 'su', 'su_user', 'su_pass' + 'su', 'su_user', 'su_pass', 'no_log', ] # to prevent typos and such @@ -41,7 +41,7 @@ class Task(object): 'delegate_to', 'local_action', 'transport', 'remote_user', 'sudo', 'sudo_user', 'sudo_pass', 'when', 'connection', 'environment', 'args', 'any_errors_fatal', 'changed_when', 'failed_when', 'always_run', 'delay', 'retries', 'until', - 'su', 'su_user', 'su_pass' + 'su', 'su_user', 'su_pass', 'no_log', ] def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None, role_name=None): @@ -106,7 +106,6 @@ class Task(object): when_name = x.replace("when_","") ds['when'] = "%s %s" % (when_name, ds[x]) ds.pop(x) - elif not x in Task.VALID_KEYS: raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x) @@ -122,7 +121,8 @@ class Task(object): self.su = utils.boolean(ds.get('su', play.su)) self.environment = ds.get('environment', {}) self.role_name = role_name - + self.no_log = utils.boolean(ds.get('no_log', "false")) + #Code to allow do until feature in a Task if 'until' in ds: if not ds.get('register'): diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 4a06fcee52..c48548b0e0 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -145,6 +145,7 @@ class Runner(object): su_user=None, # User to su to when running command, ex: 'root' su_pass=C.DEFAULT_SU_PASS, run_hosts=None, # an optional list of pre-calculated hosts to run on + no_log=False, # option to enable/disable logging for a given task ): # used to lock multiprocess inputs and outputs at various levels @@ -196,6 +197,7 @@ class Runner(object): self.su_user_var = su_user self.su_user = None self.su_pass = su_pass + self.no_log = no_log if self.transport == 'smart': # if the transport is 'smart' see if SSH can support ControlPersist if not use paramiko @@ -341,6 +343,8 @@ class Runner(object): # if module isn't using AnsibleModuleCommon infrastructure we can't be certain it knows how to # do --check mode, so to be safe we will not run it. return ReturnData(conn=conn, result=dict(skipped=True, msg="cannot yet run check mode against old-style modules")) + elif 'NO_LOG' in args: + return ReturnData(conn=conn, result=dict(skipped=True, msg="cannot use no_log: with old-style modules")) args = template.template(self.basedir, args, inject) diff --git a/lib/ansible/runner/action_plugins/copy.py b/lib/ansible/runner/action_plugins/copy.py index 6cff391d50..e1dce790b9 100644 --- a/lib/ansible/runner/action_plugins/copy.py +++ b/lib/ansible/runner/action_plugins/copy.py @@ -220,6 +220,8 @@ class ActionModule(object): pipes.quote(tmp_src), pipes.quote(source_rel)) if self.runner.noop_on_check(inject): module_args_tmp = "%s CHECKMODE=True" % module_args_tmp + if self.runner.no_log: + module_args_tmp = "%s NO_LOG=True" % module_args_tmp module_return = self.runner._execute_module(conn, tmp, 'file', module_args_tmp, inject=inject, complex_args=complex_args) module_result = module_return.result diff --git a/lib/ansible/runner/action_plugins/normal.py b/lib/ansible/runner/action_plugins/normal.py index 1df620c410..8500c6641c 100644 --- a/lib/ansible/runner/action_plugins/normal.py +++ b/lib/ansible/runner/action_plugins/normal.py @@ -45,6 +45,9 @@ class ActionModule(object): # python modules for now module_args += " CHECKMODE=True" + if self.runner.no_log: + module_args += " NO_LOG=True" + # shell and command are the same module if module_name == 'shell': module_name = 'command' diff --git a/library/commands/command b/library/commands/command index 4365daec04..76d2f828d0 100644 --- a/library/commands/command +++ b/library/commands/command @@ -184,7 +184,7 @@ class CommandModule(AnsibleModule): args = args.replace("#USE_SHELL", "") params['shell'] = True - r = re.compile(r'(^|\s)(creates|removes|chdir|executable)=(?P[\'"])?(.*?)(?(quote)(?[\'"])?(.*?)(?(quote)(?