puppet 4.9.1 → 4.9.2

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 (37) hide show
  1. data/Gemfile +1 -0
  2. data/lib/puppet/forge/repository.rb +1 -1
  3. data/lib/puppet/functions/assert_type.rb +3 -5
  4. data/lib/puppet/functions/yaml_data.rb +6 -1
  5. data/lib/puppet/pops/adapters.rb +10 -11
  6. data/lib/puppet/pops/evaluator/evaluator_impl.rb +2 -2
  7. data/lib/puppet/pops/evaluator/relationship_operator.rb +1 -1
  8. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
  9. data/lib/puppet/pops/loader/loader_paths.rb +4 -1
  10. data/lib/puppet/pops/loaders.rb +2 -0
  11. data/lib/puppet/pops/lookup/environment_data_provider.rb +10 -2
  12. data/lib/puppet/pops/lookup/hiera_config.rb +40 -8
  13. data/lib/puppet/pops/lookup/interpolation.rb +4 -2
  14. data/lib/puppet/pops/lookup/invocation.rb +2 -2
  15. data/lib/puppet/pops/lookup/lookup_adapter.rb +8 -2
  16. data/lib/puppet/pops/lookup/lookup_key_function_provider.rb +7 -3
  17. data/lib/puppet/pops/merge_strategy.rb +1 -1
  18. data/lib/puppet/pops/types/type_parser.rb +5 -11
  19. data/lib/puppet/ssl/certificate.rb +1 -1
  20. data/lib/puppet/ssl/certificate_request.rb +1 -1
  21. data/lib/puppet/version.rb +1 -1
  22. data/spec/lib/puppet_spec/language.rb +3 -1
  23. data/spec/unit/face/module/search_spec.rb +1 -1
  24. data/spec/unit/forge/repository_spec.rb +27 -0
  25. data/spec/unit/functions/lookup_spec.rb +396 -43
  26. data/spec/unit/network/http/factory_spec.rb +4 -0
  27. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +5 -0
  28. data/spec/unit/pops/evaluator/evaluator_rspec_helper.rb +28 -24
  29. data/spec/unit/pops/loaders/loaders_spec.rb +117 -22
  30. data/spec/unit/pops/types/ruby_generator_spec.rb +13 -13
  31. data/spec/unit/pops/types/type_calculator_spec.rb +13 -25
  32. data/spec/unit/pops/types/type_parser_spec.rb +1 -4
  33. data/spec/unit/resource/type_spec.rb +8 -2
  34. data/spec/unit/ssl/certificate_factory_spec.rb +2 -2
  35. data/spec/unit/ssl/certificate_request_spec.rb +2 -3
  36. data/spec/unit/util/http_proxy_spec.rb +4 -0
  37. metadata +2 -2
@@ -6,6 +6,11 @@ require 'puppet/forge/cache'
6
6
  require 'puppet/forge/errors'
7
7
 
8
8
  describe Puppet::Forge::Repository do
9
+ before(:all) do
10
+ # any local http proxy will break these tests
11
+ ENV['http_proxy'] = nil
12
+ ENV['HTTP_PROXY'] = nil
13
+ end
9
14
  let(:agent) { "Test/1.0" }
10
15
  let(:repository) { Puppet::Forge::Repository.new('http://fake.com', agent) }
11
16
  let(:ssl_repository) { Puppet::Forge::Repository.new('https://fake.com', agent) }
@@ -43,6 +48,28 @@ describe Puppet::Forge::Repository do
43
48
  expect(repository.make_http_request("the_path")).to eq(result)
44
49
  end
45
50
 
51
+ it "merges forge URI and path specified" do
52
+ result = "#{Object.new}"
53
+
54
+ performs_an_http_request result do |http|
55
+ http.expects(:request).with(responds_with(:path, "/test/the_path/"))
56
+ end
57
+
58
+ repository = Puppet::Forge::Repository.new('http://fake.com/test', agent)
59
+ expect(repository.make_http_request("/the_path/")).to eq(result)
60
+ end
61
+
62
+ it "handles trailing slashes when merging URI and path" do
63
+ result = "#{Object.new}"
64
+
65
+ performs_an_http_request result do |http|
66
+ http.expects(:request).with(responds_with(:path, "/test/the_path"))
67
+ end
68
+
69
+ repository = Puppet::Forge::Repository.new('http://fake.com/test/', agent)
70
+ expect(repository.make_http_request("/the_path")).to eq(result)
71
+ end
72
+
46
73
  it 'returns the result object from a request with ssl' do
