running handlers

25 views
Skip to first unread message

Michael DiDomenico

unread,
Mar 22, 2024, 2:15:35 PM3/22/24
to ansible...@googlegroups.com
i'm trying to copy a bunch of ssl ca certs into a directory.  this works file with the copy module and if it sees a new one it runs a handler to rehash all the certs in the directory to create *.0 symlinks to each of the certs

however, if an additional cert gets put in there by someone and they don't rehash the directory, now there's a cert without a hash

i can count the *.crt's and the *.0's using the find module, which puts a 'matched' number into the ansible registered variable from the find, but i can't figure a way to run the handler to rehash the directory if the counts aren't equal

i found some other examples where people just run handlers based on command: /bin/true with changed_when: true, but i don't want to run it all the time, only if the counts aren't equal

any suggestions?

Vladimir Botka

unread,
Mar 22, 2024, 4:01:39 PM3/22/24
to Michael DiDomenico, ansible...@googlegroups.com
On Fri, 22 Mar 2024 14:15:03 -0400
Michael DiDomenico <mdidom...@gmail.com> wrote:

> ... copy a bunch of ssl ca certs into a directory ...
> create *.0 symlinks to each of the certs

FWIW, instead of handlers, get the lists of the certs and
links, and iterate the difference


- find:
paths: /tmp/ansible/certs
patterns: '*.crt'
register: out_crt

- find:
paths: /tmp/ansible/certs
patterns: '*.0'
file_type: link
register: out_lnk

- file:
state: link
src: /tmp/ansible/certs/{{ item }}.crt
dest: /tmp/ansible/certs/{{ item }}.0
loop: "{{ certs | difference(links) }}"
vars:
certs: "{{ out_crt.files |
json_query('[].path') |
map('basename') |
map('splitext') |
map('first') }}"
links: "{{ out_lnk.files |
json_query('[].path') |
map('basename') |
map('splitext') |
map('first') }}"

Fit the paths to your needs.

--
Vladimir Botka

Michael DiDomenico

unread,
Mar 23, 2024, 11:12:52 AM3/23/24
to ansible...@googlegroups.com
thanks, eventually after a few hours i came to a similar conclusion, i was hoping there was a more elegant way which didn't need a series of finds

Vladimir Botka

unread,
Mar 23, 2024, 4:51:16 PM3/23/24
to Michael DiDomenico, ansible...@googlegroups.com
On Sat, 23 Mar 2024 11:12:20 -0400
Michael DiDomenico <mdidom...@gmail.com> wrote:

> ... i was hoping there was a more elegant way which
> didn't need a series of finds

The complexity is a consequence of you requirement to
"rehash the directory if the counts aren't equal". You
can't compare *counts* without at least two *finds*. The
elegant way is a single *find* and iteration of all
certificates

- find:
paths: /tmp/ansible/certs
patterns: '*.crt'
register: out_crt

- file:
state: link
src: /tmp/ansible/certs/{{ item }}.crt
dest: /tmp/ansible/certs/{{ item }}.0
loop: "{{ out_crt.files |
json_query('[].path') |
map('basename') |
map('splitext') |
map('first') }}"

This is, however, less efficient. The options are limited
because *file* doesn't work with wildcards. If you don't
care about idempotency and the changed/failed status
*shell* also does the job

- shell: |
cd /tmp/ansible/certs &&
for i in *.crt; do ln -s $i ${i%.crt}.0; done
failed_when: false
changed_when: false

You can write advanced scripts or custom filters that would
do what you want.

--
Vladimir Botka
Reply all
Reply to author
Forward
0 new messages