bolt 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bolt/cli.rb +43 -43
  3. data/lib/bolt/config.rb +25 -5
  4. data/lib/bolt/node.rb +3 -1
  5. data/lib/bolt/node/ssh.rb +15 -2
  6. data/lib/bolt/node/winrm.rb +20 -9
  7. data/lib/bolt/version.rb +1 -1
  8. data/modules/boltlib/lib/puppet/functions/run_plan.rb +1 -1
  9. data/modules/boltlib/lib/puppet/functions/run_task.rb +29 -32
  10. data/vendored/puppet/lib/puppet.rb +2 -5
  11. data/vendored/puppet/lib/puppet/application.rb +18 -1
  12. data/vendored/puppet/lib/puppet/application/agent.rb +8 -1
  13. data/vendored/puppet/lib/puppet/application/config.rb +1 -0
  14. data/vendored/puppet/lib/puppet/application/device.rb +1 -2
  15. data/vendored/puppet/lib/puppet/application/filebucket.rb +10 -2
  16. data/vendored/puppet/lib/puppet/application/help.rb +1 -0
  17. data/vendored/puppet/lib/puppet/application_support.rb +6 -1
  18. data/vendored/puppet/lib/puppet/configurer.rb +8 -3
  19. data/vendored/puppet/lib/puppet/defaults.rb +29 -9
  20. data/vendored/puppet/lib/puppet/environments.rb +2 -0
  21. data/vendored/puppet/lib/puppet/face/config.rb +14 -1
  22. data/vendored/puppet/lib/puppet/face/module/list.rb +1 -1
  23. data/vendored/puppet/lib/puppet/face/module/search.rb +4 -1
  24. data/vendored/puppet/lib/puppet/forge.rb +6 -0
  25. data/vendored/puppet/lib/puppet/functions/convert_to.rb +32 -0
  26. data/vendored/puppet/lib/puppet/gettext/config.rb +135 -37
  27. data/vendored/puppet/lib/puppet/gettext/module_translations.rb +42 -0
  28. data/vendored/puppet/lib/puppet/indirector/catalog/compiler.rb +2 -0
  29. data/vendored/puppet/lib/puppet/module.rb +10 -18
  30. data/vendored/puppet/lib/puppet/network/http/factory.rb +9 -0
  31. data/vendored/puppet/lib/puppet/node/environment.rb +14 -0
  32. data/vendored/puppet/lib/puppet/parser/functions/sprintf.rb +17 -3
  33. data/vendored/puppet/lib/puppet/parser/scope.rb +11 -0
  34. data/vendored/puppet/lib/puppet/pops.rb +0 -1
  35. data/vendored/puppet/lib/puppet/pops/evaluator/epp_evaluator.rb +13 -0
  36. data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +39 -5
  37. data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +64 -24
  38. data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +1 -1
  39. data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +21 -70
  40. data/vendored/puppet/lib/puppet/pops/lookup/hiera_config.rb +2 -2
  41. data/vendored/puppet/lib/puppet/pops/parser/parser_support.rb +1 -1
  42. data/vendored/puppet/lib/puppet/pops/pcore.rb +43 -1
  43. data/vendored/puppet/lib/puppet/pops/types/type_factory.rb +4 -0
  44. data/vendored/puppet/lib/puppet/pops/types/types.rb +25 -5
  45. data/vendored/puppet/lib/puppet/provider/selmodule/semodule.rb +5 -3
  46. data/vendored/puppet/lib/puppet/provider/service/smf.rb +2 -0
  47. data/vendored/puppet/lib/puppet/settings/environment_conf.rb +14 -2
  48. data/vendored/puppet/lib/puppet/ssl/certificate_authority.rb +1 -1
  49. data/vendored/puppet/lib/puppet/ssl/certificate_signer.rb +6 -0
  50. data/vendored/puppet/lib/puppet/ssl/host.rb +1 -1
  51. data/vendored/puppet/lib/puppet/type/file/checksum.rb +1 -1
  52. data/vendored/puppet/lib/puppet/type/file/checksum_value.rb +4 -3
  53. data/vendored/puppet/lib/puppet/type/k5login.rb +101 -0
  54. data/vendored/puppet/lib/puppet/type/tidy.rb +4 -2
  55. data/vendored/puppet/lib/puppet/util/checksums.rb +82 -1
  56. data/vendored/puppet/lib/puppet/util/command_line.rb +5 -0
  57. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +5 -1
  58. data/vendored/puppet/lib/puppet_pal.rb +272 -11
  59. data/vendored/require_vendored.rb +0 -6
  60. metadata +8 -8
  61. data/vendored/puppet/lib/puppet/bindings.rb +0 -147
  62. data/vendored/puppet/lib/puppet/pops/types/task.rb +0 -116
