class Chef::Resource::WindowsTask

Constants

VALID_DAYS_OF_MONTH
VALID_MONTHS
VALID_WEEKS
VALID_WEEK_DAYS

Attributes

command_arguments[RW]
exists[RW]
task[RW]

Public Instance Methods

after_created() click to toggle source
# File lib/chef/resource/windows_task.rb, line 134
def after_created
  if random_delay
    validate_random_delay(random_delay, frequency)
    random_delay(sec_to_min(random_delay))
  end

  if execution_time_limit
    execution_time_limit(259200) if execution_time_limit == "PT72H"
    raise ArgumentError, "Invalid value passed for `execution_time_limit`. Please pass seconds as an Integer (e.g. 60) or a String with numeric values only (e.g. '60')." unless numeric_value_in_string?(execution_time_limit)
    execution_time_limit(sec_to_min(execution_time_limit))
  end

  validate_frequency(frequency) if action.include?(:create) || action.include?(:change)
  validate_start_time(start_time, frequency)
  validate_start_day(start_day, frequency) if start_day
  validate_user_and_password(user, password)
  validate_create_frequency_modifier(frequency, frequency_modifier) if frequency_modifier
  validate_create_day(day, frequency, frequency_modifier) if day
  validate_create_months(months, frequency) if months
  validate_frequency_monthly(frequency_modifier, months, day) if frequency == :monthly
  validate_idle_time(idle_time, frequency)
  idempotency_warning_for_frequency_weekly(day, start_day) if frequency == :weekly
end

Private Instance Methods

days_includes_days_of_months?(days) click to toggle source

This method returns true if day has values from 1-31 which is a days of moths and used with frequency :monthly

# File lib/chef/resource/windows_task.rb, line 322
def days_includes_days_of_months?(days)
  days.map! { |day| day.to_s.strip.downcase }
  (days - VALID_DAYS_OF_MONTH).empty?
end
frequency_modifier_includes_days_of_weeks?(frequency_modifier) click to toggle source

returns true if frequency_modifer has values First, second, third, fourth, last, lastday

# File lib/chef/resource/windows_task.rb, line 196
def frequency_modifier_includes_days_of_weeks?(frequency_modifier)
  frequency_modifier = frequency_modifier.to_s.split(",")
  frequency_modifier.map! { |value| value.strip.upcase }
  (frequency_modifier - VALID_WEEKS).empty?
end
idempotency_warning_for_frequency_weekly(day, start_day) click to toggle source

Resource is not idempotent when day, start_day is not provided with frequency :weekly we set start_day when not given by user as current date based on which we set the day property for current current date day is monday .. we set the monday as the day so at next run when new_resource.day is nil and current_resource day is monday due to which udpate gets called

# File lib/chef/resource/windows_task.rb, line 163
def idempotency_warning_for_frequency_weekly(day, start_day)
  if start_day.nil? && day.nil?
    logger.warn "To maintain idempotency for frequency :weekly provide start_day, start_time and day."
  end
end
non_system_user?(user)
Alias for: password_required?
numeric_value_in_string?(val) click to toggle source

Validate the passed value is numeric values only if it is a string

# File lib/chef/resource/windows_task.rb, line 170
def numeric_value_in_string?(val)
  return true if Integer(val)
rescue ArgumentError
  false
end
password_required?(user) click to toggle source

Password is not required for system user and required for non-system user.

# File lib/chef/resource/windows_task.rb, line 251
def password_required?(user)
  @password_required ||= (!user.nil? && !Chef::ReservedNames::Win32::Security::SID.system_user?(user))
end
Also aliased as: non_system_user?
sec_to_dur(seconds) click to toggle source

Converts the number of seconds to an ISO8601 duration format and returns it. Ref : github.com/arnau/ISO8601/blob/master/lib/iso8601/duration.rb#L18-L23 e.g. ISO8601::Duration.new(65707200).to_s returns 'PT65707200S'

