puppet 4.9.3-universal-darwin → 4.9.4-universal-darwin

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.

@@ -122,6 +122,20 @@ class Invocation
122
122
  end
123
123
  end
124
124
 
125
+ def without_explain
126
+ if explainer.nil?
127
+ yield
128
+ else
129
+ save_explainer = @explainer
130
+ begin
131
+ @explainer = nil
132
+ yield
133
+ ensure
134
+ @explainer = save_explainer
135
+ end
136
+ end
137
+ end
138
+
125
139
  def only_explain_options?
126
140
  @explainer.nil? ? false : @explainer.only_explain_options?
127
141
  end
@@ -91,8 +91,9 @@ class V3BackendFunctionProvider < LookupKeyFunctionProvider
91
91
  @backend ||= instantiate_backend(lookup_invocation)
92
92
  config = parent_data_provider.config(lookup_invocation)
93
93
 
94
- # Never pass hiera.yaml defined merge_behavior down to the backend. It will pick it up from the config
95
- resolution_type = lookup_invocation.hiera_v3_merge_behavior? ? nil : convert_merge(merge)
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)
96
97
  @backend.lookup(key, lookup_invocation.scope, lookup_invocation.hiera_v3_location_overrides, resolution_type, context = {:recurse_guard => nil})
97
98
  end
98
99
 
@@ -138,13 +138,22 @@ class PAnyType < TypedModelObject
138
138
  end
139
139
  end
140
140
 
141
- # Returns `true` if this instance is a callable that accepts the given _args_
141
+ # Returns `true` if this instance is a callable that accepts the given _args_type_ type
142
142
  #
143
- # @param args [PAnyType] the arguments to test
143
+ # @param args_type [PAnyType] the arguments to test
144
144
  # @param guard [RecursionGuard] guard against recursion. Only used by internal calls
145
145
  # @return [Boolean] `true` if this instance is a callable that accepts the given _args_
146
- def callable?(args, guard = nil)
147
- args.is_a?(PAnyType) && kind_of_callable? && args.callable_args?(self, guard)
146
+ def callable?(args_type, guard = nil)
147
+ args_type.is_a?(PAnyType) && kind_of_callable? && args_type.callable_args?(self, guard)
148
+ end
149
+
150
+ # Returns `true` if this instance is a callable that accepts the given _args_
151
+ #
152
+ # @param args [Array] the arguments to test
153
+ # @param block [Proc] block, or nil if not called with a block
154
+ # @return [Boolean] `true` if this instance is a callable that accepts the given _args_
155
+ def callable_with?(args, block = nil)
156
+ false
148
157
  end
149
158
 
150
159
  # Returns `true` if this instance is considered valid as arguments to the given `callable`
@@ -438,8 +447,10 @@ class PType < PTypeWithContainedType
438
447
  def instance?(o, guard = nil)
439
448
  if o.is_a?(PAnyType)
440
449
  type.nil? || type.assignable?(o, guard)
450
+ elsif o.is_a?(Module) || o.is_a?(Puppet::Resource) || o.is_a?(Puppet::Parser::Resource)
451
+ @type.nil? ? true : assignable?(TypeCalculator.infer(o))
441
452
  else
442
- assignable?(TypeCalculator.infer(o), guard)
453
+ false
443
454
  end
444
455
  end
445
456
 
@@ -671,7 +682,13 @@ class PScalarType < PAnyType
671
682
  end
672
683
 
673
684
  def instance?(o, guard = nil)
674
- assignable?(TypeCalculator.infer(o), guard)
685
+ if o.is_a?(String) || o.is_a?(Numeric) || o.is_a?(TrueClass) || o.is_a?(FalseClass) || o.is_a?(Regexp) || o.is_a?(SemanticPuppet::VersionRange)
686
+ true
687
+ elsif o.is_a?(Array) || o.is_a?(Hash) || o.is_a?(PAnyType) || o.is_a?(NilClass)
688
+ false
689
+ else
690
+ assignable?(TypeCalculator.infer(o))
691
+ end
675
692
  end
676
693
 
677
694
  DEFAULT = PScalarType.new
@@ -732,6 +749,10 @@ class PEnumType < PScalarType
732
749
  self.class == o.class && @values == o.values
733
750
  end
734
751
 
