puppet 6.0.0 → 6.0.1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -4
  3. data/lib/puppet/application/apply.rb +99 -59
  4. data/lib/puppet/application/cert.rb +2 -112
  5. data/lib/puppet/configurer.rb +2 -3
  6. data/lib/puppet/defaults.rb +14 -1
  7. data/lib/puppet/etc.rb +20 -0
  8. data/lib/puppet/module/task.rb +29 -38
  9. data/lib/puppet/parser/catalog_compiler.rb +24 -0
  10. data/lib/puppet/parser/compiler.rb +3 -1
  11. data/lib/puppet/pops/evaluator/deferred_resolver.rb +3 -0
  12. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  13. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +18 -10
  14. data/lib/puppet/pops/loader/task_instantiator.rb +13 -70
  15. data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
  16. data/lib/puppet/pops/parser/lexer2.rb +1 -1
  17. data/lib/puppet/pops/pcore.rb +10 -33
  18. data/lib/puppet/pops/serialization.rb +1 -0
  19. data/lib/puppet/pops/serialization/to_data_converter.rb +9 -1
  20. data/lib/puppet/provider/exec.rb +57 -57
  21. data/lib/puppet/provider/group/aix.rb +1 -15
  22. data/lib/puppet/provider/group/pw.rb +4 -8
  23. data/lib/puppet/provider/group/windows_adsi.rb +7 -4
  24. data/lib/puppet/provider/nameservice.rb +1 -25
  25. data/lib/puppet/provider/nameservice/directoryservice.rb +5 -3
  26. data/lib/puppet/provider/package/portage.rb +2 -2
  27. data/lib/puppet/provider/service/launchd.rb +19 -3
  28. data/lib/puppet/provider/user/aix.rb +48 -2
  29. data/lib/puppet/type/group.rb +62 -18
  30. data/lib/puppet/type/schedule.rb +7 -0
  31. data/lib/puppet/util/execution.rb +14 -1
  32. data/lib/puppet/util/posix.rb +15 -0
  33. data/lib/puppet/util/storage.rb +12 -0
  34. data/lib/puppet/util/windows/adsi.rb +60 -1
  35. data/lib/puppet/util/windows/process.rb +16 -1
  36. data/lib/puppet/util/windows/service.rb +68 -26
  37. data/lib/puppet/version.rb +1 -1
  38. data/lib/puppet_pal.rb +36 -3
  39. data/locales/ja/puppet.po +598 -861
  40. data/locales/puppet.pot +197 -160
  41. data/man/man5/puppet.conf.5 +12 -1
  42. data/man/man8/puppet.8 +1 -1
  43. data/spec/integration/application/apply_spec.rb +4 -1
  44. data/spec/integration/util/windows/adsi_spec.rb +2 -1
  45. data/spec/unit/application/apply_spec.rb +14 -0
  46. data/spec/unit/configurer_spec.rb +11 -0
  47. data/spec/unit/etc_spec.rb +25 -0
  48. data/spec/unit/indirector/catalog/json_spec.rb +9 -3
  49. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +22 -4
  50. data/spec/unit/pops/loaders/loader_spec.rb +3 -10
  51. data/spec/unit/pops/loaders/loaders_spec.rb +30 -0
  52. data/spec/unit/pops/loaders/module_loaders_spec.rb +7 -7
  53. data/spec/unit/pops/parser/parse_heredoc_spec.rb +16 -0
  54. data/spec/unit/pops/serialization/to_from_hr_spec.rb +9 -0
  55. data/spec/unit/pops/types/task_spec.rb +42 -116
  56. data/spec/unit/provider/group/aix_spec.rb +0 -19
  57. data/spec/unit/provider/group/pw_spec.rb +0 -6
  58. data/spec/unit/provider/group/windows_adsi_spec.rb +34 -35
  59. data/spec/unit/provider/nameservice/directoryservice_spec.rb +2 -2
  60. data/spec/unit/provider/service/launchd_spec.rb +19 -0
  61. data/spec/unit/provider/user/aix_spec.rb +43 -2
  62. data/spec/unit/provider/user/windows_adsi_spec.rb +1 -4
  63. data/spec/unit/puppet_pal_2pec.rb +6 -6
  64. data/spec/unit/puppet_pal_catalog_spec.rb +58 -0
  65. data/spec/unit/task_spec.rb +50 -5
  66. data/spec/unit/type/group_spec.rb +111 -13
  67. data/spec/unit/util/execution_spec.rb +59 -0
  68. data/spec/unit/util/posix_spec.rb +28 -0
  69. data/spec/unit/util/storage_spec.rb +107 -0
  70. data/spec/unit/util/windows/adsi_spec.rb +100 -5
  71. data/spec/unit/util/windows/service_spec.rb +100 -43
  72. metadata +2 -2
