Skip to content

Commit 7939bdb

Browse files
committed
make purge idempotent; get rid of reset
The use of `logging_purge_confs` should be be idempotent. This is done by first getting a list of all unowned config files to see if there are any. If there are, then the role will remove all unowned config files not being currently written by the role invocation. That way, if you run the role again with `logging_purge_confs: true` and the same parameters, the role will detect that there should be no changes to the existing files, and return `changed: false`. Get rid of `logging_reset_confs` - use only purge. The way purge works now is that it will look if the rsyslog package needs to be reinstalled, by checking if /etc/rsyslog.conf is modified, and the user has not provided any rsyslog_inputs (because rsyslog_inputs will trigger /etc/rsyslog.conf to be overwritten if __rsyslog_enabled).
1 parent 118fd30 commit 7939bdb

8 files changed

+255
-110
lines changed

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,13 @@ These variables are set in the same level of the `logging_inputs`, `logging_outp
403403
- `logging_enabled`: When 'true', logging role will deploy specified configuration file set. Default to 'true'.
404404
- `logging_mark`: Mark message periodically by immark, if set to `true`. Default to `false`.
405405
- `logging_mark_interval`: Interval for `logging_mark` in seconds. Default to `3600`.
406-
- `logging_purge_confs`: `true` or `false`. If `logging_purge_confs` is set to `true`, remove files in rsyslog.d which do not belong to any rpm packages. That includes config files generated by the previous logging role run.
407-
- `logging_reset_confs`: `true` or `false`. If `logging_reset_confs` is set to `true`, reinstall rsyslog package, and restore the pre-existing config files, which restores the default `/etc/rsyslog.conf`.
406+
- `logging_purge_confs`: `true` or `false`. If `logging_purge_confs` is set to
407+
`true`, remove files in rsyslog.d which do not belong to any rpm packages.
408+
That includes config files generated by the previous logging role run. NOTE:
409+
If `/etc/rsyslog.conf` was modified, and you use `logging_purge_confs: true`,
410+
and you are not providing any `logging_inputs`, then the `rsyslog` package
411+
will be uninstalled and reinstalled in order to revert back to the original
412+
system default configuration.
408413
- `logging_system_log_dir`: Directory where the local log output files are placed. Default to `/var/log`.
409414
410415
### Update and Delete
@@ -430,7 +435,7 @@ logging_flows:
430435
outputs: [output_name1]
431436
```
432437

433-
If you want to remove all the configuration files previously configured, in addition to setting `state: absent` to each logging_inputs and logging_outputs item, add `logging_enabled: false` to the configuration variables as follows. It will eliminate the global and common configuration files, as well.
438+
If you want to remove all the configuration files previously configured, in addition to setting `state: absent` to each logging_inputs and logging_outputs item, add `logging_enabled: false` to the configuration variables as follows. It will eliminate the global and common configuration files, as well. Or, use `logging_purge_confs: true` to wipe out all previous configuration and replace it with your given configuration.
434439

