puppet 4.9.4 → 4.10.0

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.

Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +6 -0
  3. data/ext/project_data.yaml +2 -2
  4. data/lib/hiera/puppet_function.rb +1 -1
  5. data/lib/puppet.rb +1 -0
  6. data/lib/puppet/application.rb +14 -0
  7. data/lib/puppet/application/inspect.rb +3 -0
  8. data/lib/puppet/defaults.rb +12 -2
  9. data/lib/puppet/etc.rb +125 -0
  10. data/lib/puppet/face/help.rb +1 -1
  11. data/lib/puppet/functions.rb +49 -4
  12. data/lib/puppet/functions/eyaml_lookup_key.rb +12 -3
  13. data/lib/puppet/functions/hocon_data.rb +9 -0
  14. data/lib/puppet/functions/json_data.rb +9 -0
  15. data/lib/puppet/functions/yaml_data.rb +9 -0
  16. data/lib/puppet/indirector/file_bucket_file/file.rb +69 -22
  17. data/lib/puppet/indirector/key/file.rb +2 -1
  18. data/lib/puppet/indirector/ssl_file.rb +24 -3
  19. data/lib/puppet/module.rb +28 -22
  20. data/lib/puppet/network/http/compression.rb +2 -1
  21. data/lib/puppet/parser/compiler.rb +15 -38
  22. data/lib/puppet/parser/functions/hiera.rb +1 -1
  23. data/lib/puppet/parser/functions/hiera_array.rb +1 -1
  24. data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
  25. data/lib/puppet/parser/functions/hiera_include.rb +1 -1
  26. data/lib/puppet/parser/scope.rb +59 -17
  27. data/lib/puppet/pops/evaluator/callable_signature.rb +7 -0
  28. data/lib/puppet/pops/functions/dispatch.rb +18 -5
  29. data/lib/puppet/pops/functions/dispatcher.rb +7 -13
  30. data/lib/puppet/pops/issue_reporter.rb +1 -1
  31. data/lib/puppet/pops/issues.rb +84 -0
  32. data/lib/puppet/pops/loader/base_loader.rb +13 -5
  33. data/lib/puppet/pops/lookup/configured_data_provider.rb +8 -2
  34. data/lib/puppet/pops/lookup/data_dig_function_provider.rb +109 -19
  35. data/lib/puppet/pops/lookup/data_hash_function_provider.rb +19 -4
  36. data/lib/puppet/pops/lookup/data_provider.rb +43 -29
  37. data/lib/puppet/pops/lookup/environment_data_provider.rb +1 -1
  38. data/lib/puppet/pops/lookup/explainer.rb +1 -0
  39. data/lib/puppet/pops/lookup/function_provider.rb +36 -11
  40. data/lib/puppet/pops/lookup/global_data_provider.rb +18 -5
  41. data/lib/puppet/pops/lookup/hiera_config.rb +203 -84
  42. data/lib/puppet/pops/lookup/interpolation.rb +21 -6
  43. data/lib/puppet/pops/lookup/invocation.rb +14 -9
  44. data/lib/puppet/pops/lookup/location_resolver.rb +27 -0
  45. data/lib/puppet/pops/lookup/lookup_adapter.rb +59 -6
  46. data/lib/puppet/pops/lookup/lookup_key_function_provider.rb +9 -77
  47. data/lib/puppet/pops/lookup/module_data_provider.rb +27 -4
  48. data/lib/puppet/pops/parser/lexer2.rb +1 -1
  49. data/lib/puppet/pops/pcore.rb +3 -3
  50. data/lib/puppet/pops/types/p_object_type.rb +4 -6
  51. data/lib/puppet/pops/types/ruby_generator.rb +2 -2
  52. data/lib/puppet/pops/types/type_asserter.rb +3 -3
  53. data/lib/puppet/pops/types/type_mismatch_describer.rb +25 -7
  54. data/lib/puppet/pops/types/types.rb +20 -29
  55. data/lib/puppet/provider/exec.rb +4 -2
  56. data/lib/puppet/provider/nameservice.rb +8 -8
  57. data/lib/puppet/provider/selmodule/semodule.rb +20 -16
  58. data/lib/puppet/provider/service/src.rb +39 -39
  59. data/lib/puppet/provider/service/systemd.rb +1 -1
  60. data/lib/puppet/provider/user/aix.rb +7 -2
  61. data/lib/puppet/settings.rb +30 -17
  62. data/lib/puppet/ssl/base.rb +14 -1
  63. data/lib/puppet/ssl/certificate_authority.rb +4 -2
  64. data/lib/puppet/ssl/configuration.rb +4 -1
  65. data/lib/puppet/ssl/inventory.rb +10 -3
  66. data/lib/puppet/ssl/key.rb +7 -3
  67. data/lib/puppet/test/test_helper.rb +3 -0
  68. data/lib/puppet/type.rb +13 -1
  69. data/lib/puppet/type/exec.rb +16 -1
  70. data/lib/puppet/type/group.rb +17 -11
  71. data/lib/puppet/type/user.rb +3 -1
  72. data/lib/puppet/util.rb +1 -0
  73. data/lib/puppet/util/character_encoding.rb +95 -0
  74. data/lib/puppet/util/execution.rb +9 -6
  75. data/lib/puppet/util/reference.rb +4 -2
  76. data/lib/puppet/util/windows/file.rb +5 -1
  77. data/lib/puppet/version.rb +6 -2
  78. data/locales/config.yaml +1 -1
  79. data/locales/puppet.pot +18 -4
  80. data/spec/integration/ssl/autosign_spec.rb +18 -3
  81. data/spec/integration/ssl/key_spec.rb +104 -0
  82. data/spec/integration/type/user_spec.rb +13 -6
  83. data/spec/spec_helper.rb +7 -0
  84. data/spec/unit/application/inspect_spec.rb +9 -2
  85. data/spec/unit/data_providers/function_data_provider_spec.rb +2 -2
  86. data/spec/unit/etc_spec.rb +234 -0
  87. data/spec/unit/face/certificate_spec.rb +10 -2
  88. data/spec/unit/functions/dig_spec.rb +1 -1
  89. data/spec/unit/functions/hiera_spec.rb +40 -1
  90. data/spec/unit/functions/lookup_fixture_spec.rb +10 -10
  91. data/spec/unit/functions/lookup_spec.rb +1217 -357
  92. data/spec/unit/functions4_spec.rb +37 -1
  93. data/spec/unit/indirector/file_bucket_file/file_spec.rb +33 -2
  94. data/spec/unit/indirector/key/file_spec.rb +1 -1
  95. data/spec/unit/indirector/ssl_file_spec.rb +3 -3
  96. data/spec/unit/module_spec.rb +52 -59
  97. data/spec/unit/network/http/compression_spec.rb +39 -8
  98. data/spec/unit/parser/compiler_spec.rb +14 -0
  99. data/spec/unit/pops/loaders/loaders_spec.rb +21 -3
  100. data/spec/unit/pops/loaders/module_loaders_spec.rb +61 -0
  101. data/spec/unit/pops/lookup/context_spec.rb +56 -8
  102. data/spec/unit/pops/lookup/lookup_spec.rb +32 -1
  103. data/spec/unit/pops/parser/lexer2_spec.rb +8 -0
  104. data/spec/unit/pops/types/ruby_generator_spec.rb +48 -0
  105. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +12 -3
  106. data/spec/unit/pops/types/types_spec.rb +6 -7
  107. data/spec/unit/provider/nameservice_spec.rb +12 -12
  108. data/spec/unit/provider/package/pkg_spec.rb +2 -0
  109. data/spec/unit/provider/service/src_spec.rb +5 -0
  110. data/spec/unit/ssl/base_spec.rb +9 -0
  111. data/spec/unit/ssl/certificate_authority_spec.rb +2 -2
  112. data/spec/unit/ssl/certificate_request_attributes_spec.rb +6 -0
  113. data/spec/unit/ssl/certificate_request_spec.rb +1 -1
  114. data/spec/unit/ssl/certificate_spec.rb +1 -1
  115. data/spec/unit/ssl/configuration_spec.rb +11 -2
  116. data/spec/unit/ssl/inventory_spec.rb +27 -3
  117. data/spec/unit/ssl/key_spec.rb +7 -7
  118. data/spec/unit/type/exec_spec.rb +41 -4
  119. data/spec/unit/type/file_spec.rb +4 -1
  120. data/spec/unit/util/character_encoding_spec.rb +88 -0
  121. data/spec/unit/util/execution_spec.rb +12 -0
  122. data/spec/unit/version_spec.rb +4 -0
  123. metadata +3803 -3808
  124. data/tasks/i18n.rake +0 -20