@@ -891,7 +891,7 @@ The time to wait for data to be read from an HTTP connection\. If nothing is rea
891
891
  The HTTP User\-Agent string to send when making network requests\.
892
892
  .
893
893
  .IP "\(bu" 4
894
- \fIDefault\fR: Puppet/6\.0\.0 Ruby/2\.4\.1\-p111 (x86_64\-linux)
894
+ \fIDefault\fR: Puppet/6\.0\.1 Ruby/2\.4\.1\-p111 (x86_64\-linux)
895
895
  .
896
896
  .IP "" 0
897
897
  .
@@ -1683,6 +1683,17 @@ Where puppet agent and puppet master store state associated with the running con
1683
1683
  .
1684
1684
  .IP "" 0
1685
1685
  .
1686
+ .SS "statettl"
1687
+ How long the Puppet agent should cache when a resource was last checked or synced\. This setting can be a time interval in seconds (30 or 30s), minutes (30m), hours (6h), days (2d), or years (5y)\. A value of \fB0\fR or \fBunlimited\fR will disable cache pruning\.
1688
+ .
1689
+ .P
1690
+ This setting affects the usage of \fBschedule\fR resources, as the information about when a resource was last checked (and therefore when it needs to be checked again) is stored in the \fBstatefile\fR\. The \fBstatettl\fR needs to be large enough to ensure that a resource will not trigger multiple times during a schedule due to its entry expiring from the cache\.
1691
+ .
1692
+ .IP "\(bu" 4
1693
+ \fIDefault\fR: 32d
1694
+ .
1695
+ .IP "" 0
1696
+ .
1686
1697
  .SS "static_catalogs"
1687
1698
  Whether to compile a static catalog \fIhttps://puppet\.com/docs/puppet/latest/static_catalogs\.html#enabling\-or\-disabling\-static\-catalogs\fR, which occurs only on a Puppet Server master when the \fBcode\-id\-command\fR and \fBcode\-content\-command\fR settings are configured in its \fBpuppetserver\.conf\fR file\.
1688
1699
  .
@@ -25,4 +25,4 @@ Specialized:
25
25
  catalog Compile, save, view, and convert catalogs\. describe Display help about resource types device Manage remote network devices doc Generate Puppet references epp Interact directly with the EPP template parser/renderer\. facts Retrieve and store facts\. filebucket Store and retrieve files in a filebucket generate Generates Puppet code from Ruby definitions\. node View and manage node definitions\. parser Interact directly with the parser\. script Run a puppet manifests as a script without compiling a catalog ssl Manage SSL keys and certificates for puppet SSL clients
26
26
  .
27
27
  .P