# File lib/chef/resource/windows_task.rb, line 344
def sec_to_dur(seconds)
  ISO8601::Duration.new(seconds.to_i).to_s
end
sec_to_min(seconds) click to toggle source
# File lib/chef/resource/windows_task.rb, line 348
def sec_to_min(seconds)
  seconds.to_i / 60
end
validate_create_day(day, frequency, frequency_modifier) click to toggle source
# File lib/chef/resource/windows_task.rb, line 289
def validate_create_day(day, frequency, frequency_modifier)
  raise ArgumentError, "day property is only valid for tasks that run monthly or weekly" unless [:weekly, :monthly].include?(frequency)

  # This has been verified with schtask.exe https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks#d-dayday--
  # verified with earlier code if day "*" is given with frequency it raised exception Invalid value for /D option
  raise ArgumentError, "day wild card (*) is only valid with frequency :weekly" if frequency == :monthly && day == "*"

  if day.is_a?(String) && day.to_i.to_s != day
    days = day.split(",")
    if days_includes_days_of_months?(days)
      # Following error will be raise if day is set as 1-31 and frequency is selected as :weekly since those values are valid with only frequency :monthly
      raise ArgumentError, "day values 1-31 or last is only valid with frequency :monthly" if frequency == :weekly
    else
      days.map! { |day| day.to_s.strip.downcase }
      unless (days - VALID_WEEK_DAYS).empty?
        raise ArgumentError, "day property invalid. Only valid values are: #{VALID_WEEK_DAYS.map(&:upcase).join(', ')}. Multiple values must be separated by a comma."
      end
    end
  end
end
validate_create_frequency_modifier(frequency, frequency_modifier) click to toggle source
# File lib/chef/resource/windows_task.rb, line 257
def validate_create_frequency_modifier(frequency, frequency_modifier)
  if ([:on_logon, :onstart, :on_idle, :none].include?(frequency)) && ( frequency_modifier != 1)
    raise ArgumentError, "frequency_modifier property not supported with frequency :#{frequency}"
  end

  if frequency == :monthly
    unless (1..12).cover?(frequency_modifier.to_i) || frequency_modifier_includes_days_of_weeks?(frequency_modifier)
      raise ArgumentError, "frequency_modifier value #{frequency_modifier} is invalid. Valid values for :monthly frequency are 1 - 12, 'FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST'."
    end
  else
    unless frequency.nil? || frequency_modifier.nil?
      frequency_modifier = frequency_modifier.to_i
      min = 1
      max = case frequency
              when :minute
                1439
              when :hourly
                23
              when :daily
                365
              when :weekly
                52
              else
                min
            end
      unless frequency_modifier.between?(min, max)
        raise ArgumentError, "frequency_modifier value #{frequency_modifier} is invalid. Valid values for :#{frequency} frequency are #{min} - #{max}."
      end
    end
  end
end
validate_create_months(months, frequency) click to toggle source
# File lib/chef/resource/windows_task.rb, line 310
def validate_create_months(months, frequency)
  raise ArgumentError, "months property is only valid for tasks that run monthly" if frequency != :monthly
  if months.is_a?(String)
    months = months.split(",")
    months.map! { |month| month.strip.upcase }
    unless (months - VALID_MONTHS).empty?
      raise ArgumentError, "months property invalid. Only valid values are: #{VALID_MONTHS.join(', ')}. Multiple values must be separated by a comma."
    end
  end
end
validate_frequency(frequency) click to toggle source
# File lib/chef/resource/windows_task.rb, line 176
def validate_frequency(frequency)
  if frequency.nil? || !([:minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle, :none].include?(frequency))
    raise ArgumentError, "Frequency needs to be provided. Valid frequencies are :minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle, :none."
  end