435440
```yaml
436441
logging_enabled: false

defaults/main.yml

+3-6
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@ logging_flows: []
1616

1717
# `logging_purge_confs` is set to `true`, remove files in rsyslog.d which do
1818
# not belong to any rpm packages. That includes config files generated by the
19-
# previous logging role run.
19+
# previous logging role run. This will also remove and install the rsyslog
20+
# package in order to revert to the system default /etc/rsyslog.conf if you
21+
# do not provide any logging_inputs
2022
logging_purge_confs: false
2123

22-
# If `logging_reset_confs` is set to `true`, reinstall rsyslog package, and
23-
# restore the pre-existing config files, which restores the default
24-
# `/etc/rsyslog.conf`.
25-
logging_reset_confs: false
26-
2724
# Variable to specify the directory to put the local output files to store logs.
2825
logging_system_log_dir: /var/log
2926

roles/rsyslog/tasks/deploy.yml

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
- inner_item.options | d() or inner_item.sections | d()
3232
- inner_item.state is undefined or inner_item.state != 'absent'
3333
notify: restart rsyslogd
34+
register: __rsyslog_deploy_templates
35+
36+
- name: add deployed templates to global list
37+
set_fact:
38+
__rsyslog_template_results: "{{
39+
__rsyslog_template_results + [__rsyslog_deploy_templates] }}"
3440

3541
- name: Remove role config files from rsyslog.d
3642
file:

roles/rsyslog/tasks/deploy_nolog.yml

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
- inner_item.filename | d() or inner_item.name | d()
3737
- inner_item.options | d() or inner_item.sections | d()
3838
notify: restart rsyslogd
39+
register: __rsyslog_deploy_nolog_templates
40+
41+
- name: add deployed templates to global list
42+
set_fact:
43+
__rsyslog_template_results: "{{
44+
__rsyslog_template_results + [__rsyslog_deploy_nolog_templates] }}"
3945

4046
- name: Remove role config files from rsyslog.d with no_log
4147
file:

roles/rsyslog/tasks/main.yml

+132-95
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,50 @@
1313
{{ ansible_facts['distribution_version'] }}.yml"
1414
when: item is file
1515

16+
# if inputs are given and rsyslog_enabled is true, rsyslog.conf will be
17+
# overwritten, so no need to reinstall package
18+
- name: Reinstall package to restore rsyslog config if purging
19+
when:
20+
- logging_purge_confs | bool | d(false)
21+
- not (rsyslog_inputs and __rsyslog_enabled | bool)
22+
block:
23+
# it is assumed that the only packages providing config files that might
24+
# be modified are the base packages - if this is not so, then additional
25+
# packages will need to be added to this check
26+
- name: Get status of rsyslog packages
27+
command: rpm -V {{ item }}
28+
loop: "{{ __rsyslog_base_packages }}"
29+
register: __rsyslog_package_status
30+
failed_when: false
31+
changed_when: false
32+
args:
33+
warn: false
34+
35+
- name: Reset original confs - logging package is absent
36+
package:
37+
name: "{{ __rsyslog_base_packages }}"
38+
state: absent
39+
register: __rsyslog_erased
40+
when: __rsyslog_package_status.results |
41+
rejectattr('stdout', 'match', '^package .* is not installed') |
42+
selectattr('stdout', 'search', ' /etc/rsyslog[.]conf($|\n)') |
43+
list | length > 0
44+
1645
- name: Install/Update required packages
1746
package:
1847
name: "{{ __rsyslog_base_packages }} + {{ __rsyslog_tls_packages
1948
if (logging_pki_files | d([]) | length > 0) else [] }} +
2049
{{ rsyslog_extra_packages | flatten }}"
2150
state: present
2251
when:
23-
- __rsyslog_enabled | bool
52+
- __rsyslog_enabled | bool or
53+
(__rsyslog_erased is success and __rsyslog_erased is changed)
54+
55+
# make sure we do not pollute the global namespace for subsequent runs
56+
# of this role
57+
- name: Reset erased flag
58+
set_fact:
59+
__rsyslog_erased: false
2460

2561
- name: Gather package facts
2662
package_facts:
@@ -66,46 +102,6 @@
66102
path: '{{ __rsyslog_work_dir }}'
67103
mode: '0700'
68104

69-
# If logging_purge_confs is set to true, remove files in rsyslog.d
70-
# which do not belong to any rpm packages. That includes config
71-
# files generated by the previous logging role run.
72-
# If logging_reset_confs is set to true, reinstall rsyslog package,
73-
# and restore the pre-existing config files, which restores the
74-
# default /etc/rsyslog.conf.
75-
- name: >-
76-
Purge original conf - remove confs with no owner package and
77-
confs generated by previous logging role.
78-
shell: |-
79-
set -euo pipefail
80-
for conf in $( ls "{{ __rsyslog_config_dir }}" ); do
81-
rstr=$( rpm -qf "{{ __rsyslog_config_dir }}/$conf" 2>&1 || : )
82-
if [[ $rstr == *"not owned by any package"* ]]; then
83-
# confs generated by the logging role do not belong to
84-
# any rpm packages.
85-
/usr/bin/rm -f "{{ __rsyslog_config_dir }}/$conf"
86-
fi
87-
done
88-
when: logging_purge_confs | bool | d(false)
89-
90-
- block:
91-
- name: Reset original confs - logging package is absent
92-
package:
93-
name: "{{ __rsyslog_base_packages }}"
94-
state: absent
95-
96-
- name: Reset original confs - logging package is present
97-
package:
98-
name: "{{ __rsyslog_base_packages }}"
99-
state: present
100-
rescue:
101-
- name: Reset original configuration files failed
102-
fail:
103-
msg: >
104-
Error: Reset {{ __rsyslog_base_packages }} failed.
105-
Please ensure the package(s) are available to install
106-
from the repository.
107-
when: logging_reset_confs | bool | d(false)
108-
109105
- name: "Create logging directory if it does not exist or
110106
the ownership and/or modes are different."
111107
file:
@@ -175,6 +171,11 @@
175171
- inner_item.state is undefined or inner_item.state != 'absent'
176172
- inner_item.options | d() or inner_item.sections | d()
177173
notify: restart rsyslogd
174+
register: __rsyslog_templates
175+
176+
- name: Initialize list of template results
177+
set_fact:
178+
__rsyslog_template_results: "{{ [__rsyslog_templates] }}"
178179

179180
- name: Remove common config files in rsyslog.d
180181
file:
@@ -194,6 +195,96 @@
194195
- inner_item.options | d() or inner_item.sections | d()
195196
notify: stop rsyslogd
196197

198+
- name: Include input sub-vars
199+
include_vars:
200+
file: "{{ role_path }}/vars/{{ varfile }}"
201+
vars:
202+
varfile: "inputs/{{ input_item.type }}/main.yml"
203+
loop: "{{ rsyslog_inputs }}"
204+
loop_control:
205+
loop_var: input_item
206+
when:
207+
- input_item | d([])
208+
209+
- name: Run input sub-tasks
210+
include_tasks:
211+
file: "{{ tasks }}"
212+
vars:
213+
tasks: "{{ role_path }}/tasks/inputs/{{ input_item.type }}/main.yml"
214+
__rsyslog_input: "{{ input_item }}"
215+
loop: '{{ rsyslog_inputs | sort(attribute="type") }}'
216+
loop_control:
217+
extended: yes
218+
loop_var: input_item
219+
when:
220+
- input_item | d([])
221+
- input_item.type | d()
222+
- input_item.type != "basics" or
223+
(input_item.type == "basics" and
224+
(ansible_loop.previtem is not defined or
225+
(ansible_loop.previtem is defined and
226+
ansible_loop.previtem.type != 'basics')))
227+
228+
- name: Include output sub-vars
229+
include_vars:
230+
file: "{{ role_path }}/vars/{{ varfile }}"
231+
vars:
232+
varfile: "outputs/{{ output_item.type }}/main.yml"
233+
loop: "{{ rsyslog_outputs }}"
234+
loop_control:
235+
loop_var: output_item
236+
when:
237+
- output_item | d([])
238+
- output_item.type | d()
239+
240+
- name: Run output sub-tasks
241+
include_tasks:
242+
file: "{{ tasks }}"
243+
vars:
244+
tasks: "{{ role_path }}/tasks/outputs/{{ output_item.type }}/main.yml"
245+
__rsyslog_output: "{{ output_item }}"
246+
loop: "{{ rsyslog_outputs }}"
247+
loop_control:
248+
loop_var: output_item
249+
when:
250+
- output_item | d([])
251+
252+
- name: Get rsyslog config files not owned by any package
253+
shell: |
254+
set -euo pipefail
255+
for conf in $( ls "{{ __rsyslog_config_dir }}" ); do
256+
rstr=$( rpm -qf "{{ __rsyslog_config_dir }}/$conf" 2>&1 || : )
257+
if [[ "$rstr" == *"not owned by any package"* ]]; then
258+
echo "{{ __rsyslog_config_dir }}/$conf"
259+
fi
260+
done
261+
register: __rsyslog_confs
262+
failed_when: false
263+
changed_when: false
264+
when: logging_purge_confs | bool | d(false)
265+
266+
# If logging_purge_confs is set to true, remove files in rsyslog.d
267+
# which do not belong to any rpm packages. That includes config
268+
# files generated by the previous logging role run.
269+
- name: Purge - remove files not generated by current state
270+
file:
271+
path: "{{ item }}"
272+
state: absent
273+
loop: "{{ __rsyslog_files_to_remove }}"
274+
notify: "{{ 'restart rsyslogd' if logging_enabled else 'stop rsyslogd' }}"
275+
when:
276+
- logging_purge_confs | bool | d(false)
277+
- __rsyslog_files_to_remove | length > 0
278+
vars:
279+
__rsyslog_current_files: "{{ __rsyslog_template_results |
280+
selectattr('results', 'defined') | map(attribute='results') |
281+
flatten | selectattr('dest', 'defined') | map(attribute='dest') |
282+
list | to_nice_json
283+
}}"
284+
__rsyslog_files_to_remove: "{{
285+
__rsyslog_confs.stdout_lines | difference(__rsyslog_current_files)
286+
}}"
287+
197288
# How to set rsyslog_custom_config_files:
198289
# rsyslog_custom_config_files:
199290
# - /path/to/custom0.conf
@@ -292,60 +383,6 @@
292383
when:
293384
- __rsyslog_enabled | bool
294385

295-
- name: Include input sub-vars
296-
include_vars:
297-
file: "{{ role_path }}/vars/{{ varfile }}"
298-
vars:
299-
varfile: "inputs/{{ input_item.type }}/main.yml"
300-
loop: "{{ rsyslog_inputs }}"
301-
loop_control:
302-
loop_var: input_item
303-
when:
304-
- input_item | d([])
305-
306-
- name: Run input sub-tasks
307-
include_tasks:
308-
file: "{{ tasks }}"
309-
vars:
310-
tasks: "{{ role_path }}/tasks/inputs/{{ input_item.type }}/main.yml"
311-
__rsyslog_input: "{{ input_item }}"
312-
loop: '{{ rsyslog_inputs | sort(attribute="type") }}'
313-
loop_control:
314-
extended: yes
315-
loop_var: input_item
316-
when:
317-
- input_item | d([])
318-
- input_item.type | d()
319-
- input_item.type != "basics" or
320-
(input_item.type == "basics" and
321-
(ansible_loop.previtem is not defined or
322-
(ansible_loop.previtem is defined and
323-
ansible_loop.previtem.type != 'basics')))
324-
325-
- name: Include output sub-vars
326-
include_vars:
327-
file: "{{ role_path }}/vars/{{ varfile }}"
328-
vars:
329-
varfile: "outputs/{{ output_item.type }}/main.yml"
330-
loop: "{{ rsyslog_outputs }}"
331-
loop_control:
332-
loop_var: output_item
333-
when:
334-
- output_item | d([])
335-
- output_item.type | d()
336-
337-
- name: Run output sub-tasks
338-
include_tasks:
339-
file: "{{ tasks }}"
340-
vars:
341-
tasks: "{{ role_path }}/tasks/outputs/{{ output_item.type }}/main.yml"
342-
__rsyslog_output: "{{ output_item }}"
343-
loop: "{{ rsyslog_outputs }}"
344-
loop_control:
345-
loop_var: output_item
346-
when:
347-
- output_item | d([])
348-
349386
- name: Enable rsyslog service
350387
service:
351388
name: rsyslog

tests/tests_basics_files.yml

-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,6 @@
386386

387387
- name: END TEST CASE 3; Clean up the deployed config
388388
vars:
389-
logging_reset_confs: true
390389
logging_enabled: false
391390
logging_outputs:
392391
- name: files_output0

tests/tests_basics_forwards.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,8 @@
569569

570570
- name: END TEST CASE 2; Clean up the deployed config
571571
vars:
572-
logging_reset_confs: true
573572
logging_enabled: false
573+
logging_purge_confs: true
574574
logging_pki_files:
575575
- ca_cert_src: "{{ __test_ca_cert }}"
576576
cert_src: "{{ __test_cert }}"

0 commit comments

Comments
 (0)