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
@@ -7,6 +7,7 @@ describe 'lookup' do
|
|
7
7
|
include PuppetSpec::Files
|
8
8
|
|
9
9
|
context 'with an environment' do
|
10
|
+
let(:fqdn) { Puppet[:certname] }
|
10
11
|
let(:env_name) { 'spec' }
|
11
12
|
let(:env_dir) { tmpdir('environments') }
|
12
13
|
let(:environment_files) do
|
@@ -42,94 +43,117 @@ describe 'lookup' do
|
|
42
43
|
end
|
43
44
|
|
44
45
|
let(:app) { Puppet::Application[:lookup] }
|
45
|
-
let(:
|
46
|
-
let(:
|
46
|
+
let(:facts) { Puppet::Node::Facts.new("facts", {'my_fact' => 'my_fact_value'}) }
|
47
|
+
let(:cert) { pem_content('oid.pem') }
|
47
48
|
|
49
|
+
let(:node) { Puppet::Node.new('testnode', :facts => facts) }
|
48
50
|
let(:populated_env_dir) do
|
49
51
|
dir_contained_in(env_dir, environment_files)
|
50
52
|
env_dir
|
51
53
|
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
allow(
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
else
|
60
|
-
app.options[:render_as] = :json
|
61
|
-
end
|
62
|
-
options.each_pair { |k, v| app.options[k] = v }
|
63
|
-
capture = StringIO.new
|
64
|
-
saved_stdout = $stdout
|
65
|
-
begin
|
66
|
-
$stdout = capture
|
67
|
-
expect { app.run_command }.to exit_with(0)
|
68
|
-
ensure
|
69
|
-
$stdout = saved_stdout
|
70
|
-
end
|
71
|
-
out = capture.string.strip
|
72
|
-
if explain
|
73
|
-
out
|
74
|
-
else
|
75
|
-
out.empty? ? nil : JSON.parse("[#{out}]")[0]
|
76
|
-
end
|
77
|
-
end
|
55
|
+
before do
|
56
|
+
stub_request(:get, "https://puppet:8140/puppet-ca/v1/certificate/#{fqdn}").to_return(body: cert)
|
57
|
+
allow(Puppet::Node::Facts.indirection).to receive(:find).and_return(facts)
|
58
|
+
|
59
|
+
Puppet[:environment] = env_name
|
60
|
+
Puppet[:environmentpath] = populated_env_dir
|
78
61
|
|
79
|
-
|
80
|
-
|
62
|
+
http = Puppet::HTTP::Client.new(ssl_context: Puppet::SSL::SSLProvider.new.create_insecure_context)
|
63
|
+
Puppet.runtime[:http] = http
|
81
64
|
end
|
82
65
|
|
83
|
-
|
84
|
-
|
85
|
-
example.run
|
86
|
-
end
|
66
|
+
def expect_lookup_with_output(exitcode, out)
|
67
|
+
expect { app.run }.to exit_with(exitcode).and output(out).to_stdout
|
87
68
|
end
|
88
69
|
|
89
70
|
it 'finds data in the environment' do
|
90
|
-
|
71
|
+
app.command_line.args << 'a'
|
72
|
+
expect_lookup_with_output(0, /value a/)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "resolves hiera data using a top-level node parameter" do
|
76
|
+
File.write(File.join(env_dir, env_name, 'hiera.yaml'), <<~YAML)
|
77
|
+
---
|
78
|
+
version: 5
|
79
|
+
hierarchy:
|
80
|
+
- name: "Per Node"
|
81
|
+
data_hash: yaml_data
|
82
|
+
path: "%{my_fact}.yaml"
|
83
|
+
YAML
|
84
|
+
|
85
|
+
File.write(File.join(env_dir, env_name, 'data', "my_fact_value.yaml"), <<~YAML)
|
86
|
+
---
|
87
|
+
a: value from per node data
|
88
|
+
YAML
|
89
|
+
|
90
|
+
app.command_line.args << 'a'
|
91
|
+
expect_lookup_with_output(0, /--- value from per node data/)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'loads trusted information from the node certificate' do
|
95
|
+
Puppet.settings[:node_terminus] = 'exec'
|
96
|
+
expect_any_instance_of(Puppet::Node::Exec).to receive(:find) do |args|
|
97
|
+
info = Puppet.lookup(:trusted_information)
|
98
|
+
expect(info.certname).to eq(fqdn)
|
99
|
+
expect(info.extensions).to eq({ "1.3.6.1.4.1.34380.1.2.1.1" => "somevalue" })
|
100
|
+
end.and_return(node)
|
101
|
+
|
102
|
+
app.command_line.args << 'a' << '--compile'
|
103
|
+
expect_lookup_with_output(0, /--- value a/)
|
91
104
|
end
|
92
105
|
|
93
106
|
it 'loads external facts when running without --node' do
|
94
107
|
expect(Puppet::Util).not_to receive(:skip_external_facts)
|
95
108
|
expect(Facter).not_to receive(:load_external)
|
96
|
-
|
109
|
+
|
110
|
+
app.command_line.args << 'a'
|
111
|
+
expect_lookup_with_output(0, /--- value a/)
|
97
112
|
end
|
98
113
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
114
|
+
describe 'when using --node' do
|
115
|
+
let(:fqdn) { 'random_node' }
|
116
|
+
|
117
|
+
it 'skips loading of external facts' do
|
118
|
+
app.command_line.args << 'a' << '--node' << fqdn
|
119
|
+
|
120
|
+
expect(Puppet::Node::Facts.indirection).to receive(:find).and_return(facts)
|
121
|
+
expect(Facter).to receive(:load_external).twice.with(false)
|
122
|
+
expect(Facter).to receive(:load_external).twice.with(true)
|
123
|
+
expect_lookup_with_output(0, /--- value a/)
|
124
|
+
end
|
104
125
|
end
|
105
126
|
|
106
127
|
context 'uses node_terminus' do
|
107
128
|
require 'puppet/indirector/node/exec'
|
108
129
|
require 'puppet/indirector/node/plain'
|
109
130
|
|
110
|
-
let(:node) { Puppet::Node.new('testnode', :
|
131
|
+
let(:node) { Puppet::Node.new('testnode', :facts => facts) }
|
111
132
|
|
112
133
|
it ':plain without --compile' do
|
113
134
|
Puppet.settings[:node_terminus] = 'exec'
|
114
135
|
expect_any_instance_of(Puppet::Node::Plain).to receive(:find).and_return(node)
|
115
136
|
expect_any_instance_of(Puppet::Node::Exec).not_to receive(:find)
|
116
|
-
|
137
|
+
|
138
|
+
app.command_line.args << 'a'
|
139
|
+
expect_lookup_with_output(0, /--- value a/)
|
117
140
|
end
|
118
141
|
|
119
142
|
it 'configured in Puppet settings with --compile' do
|
120
143
|
Puppet.settings[:node_terminus] = 'exec'
|
121
144
|
expect_any_instance_of(Puppet::Node::Plain).not_to receive(:find)
|
122
145
|
expect_any_instance_of(Puppet::Node::Exec).to receive(:find).and_return(node)
|
123
|
-
|
146
|
+
|
147
|
+
app.command_line.args << 'a' << '--compile'
|
148
|
+
expect_lookup_with_output(0, /--- value a/)
|
124
149
|
end
|
125
150
|
end
|
126
151
|
|
127
152
|
context 'configured with the wrong environment' do
|
128
|
-
let(:env) { Puppet::Node::Environment.create(env_name.to_sym, [File.join(populated_env_dir, env_name, 'modules')]) }
|
129
153
|
it 'does not find data in non-existing environment' do
|
130
|
-
Puppet
|
131
|
-
|
132
|
-
|
154
|
+
Puppet[:environment] = 'doesntexist'
|
155
|
+
app.command_line.args << 'a'
|
156
|
+
expect { app.run }.to raise_error(Puppet::Environments::EnvironmentNotFound, /Could not find a directory environment named 'doesntexist'/)
|
133
157
|
end
|
134
158
|
end
|
135
159
|
|
@@ -174,15 +198,22 @@ describe 'lookup' do
|
|
174
198
|
end
|
175
199
|
|
176
200
|
it 'finds data in the module' do
|
177
|
-
|
201
|
+
app.command_line.args << 'mod_a::b'
|
202
|
+
expect_lookup_with_output(0, /value mod_a::b \(from mod_a\)/)
|
178
203
|
end
|
179
204
|
|
180
205
|
it 'finds quoted keys in the module' do
|
181
|
-
|
206
|
+
app.command_line.args << "'mod_a::a.quoted.key'"
|
207
|
+
expect_lookup_with_output(0, /value mod_a::a.quoted.key \(from mod_a\)/)
|
182
208
|
end
|
183
209
|
|
184
210
|
it 'merges hashes from environment and module when merge strategy hash is used' do
|
185
|
-
|
211
|
+
app.command_line.args << 'mod_a::hash_a' << '--merge' << 'hash'
|
212
|
+
expect_lookup_with_output(0, <<~END)
|
213
|
+
---
|
214
|
+
a: value mod_a::hash_a.a (from environment)
|
215
|
+
b: value mod_a::hash_a.b (from mod_a)
|
216
|
+
END
|
186
217
|
end
|
187
218
|
end
|
188
219
|
end
|
@@ -28,14 +28,18 @@ describe "puppet resource", unless: Puppet::Util::Platform.jruby? do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'lists types from the default environment' do
|
31
|
+
begin
|
31
32
|
modulepath = File.join(Puppet[:codedir], 'modules', 'test', 'lib', 'puppet', 'type')
|
32
33
|
FileUtils.mkdir_p(modulepath)
|
33
|
-
File.write(File.join(modulepath, '
|
34
|
+
File.write(File.join(modulepath, 'test_resource_spec.rb'), 'Puppet::Type.newtype(:test_resource_spec)')
|
34
35
|
resource.command_line.args = ['--types']
|
35
36
|
|
36
37
|
expect {
|
37
38
|
resource.run
|
38
|
-
}.to exit_with(0).and output(/
|
39
|
+
}.to exit_with(0).and output(/test_resource_spec/).to_stdout
|
40
|
+
ensure
|
41
|
+
Puppet::Type.rmtype(:test_resource_spec)
|
42
|
+
end
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
@@ -77,7 +77,13 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
77
77
|
}
|
78
78
|
}
|
79
79
|
|
80
|
-
|
80
|
+
let(:cert_file) do
|
81
|
+
res = tmpfile('cert_file')
|
82
|
+
File.write(res, https_server.ca_cert)
|
83
|
+
res
|
84
|
+
end
|
85
|
+
|
86
|
+
it "mutually authenticates the connection using an explicit context" do
|
81
87
|
client_context = ssl_provider.create_context(
|
82
88
|
cacerts: [https_server.ca_cert], crls: [https_server.ca_crl],
|
83
89
|
client_cert: https_server.server_cert, private_key: https_server.server_key
|
@@ -88,6 +94,47 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
88
94
|
expect(res).to be_success
|
89
95
|
end
|
90
96
|
end
|
97
|
+
|
98
|
+
it "mutually authenticates the connection when the client and server certs are issued from different CAs" do
|
99
|
+
# this is the client cert's CA, key and cert
|
100
|
+
Puppet[:localcacert] = fixtures('ssl/unknown-ca.pem')
|
101
|
+
Puppet[:hostprivkey] = fixtures('ssl/unknown-127.0.0.1-key.pem')
|
102
|
+
Puppet[:hostcert] = fixtures('ssl/unknown-127.0.0.1.pem')
|
103
|
+
|
104
|
+
# this is the server cert's CA that the client needs in order to authenticate the server
|
105
|
+
Puppet[:ssl_trust_store] = fixtures('ssl/ca.pem')
|
106
|
+
|
107
|
+
# need to pass both the client and server CAs. The former is needed so the server can authenticate our client cert
|
108
|
+
https_server = PuppetSpec::HTTPSServer.new(ca_cert: [cert_fixture('ca.pem'), cert_fixture('unknown-ca.pem')])
|
109
|
+
https_server.start_server(ctx_proc: ctx_proc) do |port|
|
110
|
+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {include_system_store: true})
|
111
|
+
expect(res).to be_success
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it "connects when the server's CA is in the system store and the connection is mutually authenticated using create_context" do
|
116
|
+
Puppet::Util.withenv("SSL_CERT_FILE" => cert_file) do
|
117
|
+
client_context = ssl_provider.create_context(
|
118
|
+
cacerts: [], crls: [],
|
119
|
+
client_cert: https_server.server_cert, private_key: https_server.server_key,
|
120
|
+
revocation: false, include_system_store: true
|
121
|
+
)
|
122
|
+
https_server.start_server(ctx_proc: ctx_proc) do |port|
|
123
|
+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: client_context})
|
124
|
+
expect(res).to be_success
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it "connects when the server's CA is in the system store and the connection is mutually authenticated using load_context" do
|
130
|
+
Puppet::Util.withenv("SSL_CERT_FILE" => cert_file) do
|
131
|
+
client_context = ssl_provider.load_context(revocation: false, include_system_store: true)
|
132
|
+
https_server.start_server(ctx_proc: ctx_proc) do |port|
|
133
|
+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: client_context})
|
134
|
+
expect(res).to be_success
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
91
138
|
end
|
92
139
|
|
93
140
|
context "with a system trust store" do
|
@@ -102,12 +149,12 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
102
149
|
|
103
150
|
it "connects when the server's CA is in the system store" do
|
104
151
|
# create a temp cacert bundle
|
105
|
-
|
106
|
-
File.write(
|
152
|
+
cert_file = tmpfile('cert_file')
|
153
|
+
File.write(cert_file, https_server.ca_cert)
|
107
154
|
|
108
155
|
# override path to system cacert bundle, this must be done before
|
109
156
|
# the SSLContext is created and the call to X509::Store.set_default_paths
|
110
|
-
Puppet::Util.withenv("SSL_CERT_FILE" =>
|
157
|
+
Puppet::Util.withenv("SSL_CERT_FILE" => cert_file) do
|
111
158
|
system_context = ssl_provider.create_system_context(cacerts: [])
|
112
159
|
https_server.start_server do |port|
|
113
160
|
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
|
@@ -40,7 +40,7 @@ class PuppetSpec::HTTPSServer
|
|
40
40
|
|
41
41
|
IO.pipe {|stop_pipe_r, stop_pipe_w|
|
42
42
|
store = OpenSSL::X509::Store.new
|
43
|
-
store.add_cert(
|
43
|
+
Array(@ca_cert).each { |c| store.add_cert(c) }
|
44
44
|
store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
|
45
45
|
ctx = OpenSSL::SSL::SSLContext.new
|
46
46
|
ctx.cert_store = store
|
@@ -72,6 +72,40 @@ class PuppetSpec::Puppetserver
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
class CertificateServlet < WEBrick::HTTPServlet::AbstractServlet
|
76
|
+
def initialize(server, ca_cert)
|
77
|
+
super(server)
|
78
|
+
@ca_cert = ca_cert
|
79
|
+
end
|
80
|
+
|
81
|
+
def do_GET request, response
|
82
|
+
if request.path =~ %r{/puppet-ca/v1/certificate/ca$}
|
83
|
+
response['Content-Type'] = 'text/plain'
|
84
|
+
response.body = @ca_cert.to_pem
|
85
|
+
else
|
86
|
+
response.status = 404
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class CertificateRevocationListServlet < WEBrick::HTTPServlet::AbstractServlet
|
92
|
+
def initialize(server, crl)
|
93
|
+
super(server)
|
94
|
+
@crl = crl
|
95
|
+
end
|
96
|
+
|
97
|
+
def do_GET request, response
|
98
|
+
response['Content-Type'] = 'text/plain'
|
99
|
+
response.body = @crl.to_pem
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class CertificateRequestServlet < WEBrick::HTTPServlet::AbstractServlet
|
104
|
+
def do_PUT request, response
|
105
|
+
response.status = 404
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
75
109
|
def initialize
|
76
110
|
@ca_cert = cert_fixture('ca.pem')
|
77
111
|
@ca_crl = crl_fixture('crl.pem')
|
@@ -125,15 +159,18 @@ class PuppetSpec::Puppetserver
|
|
125
159
|
register_mount('/puppet/v3/static_file_content', mounts[:static_file_content], StaticFileContentServlet)
|
126
160
|
register_mount('/puppet/v3/report', mounts[:report], ReportServlet)
|
127
161
|
register_mount('/puppet/v3/file_bucket_file', mounts[:filebucket], FilebucketServlet)
|
162
|
+
register_mount('/puppet-ca/v1/certificate', mounts[:certificate], CertificateServlet, @ca_cert)
|
163
|
+
register_mount('/puppet-ca/v1/certificate_revocation_list', mounts[:certificate_revocation_list], CertificateRevocationListServlet, @ca_crl)
|
164
|
+
register_mount('/puppet-ca/v1/certificate_request', mounts[:certificate_request], CertificateRequestServlet)
|
128
165
|
end
|
129
166
|
|
130
|
-
def register_mount(path, user_proc, default_servlet)
|
167
|
+
def register_mount(path, user_proc, default_servlet, *args)
|
131
168
|
handler = if user_proc
|
132
169
|
WEBrick::HTTPServlet::ProcHandler.new(user_proc)
|
133
170
|
else
|
134
171
|
default_servlet
|
135
172
|
end
|
136
|
-
@https.mount(path, handler)
|
173
|
+
@https.mount(path, handler, *args)
|
137
174
|
end
|
138
175
|
|
139
176
|
def upload_directory
|
@@ -4,7 +4,11 @@ RSpec.shared_context('l10n') do |locale|
|
|
4
4
|
before :all do
|
5
5
|
@old_locale = Locale.current
|
6
6
|
Locale.current = locale
|
7
|
+
|
8
|
+
@old_gettext_disabled = Puppet::GettextConfig.instance_variable_get(:@gettext_disabled)
|
9
|
+
Puppet::GettextConfig.instance_variable_set(:@gettext_disabled, false)
|
7
10
|
Puppet::GettextConfig.setup_locale
|
11
|
+
Puppet::GettextConfig.create_default_text_domain
|
8
12
|
|
9
13
|
# overwrite stubs with real implementation
|
10
14
|
::Object.send(:remove_method, :_)
|
@@ -17,6 +21,7 @@ RSpec.shared_context('l10n') do |locale|
|
|
17
21
|
after :all do
|
18
22
|
Locale.current = @old_locale
|
19
23
|
|
24
|
+
Puppet::GettextConfig.instance_variable_set(:@gettext_disabled, @old_gettext_disabled)
|
20
25
|
# restore stubs
|
21
26
|
load File.expand_path(File.join(__dir__, '../../lib/puppet/gettext/stubs.rb'))
|
22
27
|
end
|
data/spec/unit/agent_spec.rb
CHANGED
@@ -38,6 +38,10 @@ describe Puppet::Agent do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
ssl_context = Puppet::SSL::SSLContext.new
|
43
|
+
machine = instance_double("Puppet::SSL::StateMachine", ensure_client_certificate: ssl_context)
|
44
|
+
allow(Puppet::SSL::StateMachine).to receive(:new).and_return(machine)
|
41
45
|
end
|
42
46
|
|
43
47
|
after do
|
@@ -99,6 +103,8 @@ describe Puppet::Agent do
|
|
99
103
|
end
|
100
104
|
|
101
105
|
it "should splay" do
|
106
|
+
Puppet[:splay] = true
|
107
|
+
|
102
108
|
expect(@agent).to receive(:splay)
|
103
109
|
|
104
110
|
@agent.run
|
@@ -181,6 +187,26 @@ describe Puppet::Agent do
|
|
181
187
|
expect(@agent.run).to eq(:result)
|
182
188
|
end
|
183
189
|
|
190
|
+
it "should check if it's disabled after splaying and log a message" do
|
191
|
+
Puppet[:splay] = true
|
192
|
+
Puppet[:splaylimit] = '5s'
|
193
|
+
Puppet[:onetime] = true
|
194
|
+
|
195
|
+
expect(@agent).to receive(:disabled?).and_return(false, true)
|
196
|
+
|
197
|
+
allow(Puppet).to receive(:notice).and_call_original
|
198
|
+
expect(Puppet).to receive(:notice).with(/Skipping run of .*; administratively disabled.*/)
|
199
|
+
@agent.run
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should check if it's disabled after acquiring the lock and log a message" do
|
203
|
+
expect(@agent).to receive(:disabled?).and_return(false, true)
|
204
|
+
|
205
|
+
allow(Puppet).to receive(:notice).and_call_original
|
206
|
+
expect(Puppet).to receive(:notice).with(/Skipping run of .*; administratively disabled.*/)
|
207
|
+
@agent.run
|
208
|
+
end
|
209
|
+
|
184
210
|
describe "and a puppet agent is already running" do
|
185
211
|
before(:each) do
|
186
212
|
allow_any_instance_of(Object).to receive(:sleep)
|
@@ -197,7 +223,7 @@ describe Puppet::Agent do
|
|
197
223
|
@agent.run
|
198
224
|
end
|
199
225
|
|
200
|
-
it "should inform that a run is already in
|
226
|
+
it "should inform that a run is already in progress and try to run every X seconds if waitforlock is used" do
|
201
227
|
# so the locked file exists
|
202
228
|
allow(File).to receive(:file?).and_return(true)
|
203
229
|
# so we don't have to wait again for the run to exit (default maxwaitforcert is 60)
|
@@ -226,7 +252,7 @@ describe Puppet::Agent do
|
|
226
252
|
@agent.run
|
227
253
|
end
|
228
254
|
end
|
229
|
-
|
255
|
+
|
230
256
|
describe "when should_fork is true", :if => Puppet.features.posix? && RUBY_PLATFORM != 'java' do
|
231
257
|
before do
|
232
258
|
@agent = Puppet::Agent.new(AgentTestClient, true)
|
@@ -4,6 +4,11 @@ require 'puppet/agent'
|
|
4
4
|
require 'puppet/application/agent'
|
5
5
|
require 'puppet/daemon'
|
6
6
|
|
7
|
+
class TestAgentClientClass
|
8
|
+
def initialize(transaction_uuid = nil, job_id = nil); end
|
9
|
+
def run(options = {}); end
|
10
|
+
end
|
11
|
+
|
7
12
|
describe Puppet::Application::Agent do
|
8
13
|
include PuppetSpec::Files
|
9
14
|
|
@@ -12,13 +17,20 @@ describe Puppet::Application::Agent do
|
|
12
17
|
before :each do
|
13
18
|
@puppetd = Puppet::Application[:agent]
|
14
19
|
|
15
|
-
@
|
20
|
+
@client = TestAgentClientClass.new
|
21
|
+
allow(TestAgentClientClass).to receive(:new).and_return(@client)
|
22
|
+
|
23
|
+
@agent = Puppet::Agent.new(TestAgentClientClass, false)
|
16
24
|
allow(Puppet::Agent).to receive(:new).and_return(@agent)
|
17
25
|
|
18
|
-
|
26
|
+
Puppet[:pidfile] = tmpfile('pidfile')
|
27
|
+
@daemon = Puppet::Daemon.new(@agent, Puppet::Util::Pidlock.new(Puppet[:pidfile]))
|
19
28
|
allow(@daemon).to receive(:daemonize)
|
20
|
-
allow(@daemon).to receive(:start)
|
21
29
|
allow(@daemon).to receive(:stop)
|
30
|
+
# simulate one run so we don't infinite looptwo runs of the agent, then return so we don't infinite loop
|
31
|
+
allow(@daemon).to receive(:run_event_loop) do
|
32
|
+
@agent.run(splay: false)
|
33
|
+
end
|
22
34
|
allow(Puppet::Daemon).to receive(:new).and_return(@daemon)
|
23
35
|
Puppet[:daemonize] = false
|
24
36
|
|
@@ -92,10 +104,6 @@ describe Puppet::Application::Agent do
|
|
92
104
|
end
|
93
105
|
|
94
106
|
describe "when handling options" do
|
95
|
-
before do
|
96
|
-
allow(@puppetd.command_line).to receive(:args).and_return([])
|
97
|
-
end
|
98
|
-
|
99
107
|
[:enable, :debug, :fqdn, :test, :verbose, :digest].each do |option|
|
100
108
|
it "should declare handle_#{option} method" do
|
101
109
|
expect(@puppetd).to respond_to("handle_#{option}".to_sym)
|
@@ -127,32 +135,34 @@ describe Puppet::Application::Agent do
|
|
127
135
|
end
|
128
136
|
|
129
137
|
it "should set waitforcert to 0 with --onetime and if --waitforcert wasn't given" do
|
130
|
-
allow(@
|
138
|
+
allow(@client).to receive(:run).and_return(2)
|
131
139
|
Puppet[:onetime] = true
|
132
140
|
|
133
|
-
expect(Puppet::SSL::StateMachine).to receive(:new).with(waitforcert: 0).and_return(machine)
|
141
|
+
expect(Puppet::SSL::StateMachine).to receive(:new).with(hash_including(waitforcert: 0)).and_return(machine)
|
134
142
|
|
135
143
|
expect { execute_agent }.to exit_with 0
|
136
144
|
end
|
137
145
|
|
138
146
|
it "should use supplied waitforcert when --onetime is specified" do
|
139
|
-
allow(@
|
147
|
+
allow(@client).to receive(:run).and_return(2)
|
140
148
|
Puppet[:onetime] = true
|
141
149
|
@puppetd.handle_waitforcert(60)
|
142
150
|
|
143
|
-
expect(Puppet::SSL::StateMachine).to receive(:new).with(waitforcert: 60).and_return(machine)
|
151
|
+
expect(Puppet::SSL::StateMachine).to receive(:new).with(hash_including(waitforcert: 60)).and_return(machine)
|
144
152
|
|
145
153
|
expect { execute_agent }.to exit_with 0
|
146
154
|
end
|
147
155
|
|
148
156
|
it "should use a default value for waitforcert when --onetime and --waitforcert are not specified" do
|
149
|
-
|
157
|
+
allow(@client).to receive(:run).and_return(2)
|
158
|
+
|
159
|
+
expect(Puppet::SSL::StateMachine).to receive(:new).with(hash_including(waitforcert: 120)).and_return(machine)
|
150
160
|
|
151
161
|
execute_agent
|
152
162
|
end
|
153
163
|
|
154
164
|
it "should register ssl OIDs" do
|
155
|
-
expect(Puppet::SSL::StateMachine).to receive(:new).with(waitforcert: 120).and_return(
|
165
|
+
expect(Puppet::SSL::StateMachine).to receive(:new).with(hash_including(waitforcert: 120)).and_return(machine)
|
156
166
|
expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
|
157
167
|
|
158
168
|
execute_agent
|
@@ -161,7 +171,7 @@ describe Puppet::Application::Agent do
|
|
161
171
|
it "should use the waitforcert setting when checking for a signed certificate" do
|
162
172
|
Puppet[:waitforcert] = 10
|
163
173
|
|
164
|
-
expect(Puppet::SSL::StateMachine).to receive(:new).with(waitforcert: 10).and_return(machine)
|
174
|
+
expect(Puppet::SSL::StateMachine).to receive(:new).with(hash_including(waitforcert: 10)).and_return(machine)
|
165
175
|
|
166
176
|
execute_agent
|
167
177
|
end
|
@@ -413,9 +423,9 @@ describe Puppet::Application::Agent do
|
|
413
423
|
end
|
414
424
|
|
415
425
|
it "should wait for a certificate" do
|
416
|
-
|
426
|
+
Puppet[:waitforcert] = 123
|
417
427
|
|
418
|
-
expect(Puppet::SSL::StateMachine).to receive(:new).with(waitforcert: 123).and_return(machine)
|
428
|
+
expect(Puppet::SSL::StateMachine).to receive(:new).with(hash_including(waitforcert: 123)).and_return(machine)
|
419
429
|
|
420
430
|
execute_agent
|
421
431
|
end
|