puppet 6.25.1 → 6.28.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CODEOWNERS +1 -1
- data/Gemfile +2 -2
- data/Gemfile.lock +101 -34
- data/lib/puppet/agent.rb +47 -11
- data/lib/puppet/application/agent.rb +2 -12
- data/lib/puppet/application/lookup.rb +74 -24
- data/lib/puppet/concurrent/thread_local_singleton.rb +5 -3
- data/lib/puppet/configurer.rb +8 -14
- data/lib/puppet/defaults.rb +13 -3
- data/lib/puppet/face/generate.rb +2 -0
- data/lib/puppet/file_serving/metadata.rb +3 -0
- data/lib/puppet/file_system/file_impl.rb +7 -7
- data/lib/puppet/file_system/jruby.rb +1 -1
- data/lib/puppet/file_system/windows.rb +4 -4
- data/lib/puppet/file_system.rb +1 -1
- data/lib/puppet/functions/next.rb +18 -1
- data/lib/puppet/functions/tree_each.rb +0 -1
- data/lib/puppet/functions/versioncmp.rb +6 -2
- data/lib/puppet/generate/type.rb +9 -0
- data/lib/puppet/http/client.rb +22 -2
- data/lib/puppet/node.rb +1 -1
- data/lib/puppet/pops/parser/code_merger.rb +4 -4
- data/lib/puppet/pops/parser/egrammar.ra +2 -0
- data/lib/puppet/pops/parser/eparser.rb +813 -794
- data/lib/puppet/pops/serialization/to_data_converter.rb +6 -18
- data/lib/puppet/provider/package/puppetserver_gem.rb +7 -16
- data/lib/puppet/provider/package/windows/exe_package.rb +30 -1
- data/lib/puppet/provider/package/windows/package.rb +2 -1
- data/lib/puppet/provider/package/windows.rb +14 -1
- data/lib/puppet/provider/service/init.rb +5 -4
- data/lib/puppet/provider/user/directoryservice.rb +5 -0
- data/lib/puppet/ssl/ssl_provider.rb +75 -19
- data/lib/puppet/ssl/state_machine.rb +13 -17
- data/lib/puppet/ssl/verifier.rb +6 -0
- data/lib/puppet/transaction/persistence.rb +22 -12
- data/lib/puppet/type/exec.rb +1 -1
- data/lib/puppet/type/file/data_sync.rb +1 -1
- data/lib/puppet/type/user.rb +43 -38
- data/lib/puppet/util/json.rb +17 -0
- data/lib/puppet/util/log.rb +7 -2
- data/lib/puppet/util/monkey_patches.rb +6 -2
- data/lib/puppet/util/package.rb +25 -16
- data/lib/puppet/util/yaml.rb +21 -2
- data/lib/puppet/util.rb +1 -2
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet.rb +2 -14
- data/locales/puppet.pot +5 -10454
- data/man/man5/puppet.conf.5 +21 -2
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +9 -6
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/unit/forge/bacula.json +1 -1
- data/spec/integration/application/agent_spec.rb +108 -0
- data/spec/integration/application/lookup_spec.rb +81 -50
- data/spec/integration/application/resource_spec.rb +6 -2
- data/spec/integration/http/client_spec.rb +51 -4
- data/spec/lib/puppet_spec/https.rb +1 -1
- data/spec/lib/puppet_spec/puppetserver.rb +39 -2
- data/spec/shared_contexts/l10n.rb +5 -0
- data/spec/unit/agent_spec.rb +28 -2
- data/spec/unit/application/agent_spec.rb +26 -16
- data/spec/unit/application/lookup_spec.rb +131 -10
- data/spec/unit/concurrent/thread_local_singleton_spec.rb +39 -0
- data/spec/unit/configurer_spec.rb +124 -61
- data/spec/unit/daemon_spec.rb +2 -11
- data/spec/unit/face/generate_spec.rb +64 -0
- data/spec/unit/file_system_spec.rb +34 -4
- data/spec/unit/forge/module_release_spec.rb +3 -3
- data/spec/unit/functions/versioncmp_spec.rb +40 -4
- data/spec/unit/http/client_spec.rb +18 -0
- data/spec/unit/node_spec.rb +6 -0
- data/spec/unit/pops/parser/parse_containers_spec.rb +2 -2
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +0 -58
- data/spec/unit/pops/validator/validator_spec.rb +5 -0
- data/spec/unit/provider/package/puppetserver_gem_spec.rb +2 -2
- data/spec/unit/provider/package/windows/exe_package_spec.rb +17 -0
- data/spec/unit/provider/service/gentoo_spec.rb +6 -5
- data/spec/unit/provider/service/init_spec.rb +15 -9
- data/spec/unit/provider/service/openwrt_spec.rb +21 -29
- data/spec/unit/provider/service/redhat_spec.rb +3 -2
- data/spec/unit/ssl/ssl_provider_spec.rb +75 -1
- data/spec/unit/ssl/state_machine_spec.rb +1 -0
- data/spec/unit/transaction/persistence_spec.rb +51 -0
- data/spec/unit/type/user_spec.rb +0 -45
- data/spec/unit/util/json_spec.rb +126 -0
- data/spec/unit/util/windows_spec.rb +23 -0
- data/spec/unit/util/yaml_spec.rb +54 -29
- data/tasks/generate_cert_fixtures.rake +5 -4
- metadata +9 -3
@@ -19,16 +19,52 @@ describe "the versioncmp function" do
|
|
19
19
|
let(:type_parser) { Puppet::Pops::Types::TypeParser.singleton }
|
20
20
|
|
21
21
|
it 'should raise an Error if there is less than 2 arguments' do
|
22
|
-
expect { versioncmp('a,b') }.to raise_error(/expects 2 arguments, got 1/)
|
22
|
+
expect { versioncmp('a,b') }.to raise_error(/expects between 2 and 3 arguments, got 1/)
|
23
23
|
end
|
24
24
|
|
25
|
-
it 'should raise an Error if there is more than
|
26
|
-
expect { versioncmp('a,b','foo', 'bar') }.to raise_error(/expects 2 arguments, got
|
25
|
+
it 'should raise an Error if there is more than 3 arguments' do
|
26
|
+
expect { versioncmp('a,b','foo', false, 'bar') }.to raise_error(/expects between 2 and 3 arguments, got 4/)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should call Puppet::Util::Package.versioncmp (included in scope)" do
|
30
|
-
expect(Puppet::Util::Package).to receive(:versioncmp).with('1.2', '1.3').and_return(-1)
|
30
|
+
expect(Puppet::Util::Package).to receive(:versioncmp).with('1.2', '1.3', false).and_return(-1)
|
31
31
|
|
32
32
|
expect(versioncmp('1.2', '1.3')).to eq(-1)
|
33
33
|
end
|
34
|
+
|
35
|
+
context "when ignore_trailing_zeroes is true" do
|
36
|
+
it "should equate versions with 2 elements and dots but with unnecessary zero" do
|
37
|
+
expect(versioncmp("10.1.0", "10.1", true)).to eq(0)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should equate versions with 1 element and dot but with unnecessary zero" do
|
41
|
+
expect(versioncmp("11.0", "11", true)).to eq(0)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should equate versions with 1 element and dot but with unnecessary zeros" do
|
45
|
+
expect(versioncmp("11.00", "11", true)).to eq(0)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should equate versions with dots and iregular zeroes" do
|
49
|
+
expect(versioncmp("11.0.00", "11", true)).to eq(0)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should equate versions with dashes" do
|
53
|
+
expect(versioncmp("10.1-0", "10.1.0-0", true)).to eq(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should compare versions with dashes after normalization" do
|
57
|
+
expect(versioncmp("10.1-1", "10.1.0-0", true)).to eq(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not normalize versions if zeros are not trailing" do
|
61
|
+
expect(versioncmp("1.1", "1.0.1", true)).to eq(1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when ignore_trailing_zeroes is false" do
|
66
|
+
it "should not equate versions if zeros are not trailing" do
|
67
|
+
expect(versioncmp("1.1", "1.0.1")).to eq(1)
|
68
|
+
end
|
69
|
+
end
|
34
70
|
end
|
@@ -120,6 +120,24 @@ describe Puppet::HTTP::Client do
|
|
120
120
|
|
121
121
|
client.close
|
122
122
|
end
|
123
|
+
|
124
|
+
it 'reloads the default ssl context' do
|
125
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
126
|
+
expect(verifier.ssl_context).to_not equal(puppet_context)
|
127
|
+
end
|
128
|
+
|
129
|
+
client.close
|
130
|
+
client.connect(uri)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'reloads the default system ssl context' do
|
134
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
135
|
+
expect(verifier.ssl_context).to_not equal(system_context)
|
136
|
+
end
|
137
|
+
|
138
|
+
client.close
|
139
|
+
client.connect(uri, options: {include_system_store: true})
|
140
|
+
end
|
123
141
|
end
|
124
142
|
|
125
143
|
context "for GET requests" do
|
data/spec/unit/node_spec.rb
CHANGED
@@ -40,6 +40,12 @@ describe Puppet::Node do
|
|
40
40
|
expect(node.environment.name).to eq(:bar)
|
41
41
|
end
|
42
42
|
|
43
|
+
it "sets environment_name with the correct environment name" do
|
44
|
+
node = Puppet::Node.new("foo")
|
45
|
+
node.environment = Puppet::Node::Environment.remote('www123')
|
46
|
+
expect(node.environment_name).to eq(:www123)
|
47
|
+
end
|
48
|
+
|
43
49
|
it "allows its environment to be set by parameters after initialization" do
|
44
50
|
node = Puppet::Node.new("foo")
|
45
51
|
node.parameters["environment"] = :bar
|
@@ -106,7 +106,7 @@ describe "egrammar parsing containers" do
|
|
106
106
|
|
107
107
|
context 'it should allow keywords as attribute names' do
|
108
108
|
['and', 'case', 'class', 'default', 'define', 'else', 'elsif', 'if', 'in', 'inherits', 'node', 'or',
|
109
|
-
'undef', 'unless', 'type', 'attr', 'function', 'private'].each do |keyword|
|
109
|
+
'undef', 'unless', 'type', 'attr', 'function', 'private', 'plan', 'apply'].each do |keyword|
|
110
110
|
it "such as #{keyword}" do
|
111
111
|
expect { parse("class x ($#{keyword}){} class { x: #{keyword} => 1 }") }.to_not raise_error
|
112
112
|
end
|
@@ -178,7 +178,7 @@ describe "egrammar parsing containers" do
|
|
178
178
|
|
179
179
|
context 'it should allow keywords as attribute names' do
|
180
180
|
['and', 'case', 'class', 'default', 'define', 'else', 'elsif', 'if', 'in', 'inherits', 'node', 'or',
|
181
|
-
'undef', 'unless', 'type', 'attr', 'function', 'private'].each do |keyword|
|
181
|
+
'undef', 'unless', 'type', 'attr', 'function', 'private', 'plan', 'apply'].each do |keyword|
|
182
182
|
it "such as #{keyword}" do
|
183
183
|
expect {parse("define x ($#{keyword}){} x { y: #{keyword} => 1 }")}.to_not raise_error
|
184
184
|
end
|
@@ -559,29 +559,6 @@ module Serialization
|
|
559
559
|
expect(warnings).to eql(["['key'] contains the special value default. It will be converted to the String 'default'"])
|
560
560
|
end
|
561
561
|
end
|
562
|
-
context 'and force_symbol set to true' do
|
563
|
-
let(:to_converter) { ToDataConverter.new(:rich_data => false, :force_symbol => true) }
|
564
|
-
|
565
|
-
it 'A Hash with Symbol values is converted to hash with Symbol values' do
|
566
|
-
val = { 'one' => :one, 'two' => :two }
|
567
|
-
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
568
|
-
|
569
|
-
# write and read methods does not work here as we cannot force Symbols in Json.
|
570
|
-
# and a hash with symbol values cannot be an instance of Types::TypeFactory.data.
|
571
|
-
# Using YAML for this instead
|
572
|
-
io.reopen
|
573
|
-
value = to_converter.convert(val)
|
574
|
-
io << [value].to_yaml
|
575
|
-
io.rewind
|
576
|
-
|
577
|
-
val2 = from_converter.convert(YAML::load(io.read)[0])
|
578
|
-
|
579
|
-
expect(val2).to be_a(Hash)
|
580
|
-
expect(val2).to eql({ 'one' => :one, 'two' => :two })
|
581
|
-
end
|
582
|
-
expect(warnings).to be_empty
|
583
|
-
end
|
584
|
-
end
|
585
562
|
end
|
586
563
|
|
587
564
|
context 'with rich_data is set to true' do
|
@@ -655,41 +632,6 @@ module Serialization
|
|
655
632
|
end.to raise_error(/Cannot create a Pcore::TimestampType from a (Fixnum|Integer)/)
|
656
633
|
end
|
657
634
|
end
|
658
|
-
|
659
|
-
context 'when data is unknown' do
|
660
|
-
let(:to_converter) { ToDataConverter.new(:message_prefix => 'Test Hash') }
|
661
|
-
let(:logs) { [] }
|
662
|
-
let(:warnings) { logs.select { |log| log.level == :warning }.map { |log| log.message } }
|
663
|
-
let(:val) { Class.new }
|
664
|
-
|
665
|
-
context 'and :silence_warnings undefined or set to false' do
|
666
|
-
it 'convert the unknown data to string with warnings' do
|
667
|
-
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
668
|
-
write(val)
|
669
|
-
val2 = read
|
670
|
-
expect(val2).to be_a(String)
|
671
|
-
expect(val2).to match(/Class/)
|
672
|
-
end
|
673
|
-
expect(warnings).to eql([
|
674
|
-
"Test Hash contains a #{val.class} value. It will be converted to the String '#{val.to_s}'"])
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
|
-
context 'and :silence_warnings undefined or set to true' do
|
679
|
-
let(:to_converter) { ToDataConverter.new(:message_prefix => 'Test Hash', :silence_warnings => true) }
|
680
|
-
|
681
|
-
it 'convert the unknown data to string without warnings if silence_warnings set to true' do
|
682
|
-
val = Class.new
|
683
|
-
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
684
|
-
write(val)
|
685
|
-
val2 = read
|
686
|
-
expect(val2).to be_a(String)
|
687
|
-
expect(val2).to match(/Class/)
|
688
|
-
end
|
689
|
-
expect(warnings).to be_empty
|
690
|
-
end
|
691
|
-
end
|
692
|
-
end
|
693
635
|
end
|
694
636
|
end
|
695
637
|
end
|
@@ -432,6 +432,11 @@ describe "validating 4x" do
|
|
432
432
|
expect(acceptor.error_count).to eql(0)
|
433
433
|
end
|
434
434
|
|
435
|
+
it 'allows apply to be used as a resource attribute name' do
|
436
|
+
acceptor = validate(parse('apply("foo.example.com") { sometype { "resourcetitle": apply => "applyvalue" } }'))
|
437
|
+
expect(acceptor.error_count).to eql(0)
|
438
|
+
end
|
439
|
+
|
435
440
|
it 'accepts multiple arguments' do
|
436
441
|
acceptor = validate(parse('apply(["foo.example.com"], { "other" => "args" }) { }'))
|
437
442
|
expect(acceptor.error_count).to eql(0)
|
@@ -105,9 +105,9 @@ describe Puppet::Type.type(:package).provider(:puppetserver_gem) do
|
|
105
105
|
|
106
106
|
describe ".gemlist" do
|
107
107
|
context "listing installed packages" do
|
108
|
-
it "uses the
|
108
|
+
it "uses the puppet_gem provider_command to list local gems" do
|
109
109
|
expected = { name: 'world_airports', provider: :puppetserver_gem, ensure: ['1.1.3'] }
|
110
|
-
expect(described_class).to receive(:execute_rubygems_list_command).with(
|
110
|
+
expect(described_class).to receive(:execute_rubygems_list_command).with(['gem', 'list', '--local']).and_return(File.read(my_fixture('gem-list-local-packages')))
|
111
111
|
expect(described_class.gemlist({ local: true })).to include(expected)
|
112
112
|
end
|
113
113
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'puppet/provider/package/windows/exe_package'
|
3
|
+
require 'puppet/provider/package/windows'
|
3
4
|
|
4
5
|
describe Puppet::Provider::Package::Windows::ExePackage do
|
5
6
|
let (:name) { 'Git version 1.7.11' }
|
@@ -71,10 +72,26 @@ describe Puppet::Provider::Package::Windows::ExePackage do
|
|
71
72
|
|
72
73
|
context '#install_command' do
|
73
74
|
it 'should install using the source' do
|
75
|
+
allow(Puppet::FileSystem).to receive(:exist?).with(source).and_return(true)
|
74
76
|
cmd = described_class.install_command({:source => source})
|
75
77
|
|
76
78
|
expect(cmd).to eq(source)
|
77
79
|
end
|
80
|
+
|
81
|
+
it 'should raise error when URI is invalid' do
|
82
|
+
web_source = 'https://www.t e s t.test/test.exe'
|
83
|
+
|
84
|
+
expect do
|
85
|
+
described_class.install_command({:source => web_source, :name => name})
|
86
|
+
end.to raise_error(Puppet::Error, /Error when installing #{name}:/)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should download package from source file before installing', if: Puppet::Util::Platform.windows? do
|
90
|
+
web_source = 'https://www.test.test/test.exe'
|
91
|
+
stub_request(:get, web_source).to_return(status: 200, body: 'package binaries')
|
92
|
+
cmd = described_class.install_command({:source => web_source})
|
93
|
+
expect(File.read(cmd)).to eq('package binaries')
|
94
|
+
end
|
78
95
|
end
|
79
96
|
|
80
97
|
context '#uninstall_command' do
|
@@ -10,8 +10,8 @@ describe 'Puppet::Type::Service::Provider::Gentoo',
|
|
10
10
|
|
11
11
|
before :each do
|
12
12
|
allow(Puppet::Type.type(:service)).to receive(:defaultprovider).and_return(provider_class)
|
13
|
-
allow(
|
14
|
-
allow(
|
13
|
+
allow(Puppet::FileSystem).to receive(:file?).with('/sbin/rc-update').and_return(true)
|
14
|
+
allow(Puppet::FileSystem).to receive(:executable?).with('/sbin/rc-update').and_return(true)
|
15
15
|
allow(Facter).to receive(:value).with(:operatingsystem).and_return('Gentoo')
|
16
16
|
allow(Facter).to receive(:value).with(:osfamily).and_return('Gentoo')
|
17
17
|
|
@@ -52,13 +52,14 @@ describe 'Puppet::Type::Service::Provider::Gentoo',
|
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should get a list of services from /etc/init.d but exclude helper scripts" do
|
55
|
-
|
55
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
56
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('/etc/init.d').and_return(true)
|
56
57
|
expect(Dir).to receive(:entries).with('/etc/init.d').and_return(initscripts)
|
57
58
|
(initscripts - helperscripts).each do |script|
|
58
|
-
expect(
|
59
|
+
expect(Puppet::FileSystem).to receive(:executable?).with("/etc/init.d/#{script}").and_return(true)
|
59
60
|
end
|
60
61
|
helperscripts.each do |script|
|
61
|
-
expect(
|
62
|
+
expect(Puppet::FileSystem).not_to receive(:executable?).with("/etc/init.d/#{script}")
|
62
63
|
end
|
63
64
|
|
64
65
|
allow(Puppet::FileSystem).to receive(:symlink?).and_return(false)
|
@@ -85,14 +85,20 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
85
85
|
@services = ['one', 'two', 'three', 'four', 'umountfs']
|
86
86
|
allow(Dir).to receive(:entries).and_call_original
|
87
87
|
allow(Dir).to receive(:entries).with('tmp').and_return(@services)
|
88
|
-
|
89
|
-
allow(
|
88
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
89
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('tmp').and_return(true)
|
90
|
+
allow(Puppet::FileSystem).to receive(:executable?).and_return(true)
|
90
91
|
end
|
91
92
|
|
92
93
|
it "should return instances for all services" do
|
93
94
|
expect(provider_class.instances.map(&:name)).to eq(@services)
|
94
95
|
end
|
95
96
|
|
97
|
+
it "should omit directories from the service list" do
|
98
|
+
expect(Puppet::FileSystem).to receive(:directory?).with('tmp/four').and_return(true)
|
99
|
+
expect(provider_class.instances.map(&:name)).to eq(@services - ['four'])
|
100
|
+
end
|
101
|
+
|
96
102
|
it "should omit an array of services from exclude list" do
|
97
103
|
exclude = ['two', 'four']
|
98
104
|
expect(provider_class.get_services(provider_class.defpath, exclude).map(&:name)).to eq(@services - exclude)
|
@@ -140,9 +146,9 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
140
146
|
|
141
147
|
describe "when checking valid paths" do
|
142
148
|
it "should discard paths that do not exist" do
|
143
|
-
expect(
|
149
|
+
expect(Puppet::FileSystem).to receive(:directory?).with(paths[0]).and_return(false)
|
144
150
|
expect(Puppet::FileSystem).to receive(:exist?).with(paths[0]).and_return(false)
|
145
|
-
expect(
|
151
|
+
expect(Puppet::FileSystem).to receive(:directory?).with(paths[1]).and_return(true)
|
146
152
|
|
147
153
|
expect(provider.paths).to eq([paths[1]])
|
148
154
|
end
|
@@ -150,7 +156,7 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
150
156
|
it "should discard paths that are not directories" do
|
151
157
|
paths.each do |path|
|
152
158
|
expect(Puppet::FileSystem).to receive(:exist?).with(path).and_return(true)
|
153
|
-
expect(
|
159
|
+
expect(Puppet::FileSystem).to receive(:directory?).with(path).and_return(false)
|
154
160
|
end
|
155
161
|
expect(provider.paths).to be_empty
|
156
162
|
end
|
@@ -158,7 +164,7 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
158
164
|
|
159
165
|
describe "when searching for the init script" do
|
160
166
|
before :each do
|
161
|
-
paths.each {|path| expect(
|
167
|
+
paths.each {|path| expect(Puppet::FileSystem).to receive(:directory?).with(path).and_return(true) }
|
162
168
|
end
|
163
169
|
|
164
170
|
it "should be able to find the init script in the service path" do
|
@@ -191,9 +197,9 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
191
197
|
|
192
198
|
describe "if the init script is present" do
|
193
199
|
before :each do
|
194
|
-
allow(
|
195
|
-
allow(
|
196
|
-
allow(
|
200
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
201
|
+
allow(Puppet::FileSystem).to receive(:directory?).with("/service/path").and_return(true)
|
202
|
+
allow(Puppet::FileSystem).to receive(:directory?).with("/alt/service/path").and_return(true)
|
197
203
|
allow(Puppet::FileSystem).to receive(:exist?).with("/service/path/myservice").and_return(true)
|
198
204
|
end
|
199
205
|
|
@@ -2,63 +2,56 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'Puppet::Type::Service::Provider::Openwrt',
|
4
4
|
unless: Puppet::Util::Platform.windows? || Puppet::Util::Platform.jruby? do
|
5
|
+
|
5
6
|
let(:provider_class) { Puppet::Type.type(:service).provider(:openwrt) }
|
6
7
|
|
7
8
|
let(:resource) do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
resource
|
9
|
+
Puppet::Type.type(:service).new(
|
10
|
+
:name => 'myservice',
|
11
|
+
:path => '/etc/init.d',
|
12
|
+
:hasrestart => true,
|
13
|
+
)
|
14
14
|
end
|
15
15
|
|
16
16
|
let(:provider) do
|
17
17
|
provider = provider_class.new
|
18
|
-
|
19
|
-
|
18
|
+
provider.resource = resource
|
20
19
|
provider
|
21
20
|
end
|
22
21
|
|
23
22
|
before :each do
|
24
|
-
|
25
|
-
provider.resource = resource
|
26
|
-
|
27
|
-
allow(FileTest).to receive(:file?).with('/etc/rc.common').and_return(true)
|
28
|
-
allow(FileTest).to receive(:executable?).with('/etc/rc.common').and_return(true)
|
23
|
+
resource.provider = provider
|
29
24
|
|
30
25
|
# All OpenWrt tests operate on the init script directly. It must exist.
|
31
|
-
allow(
|
32
|
-
allow(
|
26
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
27
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('/etc/init.d').and_return(true)
|
33
28
|
|
34
29
|
allow(Puppet::FileSystem).to receive(:exist?).with('/etc/init.d/myservice').and_return(true)
|
35
|
-
allow(
|
36
|
-
allow(
|
37
|
-
allow(
|
30
|
+
allow(Puppet::FileSystem).to receive(:file?).and_call_original
|
31
|
+
allow(Puppet::FileSystem).to receive(:file?).with('/etc/init.d/myservice').and_return(true)
|
32
|
+
allow(Puppet::FileSystem).to receive(:executable?).with('/etc/init.d/myservice').and_return(true)
|
38
33
|
end
|
39
34
|
|
40
|
-
|
41
|
-
|
42
|
-
expect(Facter).to receive(:value).with(:operatingsystem).and_return(operatingsystem)
|
35
|
+
it "should be the default provider on 'openwrt'" do
|
36
|
+
expect(Facter).to receive(:value).with(:operatingsystem).and_return('openwrt')
|
43
37
|
expect(provider_class.default?).to be_truthy
|
44
38
|
end
|
45
39
|
|
46
40
|
# test self.instances
|
47
41
|
describe "when getting all service instances" do
|
48
|
-
let(:services) {['dnsmasq', 'dropbear', 'firewall', 'led', 'puppet', 'uhttpd' ]}
|
42
|
+
let(:services) { ['dnsmasq', 'dropbear', 'firewall', 'led', 'puppet', 'uhttpd' ] }
|
49
43
|
|
50
44
|
before :each do
|
51
45
|
allow(Dir).to receive(:entries).and_call_original
|
52
46
|
allow(Dir).to receive(:entries).with('/etc/init.d').and_return(services)
|
53
|
-
allow(
|
54
|
-
allow(FileTest).to receive(:executable?).and_return(true)
|
47
|
+
allow(Puppet::FileSystem).to receive(:executable?).and_return(true)
|
55
48
|
end
|
56
49
|
|
57
50
|
it "should return instances for all services" do
|
58
51
|
services.each do |inst|
|
59
52
|
expect(provider_class).to receive(:new).with(hash_including(:name => inst, :path => '/etc/init.d')).and_return("#{inst}_instance")
|
60
53
|
end
|
61
|
-
results = services.collect {|x| "#{x}_instance"}
|
54
|
+
results = services.collect { |x| "#{x}_instance"}
|
62
55
|
expect(provider_class.instances).to eq(results)
|
63
56
|
end
|
64
57
|
end
|
@@ -82,14 +75,13 @@ describe 'Puppet::Type::Service::Provider::Openwrt',
|
|
82
75
|
|
83
76
|
describe "when running #{method}" do
|
84
77
|
it "should use any provided explicit command" do
|
85
|
-
|
86
|
-
expect(provider).to receive(:execute).with([
|
78
|
+
resource[method] = '/user/specified/command'
|
79
|
+
expect(provider).to receive(:execute).with(['/user/specified/command'], any_args)
|
87
80
|
provider.send(method)
|
88
81
|
end
|
89
82
|
|
90
83
|
it "should execute the init script with #{method} when no explicit command is provided" do
|
91
|
-
|
92
|
-
expect(provider).to receive(:execute).with(['/etc/init.d/myservice', method ], any_args)
|
84
|
+
expect(provider).to receive(:execute).with(['/etc/init.d/myservice', method], any_args)
|
93
85
|
provider.send(method)
|
94
86
|
end
|
95
87
|
end
|
@@ -50,8 +50,9 @@ describe 'Puppet::Type::Service::Provider::Redhat',
|
|
50
50
|
@services = ['one', 'two', 'three', 'four', 'kudzu', 'functions', 'halt', 'killall', 'single', 'linuxconf', 'boot', 'reboot']
|
51
51
|
@not_services = ['functions', 'halt', 'killall', 'single', 'linuxconf', 'reboot', 'boot']
|
52
52
|
allow(Dir).to receive(:entries).and_return(@services)
|
53
|
-
allow(
|
54
|
-
allow(
|
53
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
54
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('/etc/init.d').and_return(true)
|
55
|
+
allow(Puppet::FileSystem).to receive(:executable?).and_return(true)
|
55
56
|
end
|
56
57
|
|
57
58
|
it "should return instances for all services" do
|
@@ -113,12 +113,21 @@ describe Puppet::SSL::SSLProvider do
|
|
113
113
|
}.to raise_error(/can't modify frozen/)
|
114
114
|
end
|
115
115
|
|
116
|
-
it 'trusts system ca store' do
|
116
|
+
it 'trusts system ca store by default' do
|
117
117
|
expect_any_instance_of(OpenSSL::X509::Store).to receive(:set_default_paths)
|
118
118
|
|
119
119
|
subject.create_system_context(cacerts: [])
|
120
120
|
end
|
121
121
|
|
122
|
+
it 'trusts an external ca store' do
|
123
|
+
path = tmpfile('system_cacerts')
|
124
|
+
File.write(path, cert_fixture('ca.pem').to_pem)
|
125
|
+
|
126
|
+
expect_any_instance_of(OpenSSL::X509::Store).to receive(:add_file).with(path)
|
127
|
+
|
128
|
+
subject.create_system_context(cacerts: [], path: path)
|
129
|
+
end
|
130
|
+
|
122
131
|
it 'verifies peer' do
|
123
132
|
sslctx = subject.create_system_context(cacerts: [])
|
124
133
|
expect(sslctx.verify_peer).to eq(true)
|
@@ -135,6 +144,47 @@ describe Puppet::SSL::SSLProvider do
|
|
135
144
|
expect(sslctx.private_key).to be_nil
|
136
145
|
end
|
137
146
|
|
147
|
+
it 'includes the client cert and private key when requested' do
|
148
|
+
Puppet[:hostcert] = fixtures('ssl/signed.pem')
|
149
|
+
Puppet[:hostprivkey] = fixtures('ssl/signed-key.pem')
|
150
|
+
sslctx = subject.create_system_context(cacerts: [], include_client_cert: true)
|
151
|
+
expect(sslctx.client_cert).to be_an(OpenSSL::X509::Certificate)
|
152
|
+
expect(sslctx.private_key).to be_an(OpenSSL::PKey::RSA)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'ignores non-existent client cert and private key when requested' do
|
156
|
+
Puppet[:certname] = 'doesnotexist'
|
157
|
+
sslctx = subject.create_system_context(cacerts: [], include_client_cert: true)
|
158
|
+
expect(sslctx.client_cert).to be_nil
|
159
|
+
expect(sslctx.private_key).to be_nil
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'warns if the client cert does not exist' do
|
163
|
+
Puppet[:certname] = 'missingcert'
|
164
|
+
Puppet[:hostprivkey] = fixtures('ssl/signed-key.pem')
|
165
|
+
|
166
|
+
expect(Puppet).to receive(:warning).with("Client certificate for 'missingcert' does not exist")
|
167
|
+
subject.create_system_context(cacerts: [], include_client_cert: true)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'warns if the private key does not exist' do
|
171
|
+
Puppet[:certname] = 'missingkey'
|
172
|
+
Puppet[:hostcert] = fixtures('ssl/signed.pem')
|
173
|
+
|
174
|
+
expect(Puppet).to receive(:warning).with("Private key for 'missingkey' does not exist")
|
175
|
+
subject.create_system_context(cacerts: [], include_client_cert: true)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'raises if client cert and private key are mismatched' do
|
179
|
+
Puppet[:hostcert] = fixtures('ssl/signed.pem')
|
180
|
+
Puppet[:hostprivkey] = fixtures('ssl/127.0.0.1-key.pem')
|
181
|
+
|
182
|
+
expect {
|
183
|
+
subject.create_system_context(cacerts: [], include_client_cert: true)
|
184
|
+
}.to raise_error(Puppet::SSL::SSLError,
|
185
|
+
"The certificate for 'CN=signed' does not match its private key")
|
186
|
+
end
|
187
|
+
|
138
188
|
it 'trusts additional system certs' do
|
139
189
|
path = tmpfile('system_cacerts')
|
140
190
|
File.write(path, cert_fixture('ca.pem').to_pem)
|
@@ -448,6 +498,18 @@ describe Puppet::SSL::SSLProvider do
|
|
448
498
|
sslctx = subject.create_context(**config)
|
449
499
|
expect(sslctx.verify_peer).to eq(true)
|
450
500
|
end
|
501
|
+
|
502
|
+
it 'does not trust the system ca store by default' do
|
503
|
+
expect_any_instance_of(OpenSSL::X509::Store).to receive(:set_default_paths).never
|
504
|
+
|
505
|
+
subject.create_context(**config)
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'trusts the system ca store' do
|
509
|
+
expect_any_instance_of(OpenSSL::X509::Store).to receive(:set_default_paths)
|
510
|
+
|
511
|
+
subject.create_context(**config.merge(include_system_store: true))
|
512
|
+
end
|
451
513
|
end
|
452
514
|
|
453
515
|
context 'when loading an ssl context' do
|
@@ -528,6 +590,18 @@ describe Puppet::SSL::SSLProvider do
|
|
528
590
|
subject.load_context(password: 'wrongpassword')
|
529
591
|
}.to raise_error(Puppet::SSL::SSLError, /Failed to load private key for host 'signed': Could not parse PKey/)
|
530
592
|
end
|
593
|
+
|
594
|
+
it 'does not trust the system ca store by default' do
|
595
|
+
expect_any_instance_of(OpenSSL::X509::Store).to receive(:set_default_paths).never
|
596
|
+
|
597
|
+
subject.load_context
|
598
|
+
end
|
599
|
+
|
600
|
+
it 'trusts the system ca store' do
|
601
|
+
expect_any_instance_of(OpenSSL::X509::Store).to receive(:set_default_paths)
|
602
|
+
|
603
|
+
subject.load_context(include_system_store: true)
|
604
|
+
end
|
531
605
|
end
|
532
606
|
|
533
607
|
context 'when verifying requests' do
|
@@ -27,6 +27,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
27
27
|
let(:refused_message) { %r{Connection refused|No connection could be made because the target machine actively refused it} }
|
28
28
|
|
29
29
|
before(:each) do
|
30
|
+
Puppet[:daemonize] = false
|
30
31
|
Puppet[:ssl_lockfile] = tmpfile('ssllock')
|
31
32
|
allow(Kernel).to receive(:sleep)
|
32
33
|
end
|
@@ -138,6 +138,57 @@ describe Puppet::Transaction::Persistence do
|
|
138
138
|
persistence = Puppet::Transaction::Persistence.new
|
139
139
|
expect(persistence.load.dig("File[/tmp/audit]", "parameters", "mtime", "system_value")).to contain_exactly(be_a(Time))
|
140
140
|
end
|
141
|
+
|
142
|
+
it 'should load Regexp' do
|
143
|
+
write_state_file(<<~END)
|
144
|
+
system_value:
|
145
|
+
- !ruby/regexp /regexp/
|
146
|
+
END
|
147
|
+
|
148
|
+
persistence = Puppet::Transaction::Persistence.new
|
149
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Regexp))
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should load semantic puppet version' do
|
153
|
+
write_state_file(<<~END)
|
154
|
+
system_value:
|
155
|
+
- !ruby/object:SemanticPuppet::Version
|
156
|
+
major: 1
|
157
|
+
minor: 0
|
158
|
+
patch: 0
|
159
|
+
prerelease:
|
160
|
+
build:
|
161
|
+
END
|
162
|
+
|
163
|
+
persistence = Puppet::Transaction::Persistence.new
|
164
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(SemanticPuppet::Version))
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should load puppet time related objects' do
|
168
|
+
write_state_file(<<~END)
|
169
|
+
system_value:
|
170
|
+
- !ruby/object:Puppet::Pops::Time::Timestamp
|
171
|
+
nsecs: 1638316135955087259
|
172
|
+
- !ruby/object:Puppet::Pops::Time::TimeData
|
173
|
+
nsecs: 1495789430910161286
|
174
|
+
- !ruby/object:Puppet::Pops::Time::Timespan
|
175
|
+
nsecs: 1495789430910161286
|
176
|
+
END
|
177
|
+
|
178
|
+
persistence = Puppet::Transaction::Persistence.new
|
179
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Puppet::Pops::Time::Timestamp), be_a(Puppet::Pops::Time::TimeData), be_a(Puppet::Pops::Time::Timespan))
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should load binary objects' do
|
183
|
+
write_state_file(<<~END)
|
184
|
+
system_value:
|
185
|
+
- !ruby/object:Puppet::Pops::Types::PBinaryType::Binary
|
186
|
+
binary_buffer: ''
|
187
|
+
END
|
188
|
+
|
189
|
+
persistence = Puppet::Transaction::Persistence.new
|
190
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Puppet::Pops::Types::PBinaryType::Binary))
|
191
|
+
end
|
141
192
|
end
|
142
193
|
end
|
143
194
|
|