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
@@ -114,12 +114,31 @@ describe Puppet::Application::Filebucket do
|
|
114
114
|
@filebucket.setup
|
115
115
|
end
|
116
116
|
|
117
|
-
it "should default to the first server_list entry if set" do
|
117
|
+
it "should default to the first good server_list entry if server_list is set" do
|
118
|
+
stub_request(:get, "https://foo:8140/status/v1/simple/master").to_return(status: 200)
|
118
119
|
Puppet[:server_list] = "foo,bar,baz"
|
119
120
|
expect(Puppet::FileBucket::Dipper).to receive(:new).with(hash_including(Server: "foo"))
|
120
121
|
@filebucket.setup
|
121
122
|
end
|
122
123
|
|
124
|
+
it "should walk server_list until it finds a good entry" do
|
125
|
+
stub_request(:get, "https://foo:8140/status/v1/simple/master").to_return(status: 502)
|
126
|
+
stub_request(:get, "https://bar:8140/status/v1/simple/master").to_return(status: 200)
|
127
|
+
Puppet[:server_list] = "foo,bar,baz"
|
128
|
+
expect(Puppet::FileBucket::Dipper).to receive(:new).with(hash_including(Server: "bar"))
|
129
|
+
@filebucket.setup
|
130
|
+
end
|
131
|
+
|
132
|
+
# FileBucket catches any exceptions raised, logs them, then just exits
|
133
|
+
it "raises an error if there are no functional servers in server_list" do
|
134
|
+
stub_request(:get, "https://foo:8140/status/v1/simple/master").to_return(status: 404)
|
135
|
+
stub_request(:get, "https://bar:8140/status/v1/simple/master").to_return(status: 404)
|
136
|
+
Puppet[:server] = 'horacio'
|
137
|
+
Puppet[:server_list] = "foo,bar"
|
138
|
+
|
139
|
+
expect{@filebucket.setup}.to exit_with(1)
|
140
|
+
end
|
141
|
+
|
123
142
|
it "should fall back to server if server_list is empty" do
|
124
143
|
Puppet[:server_list] = ""
|
125
144
|
expect(Puppet::FileBucket::Dipper).to receive(:new).with(hash_including(Server: "puppet"))
|
@@ -127,8 +146,9 @@ describe Puppet::Application::Filebucket do
|
|
127
146
|
end
|
128
147
|
|
129
148
|
it "should take both the server and port specified in server_list" do
|
149
|
+
stub_request(:get, "https://foo:632/status/v1/simple/master").to_return(status: 200)
|
130
150
|
Puppet[:server_list] = "foo:632,bar:6215,baz:351"
|
131
|
-
expect(Puppet::FileBucket::Dipper).to receive(:new).with({ :Server => "foo", :Port =>
|
151
|
+
expect(Puppet::FileBucket::Dipper).to receive(:new).with({ :Server => "foo", :Port => 632 })
|
132
152
|
@filebucket.setup
|
133
153
|
end
|
134
154
|
end
|
@@ -148,7 +148,7 @@ describe Puppet::Configurer do
|
|
148
148
|
configurer = Puppet::Configurer.new("test_tuuid", "test_jid")
|
149
149
|
|
150
150
|
report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
|
151
|
-
expect(Puppet::Transaction::Report).to receive(:new).with(anything, anything, 'test_tuuid', 'test_jid').and_return(report)
|
151
|
+
expect(Puppet::Transaction::Report).to receive(:new).with(anything, anything, 'test_tuuid', 'test_jid', anything).and_return(report)
|
152
152
|
expect(configurer).to receive(:send_report).with(report)
|
153
153
|
|
154
154
|
configurer.run
|
data/spec/unit/defaults_spec.rb
CHANGED
@@ -188,8 +188,31 @@ describe "Defaults" do
|
|
188
188
|
end
|
189
189
|
|
190
190
|
it "raises an exception if facter-ng could not be loaded" do
|
191
|
-
|
191
|
+
allow_any_instance_of(Puppet::Settings::BooleanSetting).to receive(:require).with('facter-ng').and_raise(LoadError)
|
192
|
+
|
192
193
|
expect{ Puppet.settings[:facterng] = true }.to raise_exception ArgumentError, 'facter-ng could not be loaded'
|
193
194
|
end
|
195
|
+
|
196
|
+
context 'set logger' do
|
197
|
+
before do
|
198
|
+
@original_facter = Object.const_get(:Facter)
|
199
|
+
|
200
|
+
Object.send(:remove_const, :Facter)
|
201
|
+
Object.const_set(:Facter, Module.new)
|
202
|
+
|
203
|
+
allow_any_instance_of(Puppet::Settings::BooleanSetting).to receive(:require).with('facter-ng').and_return(true)
|
204
|
+
allow(Facter).to receive(:respond_to?).and_return(false)
|
205
|
+
end
|
206
|
+
|
207
|
+
after do
|
208
|
+
Object.const_set(:Facter, @original_facter)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'calls setup_facter_logging!' do
|
212
|
+
allow(Puppet::Util::Logging).to receive(:setup_facter_logging!).and_return(true)
|
213
|
+
Puppet.settings[:facterng] = true
|
214
|
+
expect(Puppet::Util::Logging).to have_received(:setup_facter_logging!).once
|
215
|
+
end
|
216
|
+
end
|
194
217
|
end
|
195
218
|
end
|
@@ -35,6 +35,7 @@ describe Puppet::Environments do
|
|
35
35
|
FS::MemoryFile.a_directory("modules"),
|
36
36
|
FS::MemoryFile.a_directory("manifests"),
|
37
37
|
]),
|
38
|
+
FS::MemoryFile.a_missing_file("missing")
|
38
39
|
])
|
39
40
|
end
|
40
41
|
|
@@ -90,6 +91,13 @@ describe Puppet::Environments do
|
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
94
|
+
it "proceeds with non-existant env dir" do
|
95
|
+
loader_from(:filesystem => [directory_tree],
|
96
|
+
:directory => directory_tree.children.last) do |loader|
|
97
|
+
expect(loader.list).to eq([])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
93
101
|
it "gets a particular environment" do
|
94
102
|
loader_from(:filesystem => [directory_tree],
|
95
103
|
:directory => directory_tree.children.first) do |loader|
|
@@ -970,6 +970,16 @@ describe "Puppet::FileSystem" do
|
|
970
970
|
mode = Puppet::FileSystem.stat(dest).mode
|
971
971
|
expect(mode & 07777).to eq(0400)
|
972
972
|
end
|
973
|
+
|
974
|
+
it 'preserves file ownership' do
|
975
|
+
allow(Puppet::FileSystem).to receive(:lstat)
|
976
|
+
.with(Puppet::FileSystem.pathname(dest))
|
977
|
+
.and_return(double(uid: 1, gid: 2))
|
978
|
+
|
979
|
+
expect(FileUtils).to receive(:chown).with(1, 2, /#{dest}/)
|
980
|
+
|
981
|
+
Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
|
982
|
+
end
|
973
983
|
end
|
974
984
|
|
975
985
|
context 'on windows', if: Puppet::Util::Platform.windows? do
|
@@ -4,10 +4,9 @@ require 'puppet/http'
|
|
4
4
|
|
5
5
|
describe Puppet::HTTP::Client do
|
6
6
|
let(:uri) { URI.parse('https://www.example.com') }
|
7
|
-
let(:pool) { Puppet::Network::HTTP::Pool.new }
|
8
7
|
let(:puppet_context) { Puppet::SSL::SSLContext.new }
|
9
8
|
let(:system_context) { Puppet::SSL::SSLContext.new }
|
10
|
-
let(:client) { described_class.new(
|
9
|
+
let(:client) { described_class.new(ssl_context: puppet_context, system_ssl_context: system_context) }
|
11
10
|
let(:credentials) { ['user', 'pass'] }
|
12
11
|
|
13
12
|
it 'creates unique sessions' do
|
@@ -50,7 +49,7 @@ describe Puppet::HTTP::Client do
|
|
50
49
|
end
|
51
50
|
|
52
51
|
it 'connects using the default ssl context' do
|
53
|
-
expect(pool).to receive(:with_connection) do |_, verifier|
|
52
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
54
53
|
expect(verifier.ssl_context).to equal(puppet_context)
|
55
54
|
end
|
56
55
|
|
@@ -60,24 +59,32 @@ describe Puppet::HTTP::Client do
|
|
60
59
|
it 'connects using a specified ssl context' do
|
61
60
|
other_context = Puppet::SSL::SSLContext.new
|
62
61
|
|
63
|
-
expect(pool).to receive(:with_connection) do |_, verifier|
|
62
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
64
63
|
expect(verifier.ssl_context).to equal(other_context)
|
65
64
|
end
|
66
65
|
|
67
|
-
client.connect(uri, ssl_context: other_context)
|
66
|
+
client.connect(uri, options: {ssl_context: other_context})
|
68
67
|
end
|
69
68
|
|
70
69
|
it 'connects using the system store' do
|
71
|
-
expect(pool).to receive(:with_connection) do |_, verifier|
|
70
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
72
71
|
expect(verifier.ssl_context).to equal(system_context)
|
73
72
|
end
|
74
73
|
|
75
|
-
client.connect(uri, include_system_store: true)
|
74
|
+
client.connect(uri, options: {include_system_store: true})
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does not create a verifier for HTTP connections' do
|
78
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
79
|
+
expect(verifier).to be_nil
|
80
|
+
end
|
81
|
+
|
82
|
+
client.connect(URI.parse('http://www.example.com'))
|
76
83
|
end
|
77
84
|
|
78
85
|
it 'raises an HTTPError if both are specified' do
|
79
86
|
expect {
|
80
|
-
client.connect(uri, ssl_context: puppet_context, include_system_store: true)
|
87
|
+
client.connect(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
81
88
|
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
82
89
|
end
|
83
90
|
end
|
@@ -110,10 +117,8 @@ describe Puppet::HTTP::Client do
|
|
110
117
|
|
111
118
|
context "when closing" do
|
112
119
|
it "closes all connections in the pool" do
|
113
|
-
pool
|
114
|
-
expect(pool).to receive(:close)
|
120
|
+
expect(client.pool).to receive(:close)
|
115
121
|
|
116
|
-
client = described_class.new(pool: pool)
|
117
122
|
client.close
|
118
123
|
end
|
119
124
|
end
|
@@ -180,18 +185,18 @@ describe Puppet::HTTP::Client do
|
|
180
185
|
|
181
186
|
other_context = Puppet::SSL::SSLContext.new
|
182
187
|
|
183
|
-
client.get(uri, ssl_context: other_context)
|
188
|
+
client.get(uri, options: {ssl_context: other_context})
|
184
189
|
end
|
185
190
|
|
186
191
|
it 'uses the system store' do
|
187
192
|
stub_request(:get, uri).to_return(body: "abc")
|
188
193
|
|
189
|
-
client.get(uri, include_system_store: true)
|
194
|
+
client.get(uri, options: {include_system_store: true})
|
190
195
|
end
|
191
196
|
|
192
197
|
it 'raises an HTTPError if both are specified' do
|
193
198
|
expect {
|
194
|
-
client.get(uri, ssl_context: puppet_context, include_system_store: true)
|
199
|
+
client.get(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
195
200
|
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
196
201
|
end
|
197
202
|
end
|
@@ -237,18 +242,18 @@ describe Puppet::HTTP::Client do
|
|
237
242
|
|
238
243
|
other_context = Puppet::SSL::SSLContext.new
|
239
244
|
|
240
|
-
client.head(uri, ssl_context: other_context)
|
245
|
+
client.head(uri, options: {ssl_context: other_context})
|
241
246
|
end
|
242
247
|
|
243
248
|
it 'uses the system store' do
|
244
249
|
stub_request(:head, uri)
|
245
250
|
|
246
|
-
client.head(uri, include_system_store: true)
|
251
|
+
client.head(uri, options: {include_system_store: true})
|
247
252
|
end
|
248
253
|
|
249
254
|
it 'raises an HTTPError if both are specified' do
|
250
255
|
expect {
|
251
|
-
client.head(uri, ssl_context: puppet_context, include_system_store: true)
|
256
|
+
client.head(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
252
257
|
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
253
258
|
end
|
254
259
|
end
|
@@ -261,25 +266,25 @@ describe Puppet::HTTP::Client do
|
|
261
266
|
expect(request.headers).to_not include('X-Puppet-Profiling')
|
262
267
|
end
|
263
268
|
|
264
|
-
client.put(uri,
|
269
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'})
|
265
270
|
end
|
266
271
|
|
267
272
|
it "stringifies keys and encodes values in the query" do
|
268
273
|
stub_request(:put, "https://www.example.com").with(query: "foo=bar%3Dbaz")
|
269
274
|
|
270
|
-
client.put(uri, params: {:foo => "bar=baz"},
|
275
|
+
client.put(uri, "", params: {:foo => "bar=baz"}, headers: {'Content-Type' => 'text/plain'})
|
271
276
|
end
|
272
277
|
|
273
278
|
it "includes custom headers" do
|
274
279
|
stub_request(:put, "https://www.example.com").with(headers: { 'X-Foo' => 'Bar' })
|
275
280
|
|
276
|
-
client.put(uri, headers: {'X-Foo' => 'Bar'
|
281
|
+
client.put(uri, "", headers: {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
|
277
282
|
end
|
278
283
|
|
279
284
|
it "returns the response" do
|
280
285
|
stub_request(:put, uri)
|
281
286
|
|
282
|
-
response = client.put(uri,
|
287
|
+
response = client.put(uri, "", headers: {'Content-Type' => 'text/plain'})
|
283
288
|
expect(response).to be_an_instance_of(Puppet::HTTP::Response)
|
284
289
|
expect(response).to be_success
|
285
290
|
expect(response.code).to eq(200)
|
@@ -288,27 +293,39 @@ describe Puppet::HTTP::Client do
|
|
288
293
|
it "sets content-length and content-type for the body" do
|
289
294
|
stub_request(:put, uri).with(headers: {"Content-Length" => "5", "Content-Type" => "text/plain"})
|
290
295
|
|
291
|
-
client.put(uri,
|
296
|
+
client.put(uri, "hello", headers: {'Content-Type' => 'text/plain'})
|
292
297
|
end
|
293
298
|
|
299
|
+
it 'raises an ArgumentError if `body` is missing' do
|
300
|
+
expect {
|
301
|
+
client.put(uri, nil, headers: {'Content-Type' => 'text/plain'})
|
302
|
+
}.to raise_error(ArgumentError, /'put' requires a string 'body' argument/)
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'raises an ArgumentError if `content_type` is missing from the headers hash' do
|
306
|
+
expect {
|
307
|
+
client.put(uri, '')
|
308
|
+
}.to raise_error(ArgumentError, /'put' requires a 'content-type' header/)
|
309
|
+
end
|
310
|
+
|
294
311
|
context 'when connecting' do
|
295
312
|
it 'uses a specified ssl context' do
|
296
313
|
stub_request(:put, uri)
|
297
314
|
|
298
315
|
other_context = Puppet::SSL::SSLContext.new
|
299
316
|
|
300
|
-
client.put(uri,
|
317
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: other_context})
|
301
318
|
end
|
302
319
|
|
303
320
|
it 'uses the system store' do
|
304
321
|
stub_request(:put, uri)
|
305
322
|
|
306
|
-
client.put(uri,
|
323
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {include_system_store: true})
|
307
324
|
end
|
308
325
|
|
309
326
|
it 'raises an HTTPError if both are specified' do
|
310
327
|
expect {
|
311
|
-
client.put(uri,
|
328
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: puppet_context, include_system_store: true})
|
312
329
|
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
313
330
|
end
|
314
331
|
end
|
@@ -318,25 +335,25 @@ describe Puppet::HTTP::Client do
|
|
318
335
|
it "includes default HTTP headers" do
|
319
336
|
stub_request(:post, uri).with(headers: {'X-Puppet-Version' => /./, 'User-Agent' => /./})
|
320
337
|
|
321
|
-
client.post(uri,
|
338
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'})
|
322
339
|
end
|
323
340
|
|
324
341
|
it "stringifies keys and encodes values in the query" do
|
325
342
|
stub_request(:post, "https://www.example.com").with(query: "foo=bar%3Dbaz")
|
326
343
|
|
327
|
-
client.post(uri, params: {:foo => "bar=baz"},
|
344
|
+
client.post(uri, "", params: {:foo => "bar=baz"}, headers: {'Content-Type' => 'text/plain'})
|
328
345
|
end
|
329
346
|
|
330
347
|
it "includes custom headers" do
|
331
348
|
stub_request(:post, "https://www.example.com").with(headers: { 'X-Foo' => 'Bar' })
|
332
349
|
|
333
|
-
client.post(uri, headers: {'X-Foo' => 'Bar'
|
350
|
+
client.post(uri, "", headers: {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
|
334
351
|
end
|
335
352
|
|
336
353
|
it "returns the response" do
|
337
354
|
stub_request(:post, uri)
|
338
355
|
|
339
|
-
response = client.post(uri,
|
356
|
+
response = client.post(uri, "", headers: {'Content-Type' => 'text/plain'})
|
340
357
|
expect(response).to be_an_instance_of(Puppet::HTTP::Response)
|
341
358
|
expect(response).to be_success
|
342
359
|
expect(response.code).to eq(200)
|
@@ -345,14 +362,14 @@ describe Puppet::HTTP::Client do
|
|
345
362
|
it "sets content-length and content-type for the body" do
|
346
363
|
stub_request(:post, uri).with(headers: {"Content-Length" => "5", "Content-Type" => "text/plain"})
|
347
364
|
|
348
|
-
client.post(uri,
|
365
|
+
client.post(uri, "hello", headers: {'Content-Type' => 'text/plain'})
|
349
366
|
end
|
350
367
|
|
351
368
|
it "streams the response body when a block is given" do
|
352
369
|
stub_request(:post, uri).to_return(body: "abc")
|
353
370
|
|
354
371
|
io = StringIO.new
|
355
|
-
client.post(uri,
|
372
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}) do |response|
|
356
373
|
response.read_body do |data|
|
357
374
|
io.write(data)
|
358
375
|
end
|
@@ -361,24 +378,36 @@ describe Puppet::HTTP::Client do
|
|
361
378
|
expect(io.string).to eq("abc")
|
362
379
|
end
|
363
380
|
|
381
|
+
it 'raises an ArgumentError if `body` is missing' do
|
382
|
+
expect {
|
383
|
+
client.post(uri, nil, headers: {'Content-Type' => 'text/plain'})
|
384
|
+
}.to raise_error(ArgumentError, /'post' requires a string 'body' argument/)
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'raises an ArgumentError if `content_type` is missing from the headers hash' do
|
388
|
+
expect {
|
389
|
+
client.post(uri, "")
|
390
|
+
}.to raise_error(ArgumentError, /'post' requires a 'content-type' header/)
|
391
|
+
end
|
392
|
+
|
364
393
|
context 'when connecting' do
|
365
394
|
it 'uses a specified ssl context' do
|
366
395
|
stub_request(:post, uri)
|
367
396
|
|
368
397
|
other_context = Puppet::SSL::SSLContext.new
|
369
398
|
|
370
|
-
client.post(uri,
|
399
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {body: "", ssl_context: other_context})
|
371
400
|
end
|
372
401
|
|
373
402
|
it 'uses the system store' do
|
374
403
|
stub_request(:post, uri)
|
375
404
|
|
376
|
-
client.post(uri,
|
405
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {include_system_store: true})
|
377
406
|
end
|
378
407
|
|
379
408
|
it 'raises an HTTPError if both are specified' do
|
380
409
|
expect {
|
381
|
-
client.post(uri,
|
410
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: puppet_context, include_system_store: true})
|
382
411
|
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
383
412
|
end
|
384
413
|
end
|
@@ -424,18 +453,18 @@ describe Puppet::HTTP::Client do
|
|
424
453
|
|
425
454
|
other_context = Puppet::SSL::SSLContext.new
|
426
455
|
|
427
|
-
client.delete(uri, ssl_context: other_context)
|
456
|
+
client.delete(uri, options: {ssl_context: other_context})
|
428
457
|
end
|
429
458
|
|
430
459
|
it 'uses the system store' do
|
431
460
|
stub_request(:delete, uri)
|
432
461
|
|
433
|
-
client.delete(uri, include_system_store: true)
|
462
|
+
client.delete(uri, options: {include_system_store: true})
|
434
463
|
end
|
435
464
|
|
436
465
|
it 'raises an HTTPError if both are specified' do
|
437
466
|
expect {
|
438
|
-
client.delete(uri, ssl_context: puppet_context, include_system_store: true)
|
467
|
+
client.delete(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
439
468
|
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
440
469
|
end
|
441
470
|
end
|
@@ -445,19 +474,19 @@ describe Puppet::HTTP::Client do
|
|
445
474
|
it "submits credentials for GET requests" do
|
446
475
|
stub_request(:get, uri).with(basic_auth: credentials)
|
447
476
|
|
448
|
-
client.get(uri, user: 'user', password: 'pass')
|
477
|
+
client.get(uri, options: {user: 'user', password: 'pass'})
|
449
478
|
end
|
450
479
|
|
451
480
|
it "submits credentials for PUT requests" do
|
452
481
|
stub_request(:put, uri).with(basic_auth: credentials)
|
453
482
|
|
454
|
-
client.put(uri,
|
483
|
+
client.put(uri, "hello", headers: {'Content-Type' => 'text/plain'}, options: {user: 'user', password: 'pass'})
|
455
484
|
end
|
456
485
|
|
457
486
|
it "returns response containing access denied" do
|
458
487
|
stub_request(:get, uri).with(basic_auth: credentials).to_return(status: [403, "Ye Shall Not Pass"])
|
459
488
|
|
460
|
-
response = client.get(uri, user: 'user', password: 'pass')
|
489
|
+
response = client.get(uri, options: {user: 'user', password: 'pass'})
|
461
490
|
expect(response.code).to eq(403)
|
462
491
|
expect(response.reason).to eq("Ye Shall Not Pass")
|
463
492
|
expect(response).to_not be_success
|
@@ -468,7 +497,7 @@ describe Puppet::HTTP::Client do
|
|
468
497
|
expect(req.headers).to_not include('Authorization')
|
469
498
|
end
|
470
499
|
|
471
|
-
client.get(uri, user: nil, password: 'pass')
|
500
|
+
client.get(uri, options: {user: nil, password: 'pass'})
|
472
501
|
end
|
473
502
|
|
474
503
|
it 'omits basic auth if password is nil' do
|
@@ -476,7 +505,7 @@ describe Puppet::HTTP::Client do
|
|
476
505
|
expect(req.headers).to_not include('Authorization')
|
477
506
|
end
|
478
507
|
|
479
|
-
client.get(uri, user: 'user', password: nil)
|
508
|
+
client.get(uri, options: {user: 'user', password: nil})
|
480
509
|
end
|
481
510
|
end
|
482
511
|
|
@@ -502,7 +531,7 @@ describe Puppet::HTTP::Client do
|
|
502
531
|
stub_request(:put, start_url).to_return(redirect_to(url: bar_url))
|
503
532
|
stub_request(:put, bar_url).to_return(status: 200)
|
504
533
|
|
505
|
-
response = client.put(start_url,
|
534
|
+
response = client.put(start_url, "", headers: {'Content-Type' => 'text/plain'})
|
506
535
|
expect(response).to be_success
|
507
536
|
end
|
508
537
|
|
@@ -528,7 +557,7 @@ describe Puppet::HTTP::Client do
|
|
528
557
|
stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: bar_url))
|
529
558
|
stub_request(:get, bar_url).with(basic_auth: credentials).to_return(status: 200)
|
530
559
|
|
531
|
-
client.get(start_url, user: 'user', password: 'pass')
|
560
|
+
client.get(start_url, options: {user: 'user', password: 'pass'})
|
532
561
|
end
|
533
562
|
|
534
563
|
it "redirects given a relative location" do
|
@@ -555,7 +584,7 @@ describe Puppet::HTTP::Client do
|
|
555
584
|
stub_request(:put, start_url).with(body: data).to_return(redirect_to(url: bar_url))
|
556
585
|
stub_request(:put, bar_url).with(body: data).to_return(status: 200)
|
557
586
|
|
558
|
-
response = client.put(start_url,
|
587
|
+
response = client.put(start_url, data, headers: {'Content-Type' => 'text/plain'})
|
559
588
|
expect(response).to be_success
|
560
589
|
end
|
561
590
|
|
@@ -698,7 +727,7 @@ describe Puppet::HTTP::Client do
|
|
698
727
|
allow(http2).to receive(:started?).and_return(true)
|
699
728
|
|
700
729
|
|
701
|
-
pool = Puppet::Network::HTTP::Pool.new()
|
730
|
+
pool = Puppet::Network::HTTP::Pool.new(15)
|
702
731
|
client = Puppet::HTTP::Client.new(pool: pool)
|
703
732
|
|
704
733
|
# The "with_connection" method is required to yield started connections
|
@@ -746,4 +775,34 @@ describe Puppet::HTTP::Client do
|
|
746
775
|
client.get(uri)
|
747
776
|
end
|
748
777
|
end
|
778
|
+
|
779
|
+
context "persistent connections" do
|
780
|
+
before :each do
|
781
|
+
stub_request(:get, uri)
|
782
|
+
end
|
783
|
+
|
784
|
+
it 'defaults keepalive to http_keepalive_timeout' do
|
785
|
+
expect(client.pool.keepalive_timeout).to eq(Puppet[:http_keepalive_timeout])
|
786
|
+
end
|
787
|
+
|
788
|
+
it 'reuses a cached connection' do
|
789
|
+
allow(Puppet).to receive(:debug)
|
790
|
+
expect(Puppet).to receive(:debug).with(/^Creating new connection/)
|
791
|
+
expect(Puppet).to receive(:debug).with(/^Using cached connection/)
|
792
|
+
|
793
|
+
client.get(uri)
|
794
|
+
client.get(uri)
|
795
|
+
end
|
796
|
+
|
797
|
+
it 'can be disabled' do
|
798
|
+
Puppet[:http_keepalive_timeout] = 0
|
799
|
+
|
800
|
+
allow(Puppet).to receive(:debug)
|
801
|
+
expect(Puppet).to receive(:debug).with(/^Creating new connection/).twice
|
802
|
+
expect(Puppet).to receive(:debug).with(/^Using cached connection/).never
|
803
|
+
|
804
|
+
client.get(uri)
|
805
|
+
client.get(uri)
|
806
|
+
end
|
807
|
+
end
|
749
808
|
end
|