diff --git a/jc/cli.py b/jc/cli.py index 3ea7a44b..ec7b647b 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -8,6 +8,7 @@ import signal import json import jc.utils import jc.parsers.arp +import jc.parsers.crontab import jc.parsers.df import jc.parsers.dig import jc.parsers.du @@ -39,6 +40,7 @@ import jc.parsers.w parser_map = { '--arp': jc.parsers.arp, + '--crontab': jc.parsers.crontab, '--df': jc.parsers.df, '--dig': jc.parsers.dig, '--du': jc.parsers.du, diff --git a/jc/parsers/crontab.py b/jc/parsers/crontab.py new file mode 100644 index 00000000..f66d2f5f --- /dev/null +++ b/jc/parsers/crontab.py @@ -0,0 +1,132 @@ +"""jc - JSON CLI output utility crontab file Parser + +Usage: + + specify --crontab as the first argument if the piped input is coming from a crontab file + +Compatibility: + + 'linux', 'aix', 'freebsd' + +Examples: + + $ crontab | jc --crontab -p + [] + + $ crontab | jc --crontab -p -r + [] +""" +import jc.utils +import jc.parsers.universal + + +class info(): + version = '1.0' + description = '/etc/crontab file parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + # details = 'enter any other details here' + + # compatible options: linux, darwin, cygwin, win32, aix, freebsd + compatible = ['linux', 'aix', 'freebsd'] + + +def process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (dictionary) raw structured data to process + + Returns: + + dictionary structured data with the following schema: + + [ + { + "minute": [ + string + ], + "hour": [ + string + ], + "day_of_month": [ + string + ], + "month": [ + string + ], + "day_of_week": [ + string + ], + "username": string + } + ] + + """ + # put itmes in lists + for entry in proc_data['schedule']: + entry['minute'] = entry['minute'].split(',') + entry['hour'] = entry['hour'].split(',') + entry['day_of_month'] = entry['day_of_month'].split(',') + entry['month'] = entry['month'].split(',') + entry['day_of_week'] = entry['day_of_week'].split(',') + + return proc_data + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + dictionary raw or processed structured data + """ + if not quiet: + jc.utils.compatibility(__name__, info.compatible) + + raw_output = {} + cleandata = data.splitlines() + + # Clear any blank lines + cleandata = list(filter(None, cleandata)) + + # Clear any commented lines + for i, line in reversed(list(enumerate(cleandata))): + if line.strip().find('#') == 0: + cleandata.pop(i) + + # Pop any variable assignment lines + cron_var = [] + for i, line in reversed(list(enumerate(cleandata))): + if line.find('=') != -1: + var_line = cleandata.pop(i) + var_name = var_line.split('=', maxsplit=1)[0] + var_value = var_line.split('=', maxsplit=1)[1] + cron_var.append({'name': var_name, + 'value': var_value}) + + raw_output['variables'] = cron_var + + # TODO: support @shortcuts + + # Add header row for parsing + cleandata[0] = 'minute hour day_of_month month day_of_week username command' + + if len(cleandata) > 1: + cron_list = jc.parsers.universal.simple_table_parse(cleandata) + + raw_output['schedule'] = cron_list + + if raw: + return raw_output + else: + return process(raw_output) diff --git a/tests/fixtures/centos-7.7/crontab.out b/tests/fixtures/centos-7.7/crontab.out new file mode 100644 index 00000000..7f1f0b4a --- /dev/null +++ b/tests/fixtures/centos-7.7/crontab.out @@ -0,0 +1,43 @@ +SHELL=/bin/bash +PATH=/sbin:/bin:/usr/sbin:/usr/bin +MAILTO=root + +#-------------------------------------------------- +# example unix/linux crontab file format: +#-------------------------------------------------- +# min,hour,dayOfMonth,month,dayOfWeek command +# +# field allowed values +# ----- -------------- +# minute 0-59 +# hour 0-23 +# day of month 1-31 +# month 1-12 (or names, see below) +# day of week 0-7 (0 or 7 is Sun, or use names) +# +#-------------------------------------------------- + +# run the drupal cron process every hour of every day +0 * * * * /usr/bin/wget -O - -q -t 1 http://localhost/cron.php + +# run this apache kludge every minute of every day +* * * * * /var/www/devdaily.com/bin/check-apache.sh + +# generate links to new blog posts twice a day +5 10,22 * * * /var/www/devdaily.com/bin/mk-new-links.php + +# run the backup scripts at 4:30am +30 4 * * * /var/www/devdaily.com/bin/create-all-backups.sh + +# re-generate the blog "categories" list (four times a day) +5 0,4,10,16 * * * /var/www/devdaily.com/bin/create-cat-list.sh + +# reset the contact form just after midnight +5 0 * * * /var/www/devdaily.com/bin/resetContactForm.sh + +# rotate the ad banners every five minutes + +0,20,40 * * * * /var/www/bin/ads/freshMint.sh +5,25,45 * * * * /var/www/bin/ads/greenTaffy.sh +10,30,50 * * * * /var/www/bin/ads/raspberry.sh +15,35,55 * * * * /var/www/bin/ads/robinsEgg.sh \ No newline at end of file