Refactored crontab resource

Specifically the parsing was pretty unreadable. This refactoring
emphasizes using a default hash and merging in the differences for
what was parsed. Everything is funneled through one `merge_crontab`
method that does the actual parsing and the system vs user differences
are merged in after in their respective parse methods.

Signed-off-by: Ryan Davis <zenspider@chef.io>
This commit is contained in:
Ryan Davis 2020-01-29 13:56:11 -08:00
parent d013ac1e47
commit ceab1cbdac

View file

@ -67,6 +67,7 @@ module Inspec::Resources
end end
def crontab_cmd def crontab_cmd
# TODO: the -u scenario needs to be able to do sudo
@user.nil? ? "crontab -l" : "crontab -l -u #{@user}" @user.nil? ? "crontab -l" : "crontab -l -u #{@user}"
end end
@ -108,66 +109,63 @@ module Inspec::Resources
!@user.nil? !@user.nil?
end end
def parse_system_crontab(data) DEFAULT_TIMES = {
"minute" => "*",
"hour" => "*",
"day" => "*",
"month" => "*",
"weekday" => "*",
}
SYSTEM_COLUMNS = %w{minute hour day month weekday user command}
USER_COLUMNS = %w{minute hour day month weekday command}
HOURLY = { "minute" => "0" }
DAILY = HOURLY .merge("hour" => "0")
WEEKLY = HOURLY .merge("weekday" => "0")
MONTHLY = DAILY .merge("day" => "1")
YEARLY = MONTHLY .merge("month" => "1")
REBOOT = {
"minute" => "-1",
"hour" => "-1",
"day" => "-1",
"month" => "-1",
"weekday" => "-1",
}
def merge_crontab(data, default)
case data case data
when /@hourly .*/ when /@hourly /
elements = data.split(/\s+/, 3) default.merge(HOURLY)
{ "minute" => "0", "hour" => "*", "day" => "*", "month" => "*", "weekday" => "*", "user" => elements.at(1), "command" => elements.at(2) } when /@(midnight|daily) /
when /@(midnight|daily) .*/ default.merge(DAILY)
elements = data.split(/\s+/, 3) when /@weekly /
{ "minute" => "0", "hour" => "0", "day" => "*", "month" => "*", "weekday" => "*", "user" => elements.at(1), "command" => elements.at(2) } default.merge(WEEKLY)
when /@weekly .*/ when /@monthly /
elements = data.split(/\s+/, 3) default.merge(MONTHLY)
{ "minute" => "0", "hour" => "0", "day" => "*", "month" => "*", "weekday" => "0", "user" => elements.at(1), "command" => elements.at(2) } when /@(annually|yearly) /
when /@monthly ./ default.merge(YEARLY)
elements = data.split(/\s+/, 3) when /@reboot /
{ "minute" => "0", "hour" => "0", "day" => "1", "month" => "*", "weekday" => "*", "user" => elements.at(1), "command" => elements.at(2) } default.merge(REBOOT)
when /@(annually|yearly) .*/
elements = data.split(/\s+/, 3)
{ "minute" => "0", "hour" => "0", "day" => "1", "month" => "1", "weekday" => "*", "user" => elements.at(1), "command" => elements.at(2) }
when /@reboot .*/
elements = data.split(/\s+/, 3)
{ "minute" => "-1", "hour" => "-1", "day" => "-1", "month" => "-1", "weekday" => "-1", "user" => elements.at(1), "command" => elements.at(2) }
else
elements = data.split(/\s+/, 7)
{
"minute" => elements.at(0),
"hour" => elements.at(1),
"day" => elements.at(2),
"month" => elements.at(3),
"weekday" => elements.at(4),
"user" => elements.at(5),
"command" => elements.at(6),
}
end end
end end
def parse_system_crontab(data)
_, user, cmd = elements = data.split(/\s+/, 3)
default = DEFAULT_TIMES.merge("user" => user,
"command" => cmd)
merge_crontab(data, default) ||
SYSTEM_COLUMNS.zip(data.split(/\s+/, 7)).to_h
end
def parse_user_crontab(data) def parse_user_crontab(data)
case data _, cmd = data.split(/\s+/, 2)
when /@hourly .*/ default = DEFAULT_TIMES.merge("user" => @user,
{ "minute" => "0", "hour" => "*", "day" => "*", "month" => "*", "weekday" => "*", "user" => @user, "command" => data.split(/\s+/, 2).at(1) } "command" => cmd)
when /@(midnight|daily) .*/
{ "minute" => "0", "hour" => "0", "day" => "*", "month" => "*", "weekday" => "*", "user" => @user, "command" => data.split(/\s+/, 2).at(1) } merge_crontab(data, default) ||
when /@weekly .*/ USER_COLUMNS.zip(data.split(/\s+/, 6)).to_h.merge("user" => @user)
{ "minute" => "0", "hour" => "0", "day" => "*", "month" => "*", "weekday" => "0", "user" => @user, "command" => data.split(/\s+/, 2).at(1) }
when /@monthly ./
{ "minute" => "0", "hour" => "0", "day" => "1", "month" => "*", "weekday" => "*", "user" => @user, "command" => data.split(/\s+/, 2).at(1) }
when /@(annually|yearly) .*/
{ "minute" => "0", "hour" => "0", "day" => "1", "month" => "1", "weekday" => "*", "user" => @user, "command" => data.split(/\s+/, 2).at(1) }
when /@reboot .*/
{ "minute" => "-1", "hour" => "-1", "day" => "-1", "month" => "-1", "weekday" => "-1", "user" => @user, "command" => data.split(/\s+/, 2).at(1) }
else
elements = data.split(/\s+/, 6)
{
"minute" => elements.at(0),
"hour" => elements.at(1),
"day" => elements.at(2),
"month" => elements.at(3),
"weekday" => elements.at(4),
"user" => @user,
"command" => elements.at(5),
}
end
end end
end end
end end