28
- See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v6\.0\.0
28
+ See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v6\.0\.1
@@ -518,7 +518,10 @@ class amod::bad_type {
518
518
  apply.options[:catalog] = file_containing('manifest', serialized_catalog)
519
519
  apply.expects(:apply_catalog).with do |cat|
520
520
  expect(cat.resource(:notify, 'rx')['message']).to be_a(Regexp)
521
- expect(cat.resource(:notify, 'bin')['message']).to be_a(Puppet::Pops::Types::PBinaryType::Binary)
521
+ # The resource return in this expect is a String, but since it was a Binary type that
522
+ # was converted with `resolve_and_replace`, we want to make sure that the encoding
523
+ # of that string is the expected ASCII-8BIT.
524
+ expect(cat.resource(:notify, 'bin')['message'].encoding.inspect).to include('ASCII-8BIT')
522
525
  expect(cat.resource(:notify, 'ver')['message']).to be_a(SemanticPuppet::Version)
523
526
  expect(cat.resource(:notify, 'vrange')['message']).to be_a(SemanticPuppet::VersionRange)
524
527
  expect(cat.resource(:notify, 'tspan')['message']).to be_a(Puppet::Pops::Time::Timespan)
@@ -118,7 +118,8 @@ describe Puppet::Util::Windows::ADSI::Group,
118
118
  # create a test group and add above 5 members by SID
119
119
  group = described_class.create(temp_groupname)
120
120
  group.commit()
121
- group.set_members(users.map { |u| u[:sid]} )
121
+ members = users.map { |u| u[:sid] }
122
+ group.set_members(members.join(','))
122
123
 
123
124
  # most importantly make sure that all name are convertible to SIDs
124
125
  expect { described_class.name_sid_hash(group.members) }.to_not raise_error
@@ -279,6 +279,11 @@ describe Puppet::Application::Apply do
279
279
  expect { @apply.main }.to exit_with 0
280
280
  end
281
281
 
282
+ it 'should called the DeferredResolver to resolve any Deferred values' do
283
+ Puppet::Pops::Evaluator::DeferredResolver.expects(:resolve_and_replace).with(any_parameters)
284
+ expect { @apply.main }.to exit_with 0
285
+ end
286
+
282
287
  it 'should make the Puppet::Pops::Loaders available when applying the compiled catalog' do
283
288
  Puppet::Resource::Catalog.indirection.expects(:find).returns(@catalog)
284
289
  @apply.expects(:apply_catalog).with(@catalog) do
@@ -475,6 +480,15 @@ describe Puppet::Application::Apply do
475
480
  end
476
481
  expect { @apply.apply }.not_to raise_error
477
482
  end
483
+
484
+ it "should call the DeferredResolver to resolve Deferred values" do
485
+ @apply.options[:catalog] = temporary_catalog
486
+ Puppet::Resource::Catalog.stubs(:default_format).returns :rot13_piglatin
487
+ catalog = Puppet::Resource::Catalog.new("testing", Puppet::Node::Environment::NONE)
488
+ Puppet::Resource::Catalog.stubs(:convert_from).with(:rot13_piglatin,'"something"').returns(catalog)
489
+ Puppet::Pops::Evaluator::DeferredResolver.expects(:resolve_and_replace).with(any_parameters)
490
+ @apply.apply
491
+ end
478
492
  end
479
493
  end
480
494
 
@@ -1019,6 +1019,17 @@ describe Puppet::Configurer do
1019
1019
  expect(options[:report].master_used).to eq('myserver:123')
1020
1020
  end
1021
1021
 
1022
+ it "queries the simple status for the 'master' service" do
1023
+ Puppet.settings[:server_list] = ["myserver:123"]
1024
+ response = Net::HTTPOK.new(nil, 200, 'OK')
1025
+ http = mock('request')
1026
+ http.expects(:get).with('/status/v1/simple/master').returns(response)
1027
+ Puppet::Network::HttpPool.stubs(:http_ssl_instance).with('myserver', '123').returns(http)
1028
+ @agent.stubs(:run_internal)
1029
+
1030
+ @agent.run
1031
+ end
1032
+
1022
1033
  it "should report when a server is unavailable" do
1023
1034
  Puppet.settings[:server_list] = ["myserver:123"]
1024
1035
  response = Net::HTTPInternalServerError.new(nil, 500, 'Internal Server Error')
@@ -412,6 +412,31 @@ describe Puppet::Etc, :if => !Puppet::Util::Platform.windows? do
412
412
  end
413
413
  end
414
414
 
415
+ describe :group do
416
+ it 'should return the next group struct if a block is not provided' do
417
+ Puppet::Etc.expects(:getgrent).returns(ascii_group_struct)
418
+
419
+ expect(Puppet::Etc.group).to eql(ascii_group_struct)
420
+ end
421
+
422
+ it 'should iterate over the available groups if a block is provided' do
423
+ expected_groups = [
424
+ utf_8_group_struct,
425
+ euc_kr_group_struct,
426
+ ascii_group_struct
427
+ ]
428
+ Puppet::Etc.stubs(:getgrent).returns(*(expected_groups + [nil]))
429
+
430
+ Puppet::Etc.expects(:setgrent)
431
+ Puppet::Etc.expects(:endgrent)
432
+
433
+ actual_groups = []
434
+ Puppet::Etc.group { |group| actual_groups << group }
435
+
436
+ expect(actual_groups).to eql(expected_groups)
437
+ end
438
+ end
439
+
415
440
  describe "endgrent" do
416
441
  it "should call Etc.getgrent" do
417
442
  Etc.expects(:getgrent)
@@ -17,8 +17,9 @@ describe Puppet::Resource::Catalog::Json do
17
17
  let(:binary) { "\xC0\xFF".force_encoding(Encoding::BINARY) }
18
18
  let(:key) { 'foo' }
19
19
  let(:file) { subject.path(key) }
20
+ let(:env) { Puppet::Node::Environment.create(:testing, []) }
20
21
  let(:catalog) do
21
- catalog = Puppet::Resource::Catalog.new(key, Puppet::Node::Environment.create(:testing, []))
22
+ catalog = Puppet::Resource::Catalog.new(key, env)
22
23
  catalog.add_resource(Puppet::Resource.new(:file, '/tmp/a_file', :parameters => { :content => binary }))
23
24
  catalog
24
25
  end
@@ -27,6 +28,11 @@ describe Puppet::Resource::Catalog::Json do
27
28
  Puppet.run_mode.stubs(:master?).returns(true)
28
29
  Puppet[:server_datadir] = tmpdir('jsondir')
29
30
  FileUtils.mkdir_p(File.join(Puppet[:server_datadir], 'indirector_testing'))
31
+ Puppet.push_context(:loaders => Puppet::Pops::Loaders.new(env))
32
+ end
33
+
34
+ after :each do
35
+ Puppet.pop_context()
30
36
  end
31
37
 
32
38
  it 'saves a catalog containing binary content' do
@@ -43,7 +49,7 @@ describe Puppet::Resource::Catalog::Json do
43
49
  parsed_catalog = subject.find(request)
44
50
 
45
51
  content = parsed_catalog.resource(:file, '/tmp/a_file')[:content]
46
- expect(content.bytes.to_a).to eq(binary.bytes.to_a)
52
+ expect(content.binary_buffer.bytes.to_a).to eq(binary.bytes.to_a)
47
53
  end
48
54
 
49
55
  it 'searches for catalogs contains binary content' do
@@ -55,7 +61,7 @@ describe Puppet::Resource::Catalog::Json do
55
61
 
56
62
  expect(parsed_catalogs.size).to eq(1)
57
63
  content = parsed_catalogs.first.resource(:file, '/tmp/a_file')[:content]
58
- expect(content.bytes.to_a).to eq(binary.bytes.to_a)
64
+ expect(content.binary_buffer.bytes.to_a).to eq(binary.bytes.to_a)
59
65
  end
60
66
  end
61
67
  end
@@ -30,22 +30,40 @@ describe 'when converting to 3.x' do
30
30
  expect(converter.convert(v, {}, nil)).to equal(v)
31
31
  end
32
32
 
33
- it 'converts the symbol :undef to the undef value' do
33
+ it 'converts top level symbol :undef to the given undef value' do
34
34
  expect(converter.convert(:undef, {}, 'undef value')).to eql('undef value')
35
35
  end
36
36
 
37
- it 'converts the nil to the undef value' do
37
+ it 'converts top level nil value to the given undef value' do
38
38
  expect(converter.convert(nil, {}, 'undef value')).to eql('undef value')
39
39
  end
40
40
 
41
- it 'convert a symbol nested in an array' do
42
- expect(converter.convert({'foo' => :undef}, {}, 'undef value')).to eql({'foo' => 'undef value'})
41
+ it 'converts nested :undef in a hash to nil' do
42
+ expect(converter.convert({'foo' => :undef}, {}, 'undef value')).to eql({'foo' => nil})
43
+ end
44
+
45
+ it 'converts nested :undef in an array to nil' do
46
+ expect(converter.convert(['boo', :undef], {}, 'undef value')).to eql(['boo', nil])
47
+ end
48
+
49
+ it 'converts deeply nested :undef in to nil' do
50
+ expect(converter.convert({'foo' => [[:undef]], 'bar' => { 'x' => :undef }}, {}, 'undef value')).to eql({'foo' => [[nil]], 'bar' => { 'x' => nil}})
43
51
  end
44
52
 
45
53
  it 'does not converts nil to given undef value when nested in an array' do
46
54
  expect(converter.convert({'foo' => nil}, {}, 'undef value')).to eql({'foo' => nil})
47
55
  end
48
56
 
57
+ it 'does not convert top level symbols' do
58
+ expect(converter.convert(:default, {}, 'undef value')).to eql(:default)
59
+ expect(converter.convert(:whatever, {}, 'undef value')).to eql(:whatever)
60
+ end
61
+
62
+ it 'does not convert nested symbols' do
63
+ expect(converter.convert([:default], {}, 'undef value')).to eql([:default])
64
+ expect(converter.convert([:whatever], {}, 'undef value')).to eql([:whatever])
65
+ end
66
+
49
67
  it 'does not convert a Regex instance to string' do
50
68
  v = /^[A-Z]$/
51
69
  expect(converter.convert(v, {}, nil)).to equal(v)
@@ -329,13 +329,6 @@ describe 'The Loader' do
329
329
  'bad_syntax.json' => <<-TXT.unindent,
330
330
  text => This is not a task because JSON is unparsable
331
331
  TXT
332
- 'bad_content.sh' => '',
333
- 'bad_content.json' => <<-JSON.unindent,
334
- {
335
- "description": "This is not a task because parameters is misspelled",
336
- "paramters": { "string_param": { "type": "String[1]" } }
337
- }
338
- JSON
339
332
  'missing_adjacent.json' => <<-JSON.unindent,
340
333
  {
341
334
  "description": "This is not a task because there is no adjacent file with the same base name",
@@ -415,7 +408,7 @@ describe 'The Loader' do
415
408
  contain_exactly(tn(:task, 'c::foo')))
416
409
  end
417
410
  expect(logs.select { |log| log.level == :warning }.map { |log| log.message }).to(
418
- contain_exactly(/unexpected token/, /unrecognized key/, /No source besides task metadata was found/)
411
+ contain_exactly(/unexpected token/, /No source besides task metadata was found/)
419
412
  )
420
413
  end
421
414
 
@@ -427,11 +420,11 @@ describe 'The Loader' do
427
420
  contain_exactly(tn(:task, 'c::foo')))