@@ -55,7 +55,7 @@ module Interpolation
55
55
  is_alias = method_key == :alias
56
56
 
57
57
  # Alias is only permitted if the entire string is equal to the interpolate expression
58
- raise Puppet::DataBinding::LookupError, "'alias' interpolation is only permitted if the expression is equal to the entire string" if is_alias && subject != match
58
+ fail(Issues::HIERA_INTERPOLATION_ALIAS_NOT_ENTIRE_STRING) if is_alias && subject != match
59
59
  value = interpolate_method(method_key).call(key, lookup_invocation, subject)
60
60
  value = lookup_invocation.check(method_key == :scope ? "scope:#{key}" : key) { interpolate(value, lookup_invocation, allow_methods) }
61
61
 
@@ -69,7 +69,17 @@ module Interpolation
69
69
 
70
70
  def interpolate_method(method_key)
71
71
  @@interpolate_methods ||= begin
72
- global_lookup = lambda { |key, lookup_invocation, _| Lookup.lookup(key, nil, '', true, nil, lookup_invocation) }
72
+ global_lookup = lambda do |key, lookup_invocation, _|
73
+ if lookup_invocation.scope.is_a?(Hiera::Scope) && !lookup_invocation.global_only?
74
+ # "unwrap" the Hiera::Scope
75
+ lookup_invocation = Invocation.new(
76
+ lookup_invocation.scope.real,
77
+ lookup_invocation.override_values,
78
+ lookup_invocation.default_values,
79
+ lookup_invocation.explainer)
80
+ end
81
+ Lookup.lookup(key, nil, '', true, nil, lookup_invocation)
82
+ end
73
83
  scope_lookup = lambda do |key, lookup_invocation, subject|