752
+ def instance?(o, guard = nil)
753
+ o.is_a?(String) && @values.any? { |p| p == o }
754
+ end
755
+
735
756
  DEFAULT = PEnumType.new(EMPTY_ARRAY)
736
757
 
737
758
  protected
@@ -746,10 +767,9 @@ class PEnumType < PScalarType
746
767
  case o
747
768
  when PStringType
748
769
  # if the contained string is found in the set of enums
749
- v = o.value
750
- !v.nil? && svalues.any? { |e| e == v }
770
+ instance?(o.value, guard)
751
771
  when PEnumType
752
- !o.values.empty? && o.values.all? { |s| svalues.any? {|e| e == s }}
772
+ !o.values.empty? && o.values.all? { |s| instance?(s, guard) }
753
773
  else
754
774
  false
755
775
  end
@@ -1195,7 +1215,11 @@ class PCollectionType < PAnyType
1195
1215
  end
1196
1216
 
1197
1217
  def instance?(o, guard = nil)
1198
- assignable?(TypeCalculator.infer(o), guard)
1218
+ if o.is_a?(Array) || o.is_a?(Hash)
1219
+ @size_type.nil? || @size_type.instance?(o.size)
1220
+ else
1221
+ false
1222
+ end
1199
1223
  end
1200
1224
 
1201
1225
  # Returns an array with from (min) size to (max) size
@@ -1554,6 +1578,10 @@ class PRegexpType < PScalarType
1554
1578
  self.class == o.class && @pattern == o.pattern
1555
1579
  end
1556
1580
 
1581
+ def instance?(o, guard=nil)
1582
+ o.is_a?(Regexp) && (@pattern.nil? || @pattern == (o.options == 0 ? o.source : o.to_s))
1583
+ end
1584
+
1557
1585
  DEFAULT = PRegexpType.new(nil)
1558
1586
 
1559
1587
  protected
@@ -1594,6 +1622,10 @@ class PPatternType < PScalarType
1594
1622
  self.class == o.class && @patterns.size == o.patterns.size && (@patterns - o.patterns).empty?
1595
1623
  end
1596
1624
 
1625
+ def instance?(o, guard = nil)
1626
+ o.is_a?(String) && (@patterns.empty? || @patterns.any? { |p| p.regexp.match(o) })
1627
+ end
1628
+
1597
1629
  DEFAULT = PPatternType.new(EMPTY_ARRAY)
1598
1630
 
1599
1631
  protected
@@ -2007,14 +2039,15 @@ class PTupleType < PAnyType
2007
2039
 
2008
2040
  def instance?(o, guard = nil)
2009
2041
  return false unless o.is_a?(Array)
2010
- # compute the tuple's min/max size, and check if that size matches
2011
- size_t = size_type || PIntegerType.new(*size_range)
2012
-
2013
- return false unless size_t.instance?(o.size, guard)
2014
- o.each_with_index do |element, index|
2015
- return false unless (types[index] || types[-1]).instance?(element, guard)
2042
+ if @size_type
2043
+ return false unless @size_type.instance?(o.size, guard)
2044
+ else
2045
+ return false unless @types.empty? || @types.size == o.size
2046
+ end
2047
+ index = -1
2048
+ @types.empty? || o.all? do |element|
2049
+ @types.fetch(index += 1) { @types.last }.instance?(element, guard)
2016
2050
  end
2017
- true
2018
2051
  end
2019
2052
 
2020
2053
  def iterable?(guard = nil)
@@ -2174,7 +2207,22 @@ class PCallableType < PAnyType
2174
2207
  end
2175
2208
 
2176
2209
  def instance?(o, guard = nil)
2177
- assignable?(TypeCalculator.infer(o), guard)
2210
+ (o.is_a?(Proc) || o.is_a?(Evaluator::Closure) || o.is_a?(Functions::Function)) && assignable?(TypeCalculator.infer(o), guard)
2211
+ end
2212
+
2213
+ # Returns `true` if this instance is a callable that accepts the given _args_
2214
+ #
2215
+ # @param args [Array] the arguments to test
2216
+ # @return [Boolean] `true` if this instance is a callable that accepts the given _args_
2217
+ def callable_with?(args, block = nil)
2218
+ # nil param_types and compatible return type means other Callable is assignable
2219
+ return true if @param_types.nil?
2220
+ return false unless @param_types.instance?(args)
2221
+ if @block_type.nil?
2222
+ block == nil
2223
+ else
2224
+ @block_type.instance?(block)
2225
+ end
2178
2226
  end