47
74
  result = "#{Object.new}"
48
75
  performs_an_https_request result do |http|
@@ -13,6 +13,7 @@ describe "The lookup function" do
13
13
  let(:env_name) { 'spec' }
14
14
  let(:code_dir_files) { {} }
15
15
  let(:code_dir) { tmpdir('code') }
16
+ let(:ruby_dir) { tmpdir('ruby') }
16
17
  let(:environment_files) do
17
18
  {
18
19
  env_name => {
@@ -28,7 +29,9 @@ describe "The lookup function" do
28
29
  'data' => {
29
30
  'common.yaml' => <<-YAML.unindent
30
31
  ---
31
- a: value a
32
+ a: value a (from environment)
33
+ c:
34
+ c_b: value c_b (from environment)
32
35
  mod_a::a: value mod_a::a (from environment)
33
36
  mod_a::hash_a:
34
37
  a: value mod_a::hash_a.a (from environment)
@@ -51,6 +54,40 @@ describe "The lookup function" do
51
54
  }
52
55
  end
53
56
 
57
+ let(:ruby_dir_files) do
58
+ {
59
+ 'hiera' => {
60
+ 'backend' => {
61
+ 'custom_backend.rb' => <<-RUBY.unindent,
62
+ class Hiera::Backend::Custom_backend
63
+ def lookup(key, scope, order_override, resolution_type, context)
64
+ case key
65
+ when 'hash_c'
66
+ { 'hash_ca' => { 'cad' => 'value hash_c.hash_ca.cad (from global custom)' }}
67
+ when 'h'
68
+ [ 'x5,x6' ]
69
+ when 'datasources'
70
+ Hiera::Backend.datasources(scope, order_override) { |source| source }
71
+ else
72
+ throw :no_such_key
73
+ end
74
+ end
75
+ end
76
+ RUBY
77
+ 'other_backend.rb' => <<-RUBY.unindent,
78
+ class Hiera::Backend::Other_backend
79
+ def lookup(key, scope, order_override, resolution_type, context)
80
+ value = Hiera::Config[:other][key.to_sym]
81
+ throw :no_such_key if value.nil?
82
+ value
83
+ end
84
+ end
85
+ RUBY
86
+ }
87
+ }
88
+ }
89
+ end
90
+
54
91
  let(:logs) { [] }
55
92
  let(:notices) { logs.select { |log| log.level == :notice }.map { |log| log.message } }
56
93
  let(:warnings) { logs.select { |log| log.level == :warning }.map { |log| log.message } }
@@ -79,6 +116,11 @@ describe "The lookup function" do
79
116
  code_dir
80
117
  end
81
118
 
119
+ let(:populated_ruby_dir) do
120
+ dir_contained_in(ruby_dir, ruby_dir_files)
121
+ ruby_dir
122
+ end
123
+
82
124
  let(:env_dir) do
83
125
  d = File.join(populated_code_dir, 'environments')
84
126
  Dir.mkdir(d)
@@ -158,7 +200,7 @@ describe "The lookup function" do
158
200
  end
159
201
 
160
202
  it 'finds data in the environment' do
161
- expect(lookup('a')).to eql('value a')
203
+ expect(lookup('a')).to eql('value a (from environment)')
162
204
  end
163
205
 
164
206
  context 'that has no lookup configured' do
@@ -251,16 +293,19 @@ describe "The lookup function" do
251
293
  hierarchy:
252
294
  - name: "Varying"
253
295
  data_hash: yaml_data
254
- path: "x%{::var}.yaml"
296
+ path: "x%{::var.sub}.yaml"
255
297
  YAML
256
298
  'modules' => {},
257
299
  'data' => {
258
300
  'x.yaml' => <<-YAML.unindent,
259
301
  y: value y from x
260
302
  YAML
261
- 'x_d.yaml' => <<-YAML.unindent
303
+ 'x_d.yaml' => <<-YAML.unindent,
262
304
  y: value y from x_d
263
305
  YAML
306
+ 'x_e.yaml' => <<-YAML.unindent
307
+ y: value y from x_e
308
+ YAML
264
309
  }
265
310
  }
266
311
  }
