puppet 3.7.4 → 3.7.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +11 -6
- data/ext/build_defaults.yaml +2 -2
- data/ext/systemd/puppet.service +1 -0
- data/lib/hiera/puppet_function.rb +71 -0
- data/lib/puppet.rb +12 -0
- data/lib/puppet/application/device.rb +22 -5
- data/lib/puppet/daemon.rb +13 -4
- data/lib/puppet/defaults.rb +27 -4
- data/lib/puppet/environments.rb +1 -1
- data/lib/puppet/error.rb +4 -0
- data/lib/puppet/functions.rb +118 -65
- data/lib/puppet/functions/assert_type.rb +5 -5
- data/lib/puppet/functions/each.rb +12 -12
- data/lib/puppet/functions/epp.rb +3 -4
- data/lib/puppet/functions/filter.rb +12 -12
- data/lib/puppet/functions/hiera.rb +29 -0
- data/lib/puppet/functions/hiera_array.rb +34 -0
- data/lib/puppet/functions/hiera_hash.rb +36 -0
- data/lib/puppet/functions/hiera_include.rb +50 -0
- data/lib/puppet/functions/inline_epp.rb +2 -3
- data/lib/puppet/functions/map.rb +12 -12
- data/lib/puppet/functions/reduce.rb +6 -6
- data/lib/puppet/functions/scanf.rb +3 -3
- data/lib/puppet/functions/slice.rb +10 -9
- data/lib/puppet/functions/with.rb +3 -4
- data/lib/puppet/graph/simple_graph.rb +5 -5
- data/lib/puppet/metatype/manager.rb +1 -1
- data/lib/puppet/node/environment.rb +1 -1
- data/lib/puppet/parser/ast/arithmetic_operator.rb +1 -1
- data/lib/puppet/parser/ast/collexpr.rb +1 -1
- data/lib/puppet/parser/compiler.rb +3 -3
- data/lib/puppet/parser/functions/create_resources.rb +1 -9
- data/lib/puppet/parser/functions/defined.rb +1 -1
- data/lib/puppet/parser/functions/hiera.rb +20 -11
- data/lib/puppet/parser/functions/hiera_array.rb +23 -13
- data/lib/puppet/parser/functions/hiera_hash.rb +25 -15
- data/lib/puppet/parser/functions/hiera_include.rb +20 -9
- data/lib/puppet/parser/functions/lookup.rb +1 -1
- data/lib/puppet/parser/functions/realize.rb +1 -1
- data/lib/puppet/parser/functions/scanf.rb +21 -12
- data/lib/puppet/parser/parser_factory.rb +2 -2
- data/lib/puppet/parser/relationship.rb +1 -1
- data/lib/puppet/parser/scope.rb +34 -7
- data/lib/puppet/pops.rb +2 -0
- data/lib/puppet/pops/binder/lookup.rb +24 -7
- data/lib/puppet/pops/binder/producers.rb +2 -2
- data/lib/puppet/pops/evaluator/closure.rb +1 -1
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +109 -17
- data/lib/puppet/pops/evaluator/puppet_proc.rb +69 -0
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +175 -0
- data/lib/puppet/pops/evaluator/runtime3_support.rb +15 -128
- data/lib/puppet/pops/functions/dispatch.rb +21 -17
- data/lib/puppet/pops/functions/dispatcher.rb +3 -3
- data/lib/puppet/pops/functions/function.rb +46 -14
- data/lib/puppet/pops/issues.rb +2 -2
- data/lib/puppet/pops/model/model_label_provider.rb +1 -1
- data/lib/puppet/pops/parser/egrammar.ra +2 -0
- data/lib/puppet/pops/parser/eparser.rb +732 -724
- data/lib/puppet/pops/parser/heredoc_support.rb +1 -1
- data/lib/puppet/pops/parser/lexer2.rb +20 -22
- data/lib/puppet/pops/types/class_loader.rb +1 -1
- data/lib/puppet/pops/types/type_calculator.rb +104 -37
- data/lib/puppet/pops/types/type_factory.rb +1 -1
- data/lib/puppet/pops/types/types.rb +4 -1
- data/lib/puppet/pops/types/types_meta.rb +2 -2
- data/lib/puppet/pops/validation/checker4_0.rb +5 -3
- data/lib/puppet/provider/service/systemd.rb +1 -0
- data/lib/puppet/provider/yumrepo/inifile.rb +4 -1
- data/lib/puppet/resource.rb +3 -2
- data/lib/puppet/resource/catalog.rb +3 -2
- data/lib/puppet/resource/type.rb +1 -1
- data/lib/puppet/settings/environment_conf.rb +12 -4
- data/lib/puppet/type/package.rb +23 -13
- data/lib/puppet/util/autoload.rb +7 -7
- data/lib/puppet/util/errors.rb +4 -2
- data/lib/puppet/util/network_device/config.rb +5 -0
- data/lib/puppet/version.rb +1 -1
- data/lib/puppetx.rb +2 -2
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/callee.rb +8 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/callee_ws.rb +8 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/metadata.json +9 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/caller.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/caller_ws.rb +12 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/metadata.json +9 -0
- data/spec/integration/parser/environment_spec.rb +47 -0
- data/spec/integration/parser/future_compiler_spec.rb +11 -6
- data/spec/unit/application/device_spec.rb +52 -14
- data/spec/unit/daemon_spec.rb +0 -2
- data/spec/unit/environments_spec.rb +2 -2
- data/spec/unit/functions/assert_type_spec.rb +4 -25
- data/spec/unit/functions/hiera_spec.rb +127 -0
- data/spec/unit/functions/with_spec.rb +9 -4
- data/spec/unit/functions4_spec.rb +98 -35
- data/spec/unit/hiera/backend/puppet_backend_spec.rb +1 -1
- data/spec/unit/parser/functions/create_resources_spec.rb +2 -2
- data/spec/unit/parser/functions/defined_spec.rb +5 -0
- data/spec/unit/parser/functions/lookup_spec.rb +5 -1
- data/spec/unit/parser/functions/scanf_spec.rb +30 -0
- data/spec/unit/parser/scope_spec.rb +5 -0
- data/spec/unit/pops/binder/injector_spec.rb +1 -1
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +33 -5
- data/spec/unit/pops/loaders/loaders_spec.rb +22 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +28 -16
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +21 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +141 -19
- data/spec/unit/pops/types/type_factory_spec.rb +2 -2
- data/spec/unit/pops/validator/validator_spec.rb +25 -3
- data/spec/unit/provider/service/systemd_spec.rb +20 -4
- data/spec/unit/provider/user/hpux_spec.rb +1 -1
- data/spec/unit/provider/yumrepo/inifile_spec.rb +1 -0
- data/spec/unit/settings/environment_conf_spec.rb +12 -1
- data/spec/unit/type/package_spec.rb +0 -20
- data/spec/unit/util/network_device/config_spec.rb +6 -0
- metadata +3422 -3405
@@ -0,0 +1,175 @@
|
|
1
|
+
module Puppet::Pops::Evaluator
|
2
|
+
# Converts nested 4x supported values to 3x values. This is required because
|
3
|
+
# resources and other objects do not know about the new type system, and does not support
|
4
|
+
# regular expressions. Unfortunately this has to be done for array and hash as well.
|
5
|
+
# A complication is that catalog types needs to be resolved against the scope.
|
6
|
+
#
|
7
|
+
# Users should not create instances of this class. Instead the class methods {Runtime3Converter.convert},
|
8
|
+
# {Runtime3Converter.map_args}, or {Runtime3Converter.instance} should be used
|
9
|
+
class Runtime3Converter
|
10
|
+
# Converts 4x supported values to a 3x values. Same as calling Runtime3Converter.instance.map_args(...)
|
11
|
+
#
|
12
|
+
# @param args [Array] Array of values to convert
|
13
|
+
# @param scope [Puppet::Parser::Scope] The scope to use when converting
|
14
|
+
# @param undef_value [Object] The value that nil is converted to
|
15
|
+
# @return [Array] The converted values
|
16
|
+
#
|
17
|
+
def self.map_args(args, scope, undef_value)
|
18
|
+
@@instance.map_args(args, scope, undef_value)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Converts 4x supported values to a 3x values. Same as calling Runtime3Converter.instance.convert(...)
|
22
|
+
#
|
23
|
+
# @param o [Object]The value to convert
|
24
|
+
# @param scope [Puppet::Parser::Scope] The scope to use when converting
|
25
|
+
# @param undef_value [Object] The value that nil is converted to
|
26
|
+
# @return [Object] The converted value
|
27
|
+
#
|
28
|
+
def self.convert(o, scope, undef_value)
|
29
|
+
@@instance.convert(o, scope, undef_value)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the singleton instance of this class.
|
33
|
+
# @return [Runtime3Converter] The singleton instance
|
34
|
+
def self.instance
|
35
|
+
@@instance
|
36
|
+
end
|
37
|
+
|
38
|
+
# Converts 4x supported values to a 3x values.
|
39
|
+
#
|
40
|
+
# @param args [Array] Array of values to convert
|
41
|
+
# @param scope [Puppet::Parser::Scope] The scope to use when converting
|
42
|
+
# @param undef_value [Object] The value that nil is converted to
|
43
|
+
# @return [Array] The converted values
|
44
|
+
#
|
45
|
+
def map_args(args, scope, undef_value)
|
46
|
+
args.map {|a| convert(a, scope, undef_value) }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Converts a 4x supported value to a 3x value.
|
50
|
+
#
|
51
|
+
# @param o [Object]The value to convert
|
52
|
+
# @param scope [Puppet::Parser::Scope] The scope to use when converting
|
53
|
+
# @param undef_value [Object] The value that nil is converted to
|
54
|
+
# @return [Object] The converted value
|
55
|
+
#
|
56
|
+
def convert(o, scope, undef_value)
|
57
|
+
@convert_visitor.visit_this_2(self, o, scope, undef_value)
|
58
|
+
end
|
59
|
+
|
60
|
+
def convert_NilClass(o, scope, undef_value)
|
61
|
+
undef_value
|
62
|
+
end
|
63
|
+
|
64
|
+
def convert2_NilClass(o, scope, undef_value)
|
65
|
+
:undef
|
66
|
+
end
|
67
|
+
|
68
|
+
def convert_String(o, scope, undef_value)
|
69
|
+
# although wasteful, needed because user code may mutate these strings in Resources
|
70
|
+
o.frozen? ? o.dup : o
|
71
|
+
end
|
72
|
+
alias convert2_String :convert_String
|
73
|
+
|
74
|
+
def convert_Object(o, scope, undef_value)
|
75
|
+
o
|
76
|
+
end
|
77
|
+
alias :convert2_Object :convert_Object
|
78
|
+
|
79
|
+
def convert_Array(o, scope, undef_value)
|
80
|
+
o.map {|x| convert2(x, scope, undef_value) }
|
81
|
+
end
|
82
|
+
alias :convert2_Array :convert_Array
|
83
|
+
|
84
|
+
def convert_Hash(o, scope, undef_value)
|
85
|
+
result = {}
|
86
|
+
o.each {|k,v| result[convert2(k, scope, undef_value)] = convert2(v, scope, undef_value) }
|
87
|
+
result
|
88
|
+
end
|
89
|
+
alias :convert2_Hash :convert_Hash
|
90
|
+
|
91
|
+
def convert_Regexp(o, scope, undef_value)
|
92
|
+
# Puppet 3x cannot handle parameter values that are reqular expressions. Turn into regexp string in
|
93
|
+
# source form
|
94
|
+
o.inspect
|
95
|
+
end
|
96
|
+
alias :convert2_Regexp :convert_Regexp
|
97
|
+
|
98
|
+
def convert_Symbol(o, scope, undef_value)
|
99
|
+
case o
|
100
|
+
# Support :undef since it may come from a 3x structure
|
101
|
+
when :undef
|
102
|
+
undef_value # 3x wants undef as either empty string or :undef
|
103
|
+
else
|
104
|
+
o # :default, and all others are verbatim since they are new in future evaluator
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# The :undef symbol should not be converted when nested in arrays or hashes
|
109
|
+
def convert2_Symbol(o, scope, undef_value)
|
110
|
+
o
|
111
|
+
end
|
112
|
+
|
113
|
+
def convert_PAnyType(o, scope, undef_value)
|
114
|
+
o
|
115
|
+
end
|
116
|
+
alias :convert2_PAnyType :convert_PAnyType
|
117
|
+
|
118
|
+
def convert_PCatalogEntryType(o, scope, undef_value)
|
119
|
+
# Since 4x does not support dynamic scoping, all names are absolute and can be
|
120
|
+
# used as is (with some check/transformation/mangling between absolute/relative form
|
121
|
+
# due to Puppet::Resource's idiosyncratic behavior where some references must be
|
122
|
+
# absolute and others cannot be.
|
123
|
+
# Thus there is no need to call scope.resolve_type_and_titles to do dynamic lookup.
|
124
|
+
|
125
|
+
Puppet::Resource.new(*catalog_type_to_split_type_title(o))
|
126
|
+
end
|
127
|
+
alias :convert2_PCatalogEntryType :convert_PCatalogEntryType
|
128
|
+
|
129
|
+
# Produces an array with [type, title] from a PCatalogEntryType
|
130
|
+
# This method is used to produce the arguments for creation of reference resource instances
|
131
|
+
# (used when 3x is operating on a resource).
|
132
|
+
# Ensures that resources are *not* absolute.
|
133
|
+
#
|
134
|
+
def catalog_type_to_split_type_title(catalog_type)
|
135
|
+
split_type = catalog_type.is_a?(Puppet::Pops::Types::PType) ? catalog_type.type : catalog_type
|
136
|
+
case split_type
|
137
|
+
when Puppet::Pops::Types::PHostClassType
|
138
|
+
class_name = split_type.class_name
|
139
|
+
['class', class_name.nil? ? nil : class_name.sub(/^::/, '')]
|
140
|
+
when Puppet::Pops::Types::PResourceType
|
141
|
+
type_name = split_type.type_name
|
142
|
+
title = split_type.title
|
143
|
+
if type_name =~ /^(::)?[Cc]lass/
|
144
|
+
['class', title.nil? ? nil : title.sub(/^::/, '')]
|
145
|
+
else
|
146
|
+
# Ensure that title is '' if nil
|
147
|
+
# Resources with absolute name always results in error because tagging does not support leading ::
|
148
|
+
[type_name.nil? ? nil : type_name.sub(/^::/, ''), title.nil? ? '' : title]
|
149
|
+
end
|
150
|
+
else
|
151
|
+
raise ArgumentError, "Cannot split the type #{catalog_type.class}, it represents neither a PHostClassType, nor a PResourceType."
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
157
|
+
def initialize
|
158
|
+
@convert_visitor = Puppet::Pops::Visitor.new(self, 'convert', 2, 2)
|
159
|
+
@convert2_visitor = Puppet::Pops::Visitor.new(self, 'convert2', 2, 2)
|
160
|
+
end
|
161
|
+
|
162
|
+
@@instance = self.new
|
163
|
+
|
164
|
+
# Converts a nested 4x supported value to a 3x value.
|
165
|
+
#
|
166
|
+
# @param o [Object]The value to convert
|
167
|
+
# @param scope [Puppet::Parser::Scope] The scope to use when converting
|
168
|
+
# @param undef_value [Object] The value that nil is converted to
|
169
|
+
# @return [Object] The converted value
|
170
|
+
#
|
171
|
+
def convert2(o, scope, undef_value)
|
172
|
+
@convert2_visitor.visit_this_2(self, o, scope, undef_value)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -199,7 +199,7 @@ module Puppet::Pops::Evaluator::Runtime3Support
|
|
199
199
|
source_resource = source
|
200
200
|
else
|
201
201
|
# transform into the wonderful String representation in 3x
|
202
|
-
type, title = catalog_type_to_split_type_title(source)
|
202
|
+
type, title = Puppet::Pops::Evaluator::Runtime3Converter.instance.catalog_type_to_split_type_title(source)
|
203
203
|
source_resource = Puppet::Resource.new(type, title)
|
204
204
|
end
|
205
205
|
if target.is_a?(Puppet::Parser::Collector) || target.is_a?(Puppet::Pops::Evaluator::Collectors::AbstractCollector)
|
@@ -207,7 +207,7 @@ module Puppet::Pops::Evaluator::Runtime3Support
|
|
207
207
|
target_resource = target
|
208
208
|
else
|
209
209
|
# transform into the wonderful String representation in 3x
|
210
|
-
type, title = catalog_type_to_split_type_title(target)
|
210
|
+
type, title = Puppet::Pops::Evaluator::Runtime3Converter.instance.catalog_type_to_split_type_title(target)
|
211
211
|
target_resource = Puppet::Resource.new(type, title)
|
212
212
|
end
|
213
213
|
# Add the relationship to the compiler for later evaluation.
|
@@ -229,14 +229,14 @@ module Puppet::Pops::Evaluator::Runtime3Support
|
|
229
229
|
n
|
230
230
|
end
|
231
231
|
|
232
|
-
def call_function(name, args, o, scope)
|
232
|
+
def call_function(name, args, o, scope, &block)
|
233
233
|
# Call via 4x API if the function exists there
|
234
234
|
loaders = scope.compiler.loaders
|
235
235
|
# find the loader that loaded the code, or use the private_environment_loader (sees env + all modules)
|
236
236
|
adapter = Puppet::Pops::Utils.find_adapter(o, Puppet::Pops::Adapters::LoaderAdapter)
|
237
237
|
loader = adapter.nil? ? loaders.private_environment_loader : adapter.loader
|
238
238
|
if loader && func = loader.load(:function, name)
|
239
|
-
return func.call(scope, *args)
|
239
|
+
return func.call(scope, *args, &block)
|
240
240
|
end
|
241
241
|
|
242
242
|
# Call via 3x API if function exists there
|
@@ -244,8 +244,8 @@ module Puppet::Pops::Evaluator::Runtime3Support
|
|
244
244
|
|
245
245
|
# Arguments must be mapped since functions are unaware of the new and magical creatures in 4x.
|
246
246
|
# NOTE: Passing an empty string last converts nil/:undef to empty string
|
247
|
-
mapped_args =
|
248
|
-
result = scope.send("function_#{name}", mapped_args)
|
247
|
+
mapped_args = Puppet::Pops::Evaluator::Runtime3Converter.map_args(args, scope, '')
|
248
|
+
result = scope.send("function_#{name}", mapped_args, &block)
|
249
249
|
# Prevent non r-value functions from leaking their result (they are not written to care about this)
|
250
250
|
Puppet::Parser::Functions.rvalue?(name) ? result : nil
|
251
251
|
end
|
@@ -261,6 +261,10 @@ module Puppet::Pops::Evaluator::Runtime3Support
|
|
261
261
|
)
|
262
262
|
end
|
263
263
|
|
264
|
+
def convert(value, scope, undef_value)
|
265
|
+
Puppet::Pops::Evaluator::Runtime3Converter.convert(value, scope, undef_value)
|
266
|
+
end
|
267
|
+
|
264
268
|
CLASS_STRING = 'class'.freeze
|
265
269
|
|
266
270
|
def create_resources(o, scope, virtual, exported, type_name, resource_titles, evaluated_parameters)
|
@@ -423,127 +427,6 @@ module Puppet::Pops::Evaluator::Runtime3Support
|
|
423
427
|
x.is_a?(TrueClass) || x.is_a?(FalseClass)
|
424
428
|
end
|
425
429
|
|
426
|
-
def initialize
|
427
|
-
@@convert_visitor ||= Puppet::Pops::Visitor.new(self, "convert", 2, 2)
|
428
|
-
@@convert2_visitor ||= Puppet::Pops::Visitor.new(self, "convert2", 2, 2)
|
429
|
-
end
|
430
|
-
|
431
|
-
# Converts 4x supported values to 3x values. This is required because
|
432
|
-
# resources and other objects do not know about the new type system, and does not support
|
433
|
-
# regular expressions. Unfortunately this has to be done for array and hash as well.
|
434
|
-
# A complication is that catalog types needs to be resolved against the scope.
|
435
|
-
#
|
436
|
-
def convert(o, scope, undef_value)
|
437
|
-
@@convert_visitor.visit_this_2(self, o, scope, undef_value)
|
438
|
-
end
|
439
|
-
|
440
|
-
# Converts nested 4x supported values to 3x values. This is required because
|
441
|
-
# resources and other objects do not know about the new type system, and does not support
|
442
|
-
# regular expressions. Unfortunately this has to be done for array and hash as well.
|
443
|
-
# A complication is that catalog types needs to be resolved against the scope.
|
444
|
-
#
|
445
|
-
def convert2(o, scope, undef_value)
|
446
|
-
@@convert2_visitor.visit_this_2(self, o, scope, undef_value)
|
447
|
-
end
|
448
|
-
|
449
|
-
|
450
|
-
def convert_NilClass(o, scope, undef_value)
|
451
|
-
undef_value
|
452
|
-
end
|
453
|
-
|
454
|
-
def convert2_NilClass(o, scope, undef_value)
|
455
|
-
:undef
|
456
|
-
end
|
457
|
-
|
458
|
-
def convert_String(o, scope, undef_value)
|
459
|
-
# although wasteful, needed because user code may mutate these strings in Resources
|
460
|
-
o.frozen? ? o.dup : o
|
461
|
-
end
|
462
|
-
alias convert2_String :convert_String
|
463
|
-
|
464
|
-
def convert_Object(o, scope, undef_value)
|
465
|
-
o
|
466
|
-
end
|
467
|
-
alias :convert2_Object :convert_Object
|
468
|
-
|
469
|
-
def convert_Array(o, scope, undef_value)
|
470
|
-
o.map {|x| convert2(x, scope, undef_value) }
|
471
|
-
end
|
472
|
-
alias :convert2_Array :convert_Array
|
473
|
-
|
474
|
-
def convert_Hash(o, scope, undef_value)
|
475
|
-
result = {}
|
476
|
-
o.each {|k,v| result[convert2(k, scope, undef_value)] = convert2(v, scope, undef_value) }
|
477
|
-
result
|
478
|
-
end
|
479
|
-
alias :convert2_Hash :convert_Hash
|
480
|
-
|
481
|
-
def convert_Regexp(o, scope, undef_value)
|
482
|
-
# Puppet 3x cannot handle parameter values that are reqular expressions. Turn into regexp string in
|
483
|
-
# source form
|
484
|
-
o.inspect
|
485
|
-
end
|
486
|
-
alias :convert2_Regexp :convert_Regexp
|
487
|
-
|
488
|
-
def convert_Symbol(o, scope, undef_value)
|
489
|
-
case o
|
490
|
-
# Support :undef since it may come from a 3x structure
|
491
|
-
when :undef
|
492
|
-
undef_value # 3x wants undef as either empty string or :undef
|
493
|
-
else
|
494
|
-
o # :default, and all others are verbatim since they are new in future evaluator
|
495
|
-
end
|
496
|
-
end
|
497
|
-
|
498
|
-
# The :undef symbol should not be converted when nested in arrays or hashes
|
499
|
-
def convert2_Symbol(o, scope, undef_value)
|
500
|
-
o
|
501
|
-
end
|
502
|
-
|
503
|
-
def convert_PAnyType(o, scope, undef_value)
|
504
|
-
o
|
505
|
-
end
|
506
|
-
alias :convert2_PAnyType :convert_PAnyType
|
507
|
-
|
508
|
-
def convert_PCatalogEntryType(o, scope, undef_value)
|
509
|
-
# Since 4x does not support dynamic scoping, all names are absolute and can be
|
510
|
-
# used as is (with some check/transformation/mangling between absolute/relative form
|
511
|
-
# due to Puppet::Resource's idiosyncratic behavior where some references must be
|
512
|
-
# absolute and others cannot be.
|
513
|
-
# Thus there is no need to call scope.resolve_type_and_titles to do dynamic lookup.
|
514
|
-
|
515
|
-
Puppet::Resource.new(*catalog_type_to_split_type_title(o))
|
516
|
-
end
|
517
|
-
alias :convert2_PCatalogEntryType :convert_PCatalogEntryType
|
518
|
-
|
519
|
-
private
|
520
|
-
|
521
|
-
# Produces an array with [type, title] from a PCatalogEntryType
|
522
|
-
# This method is used to produce the arguments for creation of reference resource instances
|
523
|
-
# (used when 3x is operating on a resource).
|
524
|
-
# Ensures that resources are *not* absolute.
|
525
|
-
#
|
526
|
-
def catalog_type_to_split_type_title(catalog_type)
|
527
|
-
split_type = catalog_type.is_a?(Puppet::Pops::Types::PType) ? catalog_type.type : catalog_type
|
528
|
-
case split_type
|
529
|
-
when Puppet::Pops::Types::PHostClassType
|
530
|
-
class_name = split_type.class_name
|
531
|
-
['class', class_name.nil? ? nil : class_name.sub(/^::/, '')]
|
532
|
-
when Puppet::Pops::Types::PResourceType
|
533
|
-
type_name = split_type.type_name
|
534
|
-
title = split_type.title
|
535
|
-
if type_name =~ /^(::)?[Cc]lass/
|
536
|
-
['class', title.nil? ? nil : title.sub(/^::/, '')]
|
537
|
-
else
|
538
|
-
# Ensure that title is '' if nil
|
539
|
-
# Resources with absolute name always results in error because tagging does not support leading ::
|
540
|
-
[type_name.nil? ? nil : type_name.sub(/^::/, ''), title.nil? ? '' : title]
|
541
|
-
end
|
542
|
-
else
|
543
|
-
raise ArgumentError, "Cannot split the type #{catalog_type.class}, it represents neither a PHostClassType, nor a PResourceType."
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
430
|
def extract_file_line(o)
|
548
431
|
source_pos = Puppet::Pops::Utils.find_closest_positioned(o)
|
549
432
|
return [nil, -1] unless source_pos
|
@@ -587,7 +470,11 @@ module Puppet::Pops::Evaluator::Runtime3Support
|
|
587
470
|
class ExceptionRaisingAcceptor < Puppet::Pops::Validation::Acceptor
|
588
471
|
def accept(diagnostic)
|
589
472
|
super
|
590
|
-
Puppet::Pops::IssueReporter.assert_and_report(self, {
|
473
|
+
Puppet::Pops::IssueReporter.assert_and_report(self, {
|
474
|
+
:message => "Evaluation Error:",
|
475
|
+
:emit_warnings => true, # log warnings
|
476
|
+
:exception_class => Puppet::PreformattedError
|
477
|
+
})
|
591
478
|
if errors?
|
592
479
|
raise ArgumentError, "Internal Error: Configuration of runtime error handling wrong: should have raised exception"
|
593
480
|
end
|
@@ -41,36 +41,40 @@ class Puppet::Pops::Functions::Dispatch < Puppet::Pops::Evaluator::CallableSigna
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# @api private
|
44
|
-
def invoke(instance, calling_scope, args)
|
45
|
-
instance.send(@method_name, *weave(calling_scope, args))
|
44
|
+
def invoke(instance, calling_scope, args, &block)
|
45
|
+
instance.send(@method_name, *weave(calling_scope, args), &block)
|
46
46
|
end
|
47
47
|
|
48
48
|
# @api private
|
49
49
|
def weave(scope, args)
|
50
50
|
# no need to weave if there are no injections
|
51
|
-
if injections.empty?
|
51
|
+
if @injections.empty?
|
52
52
|
args
|
53
53
|
else
|
54
54
|
injector = nil # lazy lookup of injector Puppet.lookup(:injector)
|
55
|
-
|
55
|
+
new_args = []
|
56
|
+
@weaving.each do |knit|
|
56
57
|
if knit.is_a?(Array)
|
57
58
|
injection_data = @injections[knit[0]]
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
59
|
+
new_args <<
|
60
|
+
case injection_data[3]
|
61
|
+
when :dispatcher_internal
|
62
|
+
# currently only supports :scope injection
|
63
|
+
scope
|
64
|
+
when :producer
|
65
|
+
injector ||= Puppet.lookup(:injector)
|
66
|
+
injector.lookup_producer(scope, injection_data[0], injection_data[2])
|
67
|
+
else
|
68
|
+
injector ||= Puppet.lookup(:injector)
|
69
|
+
injector.lookup(scope, injection_data[0], injection_data[2])
|
70
|
+
end
|
69
71
|
else
|
70
|
-
#
|
71
|
-
|
72
|
+
# Careful so no new nil arguments are added since they would override default
|
73
|
+
# parameter values in the received
|
74
|
+
new_args << args[knit] if knit < args.size
|
72
75
|
end
|
73
76
|
end
|
77
|
+
new_args
|
74
78
|
end
|
75
79
|
end
|
76
80
|
end
|
@@ -27,12 +27,12 @@ class Puppet::Pops::Functions::Dispatcher
|
|
27
27
|
# @return [Object] - what the called function produced
|
28
28
|
#
|
29
29
|
# @api private
|
30
|
-
def dispatch(instance, calling_scope, args)
|
30
|
+
def dispatch(instance, calling_scope, args, &block)
|
31
31
|
tc = Puppet::Pops::Types::TypeCalculator
|
32
|
-
actual = tc.infer_set(args)
|
32
|
+
actual = tc.infer_set(block_given? ? args + [block] : args)
|
33
33
|
found = @dispatchers.find { |d| tc.callable?(d.type, actual) }
|
34
34
|
if found
|
35
|
-
found.invoke(instance, calling_scope, args)
|
35
|
+
found.invoke(instance, calling_scope, args, &block)
|
36
36
|
else
|
37
37
|
raise ArgumentError, "function '#{instance.class.name}' called with mis-matched arguments\n#{Puppet::Pops::Evaluator::CallableMismatchDescriber.diff_string(instance.class.name, actual, @dispatchers)}"
|
38
38
|
end
|
@@ -40,25 +40,21 @@ class Puppet::Pops::Functions::Function
|
|
40
40
|
# is defined) is available via the method `closure_scope`).
|
41
41
|
#
|
42
42
|
# @api public
|
43
|
-
def call(scope, *args)
|
44
|
-
self.class.dispatcher.dispatch(self, scope, args)
|
43
|
+
def call(scope, *args, &block)
|
44
|
+
self.class.dispatcher.dispatch(self, scope, args, &block)
|
45
45
|
end
|
46
46
|
|
47
47
|
# Allows the implementation of a function to call other functions by name. The callable functions
|
48
|
-
# are those visible to the same loader that loaded this function (the calling function).
|
48
|
+
# are those visible to the same loader that loaded this function (the calling function). The
|
49
|
+
# referenced function is called with the calling functions closure scope as the caller's scope.
|
50
|
+
#
|
51
|
+
# @param function_name [String] The name of the function
|
52
|
+
# @param *args [Object] splat of arguments
|
53
|
+
# @return [Object] The result returned by the called function
|
49
54
|
#
|
50
55
|
# @api public
|
51
|
-
def call_function(function_name, *args)
|
52
|
-
|
53
|
-
func = the_loader.load(:function, function_name)
|
54
|
-
if func
|
55
|
-
return func.call(closure_scope, *args)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
# Raise a generic error to allow upper layers to fill in the details about where in a puppet manifest this
|
59
|
-
# error originates. (Such information is not available here).
|
60
|
-
#
|
61
|
-
raise ArgumentError, "Function #{self.class.name}(): cannot call function '#{function_name}' - not found"
|
56
|
+
def call_function(function_name, *args, &block)
|
57
|
+
internal_call_function(closure_scope, function_name, args, &block)
|
62
58
|
end
|
63
59
|
|
64
60
|
# The dispatcher for the function
|
@@ -74,4 +70,40 @@ class Puppet::Pops::Functions::Function
|
|
74
70
|
def self.signatures
|
75
71
|
@dispatcher.signatures
|
76
72
|
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
# Allows the implementation of a function to call other functions by name and pass the caller
|
77
|
+
# scope. The callable functions are those visible to the same loader that loaded this function
|
78
|
+
# (the calling function).
|
79
|
+
#
|
80
|
+
# @param scope [Puppet::Parser::Scope] The caller scope
|
81
|
+
# @param function_name [String] The name of the function
|
82
|
+
# @param args [Array] array of arguments
|
83
|
+
# @return [Object] The result returned by the called function
|
84
|
+
#
|
85
|
+
# @api public
|
86
|
+
def internal_call_function(scope, function_name, args, &block)
|
87
|
+
|
88
|
+
the_loader = loader
|
89
|
+
raise ArgumentError, "Function #{self.class.name}(): cannot call function '#{function_name}' - no loader specified" unless the_loader
|
90
|
+
|
91
|
+
func = the_loader.load(:function, function_name)
|
92
|
+
return func.call(scope, *args, &block) if func
|
93
|
+
|
94
|
+
# Check if a 3x function is present. Raise a generic error if it's not to allow upper layers to fill in the details
|
95
|
+
# about where in a puppet manifest this error originates. (Such information is not available here).
|
96
|
+
loader_scope = closure_scope
|
97
|
+
func_3x = Puppet::Parser::Functions.function(function_name, loader_scope.environment) if loader_scope.is_a?(Puppet::Parser::Scope)
|
98
|
+
raise ArgumentError, "Function #{self.class.name}(): cannot call function '#{function_name}' - not found" unless func_3x
|
99
|
+
|
100
|
+
# Call via 3x API
|
101
|
+
# Arguments must be mapped since functions are unaware of the new and magical creatures in 4x.
|
102
|
+
# NOTE: Passing an empty string last converts nil/:undef to empty string
|
103
|
+
result = scope.send(func_3x, Puppet::Pops::Evaluator::Runtime3Converter.map_args(args, loader_scope, ''), &block)
|
104
|
+
|
105
|
+
# Prevent non r-value functions from leaking their result (they are not written to care about this)
|
106
|
+
Puppet::Parser::Functions.rvalue?(function_name) ? result : nil
|
107
|
+
end
|
108
|
+
|
77
109
|
end
|