From 12a28933b46b83e6745a873d174a1fbe9e46f13d Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Fri, 11 May 2018 11:06:35 -0700 Subject: Add cron_d and cron_access resources from the cron cookbook Cron_d was the #1 requested resource that we already had written. Everyone uses it and we should ship it. It's not a replacement for the existing cron cookbook, but just a different way of managing cron. If people want to manage the whole file or individual snippets we'll give them the option, just as we've always done by having the core resource and this resource. Signed-off-by: Tim Smith --- lib/chef/resource/cron_access.rb | 70 ++++++++++ lib/chef/resource/cron_d.rb | 213 ++++++++++++++++++++++++++++++ lib/chef/resource/support/cron.d.erb | 28 ++++ lib/chef/resource/support/cron_access.erb | 4 + lib/chef/resources.rb | 4 +- spec/unit/resource/cron_access_spec.rb | 32 +++++ spec/unit/resource/cron_d_spec.rb | 32 +++++ 7 files changed, 382 insertions(+), 1 deletion(-) create mode 100644 lib/chef/resource/cron_access.rb create mode 100644 lib/chef/resource/cron_d.rb create mode 100644 lib/chef/resource/support/cron.d.erb create mode 100644 lib/chef/resource/support/cron_access.erb create mode 100644 spec/unit/resource/cron_access_spec.rb create mode 100644 spec/unit/resource/cron_d_spec.rb diff --git a/lib/chef/resource/cron_access.rb b/lib/chef/resource/cron_access.rb new file mode 100644 index 0000000000..b89cf8e265 --- /dev/null +++ b/lib/chef/resource/cron_access.rb @@ -0,0 +1,70 @@ +# +# Author:: Sander Botman +# Author:: Tim Smith +# +# Copyright:: 2014-2018, Sander Botman +# Copyright:: 2018, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" + +class Chef + class Resource + class CronAccess < Chef::Resource + preview_resource true + resource_name :cron_access + provides(:cron_manage) # legacy name @todo in Chef 15 we should { true } this so it wins over the cookbook + + introduced "14.3" + description "" + + property :user, String, + description: "The user to allow or deny. If not provided we'll use the resource name.", + name_property: true + + action :allow do + description "Add the user to the cron.deny file." + + with_run_context :root do + edit_resource(:template, "/etc/cron.allow") do |new_resource| + source ::File.expand_path("../support/cron_access.erb", __FILE__) + local true + mode "0600" + variables["users"] ||= [] + variables["users"] << new_resource.user + action :nothing + delayed_action :create + end + end + end + + action :deny do + description "Add the user to the cron.allow file." + + with_run_context :root do + edit_resource(:template, "/etc/cron.deny") do |new_resource| + source ::File.expand_path("../support/cron_access.erb", __FILE__) + local true + mode "0600" + variables["users"] ||= [] + variables["users"] << new_resource.user + action :nothing + delayed_action :create + end + end + end + end + end +end diff --git a/lib/chef/resource/cron_d.rb b/lib/chef/resource/cron_d.rb new file mode 100644 index 0000000000..f3b102b2b3 --- /dev/null +++ b/lib/chef/resource/cron_d.rb @@ -0,0 +1,213 @@ +# +# Copyright:: 2008-2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" +require "shellwords" + +class Chef + class Resource + class CronD < Chef::Resource + preview_resource true + resource_name :cron_d + + introduced "14.3" + description "" + + property :cron_name, String, + description: "Set the name of the cron job. If this isn't specified we'll use the resource name.", + name_property: true + + property :cookbook, String + + property :predefined_value, String, + description: 'Schedule your cron job with one of the special predefined value instead of ** * pattern. This correspond to "@reboot", "@yearly", "@annually", "@monthly", "@weekly", "@daily", "@midnight" or "@hourly".', + equal_to: %w{ @reboot @yearly @annually @monthly @weekly @daily @midnight @hourly } + + property :minute, [Integer, String], + description: "", + default: "*", callbacks: { + "should be a valid minute spec" => ->(spec) { validate_numeric(spec, 0, 59) } + } + + property :hour, [Integer, String], + description: "", + default: "*", callbacks: { + "should be a valid hour spec" => ->(spec) { validate_numeric(spec, 0, 23) } + } + + property :day, [Integer, String], + description: "", + default: "*", callbacks: { + "should be a valid day spec" => ->(spec) { validate_numeric(spec, 1, 31) } + } + + property :month, [Integer, String], + description: "", + default: "*", callbacks: { + "should be a valid month spec" => ->(spec) { validate_month(spec) } + } + + property :weekday, [Integer, String], + description: "", + default: "*", callbacks: { + "should be a valid weekday spec" => ->(spec) { validate_dow(spec) } + } + + property :command, String, + description: "The command to run.", + required: true + + property :user, String, + description: "The user to run the cron job as.", + default: "root" + + property :mailto, [String, NilClass], + description: "Set the MAILTO environment variable in the cron.d file." + + property :path, [String, NilClass], + description: "Set the PATH environment variable in the cron.d file." + + property :home, [String, NilClass], + description: "" + + property :shell, [String, NilClass], + description: "Set the HOME environment variable in the cron.d file." + + property :comment, [String, NilClass], + description: "A comment to place in the cron.d file." + + property :environment, Hash, + description: "A Hash containing additional arbitrary environment variables under which the cron job will be run.", + default: {} + + property :mode, [String, Integer], + description: "The octal mode of the generated crontab file.", + default: "0600" + + def after_created + raise ArgumentError, "The 'cookbook' property for the cron_d resource is no longer supported now that this resource ships in Chef itself." if new_resource.cookbook + end + + def validate_numeric(spec, min, max) + return true if spec == "*" + # binding.pry + if spec.respond_to? :to_int + return false unless spec >= min && spec <= max + return true + end + + # Lists of invidual values, ranges, and step values all share the validity range for type + spec.split(%r{\/|-|,}).each do |x| + next if x == "*" + return false unless x =~ /^\d+$/ + x = x.to_i + return false unless x >= min && x <= max + end + true + end + + def validate_month(spec) + return true if spec == "*" + if spec.respond_to? :to_int + validate_numeric(spec, 1, 12) + elsif spec.respond_to? :to_str + return true if spec == "*" + # Named abbreviations are permitted but not as part of a range or with stepping + return true if %w{jan feb mar apr may jun jul aug sep oct nov dec}.include? spec.downcase + # 1-12 are legal for months + validate_numeric(spec, 1, 12) + else + false + end + end + + def validate_dow(spec) + return true if spec == "*" + if spec.respond_to? :to_int + validate_numeric(spec, 0, 7) + elsif spec.respond_to? :to_str + return true if spec == "*" + # Named abbreviations are permitted but not as part of a range or with stepping + return true if %w{sun mon tue wed thu fri sat}.include? spec.downcase + # 0-7 are legal for days of week + validate_numeric(spec, 0, 7) + else + false + end + end + + action :create do + create_template(:create) + end + + action :create_if_missing do + create_template(:create_if_missing) + end + + action :delete do + # cleanup the legacy named job if it exists + file "legacy named cron.d file" do + path "/etc/cron.d/#{new_resource.cron_name}" + action :delete + end + + file "/etc/cron.d/#{sanitized_name}" do + action :delete + end + end + + action_class do + def sanitized_name + new_resource.cron_name.tr(".", "-") + end + + def create_template(create_action) + # cleanup the legacy named job if it exists + file "#{new_resource.cron_name} legacy named cron.d file" do + path "/etc/cron.d/#{new_resource.cron_name}" + action :delete + only_if { new_resource.cron_name != sanitized_name } + end + + template "/etc/cron.d/#{sanitized_name}" do + source ::File.expand_path("../support/cron.d.erb", __FILE__) + local true + mode new_resource.mode + variables( + name: sanitized_name, + predefined_value: new_resource.predefined_value, + minute: new_resource.minute, + hour: new_resource.hour, + day: new_resource.day, + month: new_resource.month, + weekday: new_resource.weekday, + command: new_resource.command, + user: new_resource.user, + mailto: new_resource.mailto, + path: new_resource.path, + home: new_resource.home, + shell: new_resource.shell, + comment: new_resource.comment, + environment: new_resource.environment + ) + action create_action + end + end + end + end + end +end diff --git a/lib/chef/resource/support/cron.d.erb b/lib/chef/resource/support/cron.d.erb new file mode 100644 index 0000000000..2f27ecb36b --- /dev/null +++ b/lib/chef/resource/support/cron.d.erb @@ -0,0 +1,28 @@ +# Generated by Chef. Changes will be overwritten. +<% if @mailto -%> +MAILTO=<%= @mailto %> +<% end -%> +<% if @path -%> +PATH=<%= @path %> +<% end -%> +<% if @shell -%> +SHELL=<%= @shell %> +<% end -%> +<% if @home -%> +HOME=<%= @home %> +<% end -%> +<% if @random_delay -%> +RANDOM_DELAY=<%= @random_delay %> +<% end -%> +<% @environment.each do |key, val| -%> +<%= key %>=<%= val.to_s.shellescape %> +<% end -%> + +<% if @comment -%> +# <%= @comment %> +<% end -%> +<% if @predefined_value -%> +<%= @predefined_value %> <%= @user %> <%= @command %> +<% else -%> +<%= @minute %> <%= @hour %> <%= @day %> <%= @month %> <%= @weekday %> <%= @user %> <%= @command %> +<% end -%> diff --git a/lib/chef/resource/support/cron_access.erb b/lib/chef/resource/support/cron_access.erb new file mode 100644 index 0000000000..fdf61172ab --- /dev/null +++ b/lib/chef/resource/support/cron_access.erb @@ -0,0 +1,4 @@ +# Generated by Chef. Changes will be overwritten. +<% @users.sort.uniq.each do |user| -%> +<%= user %> +<% end -%> diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index c13a01c352..069c35691f 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -1,6 +1,6 @@ # # Author:: Daniel DeLeo () -# Copyright:: Copyright 2010-2016, Chef Software, Inc. +# Copyright:: Copyright 2010-2018, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,6 +31,8 @@ require "chef/resource/chocolatey_config" require "chef/resource/chocolatey_package" require "chef/resource/chocolatey_source" require "chef/resource/cron" +require "chef/resource/cron_access" +require "chef/resource/cron_d" require "chef/resource/csh" require "chef/resource/directory" require "chef/resource/dmg_package" diff --git a/spec/unit/resource/cron_access_spec.rb b/spec/unit/resource/cron_access_spec.rb new file mode 100644 index 0000000000..1fd16f315f --- /dev/null +++ b/spec/unit/resource/cron_access_spec.rb @@ -0,0 +1,32 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::CronAccess do + let(:resource) { Chef::Resource::CronAccess.new("bob") } + + it "has a default action of [:deny]" do + expect(resource.action).to eql([:deny]) + end + + it "accepts create or delete for action" do + expect { resource.action :allow }.not_to raise_error + expect { resource.action :deny }.not_to raise_error + expect { resource.action :lolcat }.to raise_error(ArgumentError) + end +end diff --git a/spec/unit/resource/cron_d_spec.rb b/spec/unit/resource/cron_d_spec.rb new file mode 100644 index 0000000000..99899131f8 --- /dev/null +++ b/spec/unit/resource/cron_d_spec.rb @@ -0,0 +1,32 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::CronD do + let(:resource) { Chef::Resource::CronD.new("cronify") } + + it "has a default action of [:create]" do + expect(resource.action).to eql([:create]) + end + + it "accepts create or delete for action" do + expect { resource.action :create }.not_to raise_error + expect { resource.action :delete }.not_to raise_error + expect { resource.action :lolcat }.to raise_error(ArgumentError) + end +end -- cgit v1.2.1 From 5d1938b3f00f726e0ae8c4bf1f460ac663f13c56 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 11:11:57 -0700 Subject: Add descriptions and update the Chef version to ship in Signed-off-by: Tim Smith --- lib/chef/resource/cron_access.rb | 4 ++-- lib/chef/resource/cron_d.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/chef/resource/cron_access.rb b/lib/chef/resource/cron_access.rb index b89cf8e265..dbcc0709b7 100644 --- a/lib/chef/resource/cron_access.rb +++ b/lib/chef/resource/cron_access.rb @@ -27,8 +27,8 @@ class Chef resource_name :cron_access provides(:cron_manage) # legacy name @todo in Chef 15 we should { true } this so it wins over the cookbook - introduced "14.3" - description "" + introduced "14.4" + description "Use the cron_access resource to manage the /etc/cron.allow and /etc/cron.deny files." property :user, String, description: "The user to allow or deny. If not provided we'll use the resource name.", diff --git a/lib/chef/resource/cron_d.rb b/lib/chef/resource/cron_d.rb index f3b102b2b3..f8f26290c9 100644 --- a/lib/chef/resource/cron_d.rb +++ b/lib/chef/resource/cron_d.rb @@ -24,8 +24,8 @@ class Chef preview_resource true resource_name :cron_d - introduced "14.3" - description "" + introduced "14.4" + description "Use the cron_d resource to manage cron definitions in /etc/cron.d. This is similar to the 'cron' resource, but it does not use the monolithic /etc/crontab file." property :cron_name, String, description: "Set the name of the cron job. If this isn't specified we'll use the resource name.", -- cgit v1.2.1 From 1ef7f2dbeb5e36857fd1bee784726de3d462ce96 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 12:05:09 -0700 Subject: Self the callback methods Signed-off-by: Tim Smith --- lib/chef/resource/cron_d.rb | 96 ++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/lib/chef/resource/cron_d.rb b/lib/chef/resource/cron_d.rb index f8f26290c9..5c11fb95c4 100644 --- a/lib/chef/resource/cron_d.rb +++ b/lib/chef/resource/cron_d.rb @@ -27,6 +27,54 @@ class Chef introduced "14.4" description "Use the cron_d resource to manage cron definitions in /etc/cron.d. This is similar to the 'cron' resource, but it does not use the monolithic /etc/crontab file." + def self.validate_numeric(spec, min, max) + return true if spec == "*" + # binding.pry + if spec.respond_to? :to_int + return false unless spec >= min && spec <= max + return true + end + + # Lists of invidual values, ranges, and step values all share the validity range for type + spec.split(%r{\/|-|,}).each do |x| + next if x == "*" + return false unless x =~ /^\d+$/ + x = x.to_i + return false unless x >= min && x <= max + end + true + end + + def self.validate_month(spec) + return true if spec == "*" + if spec.respond_to? :to_int + validate_numeric(spec, 1, 12) + elsif spec.respond_to? :to_str + return true if spec == "*" + # Named abbreviations are permitted but not as part of a range or with stepping + return true if %w{jan feb mar apr may jun jul aug sep oct nov dec}.include? spec.downcase + # 1-12 are legal for months + validate_numeric(spec, 1, 12) + else + false + end + end + + def self.validate_dow(spec) + return true if spec == "*" + if spec.respond_to? :to_int + validate_numeric(spec, 0, 7) + elsif spec.respond_to? :to_str + return true if spec == "*" + # Named abbreviations are permitted but not as part of a range or with stepping + return true if %w{sun mon tue wed thu fri sat}.include? spec.downcase + # 0-7 are legal for days of week + validate_numeric(spec, 0, 7) + else + false + end + end + property :cron_name, String, description: "Set the name of the cron job. If this isn't specified we'll use the resource name.", name_property: true @@ -102,54 +150,6 @@ class Chef raise ArgumentError, "The 'cookbook' property for the cron_d resource is no longer supported now that this resource ships in Chef itself." if new_resource.cookbook end - def validate_numeric(spec, min, max) - return true if spec == "*" - # binding.pry - if spec.respond_to? :to_int - return false unless spec >= min && spec <= max - return true - end - - # Lists of invidual values, ranges, and step values all share the validity range for type - spec.split(%r{\/|-|,}).each do |x| - next if x == "*" - return false unless x =~ /^\d+$/ - x = x.to_i - return false unless x >= min && x <= max - end - true - end - - def validate_month(spec) - return true if spec == "*" - if spec.respond_to? :to_int - validate_numeric(spec, 1, 12) - elsif spec.respond_to? :to_str - return true if spec == "*" - # Named abbreviations are permitted but not as part of a range or with stepping - return true if %w{jan feb mar apr may jun jul aug sep oct nov dec}.include? spec.downcase - # 1-12 are legal for months - validate_numeric(spec, 1, 12) - else - false - end - end - - def validate_dow(spec) - return true if spec == "*" - if spec.respond_to? :to_int - validate_numeric(spec, 0, 7) - elsif spec.respond_to? :to_str - return true if spec == "*" - # Named abbreviations are permitted but not as part of a range or with stepping - return true if %w{sun mon tue wed thu fri sat}.include? spec.downcase - # 0-7 are legal for days of week - validate_numeric(spec, 0, 7) - else - false - end - end - action :create do create_template(:create) end -- cgit v1.2.1 From f6b4fb5467f5213a53fc5908223091b61210d701 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 13:28:30 -0700 Subject: Add yard comments Signed-off-by: Tim Smith --- lib/chef/resource/cron_d.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/chef/resource/cron_d.rb b/lib/chef/resource/cron_d.rb index 5c11fb95c4..96ed83a19e 100644 --- a/lib/chef/resource/cron_d.rb +++ b/lib/chef/resource/cron_d.rb @@ -27,6 +27,12 @@ class Chef introduced "14.4" description "Use the cron_d resource to manage cron definitions in /etc/cron.d. This is similar to the 'cron' resource, but it does not use the monolithic /etc/crontab file." + # validate a provided value is between two other provided values + # we also allow * as a valid input + # @param spec the value to validate + # @param min the lowest value allowed + # @param max the highest value allowed + # @return [Boolean] valid or not? def self.validate_numeric(spec, min, max) return true if spec == "*" # binding.pry @@ -45,6 +51,9 @@ class Chef true end + # validate the provided month value to be jan - dec, 1 - 12, or * + # @param spec the value to validate + # @return [Boolean] valid or not? def self.validate_month(spec) return true if spec == "*" if spec.respond_to? :to_int @@ -60,6 +69,9 @@ class Chef end end + # validate the provided day of the week is sun-sat, 0-7, or * + # @param spec the value to validate + # @return [Boolean] valid or not? def self.validate_dow(spec) return true if spec == "*" if spec.respond_to? :to_int -- cgit v1.2.1 From a9f7c8931ee8dd48fbece2af43d07ae50f89f5ba Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 13:29:11 -0700 Subject: Fix the default action in the cron_access spec Signed-off-by: Tim Smith --- spec/unit/resource/cron_access_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/resource/cron_access_spec.rb b/spec/unit/resource/cron_access_spec.rb index 1fd16f315f..9ba1d5b989 100644 --- a/spec/unit/resource/cron_access_spec.rb +++ b/spec/unit/resource/cron_access_spec.rb @@ -21,7 +21,7 @@ describe Chef::Resource::CronAccess do let(:resource) { Chef::Resource::CronAccess.new("bob") } it "has a default action of [:deny]" do - expect(resource.action).to eql([:deny]) + expect(resource.action).to eql([:allow]) end it "accepts create or delete for action" do -- cgit v1.2.1 From 917e865d4a2b526e59ff8cf0df888996efcd414d Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 14:12:34 -0700 Subject: Add descriptions and fix chefstyle warnings Signed-off-by: Tim Smith --- lib/chef/resource/cron_d.rb | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/chef/resource/cron_d.rb b/lib/chef/resource/cron_d.rb index 96ed83a19e..ba78008ab8 100644 --- a/lib/chef/resource/cron_d.rb +++ b/lib/chef/resource/cron_d.rb @@ -98,33 +98,33 @@ class Chef equal_to: %w{ @reboot @yearly @annually @monthly @weekly @daily @midnight @hourly } property :minute, [Integer, String], - description: "", + description: "The minute to schedule the cron job to run at. Valid values: 0-59.", default: "*", callbacks: { - "should be a valid minute spec" => ->(spec) { validate_numeric(spec, 0, 59) } + "should be a valid minute spec" => ->(spec) { validate_numeric(spec, 0, 59) }, } property :hour, [Integer, String], - description: "", + description: "The hour to schedule the cron job to run at. Valid values: 0-23.", default: "*", callbacks: { - "should be a valid hour spec" => ->(spec) { validate_numeric(spec, 0, 23) } + "should be a valid hour spec" => ->(spec) { validate_numeric(spec, 0, 23) }, } property :day, [Integer, String], - description: "", + description: "The day to schedule the cron job to run at. Valid values: 1-31.", default: "*", callbacks: { - "should be a valid day spec" => ->(spec) { validate_numeric(spec, 1, 31) } + "should be a valid day spec" => ->(spec) { validate_numeric(spec, 1, 31) }, } property :month, [Integer, String], - description: "", + description: "The month to schedule the cron job to run at. Valid values: 1-12, jan-dec, or *.", default: "*", callbacks: { - "should be a valid month spec" => ->(spec) { validate_month(spec) } + "should be a valid month spec" => ->(spec) { validate_month(spec) }, } property :weekday, [Integer, String], - description: "", + description: "The day to schedule the cron job to run at. Valid values: 0-7, mon-sun, or *.", default: "*", callbacks: { - "should be a valid weekday spec" => ->(spec) { validate_dow(spec) } + "should be a valid weekday spec" => ->(spec) { validate_dow(spec) }, } property :command, String, @@ -142,7 +142,7 @@ class Chef description: "Set the PATH environment variable in the cron.d file." property :home, [String, NilClass], - description: "" + description: "Set the HOME environment variable in the cron.d file." property :shell, [String, NilClass], description: "Set the HOME environment variable in the cron.d file." @@ -158,19 +158,26 @@ class Chef description: "The octal mode of the generated crontab file.", default: "0600" + # warn if someone passes the deprecated cookbook property def after_created raise ArgumentError, "The 'cookbook' property for the cron_d resource is no longer supported now that this resource ships in Chef itself." if new_resource.cookbook end action :create do + description "Add a cron definition file to /etc/cron.d." + create_template(:create) end action :create_if_missing do + description "Add a cron definition file to /etc/cron.d, but do not update an existing file." + create_template(:create_if_missing) end action :delete do + description "Remove a cron definition file from /etc/cron.d if it exists." + # cleanup the legacy named job if it exists file "legacy named cron.d file" do path "/etc/cron.d/#{new_resource.cron_name}" @@ -195,6 +202,7 @@ class Chef only_if { new_resource.cron_name != sanitized_name } end + # @todo this is Chef 12 era cleanup. Someday we should remove it all template "/etc/cron.d/#{sanitized_name}" do source ::File.expand_path("../support/cron.d.erb", __FILE__) local true -- cgit v1.2.1 From 02c2e86e85cc2244587f9d729b1d9bc179484810 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 15:42:34 -0700 Subject: Add a few specs to cron_manage and cron_d Signed-off-by: Tim Smith --- spec/unit/resource/cron_access_spec.rb | 4 +++ spec/unit/resource/cron_d_spec.rb | 58 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/spec/unit/resource/cron_access_spec.rb b/spec/unit/resource/cron_access_spec.rb index 9ba1d5b989..8fd65a9c60 100644 --- a/spec/unit/resource/cron_access_spec.rb +++ b/spec/unit/resource/cron_access_spec.rb @@ -29,4 +29,8 @@ describe Chef::Resource::CronAccess do expect { resource.action :deny }.not_to raise_error expect { resource.action :lolcat }.to raise_error(ArgumentError) end + + it "the user property is the name_property" do + expect(resource.user).to eql("bob") + end end diff --git a/spec/unit/resource/cron_d_spec.rb b/spec/unit/resource/cron_d_spec.rb index 99899131f8..6d29a17aaf 100644 --- a/spec/unit/resource/cron_d_spec.rb +++ b/spec/unit/resource/cron_d_spec.rb @@ -29,4 +29,62 @@ describe Chef::Resource::CronD do expect { resource.action :delete }.not_to raise_error expect { resource.action :lolcat }.to raise_error(ArgumentError) end + + it "the cron_name property is the name_property" do + expect(resource.cron_name).to eql("cronify") + end + + context "#validate_dow" do + it "it accepts a string day" do + expect(Chef::Resource::CronD.validate_dow("mon")).to be true + end + + it "it accepts an integer day" do + expect(Chef::Resource::CronD.validate_dow(0)).to be true + end + + it "it accepts the string of *" do + expect(Chef::Resource::CronD.validate_dow("*")).to be true + end + + it "returns false for an out of range integer" do + expect(Chef::Resource::CronD.validate_dow(8)).to be false + end + + it "returns false for an invalid string" do + expect(Chef::Resource::CronD.validate_dow("monday")).to be false + end + end + + context "#validate_month" do + it "it accepts a string month" do + expect(Chef::Resource::CronD.validate_month("feb")).to be true + end + + it "it accepts an integer month" do + expect(Chef::Resource::CronD.validate_month(2)).to be true + end + + it "it accepts the string of *" do + expect(Chef::Resource::CronD.validate_month("*")).to be true + end + + it "returns false for an out of range integer" do + expect(Chef::Resource::CronD.validate_month(13)).to be false + end + + it "returns false for an invalid string" do + expect(Chef::Resource::CronD.validate_month("janurary")).to be false + end + end + + context "#validate_numeric" do + it "returns true if the value is in the allowed range" do + expect(Chef::Resource::CronD.validate_numeric(5, 1, 100)).to be true + end + + it "returns false if the value is out of the allowed range" do + expect(Chef::Resource::CronD.validate_numeric(-1, 1, 100)).to be false + end + end end -- cgit v1.2.1 From 1f11da2f2c55bbe13d4c54f71c998ffedf01737c Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 16:04:34 -0700 Subject: Replace cron cookbook with new cron resources Test chef not the cookbook Signed-off-by: Tim Smith --- kitchen-tests/cookbooks/end_to_end/metadata.rb | 1 - kitchen-tests/cookbooks/end_to_end/recipes/default.rb | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/kitchen-tests/cookbooks/end_to_end/metadata.rb b/kitchen-tests/cookbooks/end_to_end/metadata.rb index c5300705c6..83cea5c9a8 100644 --- a/kitchen-tests/cookbooks/end_to_end/metadata.rb +++ b/kitchen-tests/cookbooks/end_to_end/metadata.rb @@ -15,7 +15,6 @@ depends "resolver" depends "selinux" depends "ubuntu" depends "users" -depends "cron" depends "git" supports "ubuntu" diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/default.rb b/kitchen-tests/cookbooks/end_to_end/recipes/default.rb index 77c5d2438e..3985cefd5a 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/default.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/default.rb @@ -63,12 +63,18 @@ include_recipe "nscd" include_recipe "logrotate" -include_recipe "cron" - include_recipe "git" directory "/etc/ssl" +cron_access "bob" + +cron_d "some random cron job" do + minute 0 + hour 23 + command "/usr/bin/true" +end + # Generate new key and certificate openssl_dhparam "/etc/ssl/dhparam.pem" do key_length 1024 -- cgit v1.2.1 From 51518beeaf68d8a55efafd7428a1ba045943895d Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 13 Aug 2018 16:46:39 -0700 Subject: Temporarily install cronie in dokken images Once the docker backlog is done this will be in our images, but for now we need to add it by hand. Signed-off-by: Tim Smith --- kitchen-tests/kitchen.travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kitchen-tests/kitchen.travis.yml b/kitchen-tests/kitchen.travis.yml index aa15da8795..83c6ee839d 100644 --- a/kitchen-tests/kitchen.travis.yml +++ b/kitchen-tests/kitchen.travis.yml @@ -35,6 +35,7 @@ platforms: pid_one_command: /sbin/init intermediate_instructions: - RUN sed -i -e "s/Defaults.*requiretty.*/Defaults !requiretty/g" /etc/sudoers + - RUN yum install -y cronie # TODO: remove this anytime past 8/13 - name: amazonlinux-2 driver: @@ -63,6 +64,7 @@ platforms: pid_one_command: /sbin/init intermediate_instructions: - RUN sed -i -e "s/Defaults.*requiretty.*/Defaults !requiretty/g" /etc/sudoers + - RUN yum install -y cronie # TODO: remove this anytime past 8/13 - name: centos-7 driver: @@ -78,6 +80,7 @@ platforms: pid_one_command: /usr/lib/systemd/systemd intermediate_instructions: - RUN sed -i -e "s/Defaults.*requiretty.*/Defaults !requiretty/g" /etc/sudoers + - RUN yum install -y cronie # TODO: remove this anytime past 8/13 - name: ubuntu-14.04 driver: -- cgit v1.2.1