@@ -270,8 +315,11 @@ describe "The lookup function" do
270
315
  Puppet[:log_level] = 'debug'
271
316
  collect_notices("notice('success')") do |scope|
272
317
  expect(lookup_func.call(scope, 'y')).to eql('value y from x')
273
- scope['var'] = '_d'
318
+ var = { 'sub' => '_d' }
319
+ scope['var'] = var
274
320
  expect(lookup_func.call(scope, 'y')).to eql('value y from x_d')
321
+ var['sub'] = '_e'
322
+ expect(lookup_func.call(scope, 'y')).to eql('value y from x_e')
275
323
  end
276
324
  expect(notices).to eql(['success'])
277
325
  expect(debugs.any? { |m| m =~ /Hiera configuration recreated due to change of scope variables used in interpolation expressions/ }).to be_truthy
@@ -319,6 +367,119 @@ describe "The lookup function" do
319
367
  end
320
368
  end
321
369
 
370
+ context 'with yaml data file' do
371
+ let(:environment_files) do
372
+ {
373
+ env_name => {
374
+ 'hiera.yaml' => <<-YAML.unindent,
375
+ ---
376
+ version: 5
377
+ YAML
378
+ 'data' => {
379
+ 'common.yaml' => common_yaml
380
+ }
381
+ }
382
+ }
383
+ end
384
+
385
+ context 'that contains hash values with interpolated keys' do
386
+ let(:common_yaml) do
387
+ <<-YAML.unindent
388
+ ---
389
+ a:
390
+ "%{key}": "the %{value}"
391
+ b: "Detail in %{lookup('a.a_key')}"
392
+ YAML
393
+ end
394
+
395
+ it 'interpolates both key and value"' do
396
+ Puppet[:log_level] = 'debug'
397
+ collect_notices("notice('success')") do |scope|
398
+ expect(lookup_func.call(scope, 'a')).to eql({'' => 'the '})
399
+ scope['key'] = 'a_key'
400
+ scope['value'] = 'interpolated value'
401
+ expect(lookup_func.call(scope, 'a')).to eql({'a_key' => 'the interpolated value'})
402
+ end
403
+ expect(notices).to eql(['success'])
404
+ end
405
+
406
+ it 'navigates to a value behind an interpolated key"' do
407
+ Puppet[:log_level] = 'debug'
408
+ collect_notices("notice('success')") do |scope|
409
+ scope['key'] = 'a_key'
410
+ scope['value'] = 'interpolated value'
411
+ expect(lookup_func.call(scope, 'a.a_key')).to eql('the interpolated value')
412
+ end
413
+ expect(notices).to eql(['success'])
414
+ end
415
+
416
+ it 'navigates to a value behind an interpolated key using an interpolated value"' do
417
+ Puppet[:log_level] = 'debug'
418
+ collect_notices("notice('success')") do |scope|
419
+ scope['key'] = 'a_key'
420
+ scope['value'] = 'interpolated value'
421
+ expect(lookup_func.call(scope, 'b')).to eql('Detail in the interpolated value')
422
+ end
423
+ expect(notices).to eql(['success'])
424
+ end
425
+ end
426
+
427
+ context 'that is empty' do
428
+ let(:common_yaml) { '' }
429
+
430
+ it 'fails with a "did not find"' do
431
+ expect { lookup('a') }.to raise_error do |e|
432
+ expect(e.message).to match(/did not find a value for the name 'a'/)
433
+ end
434
+ end
435
+
436
+ it 'logs a warning that the file does not contain a hash' do
437
+ expect { lookup('a') }.to raise_error(Puppet::DataBinding::LookupError)
438
+ expect(warnings).to include(/spec\/data\/common.yaml: file does not contain a valid yaml hash/)
439
+ end
440
+ end
441
+
442
+ context 'that contains illegal yaml' do
443
+ let(:common_yaml) { "@!#%**&:\n" }
444
+
445
+ it 'fails lookup and that the key is not found' do
446
+ expect { lookup('a') }.to raise_error do |e|
447
+ expect(e.message).to match(/Unable to parse/)
448
+ end
449
+ end
450
+ end
451
+
452
+ context 'that contains a legal yaml that is not a hash' do
453
+ let(:common_yaml) { "- A list\n- of things" }
454
+
455
+ it 'fails with a "did not find"' do
456
+ expect { lookup('a') }.to raise_error do |e|
457
+ expect(e.message).to match(/did not find a value for the name 'a'/)
458
+ end
459
+ end
460
+
461
+ it 'logs a warning that the file does not contain a hash' do
462
+ expect { lookup('a') }.to raise_error(Puppet::DataBinding::LookupError)
463
+ expect(warnings).to include(/spec\/data\/common.yaml: file does not contain a valid yaml hash/)
464
+ end
465
+ end
466
+
467
+ context 'that contains a legal yaml hash with illegal types' do
468
+ let(:common_yaml) do
469
+ <<-YAML.unindent
470
+ ---
471
+ a: !ruby/object:Puppet::Graph::Key
472
+ value: x
473
+ YAML
474
+ end
475
+
476
+ it 'fails lookup and reports a type mismatch' do
477
+ expect { lookup('a') }.to raise_error do |e|
478
+ expect(e.message).to match(/wrong type, expects a value of type Scalar, Sensitive, Type, Hash, or Array, got Runtime/)
479
+ end
480
+ end
481
+ end
482
+ end
322
483
 