2179
2227
 
2180
2228
  # @api private
@@ -2710,10 +2758,9 @@ class PVariantType < PAnyType
2710
2758
  end
2711
2759
 
2712
2760
  def really_instance?(o, guard = nil)
2713
- @types.inject(-1) do |memo, type|
2761
+ @types.reduce(-1) do |memo, type|
2714
2762
  ri = type.really_instance?(o, guard)
2715
- memo = ri if ri > memo
2716
- memo
2763
+ ri > memo ? ri : memo
2717
2764
  end
2718
2765
  end
2719
2766
 
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '4.9.3'
10
+ PUPPETVERSION = '4.9.4'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -35,7 +35,13 @@ describe 'when calling' do
35
35
  when 'datasources'
36
36
  Hiera::Backend.datasources(scope, order_override) { |source| source }
37
37
  when 'resolution_type'
38
- "resolution_type=\#{resolution_type}"
38
+ if resolution_type == :hash
39
+ { key => resolution_type.to_s }
40
+ elsif resolution_type == :array
41
+ [ key, resolution_type.to_s ]
42
+ else
43
+ "resolution_type=\#{resolution_type}"
44
+ end
39
45
  else
40
46
  throw :no_such_key
41
47
  end
@@ -349,7 +355,9 @@ describe 'when calling' do
349
355
  end
350
356
  end
351
357
 
352
- context 'with merge_behavior declared in hiera.yaml' do
358
+ context 'with custom backend and merge_behavior declared in hiera.yaml' do
359
+ let(:merge_behavior) { 'deeper' }
360
+
353
361
  let(:hiera_yaml) do
354
362
  <<-YAML.unindent
355
363
  ---
@@ -359,9 +367,11 @@ describe 'when calling' do
359
367
  :yaml:
360
368
  :datadir: #{global_dir}/hieradata
361
369
  :hierarchy:
362
- - other
363
370
  - common
364
- :merge_behavior: deeper
371
+ - other
372
+ :merge_behavior: #{merge_behavior}
373
+ :deep_merge_options:
374
+ :unpack_arrays: ','
365
375
  YAML
366
376
  end
367
377
 
@@ -370,20 +380,37 @@ describe 'when calling' do
370
380
  'hiera.yaml' => hiera_yaml,
371
381
  'hieradata' => {
372
382
  'common.yaml' => <<-YAML.unindent,
383
+ da:
384
+ - da 0
385
+ - da 1
373
386
  dm:
374
387
  dm1:
375
388
  dm11: value of dm11 (from common)
376
389
  dm12: value of dm12 (from common)
377
390
  dm2:
378
391
  dm21: value of dm21 (from common)
392
+ hash:
393
+ array:
394
+ - x1,x2
395
+ array:
396
+ - x1,x2
379
397
  YAML
380
398
  'other.yaml' => <<-YAML.unindent,
399
+ da:
400
+ - da 2,da 3
381
401
  dm:
382
402
  dm1:
383
403
  dm11: value of dm11 (from other)
384
404
  dm13: value of dm13 (from other)
385
405
  dm3:
386
406
  dm31: value of dm31 (from other)
407
+ hash:
408
+ array:
409
+ - x3
410
+ - x4
411
+ array:
412
+ - x3
413
+ - x4
387
414
  YAML
388
415
  },
389
416
  'ruby_stuff' => ruby_stuff_files
@@ -393,23 +420,65 @@ describe 'when calling' do
393
420
  context 'hiera_hash' do
394
421
  let(:the_func) { Puppet.lookup(:loaders).puppet_system_loader.load(:function, 'hiera_hash') }
395
422
 