428
421
  end
429
422
  expect(logs.select { |log| log.level == :warning }.map { |log| log.message }).to be_empty
430
- expect(error_collector.size).to eql(3)
423
+ expect(error_collector.size).to eql(2)
431
424
  expect(error_collector.all? { |e| e.is_a?(Puppet::DataTypes::Error) })
432
425
  expect(error_collector.all? { |e| e.issue_code == Puppet::Pops::Issues::LOADER_FAILURE.issue_code })
433
426
  expect(error_collector.map { |e| e.details['original_error'] }).to(
434
- contain_exactly(/unexpected token/, /unrecognized key/, /No source besides task metadata was found/)
427
+ contain_exactly(/unexpected token/, /No source besides task metadata was found/)
435
428
  )
436
429
  end
437
430
 
@@ -420,6 +420,36 @@ describe 'loaders' do
420
420
  function = loader.load_typed(typed_name(:function, 'user::caller_ws')).value
421
421
  expect(function.call(scope, 'passed in scope')).to eql("usee::callee_ws() got 'passed in scope'")
422
422
  end
423
+
424
+ end
425
+
426
+ context 'when causing a 3x load followed by a 4x load' do
427
+ let(:env) { environment_for(mix_4x_and_3x_functions) }
428
+ let(:compiler) { Puppet::Parser::Compiler.new(Puppet::Node.new("test", :environment => env)) }
429
+ let(:scope) { compiler.topscope }
430
+ let(:loader) { compiler.loaders.private_loader_for_module('user') }
431
+
432
+
433
+ before(:each) do
434
+ Puppet.push_context(:current_environment => scope.environment, :global_scope => scope, :loaders => compiler.loaders)
435
+ end
436
+ after(:each) do
437
+ Puppet.pop_context
438
+ end
439
+
440
+ it 'a 3x function is loaded once' do
441
+ # create a 3x function that when called will do a load of "callee_ws"
442
+ Puppet::Parser::Functions::newfunction(:callee, :type => :rvalue, :arity => 1) do |args|
443
+ function_callee_ws(['passed in scope'])
444
+ end
445
+ Puppet.expects(:warning).with(any_parameters).never
446
+ scope['passed_in_scope'] = 'value'
447
+ function = loader.load_typed(typed_name(:function, 'callee')).value
448
+ expect(function.call(scope, 'passed in scope')).to eql("usee::callee_ws() got 'value'")
449
+
450
+ function = loader.load_typed(typed_name(:function, 'callee_ws')).value
451
+ expect(function.call(scope, 'passed in scope')).to eql("usee::callee_ws() got 'value'")
452
+ end
423
453
  end
424
454
 
425
455
  context 'loading' do
@@ -104,8 +104,8 @@ describe 'FileBased module loader' do
104
104
 
105
105
  task = module_loader.load_typed(typed_name(:task, 'testmodule::foo')).value
106
106
  expect(task.name).to eq('testmodule::foo')
107
- expect(task.implementations.length).to eq(1)
108
- expect(task.implementations[0]['name']).to eq('foo.py')
107
+ expect(task.files.length).to eq(1)
108
+ expect(task.files[0]['name']).to eq('foo.py')
109
109
  end
110
110
 
111
111
  it 'can load tasks with multiple implementations' do
@@ -116,7 +116,7 @@ describe 'FileBased module loader' do
116
116
 
117
117
  task = module_loader.load_typed(typed_name(:task, 'testmodule::foo')).value
118
118
  expect(task.name).to eq('testmodule::foo')
119
- expect(task.implementations.map {|impl| impl['name']}).to eq(['foo.py', 'foo.ps1'])
119
+ expect(task.files.map {|impl| impl['name']}).to eq(['foo.py', 'foo.ps1'])
120
120
  end
121
121
 
122
122
  it 'can load multiple tasks with multiple files' do
@@ -128,11 +128,11 @@ describe 'FileBased module loader' do
128
128
  foobar_task = module_loader.load_typed(typed_name(:task, 'testmodule::foobar')).value
129
129
 
130
130
  expect(foo_task.name).to eq('testmodule::foo')
131
- expect(foo_task.implementations.length).to eq(1)
132
- expect(foo_task.implementations[0]['name']).to eq('foo.py')
131
+ expect(foo_task.files.length).to eq(1)
132
+ expect(foo_task.files[0]['name']).to eq('foo.py')
133
133
  expect(foobar_task.name).to eq('testmodule::foobar')
134
- expect(foobar_task.implementations.length).to eq(1)
135
- expect(foobar_task.implementations[0]['name']).to eq('foobar.py')
134
+ expect(foobar_task.files.length).to eq(1)
135
+ expect(foobar_task.files[0]['name']).to eq('foobar.py')
136
136
  end
137
137
 
138
138
  it "won't load tasks with invalid names" do
@@ -140,6 +140,22 @@ describe "egrammar parsing heredoc" do
140
140
  ].join("\n"))
141
141
  end
142
142
 
143
+ it "parses interpolated [] expression by looking at the correct preceding char for space" do
144
+ # NOTE: Important not to use the left margin feature here
145
+ src = <<-CODE
146
+ $xxxxxxx = @("END")
147
+ ${facts['os']['family']}
148
+ XXXXXXX XXX
149
+ END
150
+ CODE
151
+ expect(dump(parse(src))).to eq([
152
+ "(= $xxxxxxx (@()",
153
+ " (sublocated (cat (str (slice (slice $facts 'os') 'family')) '",
154
+ "XXXXXXX XXX",
155
+ "'))",
156
+ "))"].join("\n"))
157
+ end
158
+
143
159
  it 'parses multiple heredocs on the same line' do
144
160
  src = <<-CODE
145
161
  notice({ @(foo) => @(bar) })
@@ -153,6 +153,15 @@ module Serialization
153
153
  expect(val2).to eql(val)
154
154
  end
155
155
 
156
+ it 'ACII_8BIT String as Binary' do
157
+ val = Types::PBinaryType::Binary.from_base64('w5ZzdGVuIG1lZCByw7ZzdGVuCg==')
158
+ strval = val.binary_buffer
159
+ write(strval)
160
+ val2 = read
161
+ expect(val2).to be_a(Types::PBinaryType::Binary)
162
+ expect(val2).to eql(val)
163
+ end
164
+
156
165
  it 'URI' do
157
166
  val = URI('http://bob:ewing@dallas.example.com:8080/oil/baron?crude=cash#leftovers')
158
167
  write(val)
@@ -143,13 +143,12 @@ describe 'The Task Type' do
143
143
  expect(task_t.instance?(task)).to be_truthy
144
144
  expect(task.name).to eq('testmodule::hello')
145
145
  expect(task._pcore_type).to eq(task_t)
146
- expect(task.supports_noop).to eql(true)
147
- expect(task.puppet_task_version).to eql(1)
148
- expect(task.implementations).to eql([{"name" => "hello.rb", "path" => "#{modules_dir}/testmodule/tasks/hello.rb", "requirements" => []}])
146
+ expect(task.metadata['supports_noop']).to eql(true)
147
+ expect(task.metadata['puppet_task_version']).to eql(1)
148
+ expect(task.files).to eql([{"name" => "hello.rb", "path" => "#{modules_dir}/testmodule/tasks/hello.rb"}])
149
149
 
150
- tp = task.parameters
151
- expect(tp['message']['description']).to eql('the message')
152
- expect(tp['message']['type']).to be_a(Puppet::Pops::Types::PStringType)
150
+ expect(task.metadata['parameters']['message']['description']).to eql('the message')
151
+ expect(task.parameters['message']).to be_a(Puppet::Pops::Types::PStringType)
153
152
  end
154
153
  end
155
154
 
@@ -157,8 +156,7 @@ describe 'The Task Type' do
157
156
  compile do
158
157
  task = module_loader.load(:task, 'testmodule::non_data')
159
158
  expect(task_t.instance?(task)).to be_truthy
160
- tp = task.parameters
161
- expect(tp['arg']['type']).to be_a(Puppet::Pops::Types::PHashType)
159
+ expect(task.parameters['arg']).to be_a(Puppet::Pops::Types::PHashType)
162
160
  end
163
161
  end
164
162
 
@@ -173,7 +171,9 @@ describe 'The Task Type' do
173
171
 
174
172
  it 'fails to load the task' do
175
173
  compile do
176
- expect { module_loader.load(:task, 'testmodule') }.to raise_error(ArgumentError, /No source besides task metadata was found/)
174
+ expect {
175
+ module_loader.load(:task, 'testmodule')
176
+ }.to raise_error(Puppet::Module::Task::InvalidTask, /No source besides task metadata was found/)
177
177
  end
178
178
  end
179
179
  end
@@ -192,7 +192,9 @@ describe 'The Task Type' do
192
192
 
193
193
  it "fails if metadata doesn't specify implementations" do
194
194
  compile do
195
- expect { module_loader.load(:task, 'testmodule') }.to raise_error(ArgumentError, /Multiple executables were found .*/)
195
+ expect {
196
+ module_loader.load(:task, 'testmodule')
197
+ }.to raise_error(Puppet::Module::Task::InvalidTask, /Multiple executables were found .*/)
196
198
  end
197
199
  end
198
200
 
@@ -204,9 +206,13 @@ describe 'The Task Type' do
204
206
  compile do
205
207
  task = module_loader.load(:task, 'testmodule')
206
208
  expect(task_t.instance?(task)).to be_truthy
207
- expect(task.implementations).to eql([
208
- {"name" => "init.sh", "path" => "#{modules_dir}/testmodule/tasks/init.sh", "requirements" => ['shell']},
209
- {"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1", "requirements" => ['powershell']}
209
+ expect(task.files).to eql([
210
+ {"name" => "init.sh", "path" => "#{modules_dir}/testmodule/tasks/init.sh"},
211
+ {"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1"}
212
+ ])
213
+ expect(task.metadata['implementations']).to eql([
214
+ {"name" => "init.sh", "requirements" => ['shell']},
215
+ {"name" => "init.ps1", "requirements" => ['powershell']}
210
216
  ])
211
217
  end
212
218
  end
@@ -218,21 +224,11 @@ describe 'The Task Type' do
218
224
  compile do
219
225
  task = module_loader.load(:task, 'testmodule')
220
226
  expect(task_t.instance?(task)).to be_truthy
221
- expect(task.implementations).to eql([
222
- {"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1", "requirements" => ['powershell']}
227
+ expect(task.files).to eql([
228
+ {"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1"}
223
229
  ])
224
- end
225
- end
226
-
227
- it "adds an empty requirements list if one is not specified" do
228
- impls = [{'name' => 'init.ps1'}]
229
- metadata.replace({'implementations' => impls}.to_json)
230
-
231
- compile do
232
- task = module_loader.load(:task, 'testmodule')
233
- expect(task_t.instance?(task)).to be_truthy
234
- expect(task.implementations).to eql([
235
- {"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1", "requirements" => []}
230
+ expect(task.metadata['implementations']).to eql([
231
+ {"name" => "init.ps1", "requirements" => ['powershell']}
236
232
  ])
237
233
  end
238
234
  end
@@ -244,7 +240,9 @@ describe 'The Task Type' do
244
240
  metadata.replace({'implementations' => impls}.to_json)
245
241
 
246
242
  compile do
247
- expect { module_loader.load(:task, 'testmodule') }.to raise_error(ArgumentError, /Task metadata for task testmodule specifies missing implementation init\.rb/)
243
+ expect {
244
+ module_loader.load(:task, 'testmodule')
245
+ }.to raise_error(Puppet::Module::Task::InvalidTask, /Task metadata for task testmodule specifies missing implementation init\.rb/)
248
246
  end
249
247
  end
250
248
 
@@ -252,7 +250,9 @@ describe 'The Task Type' do
252
250
  metadata.replace({'implementations' => {'init.rb' => []}}.to_json)
253
251
 
254
252
  compile do
255
- expect { module_loader.load(:task, 'testmodule') }.to raise_error(Puppet::ParseError, /Task initializer has wrong type/)
253
+ expect {
254
+ module_loader.load(:task, 'testmodule')
255
+ }.to raise_error(Puppet::Module::Task::InvalidMetadata, /Task metadata for task testmodule does not specify implementations as an array/)
256
256
  end
257
257
  end
258
258
  end
@@ -283,16 +283,18 @@ describe 'The Task Type' do
283
283
 
284
284
  compile do
285
285
  task = module_loader.load(:task, 'testmodule::bar')
286
- expect(task.implementations).to eql([
287
- {'name' => 'foo.sh', 'path' => "#{modules_dir}/testmodule/tasks/foo.sh", 'requirements' => ['shell']},
288
- {'name' => 'foo.ps1', 'path' => "#{modules_dir}/testmodule/tasks/foo.ps1", 'requirements' => ['powershell']},
286
+ expect(task.files).to eql([
287
+ {'name' => 'foo.sh', 'path' => "#{modules_dir}/testmodule/tasks/foo.sh"},
288
+ {'name' => 'foo.ps1', 'path' => "#{modules_dir}/testmodule/tasks/foo.ps1"},
289
289
  ])
290
290
  end
291
291
  end
292
292
 
293
293
  it 'fails to load the task if it has no implementations section and no associated executables' do
294
294
  compile do
295
- expect { module_loader.load(:task, 'testmodule::bar') }.to raise_error(ArgumentError, /No source besides task metadata was found/)
295
+ expect {
296
+ module_loader.load(:task, 'testmodule::bar')
297
+ }.to raise_error(Puppet::Module::Task::InvalidTask, /No source besides task metadata was found/)
296
298
  end
297
299
  end
298
300
 
@@ -327,9 +329,9 @@ describe 'The Task Type' do
327
329
  compile do
328
330
  task = module_loader.load(:task, 'testmodule')
329
331
  expect(task_t.instance?(task)).to be_truthy
330
- expect(task.implementations).to eql([{"name" => "init.sh", "path" => "#{modules_dir}/testmodule/tasks/init.sh", "requirements" => []}])
331
- expect(task.parameters).to be_a(Hash)
332
- expect(task.parameters['message']['type']).to be_a(Puppet::Pops::Types::PStringType)
332
+ expect(task.files).to eql([{"name" => "init.sh", "path" => "#{modules_dir}/testmodule/tasks/init.sh"}])
333
+ expect(task.metadata['parameters']).to be_a(Hash)
334
+ expect(task.parameters['message']).to be_a(Puppet::Pops::Types::PStringType)
333
335
  end
334
336
  end
335
337
  end
@@ -358,9 +360,9 @@ describe 'The Task Type' do
358
360
  compile do
359
361
  task = module_loader.load(:task, 'testmodule::hello')
360
362
  expect(task_t.instance?(task)).to be_truthy
361
- expect(task.implementations).to eql([{"name" => "hello.sh", "path" => "#{modules_dir}/testmodule/tasks/hello.sh", "requirements" => []}])
362
- expect(task.parameters).to be_a(Hash)
363
- expect(task.parameters['message']['type']).to be_a(Puppet::Pops::Types::PStringType)
363
+ expect(task.files).to eql([{"name" => "hello.sh", "path" => "#{modules_dir}/testmodule/tasks/hello.sh"}])
364
+ expect(task.metadata['parameters']).to be_a(Hash)
365
+ expect(task.parameters['message']).to be_a(Puppet::Pops::Types::PStringType)
364
366
  end
365
367
  end
366
368
  end
@@ -383,31 +385,6 @@ describe 'The Task Type' do
383
385
  end
384
386
  end
385
387
 
386
- context 'that has a malformed top-level entry' do
387
- let(:testmodule) {
388
- {
389
- 'tasks' => {
390
- 'hello' => 'echo hello',
391
- 'hello.json' => <<-JSON
392
- {
393
- "supports_nop": true,
394
- "parameters": {
395
- "message": { "type": "String" }
396
- }
397
- }
398
- JSON
399
- }
400
- }
401
- }
402
-
403
- it 'fails with unrecognized key error' do
404
- compile do
405
- expect{module_loader.load(:task, 'testmodule::hello')}.to raise_error(
406
- /Failed to load metadata for task testmodule::hello:.*unrecognized key 'supports_nop'/)
407
- end
408
- end
409
- end
410
-
411
388
  context 'that has no parameters' do
412
389
  let(:testmodule) {
413
390
  {
@@ -421,58 +398,7 @@ describe 'The Task Type' do
421
398
  compile do
422
399
  task = module_loader.load(:task, 'testmodule::hello')
423
400
  expect(task_t.instance?(task)).to be_truthy
424
- expect(task.parameters).to be_nil
425
- end
426
- end
427
- end
428
-
429
- context 'that has a malformed parameter name' do
430
- let(:testmodule) {
431
- {
432
- 'tasks' => {
433
- 'hello' => 'echo hello',
434
- 'hello.json' => <<-JSON
435
- {
436
- "supports_noop": true,
437
- "parameters": {
438
- "Message": { "type": "String" }
439
- }
440
- }
441
- JSON
442
- }
443
- }
444
- }
445
-
446
- it 'fails with pattern mismatch error' do
447
- compile do
448
- expect{module_loader.load(:task, 'testmodule::hello')}.to raise_error(
449
- /entry 'parameters' key of entry 'Message' expects a match for Pattern\[\/\\A\[a-z\]\[a-z0-9_\]\*\\z\/\], got 'Message'/)
450
- end
451
- end
452
- end
453
-
454
- context 'that has a puppet_task_version that is a string' do
455
- let(:testmodule) {
456
- {
457
- 'tasks' => {
458
- 'hello' => 'echo hello',
459
- 'hello.json' => <<-JSON
460
- {
461
- "puppet_task_version": "1",
462
- "supports_noop": true,
463
- "parameters": {
464
- "message": { "type": "String" }
465
- }
466
- }
467
- JSON
468
- }
469
- }
470
- }
471
-
472
- it 'fails with type mismatch error' do
473
- compile do
474
- expect{module_loader.load(:task, 'testmodule::hello')}.to raise_error(
475
- /entry 'puppet_task_version' expects an Integer value, got String/)
401
+ expect(task.metadata['parameters']).to be_nil
476
402
  end
477
403
  end
478
404
  end