@@ -260,8 +260,10 @@ Puppet::Type.newtype(:tidy) do
260
260
  end
261
261
  found_files = files.find_all { |path| tidy?(path) }.collect { |path| mkfile(path) }
262
262
  result = found_files.each { |file| debug "Tidying #{file.ref}" }.sort { |a,b| b[:path] <=> a[:path] }
263
- #TRANSLATORS "Tidy" is a program name and should not be translated
264
- notice _("Tidying %{count} files") % { count: found_files.size }
263
+ if found_files.size > 0
264
+ #TRANSLATORS "Tidy" is a program name and should not be translated
265
+ notice _("Tidying %{count} files") % { count: found_files.size }
266
+ end
265
267
 
266
268
  # No need to worry about relationships if we don't have rmdirs; there won't be
267
269
  # any directories.
@@ -10,7 +10,7 @@ module Puppet::Util::Checksums
10
10
  # It's not a good idea to use some of these in some contexts: for example, I
11
11
  # wouldn't try bucketing a file using the :none checksum type.
12
12
  def known_checksum_types
13
- [:sha256, :sha256lite, :md5, :md5lite, :sha1, :sha1lite,
13
+ [:sha256, :sha256lite, :md5, :md5lite, :sha1, :sha1lite, :sha512, :sha384, :sha224,
14
14
  :mtime, :ctime, :none]
15
15
  end
16
16
 
@@ -83,6 +83,87 @@ module Puppet::Util::Checksums
83
83
  sha256_hex_length
84
84
  end
85
85
 
86
+ # Calculate a checksum using Digest::SHA384.
87
+ def sha384(content)
88
+ require 'digest/sha2'
89
+ Digest::SHA384.hexdigest(content)
90
+ end
91
+
92
+ def sha384?(string)
93
+ string =~ /^\h{96}$/
94
+ end
95
+
96
+ def sha384_file(filename, lite = false)
97
+ require 'digest/sha2'
98
+
99
+ digest = Digest::SHA384.new
100
+ checksum_file(digest, filename, lite)
101
+ end
102
+
103
+ def sha384_stream(lite = false, &block)
104
+ require 'digest/sha2'
105
+ digest = Digest::SHA384.new
106
+ checksum_stream(digest, block, lite)
107
+ end
108
+
109
+ def sha384_hex_length
110
+ 96
111
+ end
112
+
113
+ # Calculate a checksum using Digest::SHA512.
114
+ def sha512(content)
115
+ require 'digest/sha2'
116
+ Digest::SHA512.hexdigest(content)
117
+ end
118
+
119
+ def sha512?(string)
120
+ string =~ /^\h{128}$/
121
+ end
122
+
123
+ def sha512_file(filename, lite = false)
124
+ require 'digest/sha2'
125
+
126
+ digest = Digest::SHA512.new
127
+ checksum_file(digest, filename, lite)
128
+ end
129
+
130
+ def sha512_stream(lite = false, &block)
131
+ require 'digest/sha2'
132
+ digest = Digest::SHA512.new
133
+ checksum_stream(digest, block, lite)
134
+ end
135
+
136
+ def sha512_hex_length
137
+ 128
138
+ end
139
+
140
+ # Calculate a checksum using Digest::SHA224.
141
+ def sha224(content)
142
+ require 'openssl'
143
+ OpenSSL::Digest::SHA224.new.hexdigest(content)
144
+ end
145
+
146
+ def sha224?(string)
147
+ string =~ /^\h{56}$/
148
+ end
149
+
150
+ def sha224_file(filename, lite = false)
151
+ require 'openssl'
152
+
153
+ digest = OpenSSL::Digest::SHA224.new
154
+ checksum_file(digest, filename, lite)
155
+ end
156
+
157
+ def sha224_stream(lite = false, &block)
158
+ require 'openssl'
159
+ digest = OpenSSL::Digest::SHA224.new
160
+ checksum_stream(digest, block, lite)
161
+ end
162
+
163
+ def sha224_hex_length
164
+ 56
165
+ end
166
+
86
167
  # Calculate a checksum using Digest::MD5.
87
168
  def md5(content)
88
169
  Digest::MD5.hexdigest(content)
@@ -14,6 +14,7 @@ require 'puppet/util'
14
14
  require "puppet/util/rubygems"
15
15
  require "puppet/util/limits"
16
16
  require 'puppet/util/colors'
17
+ require 'puppet/gettext/module_translations'
17
18
 
18
19
  module Puppet
19
20
  module Util
@@ -122,6 +123,10 @@ module Puppet
122
123
  $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
123
124
  end
124
125
 
126
+ Puppet::GettextConfig.reset_text_domain('cli')
127
+ Puppet::ModuleTranslations.load_from_modulepath(configured_environment.modules)
128
+ Puppet::ModuleTranslations.load_from_vardir(Puppet[:vardir])
129
+
125
130
  # Puppet requires Facter, which initializes its lookup paths. Reset Facter to
126
131
  # pickup the new $LOAD_PATH.
127
132
  Facter.reset
@@ -1,5 +1,9 @@
1
1
  module SemanticPuppet
2
- Puppet::GettextConfig.load_translations('semantic_puppet', File.absolute_path('../locales', File.dirname(__FILE__)), :po)
2
+ locales_path = File.absolute_path('../locales', File.dirname(__FILE__))
3
+ # Only create a translation repository of the relevant translations exist
4
+ if Puppet::FileSystem.exist?(File.join(locales_path, Puppet::GettextConfig.current_locale))
5
+ Puppet::GettextConfig.load_translations('semantic_puppet', locales_path, :po)
6
+ end
3
7
 
4
8
  autoload :Version, 'semantic_puppet/version'
5
9
  autoload :VersionRange, 'semantic_puppet/version_range'
@@ -26,8 +26,9 @@ require 'puppet/parser/script_compiler'
26
26
  module Puppet
27
27
  module Pal
28
28
 
29
- # @param compiler [Puppet::Pal::Compiler] a configured compiler as obtained in the callback from `with_script_compiler`
30
-
29
+ # A configured compiler as obtained in the callback from `with_script_compiler`.
30
+ # (Later, there may also be a catalog compiler available.)
31
+ #
31
32
  class Compiler
32
33
  attr_reader :internal_compiler
33
34
  protected :internal_compiler
@@ -53,17 +54,51 @@ module Pal
53
54
  internal_evaluator.evaluator.external_call_function(function_name, args, topscope, &block)
54
55
  end
55
56
 
56
- # Returns an Array[Puppet::Pops::Types::PCallableType] describing the given function's signatures, or empty array if function not found.
57
+ # Returns a Puppet::Pal::FunctionSignature object or nil if function is not found
58
+ # The returned FunctionSignature has information about all overloaded signatures of the function
59
+ #
60
+ # @example using function_signature
61
+ # # returns true if 'myfunc' is callable with three integer arguments 1, 2, 3
62
+ # compiler.function_signature('myfunc').callable_with?([1,2,3])
63
+ #
57
64
  # @param function_name [String] the name of the function to get a signature for
58
- # @return [Array<Puppet::Pops::Types::PCallableType>] an array of callable signatures, or an empty array if function not found
59
- def function_signatures(function_name)
65
+ # @return [Puppet::Pal::FunctionSignature] a function signature, or nil if function not found
66
+ #
67
+ def function_signature(function_name)
60
68
  loader = internal_compiler.loaders.private_environment_loader
61
69
  if func = loader.load(:function, function_name)
62
- t = func.class.dispatcher.to_type
63
- return t.is_a?(Puppet::Pops::Types::PVariantType) ? t.types : [t]
70
+ return FunctionSignature.new(func.class)
64
71
  end
65
72
  # Could not find function
66
- Puppet::Pops::EMPTY_ARRAY
73
+ nil
74
+ end
75
+
76
+ # Returns an array of TypedName objects for all functions, optionally filtered by a regular expression.
77
+ # The returned array has more information than just the leaf name - the typical thing is to just get
78
+ # the name as showing the following example.
79
+ #
80
+ # @example getting the names of all functions
81
+ # compiler.list_functions.map {|tn| tn.name }
82
+ #
83
+ # @param filter_regex [Regexp] an optional regexp that filters based on name (matching names are included in the result)
84
+ # @return [Array<Puppet::Pops::Loader::TypedName>] an array of typed names
85
+ #
86
+ def list_functions(filter_regex = nil)
87
+ list_loadable_kind(:function, filter_regex)
88
+ end
89
+
90
+ # Returns an array of TypedName objects for all functions, optionally filtered by a regular expression.
91
+ # The returned array has more information than just the leaf name - the typical thing is to just get
92
+ # the name as showing the following example.
93
+ #
94
+ # @example getting the names of all functions
95
+ # compiler.list_functions.map {|tn| tn.name }
96
+ #
97
+ # @param filter_regex [Regexp] an optional regexp that filters based on name (matching names are included in the result)
98
+ # @return [Array<Puppet::Pops::Loader::TypedName>] an array of typed names
99
+ #
100
+ def list_functions(filter_regex = nil)
101
+ list_loadable_kind(:function, filter_regex)
67
102
  end
68
103
 
69
104
  # Evaluates a string of puppet language code in top scope.
@@ -191,6 +226,17 @@ module Pal
191
226
  call_function('new', t, *arguments)
192
227
  end
193
228
 
229
+ protected
230
+
231
+ def list_loadable_kind(kind, filter_regex = nil)
232
+ loader = internal_compiler.loaders.private_environment_loader
233
+ if filter_regex.nil?
234
+ loader.discover(kind)
235
+ else
236
+ loader.discover(kind) {|f| f.name =~ filter_regex }
237
+ end
238
+ end
239
+
194
240
  private
195
241
 
196
242
  def topscope
@@ -199,18 +245,230 @@ module Pal
199
245
  end
200
246
 
201
247
  class ScriptCompiler < Compiler
202
- # Returns the signature callable of the given plan (the arguments it accepts, and the data type it returns)
248
+ # Returns the signature of the given plan name
203
249
  # @param plan_name [String] the name of the plan to get the signature of
204
- # @return [Puppet::Pops::Types::PCallableType, nil] returns a callable data type, or nil if plan is not found
250
+ # @return [Puppet::Pal::PlanSignature, nil] returns a PlanSignature, or nil if plan is not found
205
251
  #
206
252
  def plan_signature(plan_name)
207
253
  loader = internal_compiler.loaders.private_environment_loader
208
254
  if func = loader.load(:plan, plan_name)
209
- return func.class.dispatcher.to_type
255
+ return PlanSignature.new(func)
210
256
  end
211
257
  # Could not find plan
212
258
  nil
213
259
  end
260
+
261
+ # Returns an array of TypedName objects for all plans, optionally filtered by a regular expression.
262
+ # The returned array has more information than just the leaf name - the typical thing is to just get
263
+ # the name as showing the following example.
264
+ #
265
+ # @example getting the names of all plans
266
+ # compiler.list_plans.map {|tn| tn.name }
267
+ #
268
+ # @param filter_regex [Regexp] an optional regexp that filters based on name (matching names are included in the result)
269
+ # @return [Array<Puppet::Pops::Loader::TypedName>] an array of typed names
270
+ #
271
+ def list_plans(filter_regex = nil)
272
+ list_loadable_kind(:plan, filter_regex)
273
+ end
274
+
275
+ # Returns the signature callable of the given task (the arguments it accepts, and the data type it returns)
276
+ # @param task_name [String] the name of the task to get the signature of
277
+ # @return [Puppet::Pal::TaskSignature, nil] returns a TaskSignature, or nil if task is not found
278
+ #
279
+ def task_signature(task_name)
280
+ loader = internal_compiler.loaders.private_environment_loader
281
+ if task = loader.load(:task, task_name)
282
+ return TaskSignature.new(task)
283
+ end
284
+ # Could not find task
285
+ nil
286
+ end
287
+
288
+ # Returns an array of TypedName objects for all tasks, optionally filtered by a regular expression.
289
+ # The returned array has more information than just the leaf name - the typical thing is to just get
290
+ # the name as showing the following example.
291
+ #
292
+ # @example getting the names of all tasks
293
+ # compiler.list_tasks.map {|tn| tn.name }
294
+ #
295
+ # @param filter_regex [Regexp] an optional regexp that filters based on name (matching names are included in the result)
296
+ # @return [Array<Puppet::Pops::Loader::TypedName>] an array of typed names
297
+ #
298
+ def list_tasks(filter_regex = nil)
299
+ list_loadable_kind(:task, filter_regex)
300
+ end
301
+ end
302
+
303
+ # A FunctionSignature is returned from `function_signature`. Its purpose is to answer questions about the function's parameters
304
+ # and if it can be called with a set of parameters.
305
+ #
306
+ # It is also possible to get an array of puppet Callable data type where each callable describes one possible way
307
+ # the function can be called.
308
+ #
309
+ # @api public
310
+ #
311
+ class FunctionSignature
312
+ # @api private
313
+ def initialize(function_class)
314
+ @func = function_class
315
+ end
316
+
317
+ # Returns true if the function can be called with the given arguments and false otherwise.
318
+ # If the function is not callable, and a code block is given, it is given a formatted error message that describes
319
+ # the type mismatch. That error message can be quite complex if the function has multiple dispatch depending on
320
+ # given types.
321
+ #
322
+ # @param args [Array] The arguments as given to the function call
323
+ # @param callable [Proc, nil] An optional ruby Proc or puppet lambda given to the function
324
+ # @yield [String] a formatted error message describing a type mismatch if the function is not callable with given args + block
325
+ # @return [Boolean] true if the function can be called with given args + block, and false otherwise
326
+ # @api public
327
+ #
328
+ def callable_with?(args, callable=nil)
329
+ signatures = @func.dispatcher.to_type
330
+ callables = signatures.is_a?(Puppet::Pops::Types::PVariantType) ? signatures.types : [signatures]
331
+
332
+ return true if callables.any? {|t| t.callable_with?(args) }
333
+ return false unless block_given?
334
+ args_type = Puppet::Pops::Types::TypeCalculator.singleton.infer_set(callable.nil? ? args : args + [callable])
335
+ error_message = Puppet::Pops::Types::TypeMismatchDescriber.describe_signatures(@func.name, @func.signatures, args_type)
336
+ yield error_message
337
+ false
338
+ end
339
+
340
+ # Returns an array of Callable puppet data type
341
+ # @return [Array<Puppet::Pops::Types::PCallableType] one callable per way the function can be called
342
+ #
343
+ # @api public
344
+ #
345
+ def callables
346
+ signatures = @func.dispatcher.to_type
347
+ signatures.is_a?(Puppet::Pops::Types::PVariantType) ? signatures.types : [signatures]
348
+ end
349
+ end
350
+
351
+ # A TaskSignature is returned from `task_signature`. Its purpose is to answer questions about the task's parameters
352
+ # and if it can be run/called with a hash of named parameters.
353
+ #
354
+ class TaskSignature
355
+ def initialize(task)
356
+ @task = task
357
+ end
358
+
359
+ # Returns whether or not the given arguments are acceptable when running the task.
360
+ # In addition to returning the boolean outcome, if a block is given, it is called with a string of formatted
361
+ # error messages that describes the difference between what was given and what is expected. The error message may
362
+ # have multiple lines of text, and each line is indented one space.
363
+ #
364
+ # @param args_hash [Hash] a hash mapping parameter names to argument values
365
+ # @yieldparam [String] a formatted error message if a type mismatch occurs that explains the mismatch
366
+ # @return [Boolean] if the given arguments are acceptable when running the task
367
+ #
368
+ def runnable_with?(args_hash)
369
+ params = @task.parameters
370
+ params_type = if params.nil?
371
+ T_GENERIC_TASK_HASH
372
+ else
373
+ key_to_type = {}
374
+ @task.parameters.each_pair { |k, v| key_to_type[k] = v['type'] }
375
+ Puppet::Pops::Types::TypeFactory.struct(key_to_type)
376
+ end
377
+ return true if params_type.instance?(args_hash)
378
+
379
+ if block_given?
380
+ tm = Puppet::Pops::Types::TypeMismatchDescriber.singleton
381
+ error = if params.nil?
382
+ tm.describe_mismatch('', params_type, Puppet::Pops::Types::TypeCalculator.infer_set(args_hash))
383
+ else
384
+ tm.describe_struct_signature(params_type, args_hash).flatten.map {|e| e.format }.join("\n")
385
+ end
386
+ yield "Task #{@task.name}:\n#{error}"
387
+ end
388
+ false
389
+ end
390
+
391
+ # Returns the Task instance as a hash
392
+ #
393
+ # @return [Hash{String=>Object}] the hash representation of the task
394
+ def task_hash
395
+ @task._pcore_init_hash
396
+ end
397
+
398
+ # Returns the Task instance which can be further explored. It contains all meta-data defined for
399
+ # the task such as the description, parameters, output, etc.
400
+ #
401
+ # @return [Puppet::Pops::Types::PuppetObject] An instance of a dynamically created Task class
402
+ def task
403
+ @task
404
+ end
405
+ end
406
+
407
+ # A PlanSignature is returned from `plan_signature`. Its purpose is to answer questions about the plans's parameters
408
+ # and if it can be called with a hash of named parameters.
409
+ #
410
+ # @api public
411
+ #
412
+ class PlanSignature
413
+ def initialize(plan_function)
414
+ @plan_func = plan_function
415
+ end
416
+
417
+ # Returns true or false depending on if the given PlanSignature is callable with a set of named arguments or not
418
+ # In addition to returning the boolean outcome, if a block is given, it is called with a string of formatted
419
+ # error messages that describes the difference between what was given and what is expected. The error message may
420
+ # have multiple lines of text, and each line is indented one space.
421
+ #
422
+ # @example Checking if signature is acceptable
423
+ #
424
+ # signature = pal.plan_signature('myplan')
425
+ # signature.callable_with?({x => 10}) { |errors| raise ArgumentError("Ooops: given arguments does not match\n#{errors}") }
426
+ #
427
+ # @api public
428
+ #
429
+ def callable_with?(args_hash)
430
+ dispatcher = @plan_func.class.dispatcher.dispatchers[0]
431
+
432
+ param_scope = {}
433
+ # Assign all non-nil values, even those that represent non-existent parameters.
434
+ args_hash.each { |k, v| param_scope[k] = v unless v.nil? }
435
+ dispatcher.parameters.each do |p|
436
+ name = p.name
437
+ arg = args_hash[name]
438
+ if arg.nil?
439
+ # Arg either wasn't given, or it was undef
440
+ if p.value.nil?
441
+ # No default. Assign nil if the args_hash included it
442
+ param_scope[name] = nil if args_hash.include?(name)
443
+ else
444
+ # parameter does not have a default value, it will be assigned its default when being called
445
+ # we assume that the default value is of the correct type and therefore simply skip
446
+ # checking this
447
+ # param_scope[name] = param_scope.evaluate(name, p.value, closure_scope, @evaluator)
448
+ end
449
+ end
450
+ end
451
+
452
+ errors = Puppet::Pops::Types::TypeMismatchDescriber.singleton.describe_struct_signature(dispatcher.params_struct, param_scope).flatten
453
+ return true if errors.empty?
454
+ if block_given?
455
+ yield errors.map {|e| e.format }.join("\n")
456
+ end
457
+ false
458
+ end
459
+
460
+ # Returns a PStructType describing the parameters as a puppet Struct data type
461
+ # Note that a `to_s` on the returned structure will result in a human readable Struct datatype as a
462
+ # description of what a plan expects.
463
+ #
464
+ # @return [Puppet::Pops::Types::PStructType] a struct data type describing the parameters and their types
465
+ #
466
+ # @api public
467
+ #
468
+ def params_type
469
+ dispatcher = @plan_func.class.dispatcher.dispatchers[0]
470
+ dispatcher.params_struct
471
+ end
214
472
  end
215
473
 
216
474
  # Defines a context in which multiple operations in an env with a script compiler can be performed in a given block.
@@ -571,6 +829,9 @@ module Pal
571
829
  T_ANY_ARRAY = Puppet::Pops::Types::TypeFactory.array_of_any
572
830
  T_BOOLEAN = Puppet::Pops::Types::PBooleanType::DEFAULT
573
831
 
832
+ T_GENERIC_TASK_HASH = Puppet::Pops::Types::TypeFactory.hash_kv(
833
+ Puppet::Pops::Types::TypeFactory.pattern(/\A[a-z][a-z0-9_]*\z/), Puppet::Pops::Types::TypeFactory.data)
834
+
574
835
  def self.assert_type(type, value, what, allow_nil=false)
575
836
  Puppet::Pops::Types::TypeAsserter.assert_instance_of(nil, type, value, allow_nil) { _('Puppet Pal: %{what}') % {what: what} }
576
837
  end