396
- it 'the imposed hash strategy does not override declared merge_behavior' do
397
- expect(func('dm')).to eql({
398
- 'dm1' => {
399
- 'dm11' => 'value of dm11 (from other)',
400
- 'dm12' => 'value of dm12 (from common)',
401
- 'dm13' => 'value of dm13 (from other)'
402
- },
403
- 'dm2' => {
404
- 'dm21' => 'value of dm21 (from common)'
405
- },
406
- 'dm3' => {
407
- 'dm31' => 'value of dm31 (from other)'
408
- }
409
- })
423
+ context "using 'deeper'" do
424
+ it 'declared merge_behavior is honored' do
425
+ expect(func('dm')).to eql({
426
+ 'dm1' => {
427
+ 'dm11' => 'value of dm11 (from common)',
428
+ 'dm12' => 'value of dm12 (from common)',
429
+ 'dm13' => 'value of dm13 (from other)'
430
+ },
431
+ 'dm2' => {
432
+ 'dm21' => 'value of dm21 (from common)'
433
+ },
434
+ 'dm3' => {
435
+ 'dm31' => 'value of dm31 (from other)'
436
+ }
437
+ })
438
+ end
439
+
440
+ it "merge behavior is propagated to a custom backend as 'hash'" do
441
+ expect(func('resolution_type')).to eql({ 'resolution_type' => 'hash' })
442
+ end
443
+
444
+ it 'fails on attempts to merge an array' do
445
+ expect {func('da')}.to raise_error(/expects a Hash value/)
446
+ end
447
+
448
+ it 'honors option :unpack_arrays: (unsupported by puppet)' do
449
+ expect(func('hash')).to eql({'array' => %w(x3 x4 x1 x2)})
450
+ end
451
+ end
452
+
453
+ context "using 'deep'" do
454
+ let(:merge_behavior) { 'deep' }
455
+
456
+ it 'honors option :unpack_arrays: (unsupported by puppet)' do
457
+ expect(func('hash')).to eql({'array' => %w(x1 x2 x3 x4)})
458
+ end
459
+ end
460
+ end
461
+
462
+ context 'hiera_array' do
463
+ let(:the_func) { Puppet.lookup(:loaders).puppet_system_loader.load(:function, 'hiera_array') }
464
+
465
+ it 'declared merge_behavior is ignored' do
466
+ expect(func('da')).to eql(['da 0', 'da 1', 'da 2,da 3'])
467
+ end
468
+
469
+ it "merge behavior is propagated to a custom backend as 'array'" do
470
+ expect(func('resolution_type')).to eql(['resolution_type', 'array'])
471
+ end
472
+ end
473
+
474
+ context 'hiera' do
475
+ let(:the_func) { Puppet.lookup(:loaders).puppet_system_loader.load(:function, 'hiera') }
476
+
477
+ it 'declared merge_behavior is ignored' do
478
+ expect(func('da')).to eql(['da 0', 'da 1'])
410
479
  end
411
480
 
412
- it "the merge behavior is not propagated to a custom backend as 'resolution_type'" do
481
+ it "no merge behavior is propagated to a custom backend" do
413
482
  expect(func('resolution_type')).to eql('resolution_type=')
414
483
  end
415
484
  end
@@ -73,7 +73,9 @@ describe "The lookup function" do
73
73
  case key
74
74
  when 'hash_c'
75
75
  { 'hash_ca' => { 'cad' => 'value hash_c.hash_ca.cad (from global custom)' }}
76
- when 'h'
76
+ when 'hash'
77
+ { 'array' => [ 'x5,x6' ] }
78
+ when 'array'
77
79
  [ 'x5,x6' ]
78
80
  when 'datasources'
79
81
  Hiera::Backend.datasources(scope, order_override) { |source| source }
@@ -98,6 +100,7 @@ describe "The lookup function" do
98
100
  end
99
101
 
100
102
  let(:logs) { [] }
103
+ let(:scope_additions ) { {} }
101
104
  let(:notices) { logs.select { |log| log.level == :notice }.map { |log| log.message } }
102
105
  let(:warnings) { logs.select { |log| log.level == :warning }.map { |log| log.message } }
103
106
  let(:debugs) { logs.select { |log| log.level == :debug }.map { |log| log.message } }
@@ -154,7 +157,7 @@ describe "The lookup function" do
154
157
  if Hiera.const_defined?(:Config)
155
158
  Hiera::Config.send(:remove_instance_variable, :@config) if Hiera::Config.instance_variable_defined?(:@config)
156
159
  end