end
validate_frequency_monthly(frequency_modifier, months, day) click to toggle source
# File lib/chef/resource/windows_task.rb, line 182
def validate_frequency_monthly(frequency_modifier, months, day)
  # validates the frequency :monthly and raises error if frequency_modifier is first, second, thrid etc and day is not provided
  if (frequency_modifier != 1) && (frequency_modifier_includes_days_of_weeks?(frequency_modifier)) && !(day)
    raise ArgumentError, "Please select day on which you want to run the task e.g. 'Mon, Tue'. Multiple values must be seprated by comma."
  end

  # frequency_modifer 2-12 is used to set every (n) months, so using :months propety with frequency_modifer is not valid since they both used to set months.
  # Not checking value 1 here for frequecy_modifier since we are setting that as default value it won't break anything since preference is given to months property
  if (frequency_modifier.to_i.between?(2, 12)) && !(months.nil?)
    raise ArgumentError, "For frequency :monthly either use property months or frequency_modifier to set months."
  end
end
validate_idle_time(idle_time, frequency) click to toggle source
# File lib/chef/resource/windows_task.rb, line 327
def validate_idle_time(idle_time, frequency)
  if !idle_time.nil? && frequency != :on_idle
    raise ArgumentError, "idle_time property is only valid for tasks that run on_idle"
  end
  if idle_time.nil? && frequency == :on_idle
    raise ArgumentError, "idle_time value should be set for :on_idle frequency."
  end
  unless idle_time.nil? || idle_time > 0 && idle_time <= 999
    raise ArgumentError, "idle_time value #{idle_time} is invalid. Valid values for :on_idle frequency are 1 - 999."
  end
end
validate_random_delay(random_delay, frequency) click to toggle source
# File lib/chef/resource/windows_task.rb, line 202
def validate_random_delay(random_delay, frequency)
  if [:on_logon, :onstart, :on_idle, :none].include? frequency
    raise ArgumentError, "`random_delay` property is supported only for frequency :once, :minute, :hourly, :daily, :weekly and :monthly"
  end

  raise ArgumentError, "Invalid value passed for `random_delay`. Please pass seconds as an Integer (e.g. 60) or a String with numeric values only (e.g. '60')." unless numeric_value_in_string?(random_delay)
end
validate_start_day(start_day, frequency) click to toggle source

@todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~f

# File lib/chef/resource/windows_task.rb, line 211
def validate_start_day(start_day, frequency)
  if start_day && frequency == :none
    raise ArgumentError, "`start_day` property is not supported with frequency: #{frequency}"
  end

  # make sure the start_day is in MM/DD/YYYY format: http://rubular.com/r/cgjHemtWl5
  if start_day
    raise ArgumentError, "`start_day` property must be in the MM/DD/YYYY format." unless /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d$/ =~ start_day
  end
end
validate_start_time(start_time, frequency) click to toggle source

@todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~

# File lib/chef/resource/windows_task.rb, line 223
def validate_start_time(start_time, frequency)
  if start_time
    raise ArgumentError, "`start_time` property is not supported with `frequency :none`" if frequency == :none
    raise ArgumentError, "`start_time` property must be in the HH:mm format (e.g. 6:20pm -> 18:20)." unless /^[0-2][0-9]:[0-5][0-9]$/ =~ start_time
  else
    raise ArgumentError, "`start_time` needs to be provided with `frequency :once`" if frequency == :once
  end
end
validate_user_and_password(user, password) click to toggle source

System users will not require a password Other users will require a password if the task is non-interactive.

@param [String] user @param [String] password

# File lib/chef/resource/windows_task.rb, line 238
def validate_user_and_password(user, password)
  if non_system_user?(user)
    if password.nil? && !interactive_enabled
      raise ArgumentError, "Please provide a password or check if this task needs to be interactive! Valid passwordless users are: '#{Chef::ReservedNames::Win32::Security::SID::SYSTEM_USER.join("', '")}'"
    end
  else
    unless password.nil?
      raise ArgumentError, "Password is not required for system users."
    end
  end
end