Class: PuppetX::PuppetLabs::ScheduledTask::Trigger::Manifest Private

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet_x/puppetlabs/scheduled_task/trigger.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Scheduled Task manifest

Constant Summary collapse

ValidKeys =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Valid Keys

[ # rubocop:disable Naming/ConstantName
  'index',
  'enabled',
  'schedule',
  'start_date',
  'start_time',
  'every',
  'months',
  'on',
  'which_occurrence',
  'day_of_week',
  'minutes_interval',
  'minutes_duration',
  'user_id',
  'disable_time_zone_synchronization',
].freeze
ValidScheduleKeys =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Valid Schedule Keys

[ # rubocop:disable Naming/ConstantName
  'once',
  'daily',
  'weekly',
  'monthly',
  'boot',
  'logon',
].freeze
MINIMUM_TRIGGER_DATE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

msdn.microsoft.com/en-us/library/system.datetime.fromoadate(v=vs.110).aspx d must be a value between -657435.0 (1/1/1753) through 2958465.99999999 (12/31/9999 11:59:59)

Time.local(1753, 1, 1)

Class Method Summary collapse

Class Method Details

.canonicalize_and_validate(manifest_hash) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

canonicalize given manifest hash throws errors if hash structure is invalid does not throw errors when invalid types are specified returns original object with downcased keys

Raises:

  • (TypeError)


176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/puppet_x/puppetlabs/scheduled_task/trigger.rb', line 176

def self.canonicalize_and_validate(manifest_hash)
  raise TypeError unless manifest_hash.is_a?(Hash)
  manifest_hash = downcase_keys(manifest_hash)

  # check for valid key usage
  invalid_keys = manifest_hash.keys - ValidKeys
  raise ArgumentError, "Unknown trigger option(s): #{Puppet::Parameter.format_value_for_display(invalid_keys)}" unless invalid_keys.empty?

  unless ValidScheduleKeys.include?(manifest_hash['schedule'])
    raise ArgumentError, "Unknown schedule type: #{manifest_hash['schedule'].inspect}"
  end

  required = V2::EVENT_BASED_TRIGGER_MAP.value?(manifest_hash['schedule']) ? [] : ['start_time']

  required.each do |field|
    next if manifest_hash.key?(field)
    raise ArgumentError, "Must specify '#{field}' when defining a trigger"
  end

  start_time_valid = time_valid?(manifest_hash['start_time'])
  raise ArgumentError, "Invalid start_time value: #{manifest_hash['start_time']}" unless start_time_valid
  # The start_time must be canonicalized to match the format that the rest of the code expects
  manifest_hash['start_time'] = format_time(Time.parse(manifest_hash['start_time'])) unless manifest_hash['start_time'].nil?

  # specific setting rules for schedule types
  case manifest_hash['schedule']
  when 'monthly'
    if manifest_hash.key?('on')
      if manifest_hash.key?('day_of_week') || manifest_hash.key?('which_occurrence')
        raise ArgumentError, "Neither 'day_of_week' nor 'which_occurrence' can be specified when creating a monthly date-based trigger"
      end
    elsif manifest_hash.key?('which_occurrence') || manifest_hash.key?('day_of_week')
      raise ArgumentError, 'which_occurrence cannot be specified as an array' if manifest_hash['which_occurrence'].is_a?(Array)

      ['day_of_week', 'which_occurrence'].each do |field|
        next if manifest_hash.key?(field)
        raise ArgumentError, "#{field} must be specified when creating a monthly day-of-week based trigger"
      end
    else
      raise ArgumentError, "Don't know how to create a 'monthly' schedule with the options: #{manifest_hash.keys.sort.join(', ')}"
    end
  when 'once'
    raise ArgumentError, "Must specify 'start_date' when defining a one-time trigger" unless manifest_hash['start_date']
  end

  if manifest_hash.key?('every')
    every = begin
              Integer(manifest_hash['every'])
            rescue
              nil
            end
    raise ArgumentError, "Invalid every value: #{manifest_hash['every']}" if every.nil?
    manifest_hash['every'] = every
  end

  # day of week uses valid names (for weekly / monthly schedules)
  if manifest_hash.key?('day_of_week')
    manifest_hash['day_of_week'] = [manifest_hash['day_of_week']].flatten
    invalid_days = manifest_hash['day_of_week'] - V2::Day.names
    raise ArgumentError, "Unknown day_of_week values(s): #{invalid_days}" unless invalid_days.empty?
  end

  if manifest_hash.key?('months')
    manifest_hash['months'] = [manifest_hash['months']].flatten
    invalid_months = manifest_hash['months'] - V2::Month.indexes
    raise ArgumentError, "Unknown months values(s): #{invalid_months}" unless invalid_months.empty?
  end

  # monthly
  if manifest_hash.key?('on')
    manifest_hash['on'] = [manifest_hash['on']].flatten
    invalid_on = manifest_hash['on'] - ((1..31).to_a + ['last'])
    raise ArgumentError, "Unknown on values(s): #{invalid_on}" unless invalid_on.empty?
  end

  # monthly day of week
  if manifest_hash.key?('which_occurrence')
    # NOTE: cannot canonicalize to an array here (yet!) because more code changes required
    invalid_which_occurrence = [manifest_hash['which_occurrence']].flatten - V2::WeeksOfMonth::WEEK_OF_MONTH_CONST_MAP.keys
    raise ArgumentError, "Unknown which_occurrence values(s): #{invalid_which_occurrence}" unless invalid_which_occurrence.empty?
  end

  # duration set with / without interval
  if manifest_hash['minutes_duration']
    duration = Integer(manifest_hash['minutes_duration'])
    # defaults to -1 when unspecified
    interval = Integer(manifest_hash['minutes_interval'] || -1)
    if duration != 0 && duration <= interval
      raise ArgumentError, 'minutes_duration must be an integer greater than minutes_interval and equal to or greater than 0'
    end
  end

  # interval set with / without duration
  if manifest_hash['minutes_interval']
    interval = Integer(manifest_hash['minutes_interval'])
    # interval < 0
    if interval.negative?
      raise ArgumentError, 'minutes_interval must be an integer greater or equal to 0'
    end

    # defaults to a day when unspecified
    duration = Integer(manifest_hash['minutes_duration'] || 1440)

    if interval.positive? && interval >= duration
      raise ArgumentError, 'minutes_interval cannot be set without minutes_duration also being set to a number greater than 0'
    end
  end
  manifest_hash['minutes_interval'] = interval if interval
  manifest_hash['minutes_duration'] = duration if duration

  if manifest_hash['start_date']
    start_date = Time.parse(manifest_hash['start_date'] + ' 00:00')
    raise ArgumentError, "start_date must be on or after #{format_date(MINIMUM_TRIGGER_DATE)}" unless start_date >= MINIMUM_TRIGGER_DATE
    manifest_hash['start_date'] = format_date(start_date)
  end

  if manifest_hash['user_id']
    raise 'user_id can only be verified on a Windows Operating System' unless Puppet.features.microsoft_windows?
    # If the user specifies undef in the manifest, coerce that into an empty string;
    # This is what scheduled tasks expects to receive for 'all users'
    user_id = (manifest_hash['user_id'] == :undef) ? '' : manifest_hash['user_id']
    # If the user cannot be resolved, the task will fail to save with a vague error
    raise ArgumentError, "Invalid user, specified user must exist: #{user_id}" unless Puppet::Util::Windows::SID.name_to_sid(user_id)
    # To keep the internal comparison consistent but human readable, convert from
    # the user id specified in the manifest to the canonical representation of that
    # account's SID on the system. If the specified user_id is null/empty, leave it
    # that way so the task runs whenever _any_ user logs on.
    user_id = Puppet::Util::Windows::SID.sid_to_name(Puppet::Util::Windows::SID.name_to_sid(user_id)) unless user_id == ''
    manifest_hash['user_id'] = user_id
  end

  manifest_hash