157
- if Hiera.const_defined?(:Backend)
160
+ if Hiera.const_defined?(:Backend) && Hiera::Backend.respond_to?(:clear!)
158
161
  Hiera::Backend.clear!
159
162
  end
160
163
  end
@@ -166,8 +169,7 @@ describe "The lookup function" do
166
169
  scope = compiler.topscope
167
170
  scope['environment'] = env_name
168
171
  scope['domain'] = 'example.com'
169
- scope['scope_scalar'] = 'scope scalar value'
170
- scope['scope_hash'] = { 'a' => 'scope hash a', 'b' => 'scope hash b' }
172
+ scope_additions.each_pair { |k, v| scope[k] = v }
171
173
  if explain
172
174
  begin
173
175
  invocation_with_explain.lookup('dummy', nil) do
@@ -301,7 +303,7 @@ describe "The lookup function" do
301
303
  hierarchy:
302
304
  - name: "Varying"
303
305
  data_hash: yaml_data
304
- path: "x%{::var.sub}.yaml"
306
+ path: "x%{var.sub}.yaml"
305
307
  YAML
306
308
  end
307
309
 
@@ -329,14 +331,28 @@ describe "The lookup function" do
329
331
  Puppet[:log_level] = 'debug'
330
332
  collect_notices("notice('success')") do |scope|
331
333
  expect(lookup_func.call(scope, 'y')).to eql('value y from x')
334
+ scope['var'] = { 'sub' => '_d' }
335
+ expect(lookup_func.call(scope, 'y')).to eql('value y from x_d')
336
+ nested_scope = scope.compiler.newscope(scope)
337
+ nested_scope['var'] = { 'sub' => '_e' }
338
+ expect(lookup_func.call(nested_scope, 'y')).to eql('value y from x_e')
339
+ end
340
+ expect(notices).to eql(['success'])
341
+ expect(debugs.any? { |m| m =~ /Hiera configuration recreated due to change of scope variables used in interpolation expressions/ }).to be_truthy
342
+ end
343
+
344
+ it 'does not include the lookups performed during stability check in explain output' do
345
+ Puppet[:log_level] = 'debug'
346
+ collect_notices("notice('success')") do |scope|
332
347
  var = { 'sub' => '_d' }
333
348
  scope['var'] = var
334
349
  expect(lookup_func.call(scope, 'y')).to eql('value y from x_d')
335
- var['sub'] = '_e'
336
- expect(lookup_func.call(scope, 'y')).to eql('value y from x_e')
350
+
351
+ # Second call triggers the check
352
+ expect(lookup_func.call(scope, 'y')).to eql('value y from x_d')
337
353
  end
338
354
  expect(notices).to eql(['success'])
339
- expect(debugs.any? { |m| m =~ /Hiera configuration recreated due to change of scope variables used in interpolation expressions/ }).to be_truthy
355
+ expect(debugs.any? { |m| m =~ /Sub key: "sub"/ }).to be_falsey
340
356
  end
341
357
  end
342
358
 
@@ -926,12 +942,12 @@ describe "The lookup function" do
926
942
  expect(explanation).to include('Found key: "a" value: "value a (from global)"')
927
943
  end
928
944
 
929
- it 'uses the merge behavior specified in global hiera.yaml to merge only global backends' do
945
+ it 'ignores merge behavior specified in global hiera.yaml' do
930
946
  expect(lookup('hash_b')).to eql(
931
- { 'hash_ba' => { 'bab' => 'value hash_b.hash_ba.bab (from global)', 'bac' => 'value hash_b.hash_ba.bac (from global json)' } })
947
+ { 'hash_ba' => { 'bab' => 'value hash_b.hash_ba.bab (from global)'} })
932
948
  end
933
949
 
934
- it 'uses the merge from lookup options to merge all layers and override merge_behavior specified in global hiera.yaml' do
950
+ it 'uses the merge from lookup options to merge all layers' do
935
951
  expect(lookup('hash_c')).to eql(
936
952
  { 'hash_ca' => { 'cab' => 'value hash_c.hash_ca.cab (from global)' } })
937
953
  end
@@ -1109,8 +1125,7 @@ describe "The lookup function" do
1109
1125
  end
1110
1126
  end
1111
1127
 
