diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 268e610d482..9f2ed5f6400 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -684,6 +684,9 @@ class AnsibleModule(object): # May be used to set modifications to the environment for any # run_command invocation self.run_command_environ_update = {} + self._warnings = [] + self._deprecations = [] + self._passthrough = ['warnings', 'deprecations'] self.aliases = {} 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'] @@ -757,6 +760,22 @@ class AnsibleModule(object): # finally, make sure we're in a sane working dir self._set_cwd() + def warn(self, warning): + + if isinstance(warning, string_types): + self._warnings.append(warning) + self.log('[WARNING] %s' % warning) + else: + raise TypeError("warn requires a string not a %s" % type(warning)) + + def deprecate(self, deprecate): + + if isinstance(deprecate, string_types): + self._deprecations.append(deprecate) + self.log('[DEPRECATION WARNING] %s' % deprecate) + else: + raise TypeError("deprecate requires a string not a %s" % type(deprecate)) + def load_file_common_arguments(self, params): ''' many modules deal with files, this encapsulates common @@ -1717,7 +1736,7 @@ class AnsibleModule(object): def debug(self, msg): if self._debug: - self.log(msg) + self.log('[debug] %s' % msg) def log(self, msg, log_args=None): @@ -1888,28 +1907,53 @@ class AnsibleModule(object): for path in self.cleanup_files: self.cleanup(path) - def exit_json(self, **kwargs): - ''' return from the module, without error ''' + def _return_formatted(self, kwargs): + self.add_path_info(kwargs) - if not 'changed' in kwargs: - kwargs['changed'] = False + if 'invocation' not in kwargs: kwargs['invocation'] = {'module_args': self.params} + + if 'warnings' in kwargs: + if isinstance(kwargs['warnings'], list): + for w in kwargs['warnings']: + self.warn(w) + else: + self.warn(kwargs['warnings']) + if self._warnings: + kwargs['warnings'] = self._warnings + + if 'deprecations' in kwargs: + if isinstance(kwargs['deprecations'], list): + for d in kwargs['deprecations']: + self.warn(d) + else: + self.warn(kwargs['deprecations']) + + if self._deprecations: + kwargs['deprecations'] = self._deprecations + kwargs = remove_values(kwargs, self.no_log_values) - self.do_cleanup_files() print('\n%s' % self.jsonify(kwargs)) + + def exit_json(self, **kwargs): + ''' return from the module, without error ''' + + if not 'changed' in kwargs: + kwargs['changed'] = False + + self.do_cleanup_files() + self._return_formatted(kwargs) sys.exit(0) def fail_json(self, **kwargs): ''' return from the module, with an error message ''' - self.add_path_info(kwargs) + assert 'msg' in kwargs, "implementation error -- msg to explain the error is required" kwargs['failed'] = True - if 'invocation' not in kwargs: - kwargs['invocation'] = {'module_args': self.params} - kwargs = remove_values(kwargs, self.no_log_values) + self.do_cleanup_files() - print('\n%s' % self.jsonify(kwargs)) + self._return_formatted(kwargs) sys.exit(1) def fail_on_missing_params(self, required_params=None): diff --git a/lib/ansible/plugins/callback/__init__.py b/lib/ansible/plugins/callback/__init__.py index 1005309881d..5f1174e72a7 100644 --- a/lib/ansible/plugins/callback/__init__.py +++ b/lib/ansible/plugins/callback/__init__.py @@ -99,9 +99,13 @@ class CallbackBase: def _handle_warnings(self, res): ''' display warnings, if enabled and any exist in the result ''' - if C.COMMAND_WARNINGS and 'warnings' in res and res['warnings']: - for warning in res['warnings']: - self._display.warning(warning) + if C.COMMAND_WARNINGS: + if 'warnings' in res and res['warnings']: + for warning in res['warnings']: + self._display.warning(warning) + if 'deprecations' in res and res['deprecations']: + for warning in res['deprecations']: + self._display.deprecated(warning) def _get_diff(self, difflist):