323
484
  context 'with lookup_options configured using patterns' do
324
485
  let(:mod_common) {
@@ -508,13 +669,39 @@ describe "The lookup function" do
508
669
  'hiera.yaml' => <<-YAML.unindent,
509
670
  ---
510
671
  :backends: yaml
511
- YAML
672
+ :yaml:
673
+ :datadir: #{env_dir}/#{env_name}/hieradata
674
+ YAML
675
+ 'hieradata' => {
676
+ 'common.yaml' => <<-YAML.unindent,
677
+ g: Value g
678
+ YAML
679
+ }
512
680
  }
513
681
  }
514
682
  end
515
683
 
516
- it 'raises an error' do
517
- expect { lookup('a') }.to raise_error(Puppet::Error, /hiera configuration version 3 cannot be used in an environment/)
684
+ it 'will raise an error if --strict is set to error' do
685
+ Puppet[:strict] = :error
686
+ expect { lookup('g') }.to raise_error(Puppet::Error, /hiera configuration version 3 cannot be used in an environment/)
687
+ end
688
+
689
+ it 'will log a warning and ignore the file if --strict is set to warning' do
690
+ Puppet[:strict] = :warning
691
+ expect { lookup('g') }.to raise_error(Puppet::Error, /did not find a value for the name 'g'/)
692
+ end
693
+
694
+ it 'will not log a warning and ignore the file if --strict is set to off' do
695
+ Puppet[:strict] = :off
696
+ expect { lookup('g') }.to raise_error(Puppet::Error, /did not find a value for the name 'g'/)
697
+ expect(warnings).to include(/hiera.yaml version 3 found at the environment root was ignored/)
698
+ end
699
+
700
+ it 'will use the configuration if appointed by global setting but still warn when encountered by environment data provider' do
701
+ Puppet[:strict] = :warning
702
+ Puppet.settings[:hiera_config] = File.join(env_dir, env_name, 'hiera.yaml')
703
+ expect(lookup('g')).to eql('Value g')
704
+ expect(warnings).to include(/hiera.yaml version 3 found at the environment root was ignored/)
518
705
  end
519
706
  end
520
707
 
@@ -582,35 +769,6 @@ describe "The lookup function" do
582
769
  let(:code_dir_files) do