1112
- context 'using deep_merge_options supported by deep_merge gem but not supported by Puppet' do
1113
-
1128
+ context 'using deep_merge_options' do
1114
1129
  let(:hiera_yaml) do
1115
1130
  <<-YAML.unindent
1116
1131
  ---
@@ -1119,8 +1134,8 @@ describe "The lookup function" do
1119
1134
  :yaml:
1120
1135
  :datadir: #{code_dir}/hieradata
1121
1136
  :hierarchy:
1122
- - other
1123
1137
  - common
1138
+ - other
1124
1139
  :merge_behavior: deeper
1125
1140
  :deep_merge_options:
1126
1141
  :unpack_arrays: ','
@@ -1132,7 +1147,10 @@ describe "The lookup function" do
1132
1147
  'hiera.yaml' => hiera_yaml,
1133
1148
  'hieradata' => {
1134
1149
  'common.yaml' => <<-YAML.unindent,
1135
- h:
1150
+ hash:
1151
+ array:
1152
+ - x1,x2
1153
+ array:
1136
1154
  - x1,x2
1137
1155
  str: a string
1138
1156
  mixed:
@@ -1140,7 +1158,11 @@ describe "The lookup function" do
1140
1158
  y: hy
1141
1159
  YAML
1142
1160
  'other.yaml' => <<-YAML.unindent,
1143
- h:
1161
+ hash:
1162
+ array:
1163
+ - x3
1164
+ - x4
1165
+ array:
1144
1166
  - x3
1145
1167
  - x4
1146
1168
  str: another string
@@ -1152,49 +1174,20 @@ describe "The lookup function" do
1152
1174
  }
1153
1175
  end
1154
1176
 
1155
- it 'honors option :unpack_arrays: (unsupported by puppet)' do
1156
- expect(lookup('h')).to eql(%w(x1 x2 x3 x4))
1177
+ it 'ignores configured merge_behavior when looking up arrays' do
1178
+ expect(lookup('array')).to eql(['x1,x2'])
1157
1179
  end
1158
1180
 
1159
- it 'will treat merge of strings as a unique (first found)' do
1160
- expect(lookup('str')).to eql('another string')
1181
+ it 'ignores configured merge_behavior when merging arrays' do
1182
+ expect(lookup('array', 'merge' => 'unique')).to eql(['x1,x2', 'x3', 'x4'])
1161
1183
  end
1162
1184
 
1163
- it 'will treat merge of array and hash as a unique (first found)' do
1164
- expect(lookup('mixed')).to eql(%w(h1 h2))
1185
+ it 'ignores configured merge_behavior when looking up hashes' do
1186
+ expect(lookup('hash')).to eql({'array' => ['x1,x2']})
1165
1187
  end
1166
1188
 
1167
- context 'together with a custom backend' do
1168
- let(:hiera_yaml) do
1169
- <<-YAML.unindent
1170
- ---
1171
- :backends:
1172
- - custom
1173
- - yaml
1174
- :yaml:
1175
- :datadir: #{code_dir}/hieradata
1176
- :hierarchy:
1177
- - other
1178
- - common
1179
- :merge_behavior: #{merge_behavior}
1180
- :deep_merge_options:
1181
- :unpack_arrays: ','
1182
- YAML
1183
- end
1184
-
1185
- context "using 'deeper'" do
1186
- let(:merge_behavior) { 'deeper' }
1187
- it 'honors option :unpack_arrays: (unsupported by puppet)' do
1188
- expect(lookup('h')).to eql(%w(x1 x2 x3 x4 x5 x6))
1189
- end
1190
- end
1191
-
1192
- context "using 'deep'" do
1193
- let(:merge_behavior) { 'deep' }
1194
- it 'honors option :unpack_arrays: (unsupported by puppet)' do
1195
- expect(lookup('h')).to eql(%w(x5 x6 x3 x4 x1 x2))
1196
- end
1197
- end
1189
+ it 'ignores configured merge_behavior when merging hashes' do
1190
+ expect(lookup('hash', 'merge' => 'hash')).to eql({'array' => ['x1,x2']})
1198
1191
  end
1199
1192
  end
1200
1193
 
@@ -1241,12 +1234,13 @@ describe "The lookup function" do
1241
1234
  end
1242
1235
 
1243
1236
  context 'version 5' do