74
84
  segments = split_key(key) { |problem| Puppet::DataBinding::LookupError.new("#{problem} in string: #{subject}") }
75
85
  root_key = segments.shift
@@ -92,8 +102,8 @@ module Interpolation
92
102
  end
93
103
  end
94
104
  end
95
- unless segments.empty?
96
- found = '';
105
+ unless value.nil? || segments.empty?
106
+ found = nil;
97
107
  catch(:no_such_key) { found = sub_lookup(key, lookup_invocation, segments, value) }
98
108
  value = found;
99
109
  end
@@ -110,7 +120,7 @@ module Interpolation
110
120
  }.freeze
111
121
  end
112
122
  interpolate_method = @@interpolate_methods[method_key]
113
- raise Puppet::DataBinding::LookupError, "Unknown interpolation method '#{method_key}'" unless interpolate_method
123
+ fail(Issues::HIERA_INTERPOLATION_UNKNOWN_INTERPOLATION_METHOD, :name => method_key) unless interpolate_method
114
124
  interpolate_method
115
125
  end
116
126
 
@@ -125,7 +135,7 @@ module Interpolation
125
135
 
126
136
  def get_method_and_data(data, allow_methods)
127
137
  if match = data.match(/^(\w+)\((?:["]([^"]+)["]|[']([^']+)['])\)$/)
128
- raise Puppet::DataBinding::LookupError, 'Interpolation using method syntax is not allowed in this context' unless allow_methods
138
+ fail(Issues::HIERA_INTERPOLATION_METHOD_SYNTAX_NOT_ALLOWED) unless allow_methods
129
139
  key = match[1].to_sym
130
140
  data = match[2] || match[3] # double or single qouted
131
141
  else
@@ -133,6 +143,11 @@ module Interpolation
133
143
  end
134
144
  [key, data]
135
145
  end
146
+
147
+ def fail(issue, args = EMPTY_HASH)
148
+ raise Puppet::DataBinding::LookupError.new(
149
+ issue.format(args), nil, nil, nil, nil, issue.issue_code)
150
+ end
136
151
  end
137
152
  end
138
153
  end
@@ -22,28 +22,33 @@ class Invocation
22
22
  # @param override_values [Hash<String,Object>|nil] A map to use as override. Values found here are returned immediately (no merge)
23
23
  # @param default_values [Hash<String,Object>] A map to use as the last resort (but before default)
24
24
  # @param explainer [boolean,Explanainer] An boolean true to use the default explanation acceptor or an explainer instance that will receive information about the lookup
25
- def initialize(scope, override_values = EMPTY_HASH, default_values = EMPTY_HASH, explainer = nil, adapter_class = LookupAdapter)
25
+ def initialize(scope, override_values = EMPTY_HASH, default_values = EMPTY_HASH, explainer = nil, adapter_class = nil)
26
26
  @scope = scope
27
27
  @override_values = override_values
28
28
  @default_values = default_values
29
29
 
30
30
  parent_invocation = self.class.current
31
- if parent_invocation.nil?
32
- @name_stack = []
33
- @adapter_class = adapter_class
34
- unless explainer.is_a?(Explainer)
35
- explainer = explainer == true ? Explainer.new : nil
36
- end
37
- explainer = DebugExplainer.new(explainer) if Puppet[:debug] && !explainer.is_a?(DebugExplainer)
38
- else
31
+ if parent_invocation && (adapter_class.nil? || adapter_class == parent_invocation.adapter_class)
32
+ # Inherit from parent invocation (track recursion)
39
33
  @name_stack = parent_invocation.name_stack
40
34
  @adapter_class = parent_invocation.adapter_class
35
+
36
+ # Inherit Hiera 3 legacy properties
41
37
  set_hiera_xxx_call if parent_invocation.hiera_xxx_call?
42
38
  set_hiera_v3_merge_behavior if parent_invocation.hiera_v3_merge_behavior?
43
39
  set_global_only if parent_invocation.global_only?
44
40
  povr = parent_invocation.hiera_v3_location_overrides
45
41
  set_hiera_v3_location_overrides(povr) unless povr.empty?
42
+
43
+ # Inherit explainer unless a new explainer is given or disabled using false
46
44
  explainer = explainer == false ? nil : parent_invocation.explainer
45
+ else
46
+ @name_stack = []
47
+ @adapter_class = adapter_class.nil? ? LookupAdapter : adapter_class
48
+ unless explainer.is_a?(Explainer)
49
+ explainer = explainer == true ? Explainer.new : nil
50
+ end
51
+ explainer = DebugExplainer.new(explainer) if Puppet[:debug] && !explainer.is_a?(DebugExplainer)
47
52
  end
48
53
  @explainer = explainer
49
54
  end
@@ -25,6 +25,11 @@ module Lookup
25
25
  def exist?
26
26
  @exist
27
27
  end
28
+
29
+ # @return the resolved location as a string
30
+ def to_s
31
+ @location.to_s
32
+ end
28
33
  end
29
34
 
30
35
  # Helper methods to resolve interpolated locations
@@ -67,6 +72,28 @@ module Lookup
67
72
  ResolvedLocation.new(declared_uri, uri, true)
68
73
  end
69
74
  end
75
+
76
+ def expand_mapped_paths(datadir, mapped_path_triplet, lookup_invocation)
77
+ # The scope interpolation method is used directly to avoid unnecessary parsing of the string that otherwise
78
+ # would need to be generated
79
+ mapped_vars = interpolate_method(:scope).call(mapped_path_triplet[0], lookup_invocation, 'mapped_path[0]')
80
+
81
+ # No paths here unless the scope lookup returned something
82
+ return EMPTY_ARRAY if mapped_vars.nil? || mapped_vars.empty?
83
+
84
+ mapped_vars = [mapped_vars] if mapped_vars.is_a?(String)
85
+ var_key = mapped_path_triplet[1]
86
+ template = mapped_path_triplet[2]
87
+ scope = lookup_invocation.scope
88
+ lookup_invocation.with_local_memory_eluding(var_key) do
89
+ mapped_vars.map do |var|
90
+ # Need to use parent lookup invocation to avoid adding 'var' to the set of variables to track for changes. The
91
+ # variable that 'var' stems from is added above.
92
+ path = scope.with_local_scope(var_key => var) { datadir + interpolate(template, lookup_invocation, false) }
93
+ ResolvedLocation.new(template, path, path.exist?)
94
+ end
95
+ end
96
+ end
70
97
  end
71
98
  end
72
99
  end
@@ -58,7 +58,11 @@ class LookupAdapter < DataAdapter
58
58
  merge = lookup_merge_options(key, lookup_invocation)
59
59
  lookup_invocation.report_merge_source(LOOKUP_OPTIONS) unless merge.nil?
60
60
  end
61
- lookup_invocation.with(:data, key.to_s) { do_lookup(key, lookup_invocation, merge) }
61
+ lookup_invocation.with(:data, key.to_s) do
62
+ catch(:no_such_key) { return do_lookup(key, lookup_invocation, merge) }
63
+ throw :no_such_key if lookup_invocation.global_only?
64
+ key.dig(lookup_invocation, lookup_default_in_module(key, lookup_invocation))
65
+ end
62
66
  end
63
67
  end
64
68
  end
@@ -85,6 +89,7 @@ class LookupAdapter < DataAdapter
85
89
  end
86
90
  end
87
91
  rescue Puppet::DataBinding::LookupError => detail
92
+ raise detail unless detail.issue_code.nil?
88
93
  error = Puppet::Error.new("Lookup of key '#{lookup_invocation.top_key}' failed: #{detail.message}")
89
94
  error.set_backtrace(detail.backtrace)
90
95
  raise error
@@ -114,6 +119,43 @@ class LookupAdapter < DataAdapter
114
119
  provider.key_lookup(key, lookup_invocation, merge_strategy)
115
120
  end
116
121
 
122
+ def lookup_default_in_module(key, lookup_invocation)
123
+ module_name = lookup_invocation.module_name
124
+
125
+ # Do not attempt to do a lookup in a module unless the name is qualified.
126
+ throw :no_such_key if module_name.nil?
127
+
128
+ provider = module_provider(lookup_invocation, module_name)
129
+ throw :no_such_key if provider.nil? || !provider.config(lookup_invocation).has_default_hierarchy?
130
+
131
+ lookup_invocation.with(:scope, "Searching default_hierarchy of module \"#{module_name}\"") do
132
+ merge_strategy = nil
133
+ if merge_strategy.nil?
134
+ @module_default_lookup_options ||= {}
135
+ options = @module_default_lookup_options.fetch(module_name) do |k|
136
+ meta_invocation = Invocation.new(lookup_invocation.scope)
137
+ meta_invocation.lookup(LookupKey::LOOKUP_OPTIONS, k) do
138
+ opts = nil
139
+ lookup_invocation.with(:scope, "Searching for \"#{LookupKey::LOOKUP_OPTIONS}\"") do
140
+ catch(:no_such_key) do
141
+ opts = compile_patterns(
142
+ validate_lookup_options(
143
+ provider.key_lookup_in_default(LookupKey::LOOKUP_OPTIONS, meta_invocation, MergeStrategy.strategy(HASH)), k))
144
+ end
145
+ end
146
+ @module_default_lookup_options[k] = opts
147
+ end
148
+ end
149
+ lookup_options = extract_lookup_options_for_key(key, options)
150
+ merge_strategy = lookup_options[MERGE] unless lookup_options.nil?
151
+ end
152
+
153
+ lookup_invocation.with(:scope, "Searching for \"#{key}\"") do
154
+ provider.key_lookup_in_default(key, lookup_invocation, merge_strategy)
155
+ end
156
+ end
157
+ end
158
+
117
159
  # Retrieve the merge options that match the given `name`.
118
160
  #
119
161
  # @param key [LookupKey] The key for which we want merge options
@@ -141,11 +183,18 @@ class LookupAdapter < DataAdapter
141
183
  else
142
184
  options = @lookup_options[module_name]
143
185
  end
186
+ extract_lookup_options_for_key(key, options)
187
+ end
188
+
189
+ def extract_lookup_options_for_key(key, options)
144
190
  return nil if options.nil?
145
191
 
146
192
  rk = key.root_key
147
- key_opts = options[0][rk]
148
- return key_opts unless key_opts.nil?
193
+ key_opts = options[0]
194
+ unless key_opts.nil?
195
+ key_opt = key_opts[rk]
196
+ return key_opt unless key_opt.nil?
197
+ end
149
198
 
150
199
  patterns = options[1]
151
200
  patterns.each_pair { |pattern, value| return value if pattern =~ rk } unless patterns.nil?
@@ -237,7 +286,7 @@ class LookupAdapter < DataAdapter
237
286
  meta_invocation.lookup(LookupKey::LOOKUP_OPTIONS, lookup_invocation.module_name) do
238
287
  meta_invocation.with(:meta, LOOKUP_OPTIONS) do
239
288
  if meta_invocation.global_only?
240
- global_lookup_options(meta_invocation, merge_strategy)
289
+ compile_patterns(global_lookup_options(meta_invocation, merge_strategy))
241
290
  else
242
291
  opts = env_lookup_options(meta_invocation, merge_strategy)
243
292
  catch(:no_such_key) do
@@ -356,7 +405,9 @@ class LookupAdapter < DataAdapter
356
405
  when 'hiera'
357
406
  mp || ModuleDataProvider.new(module_name)
358
407
  when 'function'
359
- ModuleDataProvider.new(module_name, HieraConfig.v4_function_config(Pathname(mod.path), "#{module_name}::data"))
408
+ mp = ModuleDataProvider.new(module_name)
409
+ mp.config = HieraConfig.v4_function_config(Pathname(mod.path), "#{module_name}::data", mp)
410
+ mp
360
411
  else
361
412
  injector = Puppet.lookup(:injector) { nil }
362
413
  provider = injector.lookup(nil,
@@ -424,7 +475,9 @@ class LookupAdapter < DataAdapter
424
475
  # Use hiera.yaml or default settings if it is missing
425
476
  ep || EnvironmentDataProvider.new
426
477
  when 'function'
427
- EnvironmentDataProvider.new(HieraConfigV5.v4_function_config(env_path, 'environment::data'))
478
+ ep = EnvironmentDataProvider.new
479
+ ep.config = HieraConfigV5.v4_function_config(env_path, 'environment::data', ep)
480
+ ep
428
481
  else
429
482
  injector = Puppet.lookup(:injector) { nil }
430
483
 
@@ -25,11 +25,11 @@ class LookupKeyFunctionProvider < FunctionProvider
25
25
  def invoke_with_location(lookup_invocation, location, root_key, merge)
26
26
  if location.nil?
27
27
  value = lookup_key(root_key, lookup_invocation, nil, merge)
28
- lookup_invocation.report_found(root_key, validate_data_value(self, value))
28
+ lookup_invocation.report_found(root_key, value)
29
29
  else
30
30
  lookup_invocation.with(:location, location) do
31
- value = lookup_key(root_key, lookup_invocation, location.location, merge)
32
- lookup_invocation.report_found(root_key, validate_data_value(self, value))
31
+ value = lookup_key(root_key, lookup_invocation, location, merge)
32
+ lookup_invocation.report_found(root_key, value)
33
33
  end
34
34
  end
35
35
  end
@@ -49,7 +49,12 @@ class LookupKeyFunctionProvider < FunctionProvider
49
49
  ctx.data_hash ||= {}
50
50
  catch(:no_such_key) do
51
51
  hash = ctx.data_hash
52
- hash[key] = ctx.function.call(lookup_invocation.scope, key, options(location), Context.new(ctx, lookup_invocation)) unless hash.include?(key)
52
+ unless hash.include?(key)
53
+ hash[key] = validate_data_value(ctx.function.call(lookup_invocation.scope, key, options(location), Context.new(ctx, lookup_invocation))) do
54
+ msg = "Value for key '#{key}', returned from #{full_name}"
55
+ location.nil? ? msg : "#{msg}, when using location '#{location}',"
56
+ end
57
+ end
53
58
  return hash[key]
54
59
  end
55
60
  lookup_invocation.report_not_found(key)
@@ -83,78 +88,5 @@ class V3LookupKeyFunctionProvider < LookupKeyFunctionProvider
83
88
  end
84
89
  end
85
90
  end
86
-
87
- class V3BackendFunctionProvider < LookupKeyFunctionProvider
88
- TAG = 'hiera3_backend'.freeze
89
-
90
- def lookup_key(key, lookup_invocation, location, merge)
91
- @backend ||= instantiate_backend(lookup_invocation)
92
- config = parent_data_provider.config(lookup_invocation)
93
-
94
- # A merge_behavior retrieved from hiera.yaml must not be converted here. Instead, passing the symbol :hash
95
- # tells the V3 backend to pick it up from the config.
96
- resolution_type = lookup_invocation.hiera_v3_merge_behavior? ? :hash : convert_merge(merge)
97
- @backend.lookup(key, lookup_invocation.scope, lookup_invocation.hiera_v3_location_overrides, resolution_type, context = {:recurse_guard => nil})
98
- end
99
-
100
- private
101
-
102
- def instantiate_backend(lookup_invocation)
103
- backend_name = options[HieraConfig::KEY_BACKEND]
104
- begin
105
- require 'hiera/backend'
106
- require "hiera/backend/#{backend_name.downcase}_backend"
107
- backend = Hiera::Backend.const_get("#{backend_name.capitalize}_backend").new
108
- return backend.method(:lookup).arity == 4 ? Hiera::Backend::Backend1xWrapper.new(backend) : backend
109
- rescue LoadError => e
110
- lookup_invocation.report_text { "Unable to load backend '#{backend_name}': #{e.message}" }
111
- throw :no_such_key
112
- rescue NameError => e
113
- lookup_invocation.report_text { "Unable to instantiate backend '#{backend_name}': #{e.message}" }
114
- throw :no_such_key
115
- end
116
- end
117
-
118
- # Converts a lookup 'merge' parameter argument into a Hiera 'resolution_type' argument.
119
- #
120
- # @param merge [String,Hash,nil] The lookup 'merge' argument
121
- # @return [Symbol,Hash,nil] The Hiera 'resolution_type'
122
- def convert_merge(merge)
123
- case merge
124
- when nil
125
- when 'first', 'default'
126
- # Nil is OK. Defaults to Hiera :priority
127
- nil
128
- when Puppet::Pops::MergeStrategy
129
- convert_merge(merge.configuration)
130
- when 'unique'
131
- # Equivalent to Hiera :array
132
- :array
133
- when 'hash'
134
- # Equivalent to Hiera :hash with default :native merge behavior. A Hash must be passed here
135
- # to override possible Hiera deep merge config settings.
136
- { :behavior => :native }
137
- when 'deep', 'unconstrained_deep'
138
- # Equivalent to Hiera :hash with :deeper merge behavior.
139
- { :behavior => :deeper }
140
- when 'reverse_deep'
141
- # Equivalent to Hiera :hash with :deep merge behavior.
142
- { :behavior => :deep }
143
- when Hash
144
- strategy = merge['strategy']
145
- case strategy
146
- when 'deep', 'unconstrained_deep', 'reverse_deep'
147
- result = { :behavior => strategy == 'reverse_deep' ? :deep : :deeper }
148
- # Remaining entries must have symbolic keys
149
- merge.each_pair { |k,v| result[k.to_sym] = v unless k == 'strategy' }
150
- result
151
- else
152
- convert_merge(strategy)
153
- end
154
- else
155
- raise Puppet::DataBinding::LookupError, "Unrecognized value for request 'merge' parameter: '#{merge}'"
156
- end
157
- end
158
- end
159
91
  end
160
92
  end
@@ -16,28 +16,51 @@ class ModuleDataProvider < ConfiguredDataProvider
16
16
  'Module'
17
17
  end
18
18
 
19
+ # Performs a lookup using a module default hierarchy with an endless recursion check.
20
+ #
21
+ # @param key [LookupKey] The key to lookup
22
+ # @param lookup_invocation [Invocation] The current lookup invocation
23
+ # @param merge [MergeStrategy,String,Hash{String=>Object},nil] Merge strategy or hash with strategy and options
24
+ #
25
+ def key_lookup_in_default(key, lookup_invocation, merge)
26
+ dps = config(lookup_invocation).configured_data_providers(lookup_invocation, self, true)
27
+ if dps.empty?
28
+ lookup_invocation.report_not_found(key)
29
+ throw :no_such_key
30
+ end
31
+ merge_strategy = MergeStrategy.strategy(merge)
32
+ lookup_invocation.check(key.to_s) do
33
+ lookup_invocation.with(:data_provider, self) do
34
+ merge_strategy.lookup(dps, lookup_invocation) do |data_provider|
35
+ data_provider.unchecked_key_lookup(key, lookup_invocation, merge_strategy)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
19
41
  # Asserts that all keys in the given _data_hash_ are prefixed with the configured _module_name_. Removes entries
20
42
  # that does not follow the convention and logs a warning.
21
43
  #
22
44
  # @param data_hash [Hash] The data hash
23
45
  # @return [Hash] The possibly pruned hash
24
- def validate_data_hash(data_provider, data_hash)
46
+ def validate_data_hash(data_hash)
25
47
  super
26
48
  module_prefix = "#{module_name}::"
27
49
  data_hash.each_key.reduce(data_hash) do |memo, k|
28
50
  next memo if k == LOOKUP_OPTIONS || k.start_with?(module_prefix)
29
- msg = 'must use keys qualified with the name of the module'
51
+ msg = "#{yield} must use keys qualified with the name of the module"
30
52
  memo = memo.clone if memo.equal?(data_hash)
31
53
  memo.delete(k)
32
- Puppet.warning("Module '#{module_name}': #{data_provider.name} #{msg}")
54
+ Puppet.warning("Module '#{module_name}': #{msg}")
33
55
  memo
34
56
  end
57
+ data_hash
35
58
  end
36
59
 
37
60
  protected
38
61
 
39
62
  def assert_config_version(config)
40
- raise Puppet::DataBinding::LookupError, "#{config.name} cannot be used in a module" unless config.version > 3
63
+ config.fail(Issues::HIERA_VERSION_3_NOT_GLOBAL, :where => 'module') unless config.version > 3
41
64
  config
42
65
  end
43
66
 
@@ -179,7 +179,7 @@ class Lexer2
179
179
  PATTERN_COMMENT = %r{#.*\r?}
180
180
  PATTERN_MLCOMMENT = %r{/\*(.*?)\*/}m
181
181
 
182
- PATTERN_REGEX = %r{/[^/\n]*/}
182
+ PATTERN_REGEX = %r{/[^/]*/}
183
183
  PATTERN_REGEX_END = %r{/}
184
184
  PATTERN_REGEX_A = %r{\A/} # for replacement to ""
185
185
  PATTERN_REGEX_Z = %r{/\Z} # for replacement to ""
@@ -41,6 +41,7 @@ module Pcore
41
41
 
42
42
  Resource.register_ptypes(loader, ir)
43
43
  Lookup::Context.register_ptype(loader, ir);
44
+ Lookup::DataProvider.register_types(loader)
44
45
  end
45
46
  end
46
47
 
@@ -81,11 +82,10 @@ module Pcore
81
82
  end
82
83
 
83
84
  def self.register_implementations(impls, name_authority = RUNTIME_NAME_AUTHORITY)
84
- Loaders.loaders.register_implementations(impls, name_authority = RUNTIME_NAME_AUTHORITY)
85
+ Loaders.loaders.register_implementations(impls, name_authority)
85
86
  end
86
87
 
87
- def self.register_aliases(aliases, name_authority = RUNTIME_NAME_AUTHORITY)
88
- loader = Loaders.loaders.private_environment_loader
88
+ def self.register_aliases(aliases, name_authority = RUNTIME_NAME_AUTHORITY, loader = Loaders.loaders.private_environment_loader)
89
89
  aliases.each do |name, type_string|
90
90
  add_type(Types::PTypeAliasType.new(name, Types::TypeFactory.type_reference(type_string), nil), loader, name_authority)
91
91
  end