583
770
  {
584
771
  'hiera.yaml' => hiera_yaml,
585
- 'ruby_stuff' => {
586
- 'hiera' => {
587
- 'backend' => {
588
- 'custom_backend.rb' => <<-RUBY.unindent,
589
- class Hiera::Backend::Custom_backend
590
- def lookup(key, scope, order_override, resolution_type, context)
591
- case key
592
- when 'hash_c'
593
- { 'hash_ca' => { 'cad' => 'value hash_c.hash_ca.cad (from global custom)' }}
594
- when 'datasources'
595
- Hiera::Backend.datasources(scope, order_override) { |source| source }
596
- else
597
- throw :no_such_key
598
- end
599
- end
600
- end
601
- RUBY
602
- 'other_backend.rb' => <<-RUBY.unindent,
603
- class Hiera::Backend::Other_backend
604
- def lookup(key, scope, order_override, resolution_type, context)
605
- value = Hiera::Config[:other][key.to_sym]
606
- throw :no_such_key if value.nil?
607
- value
608
- end
609
- end
610
- RUBY
611
- }
612
- }
613
- },
614
772
  'hieradata' => {
615
773
  'common.yaml' => <<-YAML.unindent,
616
774
  a: value a (from global)
@@ -655,14 +813,16 @@ describe "The lookup function" do
655
813
  around(:each) do |example|
656
814
  # Faking the load path to enable 'require' to load from 'ruby_stuff'. It removes the need for a static fixture
657
815
  # for the custom backend
658
- $LOAD_PATH.unshift(File.join(code_dir, 'ruby_stuff'))
816
+ $LOAD_PATH.unshift(populated_ruby_dir)
659
817
  begin
660
818
  Puppet.override(:environments => environments, :current_environment => env) do
661
819
  example.run
662
820
  end
663
821
  ensure
664
- Hiera::Backend.send(:remove_const, :Custom_backend) if Hiera::Backend.const_defined?(:Custom_backend)
665
- Hiera::Backend.send(:remove_const, :Other_backend) if Hiera::Backend.const_defined?(:Other_backend)
822
+ if Kernel.const_defined?(:Hiera) && Hiera.const_defined?(:Backend)
823
+ Hiera::Backend.send(:remove_const, :Custom_backend) if Hiera::Backend.const_defined?(:Custom_backend)
824
+ Hiera::Backend.send(:remove_const, :Other_backend) if Hiera::Backend.const_defined?(:Other_backend)
825
+ end
666
826
  $LOAD_PATH.shift
667
827
  end
668
828
  end
@@ -720,6 +880,150 @@ describe "The lookup function" do
720
880
  expect(lookup('xs.subkey')).to eql('value xs.subkey (from global hocon)')
721
881
  end
722
882
 
883
+ context 'using an eyaml backend' do
884
+ let(:private_key_name) { 'private_key.pkcs7.pem' }
885
+ let(:public_key_name) { 'public_key.pkcs7.pem' }
886
+
887
+ let(:private_key) do
888
+ <<-PKCS7.unindent
889
+ -----BEGIN RSA PRIVATE KEY-----
890
+ MIIEogIBAAKCAQEAwHB3GvImq59em4LV9DMfP0Zjs21eW3Jd5I9fuY0jLJhIkH6f
891
+ CR7tyOpYV6xUj+TF8giq9WLxZI7sourMJMWjEWhVjgUr5lqp1RLv4lwfDv3Wk4XC
892
+ 2LUuqj1IAErUXKeRz8i3lUSZW1Pf4CaMpnIiPdWbz6f0KkaJSFi9bqexONBx4fKQ
893
+ NlgZwm2/aYjjrYng788I0QhWDKUqsQOi5mZKlHNRsDlk7J3Afhsx/jTLrCX/G8+2
894
+ tPtLsHyRN39kluM5vYHbKXDsCG/a88Z2yUE2+r4Clp0FUKffiEDBPm0/H0sQ4Q1o
895
+ EfQFDQRKaIkhpsm0nOnLYTy3/xJc5uqDNkLiawIDAQABAoIBAE98pNXOe8ab93oI
896
+ mtNZYmjCbGAqprTjEoFb71A3SfYbmK2Gf65GxjUdBwx/tBYTiuekSOk+yzKcDoZk
897
+ sZnmwKpqDByzaiSmAkxunANFxdZtZvpcX9UfUX0j/t+QCROUa5gF8j6HrUiZ5nkx
898
+ sxr1PcuItekaGLJ1nDLz5JsWTQ+H4M+GXQw7/t96x8v8g9el4exTiAHGk6Fv16kD
899
+ 017T02M9qTTmV3Ab/enDIBmKVD42Ta36K/wc4l1aoUQNiRbIGVh96Cgd1CFXLF3x
900
+ CsaNbYT4SmRXaYqoj6MKq+QFEGxadFmJy48NoSd4joirIn2lUjHxJebw3lLbNLDR
901
+ uvQnQ2ECgYEA/nD94wEMr6078uMv6nKxPpNGq7fihwSKf0G/PQDqrRmjUCewuW+k
902
+ /iXMe1Y/y0PjFeNlSbUsUvKQ5xF7F/1AnpuPHIrn3cjGVLb71W+zen1m8SnhsW/f
903
+ 7dPgtcb4SCvfhmLgoov+P34YcNfGi6qgPUu6319IqoB3BIi7PvfEomkCgYEAwZ4+
904
+ V0bMjFdDn2hnYzjTNcF2aUQ1jPvtuETizGwyCbbMLl9522lrjC2DrH41vvqX35ct
905
+ CBJkhQFbtHM8Gnmozv0vxhI2jP+u14mzfePZsaXuYrEgWRj+BCsYUHodXryxnEWj
906
+ yVrTNskab1B5jFm2SCJDmKcycBOYpRBLCMx6W7MCgYBA99z7/6KboOIzzKrJdGup
907
+ jLV410UyMIikoccQ7pD9jhRTPS80yjsY4dHqlEVJw5XSWvPb9DTTITi6p44EvBep
908
+ 6BKMuTMnQELUEr0O7KypVCfa4FTOl8BX28f+4kU3OGykxc6R8qkC0VGwTohV1UWB
909
+ ITsgGhZV4uOA9uDI3T8KMQKBgEnQY2HwmuDSD/TA39GDA3qV8+ez2lqSXRGIKZLX
910
+ mMf9SaBQQ+uzKA4799wWDbVuYeIbB07xfCL83pJP8FUDlqi6+7Celu9wNp7zX1ua
911
+ Nw8z/ErhzjxJe+Xo7A8aTwIkG+5A2m1UU/up9YsEeiJYvVaIwY58B42U2vfq20BS
912
+ fD9jAoGAX2MscBzIsmN+U9R0ptL4SXcPiVnOl8mqvQWr1B4OLgxX7ghht5Fs956W
913
+ bHipxOWMFCPJA/AhNB8q1DvYiD1viZbIALSCJVUkzs4AEFIjiPsCBKxerl7jF6Xp
914
+ 1WYSaCmfvoCVEpFNt8cKp4Gq+zEBYAV4Q6TkcD2lDtEW49MuN8A=
915
+ -----END RSA PRIVATE KEY-----
916
+ PKCS7
917
+ end
918
+
919
+ let(:public_key) do
920
+ <<-PKCS7.unindent
921
+ -----BEGIN CERTIFICATE-----
922
+ MIIC2TCCAcGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAAMCAXDTE3MDExMzA5MTY1
923
+ MloYDzIwNjcwMTAxMDkxNjUyWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
924
+ CgKCAQEAwHB3GvImq59em4LV9DMfP0Zjs21eW3Jd5I9fuY0jLJhIkH6fCR7tyOpY
925
+ V6xUj+TF8giq9WLxZI7sourMJMWjEWhVjgUr5lqp1RLv4lwfDv3Wk4XC2LUuqj1I
926
+ AErUXKeRz8i3lUSZW1Pf4CaMpnIiPdWbz6f0KkaJSFi9bqexONBx4fKQNlgZwm2/
927
+ aYjjrYng788I0QhWDKUqsQOi5mZKlHNRsDlk7J3Afhsx/jTLrCX/G8+2tPtLsHyR
928
+ N39kluM5vYHbKXDsCG/a88Z2yUE2+r4Clp0FUKffiEDBPm0/H0sQ4Q1oEfQFDQRK
929
+ aIkhpsm0nOnLYTy3/xJc5uqDNkLiawIDAQABo1wwWjAPBgNVHRMBAf8EBTADAQH/
930
+ MB0GA1UdDgQWBBSejWrVnw7QaBjNFCHMNFi+doSOcTAoBgNVHSMEITAfgBSejWrV
931
+ nw7QaBjNFCHMNFi+doSOcaEEpAIwAIIBATANBgkqhkiG9w0BAQUFAAOCAQEAAe85
932
+ BQ1ydAHFqo0ib38VRPOwf5xPHGbYGhvQi4/sU6aTuR7pxaOJPYz05jLhS+utEmy1
933
+ sknBq60G67yhQE7IHcfwrl1arirG2WmKGvAbjeYL2K1UiU0pVD3D+Klkv/pK6jIQ
934
+ eOJRGb3qNUn0Sq9EoYIOXiGXQ641F0bZZ0+5H92kT1lmnF5oLfCb84ImD9T3snH6
935
+ pIr5RKRx/0YmJIcv3WdpoPT903rOJiRIEgIj/hDk9QZTBpm222Ul5yQQ5pBywpSp
936
+ xh0bmJKAQWhQm7QlybKfyaQmg5ot1jEzWAvD2I5FjHQxmAlchjb6RreaRhExj+JE
937
+ 5O117dMBdzDBjcNMOA==
938
+ -----END CERTIFICATE-----
939
+ PKCS7
940
+ end
941
+
942
+ let(:keys_dir) do
943
+ keys = tmpdir('keys')
944
+ dir_contained_in(keys, {
945
+ private_key_name => private_key,
946
+ public_key_name => public_key
947
+ })
948
+ keys
949
+ end
950
+
951
+ let(:private_key_path) { File.join(keys_dir, private_key_name) }
952
+ let(:public_key_path) { File.join(keys_dir, public_key_name) }
953
+ let(:hiera_yaml) do
954
+ <<-YAML.unindent
955
+ :backends:
956
+ - eyaml
957
+ - yaml
958
+ :eyaml:
959
+ :datadir: #{code_dir}/hieradata
960
+ :pkcs7_private_key: #{private_key_path}
961
+ :pkcs7_public_key: #{public_key_path}
962
+ :yaml:
963
+ :datadir: #{code_dir}/hieradata
964
+ :hierarchy:
965
+ - common
966
+ YAML
967
+ end
968
+
969
+ let(:data_files) do
970
+ {
971
+ 'common.yaml' => <<-YAML.unindent,
972
+ b: value 'b' (from global)
973
+ c:
974
+ c_a: value c_a (from global)
975
+ YAML
976
+ 'common.eyaml' => <<-YAML.unindent
977
+ a: >
978
+ ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEw
979
+ DQYJKoZIhvcNAQEBBQAEggEAH457bsfL8kYw9O50roE3dcE21nCnmPnQ2XSX
980
+ LYRJ2C78LarbfFonKz0gvDW7tyhsLWASFCFaiU8T1QPBd2b3hoQK8E4B2Ual
981
+ xga/K7r9y3OSgRomTm9tpTltC6re0Ubh3Dy71H61obwxEdNVTqjPe95+m2b8
982
+ 6zWZVnzZzXXsTG1S17yJn1zaB/LXHbWNy4KyLLKCGAml+Gfl6ZMjmaplTmUA
983
+ QIC5rI8abzbPP3TDMmbLOGNkrmLqI+3uS8tSueTMoJmWaMF6c+H/cA7oRxmV
984
+ QCeEUVXjyFvCHcmbA+keS/RK9XF+vc07/XS4XkYSPs/I5hLQji1y9bkkGAs0
985
+ tehxQjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDHpA6Fcl/R16aIYcow
986
+ oiO4gDAvfFH6jLUwXkcYtagnwdmhkd9TQJtxNWcIwMpvmk036MqIoGwwhQdg
987
+ gV4beiCFtLU=]
988
+ a_ref: "A reference to %{hiera('a')}"
989
+ b_ref: "A reference to %{hiera('b')}"
990
+ c_ref: "%{alias('c')}"
991
+ YAML
992
+ }
993
+ end
994
+
995
+ let(:code_dir_files) do
996
+ {
997
+ 'hiera.yaml' => hiera_yaml,
998
+ 'hieradata' => data_files
999
+ }
1000
+ end
1001
+
1002
+ before(:each) do
1003
+ Puppet.settings[:hiera_config] = File.join(code_dir, 'hiera.yaml')
1004
+ end
1005
+
1006
+ it 'finds data in the global layer' do
1007
+ expect(lookup('a')).to eql("Encrypted value 'a' (from global)")
1008
+ end
1009
+
1010
+ it 'can use a hiera interpolation' do
1011
+ expect(lookup('a_ref')).to eql("A reference to Encrypted value 'a' (from global)")
1012
+ end
1013
+
1014
+ it 'can use a hiera interpolation that refers back to yaml' do
1015
+ expect(lookup('b_ref')).to eql("A reference to value 'b' (from global)")
1016
+ end
1017
+
1018
+ it 'can use a hiera interpolation that refers back to yaml, but only in global layer' do
1019
+ expect(lookup(['c', 'c_ref'], 'merge' => 'deep')).to eql([{'c_a' => 'value c_a (from global)', 'c_b' => 'value c_b (from environment)'}, { 'c_a' => 'value c_a (from global)' }])
1020
+ end
1021
+
1022
+ it 'delegates configured eyaml backend to eyaml_lookup_key function' do
1023
+ expect(explain('a')).to match(/Hierarchy entry "eyaml"\n.*\n.*\n.*"common"\n\s*Found key: "a"/m)
1024
+ end
1025
+ end
1026
+
723
1027
  context 'using deep_merge_options supported by deep_merge gem but not supported by Puppet' do
724
1028
 
725
1029
  let(:hiera_yaml) do
@@ -743,20 +1047,69 @@ describe "The lookup function" do
743
1047
  'hiera.yaml' => hiera_yaml,
744
1048
  'hieradata' => {
745
1049
  'common.yaml' => <<-YAML.unindent,
746
- a:
1050
+ h:
747
1051
  - x1,x2
1052
+ str: a string
1053
+ mixed:
1054
+ x: hx
1055
+ y: hy
748
1056
  YAML
749
1057
  'other.yaml' => <<-YAML.unindent,
750
- a:
1058
+ h:
751
1059
  - x3
752
1060
  - x4
1061
+ str: another string
1062
+ mixed:
1063
+ - h1
1064
+ - h2
753
1065
  YAML
754
1066
  }
755
1067
  }