end

.default_trigger_for(schedule = 'once') ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the default trigger for a specified schedule



153
154
155
156
157
158
159
160
161
162
# File 'lib/puppet_x/puppetlabs/scheduled_task/trigger.rb', line 153

def self.default_trigger_for(schedule = 'once')
  now = Time.now
  {
    'enabled'             => true,
    'minutes_interval'    => 0,
    'minutes_duration'    => 0,
    'start_date'          => format_date(now),
    'start_time'          => format_time(now),
  }.merge(default_trigger_settings_for(schedule))
end

.default_trigger_settings_for(schedule = 'once') ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the default trigger setting for a specified schedule



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/puppet_x/puppetlabs/scheduled_task/trigger.rb', line 126

def self.default_trigger_settings_for(schedule = 'once')
  case schedule
  when 'once'
    {
      'schedule' => 'once',
    }
  when 'daily'
    {
      'schedule' => 'daily',
      'every'    => 1,
    }
  when 'weekly'
    {
      'schedule'     => 'weekly',
      'days_of_week' => V2::Day.names,
      'every'        => 1,
    }
  when 'monthly'
    {
      'schedule' => 'monthly',
      'months'   => V2::Month.indexes,
      'days'     => 0,
    }
  end
end

.format_date(time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Formats time in a %Y-%-m-%-d format



115
116
117
# File 'lib/puppet_x/puppetlabs/scheduled_task/trigger.rb', line 115

def self.format_date(time)
  time.strftime('%Y-%-m-%-d')
end

.format_time(time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Formats time to the ISO8601 %H:%M format



120
121
122
123
# File 'lib/puppet_x/puppetlabs/scheduled_task/trigger.rb', line 120

def self.format_time(time)
  # equivalent to the ISO8601 %H:%M
  time.strftime('%R')
end

.time_valid?(time) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks if a given string is in a valid time format

Returns:

  • (Boolean)


165
166
167
168
169
170
# File 'lib/puppet_x/puppetlabs/scheduled_task/trigger.rb', line 165

def self.time_valid?(time)
  Time.parse("2016-5-1 #{time}")
  true
rescue
  false
end