I want to have all cron jobs of a server parsed by Ansible and write the existing entries into a JSON file on the Ansible management node.
Sadly I have no idea how to read the crontab and even more how to write all entries into a JSON.
Intention of this requirement:
This JSON shall be used by administrators to manage centrally all crons of all servers and to be able to push "Updates" down to the nodes.
How to solve this requirement?
CodePudding user response:
As the comments mention, you need to write the logic yourself, as there is no module that does that for you.
You can use this python-library to parse the files. But be aware that there can be a lot of locations where cron-jobs can be configured. Including, but not limited to
/etc/crontab
/etc/cron.d/*
/etc/cron.daily
,weekly
etc.- users contabs, that are modified using the
crontab
command
Then you can use the json-module in the standard-library to dump a JSON string.
In any case, you are approaching this in the wrong way. You should use the ansible.builtin.cron
module to define all cron-tab entries in a playbook. You can then add, update or delete cron-jobs on the servers by updating the playbook and running it. You can even version your playbook using git, introduce a review-process etc.
CodePudding user response:
Use filter community.general.jc. It's a wrapper of the Python jc converter. For example, given the crontab
shell> ssh admin@test_11 cat /etc/crontab
# /etc/crontab - root's crontab for FreeBSD
#
# $FreeBSD$
#
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
#
#minute hour mday month wday who command
#
# Save some entropy so that /dev/random can re-seed on boot.
*/11 * * * * operator /usr/libexec/save-entropy
#
# Rotate log files every hour, if necessary.
0 * * * * root newsyslog
#
# Perform daily/weekly/monthly maintenance.
1 3 * * * root periodic daily
15 4 * * 6 root periodic weekly
30 5 1 * * root periodic monthly
#
# Adjust the time zone if the CMOS clock keeps local time, as opposed to
# UTC time. See adjkerntz(8) for details.
1,31 0-5 * * * root adjkerntz -a
The playbook below
shell> cat pb.yml
- hosts: test_11,test_12
tasks:
- command:
cmd: cat /etc/crontab
register: result
- set_fact:
crontab: "{{ result.stdout|community.general.jc('crontab') }}"
- copy:
dest: /tmp/crontabs.json
content: |
{{ crontabs_dict|to_json }}
vars:
crontabs_list: "{{ ansible_play_hosts|map('extract', hostvars, 'crontab')|list }}"
crontabs_dict: "{{ dict(ansible_play_hosts|zip(crontabs_list)) }}"
delegate_to: localhost
run_once: true
creates the file at the controller
shell> cat /tmp/crontabs.json
{"test_11": {"variables": [{"name": "PATH", "value": "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"}, {"name": "SHELL", "value": "/bin/sh"}], "schedule": [{"minute": ["/11"], "hour": [""], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "operator /usr/libexec/save-entropy"}, {"minute": ["0"], "hour": [""], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "root\tnewsyslog"}, {"minute": ["1"], "hour": ["3"], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "root\tperiodic daily"}, {"minute": ["15"], "hour": ["4"], "day_of_month": [""], "month": [""], "day_of_week": ["6"], "command": "root\tperiodic weekly"}, {"minute": ["30"], "hour": ["5"], "day_of_month": ["1"], "month": [""], "day_of_week": [""], "command": "root\tperiodic monthly"}, {"minute": ["1", "31"], "hour": ["0-5"], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "root\tadjkerntz -a"}]}, "test_12": {"variables": [{"name": "PATH", "value": "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"}, {"name": "SHELL", "value": "/bin/sh"}], "schedule": [{"minute": ["/11"], "hour": [""], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "operator /usr/libexec/save-entropy"}, {"minute": ["0"], "hour": [""], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "root\tnewsyslog"}, {"minute": ["1"], "hour": ["3"], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "root\tperiodic daily"}, {"minute": ["15"], "hour": ["4"], "day_of_month": [""], "month": [""], "day_of_week": ["6"], "command": "root\tperiodic weekly"}, {"minute": ["30"], "hour": ["5"], "day_of_month": ["1"], "month": [""], "day_of_week": [""], "command": "root\tperiodic monthly"}, {"minute": ["1", "31"], "hour": ["0-5"], "day_of_month": [""], "month": [""], "day_of_week": [""], "command": "root\tadjkerntz -a"}]}}
The variable crontabs_dict in YAML
crontabs_dict:
test_11:
schedule:
- command: operator /usr/libexec/save-entropy
day_of_month: ['*']
day_of_week: ['*']
hour: ['*']
minute: ['*/11']
month: ['*']
- command: "root\tnewsyslog"
day_of_month: ['*']
day_of_week: ['*']
hour: ['*']
minute: ['0']
month: ['*']
- command: "root\tperiodic daily"
day_of_month: ['*']
day_of_week: ['*']
hour: ['3']
minute: ['1']
month: ['*']
- command: "root\tperiodic weekly"
day_of_month: ['*']
day_of_week: ['6']
hour: ['4']
minute: ['15']
month: ['*']
- command: "root\tperiodic monthly"
day_of_month: ['1']
day_of_week: ['*']
hour: ['5']
minute: ['30']
month: ['*']
- command: "root\tadjkerntz -a"
day_of_month: ['*']
day_of_week: ['*']
hour: [0-5]
minute: ['1', '31']
month: ['*']
variables:
- {name: PATH, value: '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin'}
- {name: SHELL, value: /bin/sh}
test_12:
schedule:
- command: operator /usr/libexec/save-entropy
day_of_month: ['*']
day_of_week: ['*']
hour: ['*']
minute: ['*/11']
month: ['*']
- command: "root\tnewsyslog"
day_of_month: ['*']
day_of_week: ['*']
hour: ['*']
minute: ['0']
month: ['*']
- command: "root\tperiodic daily"
day_of_month: ['*']
day_of_week: ['*']
hour: ['3']
minute: ['1']
month: ['*']
- command: "root\tperiodic weekly"
day_of_month: ['*']
day_of_week: ['6']
hour: ['4']
minute: ['15']
month: ['*']
- command: "root\tperiodic monthly"
day_of_month: ['1']
day_of_week: ['*']
hour: ['5']
minute: ['30']
month: ['*']
- command: "root\tadjkerntz -a"
day_of_month: ['*']
day_of_week: ['*']
hour: [0-5]
minute: ['1', '31']
month: ['*']
variables:
- {name: PATH, value: '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin'}
- {name: SHELL, value: /bin/sh}