1237
+ let(:scope_additions) { { 'ipl_datadir' => 'hieradata' } }
1244
1238
  let(:hiera_yaml) do
1245
1239
  <<-YAML.unindent
1246
1240
  ---
1247
1241
  version: 5
1248
1242
  defaults:
1249
- datadir: hieradata
1243
+ datadir: "%{ipl_datadir}"
1250
1244
 
1251
1245
  hierarchy:
1252
1246
  - name: Yaml
@@ -1444,6 +1438,13 @@ describe "The lookup function" do
1444
1438
  end
1445
1439
 
1446
1440
  context 'using a data_hash that reads a yaml file' do
1441
+ let(:scope_additions) do
1442
+ {
1443
+ 'scope_scalar' => 'scope scalar value',
1444
+ 'scope_hash' => { 'a' => 'scope hash a', 'b' => 'scope hash b' }
1445
+ }
1446
+ end
1447
+
1447
1448
  let(:mod_a_files) do
1448
1449
  {
1449
1450
  'mod_a' => {
@@ -1963,6 +1964,7 @@ describe "The lookup function" do
1963
1964
  YAML
1964
1965
  end
1965
1966
 
1967
+ let(:scope_additions) { { 'ipl_suffix' => 'aa' } }
1966
1968
  let(:data_files) do
1967
1969
  {
1968
1970
  'common.eyaml' => <<-YAML.unindent
@@ -1978,7 +1980,7 @@ describe "The lookup function" do
1978
1980
  JHUngDDS5s52FsuSIMin7Z/pV+XuaJGFkL80ia4bXnCWilmtM8oUa/DZuBje
1979
1981
  dCILO7I8QqU=]
1980
1982
  hash_a:
1981
- hash_aa:
1983
+ "hash_%{ipl_suffix}":
1982
1984
  aaa: >
1983
1985
  ENC[PKCS7,MIIBqQYJKoZIhvcNAQcDoIIBmjCCAZYCAQAxggEhMIIBHQIBADAFMAACAQEw
1984
1986
  DQYJKoZIhvcNAQEBBQAEggEAhvGXL5RxVUs9wdqJvpCyXtfCHrm2HbG/u30L
@@ -2021,6 +2023,10 @@ describe "The lookup function" do
2021
2023
  expect(lookup('a')).to eql("Encrypted value 'a' (from environment)")
2022
2024
  end
2023
2025
 
2026
+ it 'evaluates interpolated keys' do
2027
+ expect(lookup('hash_a')).to include('hash_aa')
2028
+ end
2029
+
2024
2030
  it 'can read encrypted values inside a hash' do
2025
2031
  expect(lookup('hash_a.hash_aa.aaa')).to eql('Encrypted value hash_a.hash_aa.aaa (from environment)')
2026
2032
  end
@@ -2031,6 +2037,20 @@ describe "The lookup function" do
2031
2037
 
2032
2038
  context 'declared in global scope as a Hiera v3 backend' do
2033
2039
  let(:environment_files) { {} }
2040
+ let(:data_file_content) { <<-YAML.unindent }
2041
+ a: >
2042
+ ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEw
2043
+ DQYJKoZIhvcNAQEBBQAEggEAH457bsfL8kYw9O50roE3dcE21nCnmPnQ2XSX
2044
+ LYRJ2C78LarbfFonKz0gvDW7tyhsLWASFCFaiU8T1QPBd2b3hoQK8E4B2Ual
2045
+ xga/K7r9y3OSgRomTm9tpTltC6re0Ubh3Dy71H61obwxEdNVTqjPe95+m2b8
2046
+ 6zWZVnzZzXXsTG1S17yJn1zaB/LXHbWNy4KyLLKCGAml+Gfl6ZMjmaplTmUA
2047
+ QIC5rI8abzbPP3TDMmbLOGNkrmLqI+3uS8tSueTMoJmWaMF6c+H/cA7oRxmV
2048
+ QCeEUVXjyFvCHcmbA+keS/RK9XF+vc07/XS4XkYSPs/I5hLQji1y9bkkGAs0
2049
+ tehxQjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDHpA6Fcl/R16aIYcow
2050
+ oiO4gDAvfFH6jLUwXkcYtagnwdmhkd9TQJtxNWcIwMpvmk036MqIoGwwhQdg
2051
+ gV4beiCFtLU=]
2052
+ YAML
2053
+
2034
2054
  let(:hiera_yaml) do
2035
2055
  <<-YAML.unindent
2036
2056
  :backends: eyaml
@@ -2045,19 +2065,7 @@ describe "The lookup function" do
2045
2065
 
2046
2066
  let(:data_files) do
2047
2067
  {
2048
- 'common.eyaml' => <<-YAML.unindent
2049
- a: >
2050
- ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEw
2051
- DQYJKoZIhvcNAQEBBQAEggEAH457bsfL8kYw9O50roE3dcE21nCnmPnQ2XSX
2052
- LYRJ2C78LarbfFonKz0gvDW7tyhsLWASFCFaiU8T1QPBd2b3hoQK8E4B2Ual
2053
- xga/K7r9y3OSgRomTm9tpTltC6re0Ubh3Dy71H61obwxEdNVTqjPe95+m2b8
2054
- 6zWZVnzZzXXsTG1S17yJn1zaB/LXHbWNy4KyLLKCGAml+Gfl6ZMjmaplTmUA
2055
- QIC5rI8abzbPP3TDMmbLOGNkrmLqI+3uS8tSueTMoJmWaMF6c+H/cA7oRxmV
2056
- QCeEUVXjyFvCHcmbA+keS/RK9XF+vc07/XS4XkYSPs/I5hLQji1y9bkkGAs0
2057
- tehxQjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDHpA6Fcl/R16aIYcow
2058
- oiO4gDAvfFH6jLUwXkcYtagnwdmhkd9TQJtxNWcIwMpvmk036MqIoGwwhQdg
2059
- gV4beiCFtLU=]
2060
- YAML
2068
+ 'common.eyaml' => data_file_content
2061
2069
  }
2062
2070
  end
2063
2071
 
@@ -2079,6 +2087,56 @@ describe "The lookup function" do
2079
2087
  it 'delegates configured eyaml backend to eyaml_lookup_key function' do
2080
2088
  expect(explain('a')).to match(/Hierarchy entry "eyaml"\n.*\n.*\n.*"common"\n\s*Found key: "a"/m)
2081
2089
  end
2090
+
2091
+ context 'using intepolated paths to the key pair' do
2092
+ let(:scope_additions) { { 'priv_path' => private_key_path, 'pub_path' => public_key_path } }
2093
+
2094
+ let(:hiera_yaml) do
2095
+ <<-YAML.unindent
2096
+ :backends: eyaml
2097
+ :eyaml:
2098
+ :datadir: #{code_dir}/hieradata
2099
+ :pkcs7_private_key: "%{priv_path}"
2100
+ :pkcs7_public_key: "%{pub_path}"
2101
+ :hierarchy:
2102
+ - common
2103
+ YAML
2104
+ end
2105
+
2106
+ it 'finds data in the global layer' do
2107
+ expect(lookup('a')).to eql("Encrypted value 'a' (from global)")
2108
+ end
2109
+ end
2110
+
2111
+ context 'with special extension declared in options' do
2112
+ let(:environment_files) { {} }
2113
+ let(:hiera_yaml) do
2114
+ <<-YAML.unindent
2115
+ :backends: eyaml
2116
+ :eyaml:
2117
+ :extension: xyaml
2118
+ :datadir: #{code_dir}/hieradata
2119
+ :pkcs7_private_key: #{private_key_path}
2120
+ :pkcs7_public_key: #{public_key_path}
2121
+ :hierarchy:
2122
+ - common
2123
+ YAML
2124
+ end
2125
+
2126
+ let(:data_files) do
2127
+ {
2128
+ 'common.xyaml' => data_file_content
2129
+ }
2130
+ end
2131
+
2132
+ it 'finds data in the global layer' do
2133
+ expect(lookup('a')).to eql("Encrypted value 'a' (from global)")
2134
+ end
2135
+
2136
+ it 'delegates configured eyaml backend to eyaml_lookup_key function' do
2137
+ expect(explain('a')).to match(/Hierarchy entry "eyaml"\n.*\n.*\n.*"common"\n\s*Found key: "a"/m)
2138
+ end
2139
+ end
2082
2140
  end
2083
2141
  end
2084
2142
  end