Repository: ansible/ansible

Issue:
Modules don't know their own name
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Feature Idea
##### ANSIBLE VERSION

All
##### SUMMARY

<!--- Explain the problem briefly -->

In the old days when modules were run, they lived on disk and one way to get the module name was to simply run `os.path.basename(__file__)`. This is still used at various places.

However with pipelining the module name is no longer retrievable this way (it returns `<stdin>` instead), however various errors would be much better if it would explicitly mention the module name when throwing the error (e.g. remote module _cron_ does not support check mode).

Also logging now logs using logname "<stdin>" and you get syslog messages like:

```
Jan 01 00:00:00 system01 ansible-<stdin>: Invoked with parm1=foo parm2=bar
```

It would be quite easy to retain the module name so the ansible core in every context knows the module name, but also so that the module itself can report its own name in a consistent way.



Discussion:

Resolving patch:
diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py
--- a/lib/ansible/module_utils/basic.py
+++ b/lib/ansible/module_utils/basic.py
@@ -608,7 +608,7 @@ def __init__(self, argument_spec, bypass_checks=False, no_log=False,
         self.run_command_environ_update = {}
 
         self.aliases = {}
-        self._legal_inputs = ['_ansible_check_mode', '_ansible_no_log', '_ansible_debug', '_ansible_diff', '_ansible_verbosity', '_ansible_selinux_special_fs', '_ansible_version', '_ansible_syslog_facility']
+        self._legal_inputs = ['_ansible_check_mode', '_ansible_no_log', '_ansible_debug', '_ansible_diff', '_ansible_verbosity', '_ansible_selinux_special_fs', '_ansible_module_name', '_ansible_version', '_ansible_syslog_facility']
 
         if add_file_common_args:
             for k, v in FILE_COMMON_ARGUMENTS.items():
@@ -1229,8 +1229,6 @@ def _check_arguments(self, check_invalid_arguments):
         for (k,v) in list(self.params.items()):
 
             if k == '_ansible_check_mode' and v:
-                if not self.supports_check_mode:
-                    self.exit_json(skipped=True, msg="remote module does not support check mode")
                 self.check_mode = True
 
             elif k == '_ansible_no_log':
@@ -1254,6 +1252,9 @@ def _check_arguments(self, check_invalid_arguments):
             elif k == '_ansible_version':
                 self.ansible_version = v
 
+            elif k == '_ansible_module_name':
+                self._name = v
+
             elif check_invalid_arguments and k not in self._legal_inputs:
                 self.fail_json(msg="unsupported parameter for module: %s" % k)
 
@@ -1261,6 +1262,9 @@ def _check_arguments(self, check_invalid_arguments):
             if k.startswith('_ansible_'):
                 del self.params[k]
 
+        if self.check_mode and not self.supports_check_mode:
+                self.exit_json(skipped=True, msg="remote module (%s) does not support check mode" % self._name)
+
     def _count_terms(self, check):
         count = 0
         for term in check:
@@ -1537,7 +1541,7 @@ def _load_params(self):
 
     def _log_to_syslog(self, msg):
         if HAS_SYSLOG:
-            module = 'ansible-%s' % os.path.basename(__file__)
+            module = 'ansible-%s' % self._name
             facility = getattr(syslog, self._syslog_facility, syslog.LOG_USER)
             syslog.openlog(str(module), 0, facility)
             syslog.syslog(syslog.LOG_INFO, msg)
@@ -1553,7 +1557,7 @@ def log(self, msg, log_args=None):
             if log_args is None:
                 log_args = dict()
 
-            module = 'ansible-%s' % os.path.basename(__file__)
+            module = 'ansible-%s' % self._name
             if isinstance(module, bytes):
                 module = module.decode('utf-8', 'replace')
 
diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py
--- a/lib/ansible/plugins/action/__init__.py
+++ b/lib/ansible/plugins/action/__init__.py
@@ -574,6 +574,9 @@ def _execute_module(self, module_name=None, module_args=None, tmp=None, task_var
         # give the module information about the ansible version
         module_args['_ansible_version'] = __version__
 
+        # give the module information about its name
+        module_args['_ansible_module_name'] = module_name
+
         # set the syslog facility to be used in the module
         module_args['_ansible_syslog_facility'] = task_vars.get('ansible_syslog_facility', C.DEFAULT_SYSLOG_FACILITY)
 


Test patch: