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.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -4
- data/lib/puppet/application/apply.rb +99 -59
- data/lib/puppet/application/cert.rb +2 -112
- data/lib/puppet/configurer.rb +2 -3
- data/lib/puppet/defaults.rb +14 -1
- data/lib/puppet/etc.rb +20 -0
- data/lib/puppet/module/task.rb +29 -38
- data/lib/puppet/parser/catalog_compiler.rb +24 -0
- data/lib/puppet/parser/compiler.rb +3 -1
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +3 -0
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
- data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +18 -10
- data/lib/puppet/pops/loader/task_instantiator.rb +13 -70
- data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
- data/lib/puppet/pops/parser/lexer2.rb +1 -1
- data/lib/puppet/pops/pcore.rb +10 -33
- data/lib/puppet/pops/serialization.rb +1 -0
- data/lib/puppet/pops/serialization/to_data_converter.rb +9 -1
- data/lib/puppet/provider/exec.rb +57 -57
- data/lib/puppet/provider/group/aix.rb +1 -15
- data/lib/puppet/provider/group/pw.rb +4 -8
- data/lib/puppet/provider/group/windows_adsi.rb +7 -4
- data/lib/puppet/provider/nameservice.rb +1 -25
- data/lib/puppet/provider/nameservice/directoryservice.rb +5 -3
- data/lib/puppet/provider/package/portage.rb +2 -2
- data/lib/puppet/provider/service/launchd.rb +19 -3
- data/lib/puppet/provider/user/aix.rb +48 -2
- data/lib/puppet/type/group.rb +62 -18
- data/lib/puppet/type/schedule.rb +7 -0
- data/lib/puppet/util/execution.rb +14 -1
- data/lib/puppet/util/posix.rb +15 -0
- data/lib/puppet/util/storage.rb +12 -0
- data/lib/puppet/util/windows/adsi.rb +60 -1
- data/lib/puppet/util/windows/process.rb +16 -1
- data/lib/puppet/util/windows/service.rb +68 -26
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet_pal.rb +36 -3
- data/locales/ja/puppet.po +598 -861
- data/locales/puppet.pot +197 -160
- data/man/man5/puppet.conf.5 +12 -1
- data/man/man8/puppet.8 +1 -1
- data/spec/integration/application/apply_spec.rb +4 -1
- data/spec/integration/util/windows/adsi_spec.rb +2 -1
- data/spec/unit/application/apply_spec.rb +14 -0
- data/spec/unit/configurer_spec.rb +11 -0
- data/spec/unit/etc_spec.rb +25 -0
- data/spec/unit/indirector/catalog/json_spec.rb +9 -3
- data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +22 -4
- data/spec/unit/pops/loaders/loader_spec.rb +3 -10
- data/spec/unit/pops/loaders/loaders_spec.rb +30 -0
- data/spec/unit/pops/loaders/module_loaders_spec.rb +7 -7
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +16 -0
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +9 -0
- data/spec/unit/pops/types/task_spec.rb +42 -116
- data/spec/unit/provider/group/aix_spec.rb +0 -19
- data/spec/unit/provider/group/pw_spec.rb +0 -6
- data/spec/unit/provider/group/windows_adsi_spec.rb +34 -35
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +2 -2
- data/spec/unit/provider/service/launchd_spec.rb +19 -0
- data/spec/unit/provider/user/aix_spec.rb +43 -2
- data/spec/unit/provider/user/windows_adsi_spec.rb +1 -4
- data/spec/unit/puppet_pal_2pec.rb +6 -6
- data/spec/unit/puppet_pal_catalog_spec.rb +58 -0
- data/spec/unit/task_spec.rb +50 -5
- data/spec/unit/type/group_spec.rb +111 -13
- data/spec/unit/util/execution_spec.rb +59 -0
- data/spec/unit/util/posix_spec.rb +28 -0
- data/spec/unit/util/storage_spec.rb +107 -0
- data/spec/unit/util/windows/adsi_spec.rb +100 -5
- data/spec/unit/util/windows/service_spec.rb +100 -43
- metadata +2 -2
data/man/man5/puppet.conf.5
CHANGED
@@ -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\.
|
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
|
.
|
data/man/man8/puppet.8
CHANGED
@@ -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\.
|
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
|
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
|
-
|
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')
|
data/spec/unit/etc_spec.rb
CHANGED
@@ -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,
|
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
|
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
|
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 '
|
42
|
-
expect(converter.convert({'foo' => :undef}, {}, 'undef value')).to eql({'foo' =>
|
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/, /
|
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(
|
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/, /
|
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.
|
108
|
-
expect(task.
|
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.
|
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.
|
132
|
-
expect(foo_task.
|
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.
|
135
|
-
expect(foobar_task.
|
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.
|
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
|
-
|
151
|
-
expect(
|
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
|
-
|
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 {
|
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 {
|
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.
|
208
|
-
{"name" => "init.sh", "path" => "#{modules_dir}/testmodule/tasks/init.sh"
|
209
|
-
{"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1"
|
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.
|
222
|
-
{"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1"
|
227
|
+
expect(task.files).to eql([
|
228
|
+
{"name" => "init.ps1", "path" => "#{modules_dir}/testmodule/tasks/init.ps1"}
|
223
229
|
])
|
224
|
-
|
225
|
-
|
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 {
|
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 {
|
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.
|
287
|
-
{'name' => 'foo.sh', 'path' => "#{modules_dir}/testmodule/tasks/foo.sh"
|
288
|
-
{'name' => 'foo.ps1', 'path' => "#{modules_dir}/testmodule/tasks/foo.ps1"
|
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 {
|
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.
|
331
|
-
expect(task.parameters).to be_a(Hash)
|
332
|
-
expect(task.parameters['message']
|
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.
|
362
|
-
expect(task.parameters).to be_a(Hash)
|
363
|
-
expect(task.parameters['message']
|
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
|