puppet 6.14.0 → 6.15.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/Gemfile.lock +15 -15
- data/ext/windows/service/daemon.rb +3 -3
- data/lib/puppet.rb +1 -1
- data/lib/puppet/agent.rb +2 -10
- data/lib/puppet/application/agent.rb +2 -1
- data/lib/puppet/application/filebucket.rb +5 -14
- data/lib/puppet/application/ssl.rb +2 -2
- data/lib/puppet/configurer.rb +7 -3
- data/lib/puppet/configurer/plugin_handler.rb +1 -1
- data/lib/puppet/defaults.rb +22 -2
- data/lib/puppet/environments.rb +4 -5
- data/lib/puppet/face/plugin.rb +1 -1
- data/lib/puppet/file_system/file_impl.rb +13 -9
- data/lib/puppet/forge/repository.rb +1 -1
- data/lib/puppet/functions/call.rb +1 -1
- data/lib/puppet/functions/reduce.rb +2 -4
- data/lib/puppet/http.rb +2 -0
- data/lib/puppet/http/client.rb +191 -52
- data/lib/puppet/http/external_client.rb +96 -0
- data/lib/puppet/http/redirector.rb +34 -0
- data/lib/puppet/http/resolver.rb +46 -3
- data/lib/puppet/http/resolver/server_list.rb +75 -15
- data/lib/puppet/http/resolver/settings.rb +22 -2
- data/lib/puppet/http/resolver/srv.rb +28 -2
- data/lib/puppet/http/response.rb +63 -1
- data/lib/puppet/http/retry_after_handler.rb +39 -0
- data/lib/puppet/http/service.rb +67 -1
- data/lib/puppet/http/service/ca.rb +71 -9
- data/lib/puppet/http/service/compiler.rb +213 -11
- data/lib/puppet/http/service/file_server.rb +105 -4
- data/lib/puppet/http/service/report.rb +36 -3
- data/lib/puppet/http/session.rb +59 -8
- data/lib/puppet/indirector/catalog/rest.rb +2 -1
- data/lib/puppet/indirector/facts/rest.rb +2 -1
- data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
- data/lib/puppet/indirector/file_metadata/rest.rb +4 -2
- data/lib/puppet/indirector/node/rest.rb +2 -1
- data/lib/puppet/indirector/report/yaml.rb +23 -0
- data/lib/puppet/indirector/status/rest.rb +2 -1
- data/lib/puppet/metatype/manager.rb +80 -80
- data/lib/puppet/network/http/base_pool.rb +6 -1
- data/lib/puppet/network/http/pool.rb +2 -4
- data/lib/puppet/network/http_pool.rb +1 -0
- data/lib/puppet/node/environment.rb +11 -1
- data/lib/puppet/pal/pal_impl.rb +1 -29
- data/lib/puppet/parser/compiler.rb +14 -7
- data/lib/puppet/parser/functions.rb +18 -13
- data/lib/puppet/pops/loaders.rb +7 -5
- data/lib/puppet/provider/group/windows_adsi.rb +3 -3
- data/lib/puppet/provider/package/apt.rb +61 -1
- data/lib/puppet/provider/package/dnfmodule.rb +39 -12
- data/lib/puppet/provider/package/gem.rb +41 -7
- data/lib/puppet/provider/package/pacman.rb +2 -5
- data/lib/puppet/provider/package/pip.rb +105 -33
- data/lib/puppet/provider/package/pip3.rb +0 -2
- data/lib/puppet/provider/package/pkgdmg.rb +1 -1
- data/lib/puppet/provider/package/pkgng.rb +16 -4
- data/lib/puppet/provider/package/puppet_gem.rb +6 -2
- data/lib/puppet/provider/package/rpm.rb +6 -213
- data/lib/puppet/provider/package/yum.rb +92 -19
- data/lib/puppet/provider/service/systemd.rb +2 -1
- data/lib/puppet/reports/http.rb +13 -11
- data/lib/puppet/resource/type_collection.rb +20 -16
- data/lib/puppet/ssl.rb +1 -0
- data/lib/puppet/ssl/host.rb +4 -4
- data/lib/puppet/ssl/oids.rb +1 -0
- data/lib/puppet/ssl/state_machine.rb +50 -33
- data/lib/puppet/transaction/report.rb +2 -2
- data/lib/puppet/type.rb +6 -1
- data/lib/puppet/type/file/source.rb +4 -2
- data/lib/puppet/type/package.rb +25 -2
- data/lib/puppet/type/user.rb +0 -19
- data/lib/puppet/util/at_fork.rb +1 -1
- data/lib/puppet/util/autoload.rb +3 -0
- data/lib/puppet/util/instance_loader.rb +14 -10
- data/lib/puppet/util/package/version/debian.rb +175 -0
- data/lib/puppet/util/package/version/gem.rb +15 -0
- data/lib/puppet/util/package/version/pip.rb +167 -0
- data/lib/puppet/util/package/version/range.rb +50 -0
- data/lib/puppet/util/package/version/range/gt.rb +14 -0
- data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
- data/lib/puppet/util/package/version/range/lt.rb +14 -0
- data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
- data/lib/puppet/util/package/version/range/min_max.rb +21 -0
- data/lib/puppet/util/package/version/range/simple.rb +11 -0
- data/lib/puppet/util/package/version/rpm.rb +73 -0
- data/lib/puppet/util/pidlock.rb +13 -7
- data/lib/puppet/util/platform.rb +5 -0
- data/lib/puppet/util/rpm_compare.rb +193 -0
- data/lib/puppet/util/windows/adsi.rb +2 -2
- data/lib/puppet/util/windows/process.rb +15 -14
- data/lib/puppet/util/windows/security.rb +1 -0
- data/lib/puppet/util/windows/sid.rb +3 -3
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +207 -201
- data/man/man5/puppet.conf.5 +11 -3
- 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 +1 -1
- 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/ssl/unknown-127.0.0.1-key.pem +67 -0
- data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
- data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
- data/spec/fixtures/ssl/unknown-ca.pem +59 -0
- data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list-enabled.txt} +2 -0
- data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
- data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
- data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
- data/spec/integration/application/agent_spec.rb +329 -0
- data/spec/integration/application/apply_spec.rb +132 -3
- data/spec/integration/application/filebucket_spec.rb +190 -0
- data/spec/integration/application/plugin_spec.rb +50 -0
- data/spec/integration/http/client_spec.rb +34 -40
- data/spec/integration/indirector/report/yaml.rb +83 -0
- data/spec/integration/module_tool/forge_spec.rb +2 -15
- data/spec/integration/network/http_pool_spec.rb +11 -19
- data/spec/integration/node/environment_spec.rb +15 -0
- data/spec/integration/util/windows/adsi_spec.rb +1 -1
- data/spec/lib/puppet/test_ca.rb +2 -2
- data/spec/lib/puppet_spec/https.rb +10 -7
- data/spec/lib/puppet_spec/puppetserver.rb +119 -0
- data/spec/shared_contexts/https.rb +29 -0
- data/spec/unit/agent_spec.rb +33 -25
- data/spec/unit/application/agent_spec.rb +5 -1
- data/spec/unit/application/device_spec.rb +2 -2
- data/spec/unit/application/filebucket_spec.rb +22 -2
- data/spec/unit/configurer_spec.rb +1 -1
- data/spec/unit/defaults_spec.rb +24 -1
- data/spec/unit/environments_spec.rb +8 -0
- data/spec/unit/file_system_spec.rb +10 -0
- data/spec/unit/http/client_spec.rb +105 -46
- data/spec/unit/http/external_client_spec.rb +201 -0
- data/spec/unit/http/resolver_spec.rb +20 -0
- data/spec/unit/http/service/ca_spec.rb +25 -2
- data/spec/unit/http/service/compiler_spec.rb +184 -6
- data/spec/unit/http/service/file_server_spec.rb +35 -3
- data/spec/unit/http/service/report_spec.rb +3 -1
- data/spec/unit/http/service_spec.rb +3 -3
- data/spec/unit/http/session_spec.rb +56 -7
- data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
- data/spec/unit/network/http/pool_spec.rb +3 -3
- data/spec/unit/node/environment_spec.rb +16 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
- data/spec/unit/provider/package/apt_spec.rb +30 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +33 -14
- data/spec/unit/provider/package/gem_spec.rb +40 -0
- data/spec/unit/provider/package/pacman_spec.rb +6 -21
- data/spec/unit/provider/package/pip_spec.rb +26 -3
- data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
- data/spec/unit/provider/package/pkgng_spec.rb +38 -0
- data/spec/unit/provider/package/puppet_gem_spec.rb +8 -0
- data/spec/unit/provider/package/rpm_spec.rb +0 -212
- data/spec/unit/provider/package/yum_spec.rb +235 -1
- data/spec/unit/provider/service/systemd_spec.rb +10 -1
- data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
- data/spec/unit/puppet_pal_2pec.rb +0 -29
- data/spec/unit/reports/http_spec.rb +70 -52
- data/spec/unit/ssl/host_spec.rb +4 -2
- data/spec/unit/ssl/oids_spec.rb +1 -0
- data/spec/unit/ssl/state_machine_spec.rb +38 -6
- data/spec/unit/transaction/report_spec.rb +4 -0
- data/spec/unit/util/at_fork_spec.rb +2 -2
- data/spec/unit/util/package/version/debian_spec.rb +83 -0
- data/spec/unit/util/package/version/pip_spec.rb +464 -0
- data/spec/unit/util/package/version/range_spec.rb +154 -0
- data/spec/unit/util/package/version/rpm_spec.rb +121 -0
- data/spec/unit/util/pidlock_spec.rb +83 -47
- data/spec/unit/util/rpm_compare_spec.rb +196 -0
- data/spec/unit/util/windows/adsi_spec.rb +4 -4
- data/spec/unit/util/windows/sid_spec.rb +2 -2
- data/tasks/generate_cert_fixtures.rake +15 -1
- metadata +51 -6
- data/spec/integration/faces/plugin_spec.rb +0 -63
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/face'
|
3
|
+
require 'puppet_spec/puppetserver'
|
4
|
+
require 'puppet_spec/files'
|
5
|
+
|
6
|
+
describe "puppet filebucket", unless: Puppet::Util::Platform.jruby? do
|
7
|
+
include PuppetSpec::Files
|
8
|
+
include_context "https client"
|
9
|
+
|
10
|
+
let(:server) { PuppetSpec::Puppetserver.new }
|
11
|
+
let(:filebucket) { Puppet::Application[:filebucket] }
|
12
|
+
let(:backup_file) { tmpfile('backup_file') }
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
Puppet[:log_level] = 'debug'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "backs up files to the filebucket server" do
|
19
|
+
File.binwrite(backup_file, 'some random text')
|
20
|
+
md5 = Digest::MD5.file(backup_file).to_s
|
21
|
+
|
22
|
+
server.start_server do |port|
|
23
|
+
Puppet[:masterport] = port
|
24
|
+
expect {
|
25
|
+
filebucket.command_line.args << 'backup'
|
26
|
+
filebucket.command_line.args << backup_file
|
27
|
+
filebucket.run
|
28
|
+
}.to output(a_string_matching(
|
29
|
+
%r{Debug: HTTP HEAD https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/#{md5}\/#{File.realpath(backup_file)}\?environment\=production returned 404 Not Found}
|
30
|
+
).and matching(
|
31
|
+
%r{Debug: HTTP PUT https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/#{md5}\/#{File.realpath(backup_file)}\?environment\=production returned 200 OK}
|
32
|
+
).and matching(
|
33
|
+
%r{#{backup_file}: #{md5}}
|
34
|
+
)).to_stdout
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "doesn't attempt to back up file that already exists on the filebucket server" do
|
39
|
+
file_exists_handler = -> (req, res) {
|
40
|
+
res.status = 200
|
41
|
+
}
|
42
|
+
|
43
|
+
File.binwrite(backup_file, 'some random text')
|
44
|
+
md5 = Digest::MD5.file(backup_file).to_s
|
45
|
+
|
46
|
+
server.start_server(mounts: {filebucket: file_exists_handler}) do |port|
|
47
|
+
Puppet[:masterport] = port
|
48
|
+
expect {
|
49
|
+
filebucket.command_line.args << 'backup'
|
50
|
+
filebucket.command_line.args << backup_file
|
51
|
+
filebucket.run
|
52
|
+
}.to output(a_string_matching(
|
53
|
+
%r{Debug: HTTP HEAD https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/#{md5}\/#{File.realpath(backup_file)}\?environment\=production returned 200 OK}
|
54
|
+
).and matching(
|
55
|
+
%r{#{backup_file}: #{md5}}
|
56
|
+
)).to_stdout
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "downloads files from the filebucket server" do
|
61
|
+
get_handler = -> (req, res) {
|
62
|
+
res['Content-Type'] = 'application/octet-stream'
|
63
|
+
res.body = 'something to store'
|
64
|
+
}
|
65
|
+
|
66
|
+
server.start_server(mounts: {filebucket: get_handler}) do |port|
|
67
|
+
Puppet[:masterport] = port
|
68
|
+
expect {
|
69
|
+
filebucket.command_line.args << 'get'
|
70
|
+
filebucket.command_line.args << 'fac251367c9e083c6b1f0f3181'
|
71
|
+
filebucket.run
|
72
|
+
}.to output(a_string_matching(
|
73
|
+
%r{Debug: HTTP GET https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/fac251367c9e083c6b1f0f3181\?environment\=production returned 200 OK}
|
74
|
+
).and matching(
|
75
|
+
%r{something to store}
|
76
|
+
)).to_stdout
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'diff', unless: Puppet::Util::Platform.windows? || Puppet::Util::Platform.jruby? do
|
81
|
+
context 'using a remote bucket' do
|
82
|
+
it 'outputs a diff between a local and remote file' do
|
83
|
+
File.binwrite(backup_file, "bar\nbaz")
|
84
|
+
|
85
|
+
get_handler = -> (req, res) {
|
86
|
+
res['Content-Type'] = 'application/octet-stream'
|
87
|
+
res.body = 'foo'
|
88
|
+
}
|
89
|
+
|
90
|
+
server.start_server(mounts: {filebucket: get_handler}) do |port|
|
91
|
+
Puppet[:masterport] = port
|
92
|
+
expect {
|
93
|
+
filebucket.command_line.args += ['diff', 'fac251367c9e083c6b1f0f3181', backup_file, '--remote']
|
94
|
+
filebucket.run
|
95
|
+
}.to output(a_string_matching(
|
96
|
+
/[-<] ?foo/
|
97
|
+
).and matching(
|
98
|
+
/[+>] ?bar/
|
99
|
+
).and matching(
|
100
|
+
/[+>] ?baz/
|
101
|
+
)).to_stdout
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'outputs a diff between two remote files' do
|
106
|
+
get_handler = -> (req, res) {
|
107
|
+
res['Content-Type'] = 'application/octet-stream'
|
108
|
+
res.body = <<~END
|
109
|
+
--- /opt/puppetlabs/server/data/puppetserver/bucket/d/3/b/0/7/3/8/4/d3b07384d113edec49eaa6238ad5ff00/contents\t2020-04-06 21:25:24.892367570 +0000
|
110
|
+
+++ /opt/puppetlabs/server/data/puppetserver/bucket/9/9/b/9/9/9/2/0/99b999207e287afffc86c053e5693247/contents\t2020-04-06 21:26:13.603398063 +0000
|
111
|
+
@@ -1 +1,2 @@
|
112
|
+
-foo
|
113
|
+
+bar
|
114
|
+
+baz
|
115
|
+
END
|
116
|
+
}
|
117
|
+
|
118
|
+
server.start_server(mounts: {filebucket: get_handler}) do |port|
|
119
|
+
Puppet[:masterport] = port
|
120
|
+
expect {
|
121
|
+
filebucket.command_line.args += ['diff', 'd3b07384d113edec49eaa6238ad5ff00', "99b999207e287afffc86c053e5693247", '--remote']
|
122
|
+
filebucket.run
|
123
|
+
}.to output(a_string_matching(
|
124
|
+
/[-<] ?foo/
|
125
|
+
).and matching(
|
126
|
+
/[+>] ?bar/
|
127
|
+
).and matching(
|
128
|
+
/[+>] ?baz/
|
129
|
+
)).to_stdout
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'using a local bucket' do
|
135
|
+
let(:filea) {
|
136
|
+
f = tmpfile('filea')
|
137
|
+
File.binwrite(f, 'foo')
|
138
|
+
f
|
139
|
+
}
|
140
|
+
let(:fileb) {
|
141
|
+
f = tmpfile('fileb')
|
142
|
+
File.binwrite(f, "bar\nbaz")
|
143
|
+
f
|
144
|
+
}
|
145
|
+
let(:checksuma) { Digest::MD5.file(filea).to_s }
|
146
|
+
let(:checksumb) { Digest::MD5.file(fileb).to_s }
|
147
|
+
|
148
|
+
it 'compares to files stored in a local bucket' do
|
149
|
+
expect {
|
150
|
+
filebucket.command_line.args = ['backup', filea, '--local']
|
151
|
+
filebucket.run
|
152
|
+
}.to output(/#{filea}: #{checksuma}/).to_stdout
|
153
|
+
|
154
|
+
expect{
|
155
|
+
filebucket.command_line.args = ['backup', fileb, '--local']
|
156
|
+
filebucket.run
|
157
|
+
}.to output(/#{fileb}: #{checksumb}\n/).to_stdout
|
158
|
+
|
159
|
+
expect {
|
160
|
+
filebucket.command_line.args = ['diff', checksuma, checksumb, '--local']
|
161
|
+
filebucket.run
|
162
|
+
}.to output(a_string_matching(
|
163
|
+
/[-<] ?foo/
|
164
|
+
).and matching(
|
165
|
+
/[+>] ?bar/
|
166
|
+
).and matching(
|
167
|
+
/[+>] ?baz/
|
168
|
+
)).to_stdout
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'compares a file on the filesystem and a file stored in a local bucket' do
|
172
|
+
expect {
|
173
|
+
filebucket.command_line.args = ['backup', filea, '--local']
|
174
|
+
filebucket.run
|
175
|
+
}.to output(/#{filea}: #{checksuma}/).to_stdout
|
176
|
+
|
177
|
+
expect {
|
178
|
+
filebucket.command_line.args = ['diff', checksuma, fileb, '--local']
|
179
|
+
filebucket.run
|
180
|
+
}.to output(a_string_matching(
|
181
|
+
/[-<] ?foo/
|
182
|
+
).and matching(
|
183
|
+
/[+>] ?bar/
|
184
|
+
).and matching(
|
185
|
+
/[+>] ?baz/
|
186
|
+
)).to_stdout
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/face'
|
3
|
+
require 'puppet_spec/puppetserver'
|
4
|
+
|
5
|
+
describe "puppet plugin" do
|
6
|
+
include_context "https client"
|
7
|
+
|
8
|
+
let(:server) { PuppetSpec::Puppetserver.new }
|
9
|
+
let(:plugin) { Puppet::Application[:plugin] }
|
10
|
+
let(:response_body) { "[{\"path\":\"/etc/puppetlabs/code/environments/production/modules\",\"relative_path\":\".\",\"links\":\"follow\",\"owner\":0,\"group\":0,\"mode\":493,\"checksum\":{\"type\":\"ctime\",\"value\":\"{ctime}2020-03-06 20:14:25 UTC\"},\"type\":\"directory\",\"destination\":null}]" }
|
11
|
+
|
12
|
+
it "downloads from plugins, pluginsfacts and locales mounts" do
|
13
|
+
current_version_handler = -> (req, res) {
|
14
|
+
res['X-Puppet-Version'] = Puppet.version
|
15
|
+
res['Content-Type'] = 'application/json'
|
16
|
+
res.body = response_body
|
17
|
+
}
|
18
|
+
|
19
|
+
server.start_server(mounts: {file_metadatas: current_version_handler}) do |port|
|
20
|
+
Puppet[:masterport] = port
|
21
|
+
expect {
|
22
|
+
plugin.command_line.args << 'download'
|
23
|
+
plugin.run
|
24
|
+
}.to exit_with(0)
|
25
|
+
.and output(matching(
|
26
|
+
"Downloaded these plugins: #{Regexp.escape(Puppet[:pluginfactdest])}, #{Regexp.escape(Puppet[:plugindest])}, #{Regexp.escape(Puppet[:localedest])}"
|
27
|
+
)).to_stdout
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "downloads from plugins and pluginsfacts from older puppetservers" do
|
32
|
+
no_locales_handler = -> (req, res) {
|
33
|
+
res['X-Puppet-Version'] = '5.3.3' # locales mount was added in 5.3.4
|
34
|
+
res['Content-Type'] = 'application/json'
|
35
|
+
res.body = response_body
|
36
|
+
}
|
37
|
+
|
38
|
+
server.start_server(mounts: {file_metadatas: no_locales_handler}) do |port|
|
39
|
+
Puppet[:masterport] = port
|
40
|
+
expect {
|
41
|
+
plugin.command_line.args << 'download'
|
42
|
+
plugin.run
|
43
|
+
}.to exit_with(0)
|
44
|
+
.and output(matching(
|
45
|
+
"Downloaded these plugins: #{Regexp.escape(Puppet[:pluginfactdest])}, #{Regexp.escape(Puppet[:plugindest])}"
|
46
|
+
)).to_stdout
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -4,31 +4,17 @@ require 'puppet_spec/files'
|
|
4
4
|
|
5
5
|
describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
6
6
|
include PuppetSpec::Files
|
7
|
+
include_context "https client"
|
7
8
|
|
8
|
-
before :all do
|
9
|
-
WebMock.disable!
|
10
|
-
end
|
11
|
-
|
12
|
-
after :all do
|
13
|
-
WebMock.enable!
|
14
|
-
end
|
15
|
-
|
16
|
-
before :each do
|
17
|
-
# make sure we don't take too long
|
18
|
-
Puppet[:http_connect_timeout] = '5s'
|
19
|
-
end
|
20
|
-
|
21
|
-
let(:hostname) { '127.0.0.1' }
|
22
9
|
let(:wrong_hostname) { 'localhost' }
|
23
|
-
let(:server) { PuppetSpec::HTTPSServer.new }
|
24
10
|
let(:client) { Puppet::HTTP::Client.new }
|
25
11
|
let(:ssl_provider) { Puppet::SSL::SSLProvider.new }
|
26
|
-
let(:root_context) { ssl_provider.create_root_context(cacerts: [
|
12
|
+
let(:root_context) { ssl_provider.create_root_context(cacerts: [https_server.ca_cert], crls: [https_server.ca_crl]) }
|
27
13
|
|
28
14
|
context "when verifying an HTTPS server" do
|
29
15
|
it "connects over SSL" do
|
30
|
-
|
31
|
-
res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: root_context)
|
16
|
+
https_server.start_server do |port|
|
17
|
+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: root_context})
|
32
18
|
expect(res).to be_success
|
33
19
|
end
|
34
20
|
end
|
@@ -41,14 +27,14 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
41
27
|
port = tcps.connect_address.ip_port
|
42
28
|
|
43
29
|
expect {
|
44
|
-
client.get(URI("https://127.0.0.1:#{port}"), ssl_context: root_context)
|
30
|
+
client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: root_context})
|
45
31
|
}.to raise_error(Puppet::HTTP::ConnectionError, %r{^Request to https://127.0.0.1:#{port} timed out connect operation after .* seconds})
|
46
32
|
end
|
47
33
|
|
48
34
|
it "raises if the server's cert doesn't match the hostname we connected to" do
|
49
|
-
|
35
|
+
https_server.start_server do |port|
|
50
36
|
expect {
|
51
|
-
client.get(URI("https://#{wrong_hostname}:#{port}"), ssl_context: root_context)
|
37
|
+
client.get(URI("https://#{wrong_hostname}:#{port}"), options: {ssl_context: root_context})
|
52
38
|
}.to raise_error { |err|
|
53
39
|
expect(err).to be_instance_of(Puppet::SSL::CertMismatchError)
|
54
40
|
expect(err.message).to match(/Server hostname '#{wrong_hostname}' did not match server certificate; expected one of (.+)/)
|
@@ -63,9 +49,9 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
63
49
|
wrong_ca = cert_fixture('netlock-arany-utf8.pem')
|
64
50
|
alt_context = ssl_provider.create_root_context(cacerts: [wrong_ca], revocation: false)
|
65
51
|
|
66
|
-
|
52
|
+
https_server.start_server do |port|
|
67
53
|
expect {
|
68
|
-
client.get(URI("https://127.0.0.1:#{port}"), ssl_context: alt_context)
|
54
|
+
client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: alt_context})
|
69
55
|
}.to raise_error(Puppet::SSL::CertVerifyError,
|
70
56
|
%r{certificate verify failed.* .self signed certificate in certificate chain for CN=Test CA.})
|
71
57
|
end
|
@@ -73,8 +59,8 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
73
59
|
|
74
60
|
it "prints TLS protocol and ciphersuite in debug" do
|
75
61
|
Puppet[:log_level] = 'debug'
|
76
|
-
|
77
|
-
client.get(URI("https://127.0.0.1:#{port}"), ssl_context: root_context)
|
62
|
+
https_server.start_server do |port|
|
63
|
+
client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: root_context})
|
78
64
|
# TLS version string can be TLSv1 or TLSv1.[1-3], but not TLSv1.0
|
79
65
|
expect(@logs).to include(
|
80
66
|
an_object_having_attributes(level: :debug, message: /Using TLSv1(\.[1-3])? with cipher .*/),
|
@@ -93,12 +79,12 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
93
79
|
|
94
80
|
it "mutually authenticates the connection" do
|
95
81
|
client_context = ssl_provider.create_context(
|
96
|
-
cacerts: [
|
97
|
-
client_cert:
|
82
|
+
cacerts: [https_server.ca_cert], crls: [https_server.ca_crl],
|
83
|
+
client_cert: https_server.server_cert, private_key: https_server.server_key
|
98
84
|
)
|
99
85
|
|
100
|
-
|
101
|
-
res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: client_context)
|
86
|
+
https_server.start_server(ctx_proc: ctx_proc) do |port|
|
87
|
+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: client_context})
|
102
88
|
expect(res).to be_success
|
103
89
|
end
|
104
90
|
end
|
@@ -106,10 +92,10 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
106
92
|
|
107
93
|
context "with a system trust store" do
|
108
94
|
it "connects when the client trusts the server's CA" do
|
109
|
-
system_context = ssl_provider.create_system_context(cacerts: [
|
95
|
+
system_context = ssl_provider.create_system_context(cacerts: [https_server.ca_cert])
|
110
96
|
|
111
|
-
|
112
|
-
res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: system_context)
|
97
|
+
https_server.start_server do |port|
|
98
|
+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
|
113
99
|
expect(res).to be_success
|
114
100
|
end
|
115
101
|
end
|
@@ -117,14 +103,14 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
117
103
|
it "connects when the server's CA is in the system store" do
|
118
104
|
# create a temp cacert bundle
|
119
105
|
ssl_file = tmpfile('systemstore')
|
120
|
-
File.write(ssl_file,
|
106
|
+
File.write(ssl_file, https_server.ca_cert)
|
121
107
|
|
122
108
|
# override path to system cacert bundle, this must be done before
|
123
109
|
# the SSLContext is created and the call to X509::Store.set_default_paths
|
124
110
|
Puppet::Util.withenv("SSL_CERT_FILE" => ssl_file) do
|
125
111
|
system_context = ssl_provider.create_system_context(cacerts: [])
|
126
|
-
|
127
|
-
res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: system_context)
|
112
|
+
https_server.start_server do |port|
|
113
|
+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
|
128
114
|
expect(res).to be_success
|
129
115
|
end
|
130
116
|
end
|
@@ -133,9 +119,9 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
133
119
|
it "raises if the server's CA is not in the context or system store" do
|
134
120
|
system_context = ssl_provider.create_system_context(cacerts: [cert_fixture('netlock-arany-utf8.pem')])
|
135
121
|
|
136
|
-
|
122
|
+
https_server.start_server do |port|
|
137
123
|
expect {
|
138
|
-
client.get(URI("https://127.0.0.1:#{port}"), ssl_context: system_context)
|
124
|
+
client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
|
139
125
|
}.to raise_error(Puppet::SSL::CertVerifyError,
|
140
126
|
%r{certificate verify failed.* .self signed certificate in certificate chain for CN=Test CA.})
|
141
127
|
end
|
@@ -144,11 +130,19 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
|
|
144
130
|
|
145
131
|
context 'persistent connections' do
|
146
132
|
it "detects when the server has closed the connection and reconnects" do
|
147
|
-
|
133
|
+
Puppet[:http_debug] = true
|
134
|
+
|
135
|
+
https_server.start_server do |port|
|
148
136
|
uri = URI("https://127.0.0.1:#{port}")
|
137
|
+
kwargs = {headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: root_context}}
|
149
138
|
|
150
|
-
expect
|
151
|
-
|
139
|
+
expect {
|
140
|
+
expect(client.post(uri, '', **kwargs)).to be_success
|
141
|
+
# the server closes its connection after each request, so posting
|
142
|
+
# again will force ruby to detect that the remote side closed the
|
143
|
+
# connection, and reconnect
|
144
|
+
expect(client.post(uri, '', **kwargs)).to be_success
|
145
|
+
}.to output(/Conn close because of EOF/).to_stderr
|
152
146
|
end
|
153
147
|
end
|
154
148
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'puppet/transaction/report'
|
4
|
+
require 'puppet/indirector/report/yaml'
|
5
|
+
|
6
|
+
describe Puppet::Transaction::Report::Yaml do
|
7
|
+
describe '#save' do
|
8
|
+
subject(:indirection) { described_class.indirection }
|
9
|
+
|
10
|
+
let(:request) { described_class.new }
|
11
|
+
let(:certname) { 'ziggy' }
|
12
|
+
let(:report) do
|
13
|
+
report = Puppet::Transaction::Report.new
|
14
|
+
report.host = certname
|
15
|
+
report
|
16
|
+
end
|
17
|
+
let(:file) { request.path(:me) }
|
18
|
+
|
19
|
+
before do
|
20
|
+
indirection.terminus_class = :yaml
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'is saves a report' do
|
24
|
+
indirection.save(report)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'saves the instance of the report as YAML to disk' do
|
28
|
+
indirection.save(report)
|
29
|
+
content = Puppet::Util::Yaml.safe_load_file(
|
30
|
+
Puppet[:lastrunreport], [Puppet::Transaction::Report]
|
31
|
+
)
|
32
|
+
expect(content.host).to eq(certname)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'allows mode overwrite' do
|
36
|
+
Puppet.settings.setting(:lastrunreport).mode = '0644'
|
37
|
+
indirection.save(report)
|
38
|
+
|
39
|
+
if Puppet::Util::Platform.windows?
|
40
|
+
require 'puppet/util/windows/security'
|
41
|
+
mode = Puppet::Util::Windows::Security.get_mode(file)
|
42
|
+
else
|
43
|
+
mode = Puppet::FileSystem.stat(file).mode
|
44
|
+
end
|
45
|
+
|
46
|
+
expect(mode & 07777).to eq(0644)
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when mode is invalid' do
|
50
|
+
before do
|
51
|
+
Puppet.settings.setting(:lastrunreport).mode = '9999'
|
52
|
+
end
|
53
|
+
|
54
|
+
after do
|
55
|
+
Puppet.settings.setting(:lastrunreport).mode = '0644'
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'raises Puppet::DevError ' do
|
59
|
+
expect{
|
60
|
+
indirection.save(report)
|
61
|
+
}.to raise_error(Puppet::DevError, "replace_file mode: 9999 is invalid")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when repport is invalid' do
|
66
|
+
it 'logs error' do
|
67
|
+
expect(Puppet).to receive(:send_log).with(:err, /Could not save yaml ziggy: can't dump anonymous class/)
|
68
|
+
|
69
|
+
report.configuration_version = Class.new
|
70
|
+
indirection.save(report)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when report cannot be saved' do
|
75
|
+
it 'raises Errno::EISDIR' do
|
76
|
+
FileUtils.mkdir_p(file)
|
77
|
+
expect {
|
78
|
+
indirection.save(report)
|
79
|
+
}.to raise_error(Errno::EISDIR, /last_run_report.yaml/)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|