Skip to content

Commit

Permalink
Throw a prettier error in m_u.basic syslog (#70312)
Browse files Browse the repository at this point in the history
Change:
- In certain situations, such as when the input string contains null
  bytes (\0), syslog.syslog will throw a TypeError. Handle that and
  fail_json instead.

Test Plan:
- New test
- ansible-test --docker centos[68] (for py2 and py3 respectively)

Tickets:
- Refs #70269

Signed-off-by: Rick Elrod <rick@elrod.me>
  • Loading branch information
relrod committed Jul 1, 2020
1 parent a1ac595 commit f7078c1
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/syslog-prettier-error.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- The logging functionality in module_utils.basic now returns a nicer error when it falls back to syslog but ends up getting a TypeError thrown back.
17 changes: 13 additions & 4 deletions lib/ansible/module_utils/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1879,10 +1879,19 @@ def _load_params(self):

def _log_to_syslog(self, msg):
if HAS_SYSLOG:
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)
try:
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)
except TypeError as e:
self.fail_json(
msg='Failed to log to syslog (%s). To proceed anyway, '
'disable syslog logging by setting no_target_syslog '
'to True in your Ansible config.' % to_native(e),
exception=traceback.format_exc(),
msg_to_log=msg,
)

def debug(self, msg):
if self._debug:
Expand Down
37 changes: 37 additions & 0 deletions test/integration/targets/module_utils/module_utils_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,40 @@
that:
- result.deprecations[0].msg == "Alias 'baz' is deprecated. See the module docs for more information"
- result.deprecations[0].version == '9.99'

- block:
- name: Get a string with a \0 in it
command: echo -e 'hi\0foo'
register: string_with_null

- name: Use the null string as a module parameter
lineinfile:
path: "{{ output_dir }}/nulltest"
line: "{{ string_with_null.stdout }}"
create: yes
ignore_errors: yes
register: nulltest

- name: See if the file exists
stat:
path: "{{ output_dir }}/nulltest"
register: nullstat

- assert:
that:
- nulltest is failed
- nulltest.msg_to_log.startswith('Invoked ')
- nulltest.msg.startswith('Failed to log to syslog')
# Conditionalize this, because when we log with something other than
# syslog, it's probably successful and these assertions will fail.
when: nulltest is failed

# Ensure we fail out early and don't actually run the module if logging
# failed.
- assert:
that:
- nullstat.stat.exists == nulltest is successful
always:
- file:
path: "{{ output_dir }}/nulltest"
state: absent
2 changes: 1 addition & 1 deletion test/integration/targets/module_utils/runme.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ ANSIBLE_ROLES_PATH=../ ansible-playbook module_utils_basic_setcwd.yml -i ../../i
# doesn't traceback with unicode in the custom module_utils directory path.
ansible-playbook module_utils_vvvvv.yml -i ../../inventory -vvvvv "$@"

ansible-playbook module_utils_test.yml -i ../../inventory -v "$@"
ansible-playbook module_utils_test.yml -i ../../inventory -e output_dir="$OUTPUT_DIR" -v "$@"

ANSIBLE_MODULE_UTILS=other_mu_dir ansible-playbook module_utils_envvar.yml -i ../../inventory -v "$@"

0 comments on commit f7078c1

Please sign in to comment.