756
1068
  end
757
1069
 
758
1070
  it 'honors option :unpack_arrays: (unsupported by puppet)' do
759
- expect(lookup('a')).to eql(%w(x1 x2 x3 x4))
1071
+ expect(lookup('h')).to eql(%w(x1 x2 x3 x4))
1072
+ end
1073
+
1074
+ it 'will treat merge of strings as a unique (first found)' do
1075
+ expect(lookup('str')).to eql('another string')
1076
+ end
1077
+
1078
+ it 'will treat merge of array and hash as a unique (first found)' do
1079
+ expect(lookup('mixed')).to eql(%w(h1 h2))
1080
+ end
1081
+
1082
+ context 'together with a custom backend' do
1083
+ let(:hiera_yaml) do
1084
+ <<-YAML.unindent
1085
+ ---
1086
+ :backends:
1087
+ - custom
1088
+ - yaml
1089
+ :yaml:
1090
+ :datadir: #{code_dir}/hieradata
1091
+ :hierarchy:
1092
+ - other
1093
+ - common
1094
+ :merge_behavior: #{merge_behavior}
1095
+ :deep_merge_options:
1096
+ :unpack_arrays: ','
1097
+ YAML
1098
+ end
1099
+
1100
+ context "using 'deeper'" do
1101
+ let(:merge_behavior) { 'deeper' }
1102
+ it 'honors option :unpack_arrays: (unsupported by puppet)' do
1103
+ expect(lookup('h')).to eql(%w(x1 x2 x3 x4 x5 x6))
1104
+ end
1105
+ end
1106
+
1107
+ context "using 'deep'" do
1108
+ let(:merge_behavior) { 'deep' }
1109
+ it 'honors option :unpack_arrays: (unsupported by puppet)' do
1110
+ expect(lookup('h')).to eql(%w(x5 x6 x3 x4 x1 x2))
1111
+ end
1112
+ end
760
1113
  end
761
1114
  end
762
1115