puppet 6.12.0 → 6.13.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 +12 -12
- data/README.md +1 -1
- data/ext/project_data.yaml +1 -1
- data/lib/puppet.rb +22 -7
- data/lib/puppet/application/resource.rb +1 -1
- data/lib/puppet/configurer.rb +8 -13
- data/lib/puppet/defaults.rb +83 -49
- data/lib/puppet/environments.rb +26 -18
- data/lib/puppet/face/facts.rb +8 -5
- data/lib/puppet/file_system/memory_file.rb +6 -0
- data/lib/puppet/file_system/memory_impl.rb +13 -0
- data/lib/puppet/file_system/windows.rb +7 -10
- data/lib/puppet/http.rb +2 -0
- data/lib/puppet/http/client.rb +30 -0
- data/lib/puppet/http/errors.rb +2 -0
- data/lib/puppet/http/service.rb +61 -2
- data/lib/puppet/http/service/compiler.rb +86 -0
- data/lib/puppet/http/service/file_server.rb +85 -0
- data/lib/puppet/http/service/report.rb +4 -8
- data/lib/puppet/http/session.rb +8 -1
- data/lib/puppet/indirector/catalog/compiler.rb +10 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
- data/lib/puppet/indirector/json.rb +1 -1
- data/lib/puppet/indirector/msgpack.rb +1 -1
- data/lib/puppet/network/http/connection.rb +4 -0
- data/lib/puppet/network/http/nocache_pool.rb +1 -0
- data/lib/puppet/network/http/pool.rb +5 -1
- data/lib/puppet/parser/ast/pops_bridge.rb +6 -11
- data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
- data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +12 -3
- data/lib/puppet/pops/parser/evaluating_parser.rb +5 -7
- data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
- data/lib/puppet/pops/types/type_calculator.rb +24 -0
- data/lib/puppet/pops/validation/checker4_0.rb +1 -1
- data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
- data/lib/puppet/provider/aix_object.rb +4 -2
- data/lib/puppet/provider/group/aix.rb +1 -0
- data/lib/puppet/provider/group/groupadd.rb +52 -24
- data/lib/puppet/provider/package/apt.rb +14 -3
- data/lib/puppet/provider/package/dnfmodule.rb +9 -2
- data/lib/puppet/provider/package/dpkg.rb +14 -7
- data/lib/puppet/provider/package/fink.rb +20 -3
- data/lib/puppet/provider/package/openbsd.rb +13 -1
- data/lib/puppet/provider/package/pkg.rb +18 -5
- data/lib/puppet/provider/package/yum.rb +9 -5
- data/lib/puppet/provider/user/aix.rb +1 -0
- data/lib/puppet/provider/user/directoryservice.rb +30 -5
- data/lib/puppet/provider/user/useradd.rb +6 -7
- data/lib/puppet/reports/store.rb +1 -1
- data/lib/puppet/settings.rb +2 -0
- data/lib/puppet/ssl/certificate.rb +2 -1
- data/lib/puppet/test/test_helper.rb +4 -0
- data/lib/puppet/transaction/resource_harness.rb +1 -1
- data/lib/puppet/type/group.rb +2 -2
- data/lib/puppet/type/package.rb +63 -9
- data/lib/puppet/type/user.rb +2 -2
- data/lib/puppet/util/log/destinations.rb +1 -1
- data/lib/puppet/util/pidlock.rb +26 -6
- data/lib/puppet/util/plist.rb +6 -0
- data/lib/puppet/util/storage.rb +0 -1
- data/lib/puppet/util/yaml.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +127 -115
- data/man/man5/puppet.conf.5 +21 -7
- 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/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +0 -35
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +0 -37
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +0 -37
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +0 -35
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +0 -33
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +0 -35
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +0 -35
- data/spec/integration/configurer_spec.rb +26 -7
- data/spec/integration/indirector/facts/facter_spec.rb +4 -0
- data/spec/unit/application/apply_spec.rb +2 -12
- data/spec/unit/application/resource_spec.rb +2 -2
- data/spec/unit/configurer/fact_handler_spec.rb +0 -4
- data/spec/unit/configurer_spec.rb +0 -3
- data/spec/unit/defaults_spec.rb +1 -1
- data/spec/unit/environments_spec.rb +57 -28
- data/spec/unit/face/facts_spec.rb +24 -20
- data/spec/unit/file_system_spec.rb +16 -2
- data/spec/unit/http/client_spec.rb +6 -0
- data/spec/unit/http/service/compiler_spec.rb +322 -0
- data/spec/unit/http/service/file_server_spec.rb +219 -0
- data/spec/unit/http/service/report_spec.rb +8 -1
- data/spec/unit/http/service_spec.rb +4 -0
- data/spec/unit/http/session_spec.rb +31 -0
- data/spec/unit/indirector/catalog/compiler_spec.rb +46 -29
- data/spec/unit/network/http/connection_spec.rb +23 -1
- data/spec/unit/network/http/nocache_pool_spec.rb +3 -3
- data/spec/unit/network/http/pool_spec.rb +32 -0
- data/spec/unit/node/facts_spec.rb +2 -1
- data/spec/unit/node_spec.rb +7 -4
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
- data/spec/unit/pops/validator/validator_spec.rb +7 -2
- data/spec/unit/provider/aix_object_spec.rb +16 -2
- data/spec/unit/provider/group/groupadd_spec.rb +167 -56
- data/spec/unit/provider/package/apt_spec.rb +13 -2
- data/spec/unit/provider/package/aptitude_spec.rb +1 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +22 -0
- data/spec/unit/provider/package/dpkg_spec.rb +28 -6
- data/spec/unit/provider/package/openbsd_spec.rb +17 -0
- data/spec/unit/provider/package/pkg_spec.rb +15 -1
- data/spec/unit/provider/package/yum_spec.rb +50 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
- data/spec/unit/provider/user/useradd_spec.rb +13 -8
- data/spec/unit/puppet_pal_2pec.rb +3 -0
- data/spec/unit/puppet_pal_catalog_spec.rb +3 -0
- data/spec/unit/puppet_spec.rb +14 -0
- data/spec/unit/ssl/certificate_spec.rb +7 -0
- data/spec/unit/transaction/persistence_spec.rb +1 -10
- data/spec/unit/type/package_spec.rb +8 -0
- data/spec/unit/type/user_spec.rb +0 -1
- data/spec/unit/util/pidlock_spec.rb +38 -16
- data/spec/unit/util/plist_spec.rb +20 -0
- data/spec/unit/util/storage_spec.rb +1 -8
- metadata +10 -4
@@ -159,12 +159,33 @@ describe Puppet::Network::HTTP::Connection do
|
|
159
159
|
end
|
160
160
|
|
161
161
|
it "should return a 503 response if Retry-After is not convertible to an Integer or RFC 2822 Date" do
|
162
|
-
|
162
|
+
retry_after('foo')
|
163
163
|
|
164
164
|
result = subject.get('/foo')
|
165
165
|
expect(result.code).to eq("503")
|
166
166
|
end
|
167
167
|
|
168
|
+
it "should close the connection before sleeping" do
|
169
|
+
retry_after('42')
|
170
|
+
|
171
|
+
http1 = Net::HTTP.new(host, port)
|
172
|
+
http1.use_ssl = true
|
173
|
+
allow(http1).to receive(:started?).and_return(true)
|
174
|
+
|
175
|
+
http2 = Net::HTTP.new(host, port)
|
176
|
+
http2.use_ssl = true
|
177
|
+
allow(http1).to receive(:started?).and_return(true)
|
178
|
+
|
179
|
+
# The "with_connection" method is required to yield started connections
|
180
|
+
pool = Puppet.lookup(:http_pool)
|
181
|
+
allow(pool).to receive(:with_connection).and_yield(http1).and_yield(http2)
|
182
|
+
|
183
|
+
expect(http1).to receive(:finish).ordered
|
184
|
+
expect(::Kernel).to receive(:sleep).with(42).ordered
|
185
|
+
|
186
|
+
subject.get('/foo')
|
187
|
+
end
|
188
|
+
|
168
189
|
it "should sleep and retry if Retry-After is an Integer" do
|
169
190
|
retry_after('42')
|
170
191
|
|
@@ -188,6 +209,7 @@ describe Puppet::Network::HTTP::Connection do
|
|
188
209
|
|
189
210
|
it "should sleep for no more than the Puppet runinterval" do
|
190
211
|
retry_after('60')
|
212
|
+
|
191
213
|
Puppet[:runinterval] = 30
|
192
214
|
|
193
215
|
expect(::Kernel).to receive(:sleep).with(30)
|
@@ -8,7 +8,7 @@ describe Puppet::Network::HTTP::NoCachePool do
|
|
8
8
|
let(:verifier) { double('verifier', :setup_connection => nil) }
|
9
9
|
|
10
10
|
it 'yields a started connection' do
|
11
|
-
http = double('http', start: nil, finish: nil)
|
11
|
+
http = double('http', start: nil, finish: nil, started?: true)
|
12
12
|
|
13
13
|
factory = Puppet::Network::HTTP::Factory.new
|
14
14
|
allow(factory).to receive(:create_connection).and_return(http)
|
@@ -20,8 +20,8 @@ describe Puppet::Network::HTTP::NoCachePool do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'yields a new connection each time' do
|
23
|
-
http1 = double('http1', start: nil, finish: nil)
|
24
|
-
http2 = double('http2', start: nil, finish: nil)
|
23
|
+
http1 = double('http1', start: nil, finish: nil, started?: true)
|
24
|
+
http2 = double('http2', start: nil, finish: nil, started?: true)
|
25
25
|
|
26
26
|
factory = Puppet::Network::HTTP::Factory.new
|
27
27
|
allow(factory).to receive(:create_connection).and_return(http1, http2)
|
@@ -63,6 +63,8 @@ describe Puppet::Network::HTTP::Pool do
|
|
63
63
|
|
64
64
|
it 'returns the connection to the pool' do
|
65
65
|
conn = create_connection(site)
|
66
|
+
expect(conn).to receive(:started?).and_return(true)
|
67
|
+
|
66
68
|
pool = create_pool
|
67
69
|
pool.release(site, verifier, conn)
|
68
70
|
|
@@ -140,6 +142,7 @@ describe Puppet::Network::HTTP::Pool do
|
|
140
142
|
it 'releases HTTP connections' do
|
141
143
|
conn = create_connection(site)
|
142
144
|
expect(conn).to receive(:use_ssl?).and_return(false)
|
145
|
+
expect(conn).to receive(:started?).and_return(true)
|
143
146
|
|
144
147
|
pool = create_pool_with_connections(site, conn)
|
145
148
|
expect(pool).to receive(:release).with(site, verifier, conn)
|
@@ -151,6 +154,7 @@ describe Puppet::Network::HTTP::Pool do
|
|
151
154
|
conn = create_connection(site)
|
152
155
|
expect(conn).to receive(:use_ssl?).and_return(true)
|
153
156
|
expect(conn).to receive(:verify_mode).and_return(OpenSSL::SSL::VERIFY_PEER)
|
157
|
+
expect(conn).to receive(:started?).and_return(true)
|
154
158
|
|
155
159
|
pool = create_pool_with_connections(site, conn)
|
156
160
|
expect(pool).to receive(:release).with(site, verifier, conn)
|
@@ -169,6 +173,19 @@ describe Puppet::Network::HTTP::Pool do
|
|
169
173
|
|
170
174
|
pool.with_connection(site, verifier) {|c| }
|
171
175
|
end
|
176
|
+
|
177
|
+
it "doesn't add a closed connection back to the pool" do
|
178
|
+
http = Net::HTTP.new(site.addr)
|
179
|
+
http.use_ssl = true
|
180
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
181
|
+
http.start
|
182
|
+
|
183
|
+
pool = create_pool_with_connections(site, http)
|
184
|
+
|
185
|
+
pool.with_connection(site, verifier) {|c| c.finish}
|
186
|
+
|
187
|
+
expect(pool.pool[site]).to be_empty
|
188
|
+
end
|
172
189
|
end
|
173
190
|
end
|
174
191
|
|
@@ -258,6 +275,7 @@ describe Puppet::Network::HTTP::Pool do
|
|
258
275
|
|
259
276
|
it 'finishes expired connections' do
|
260
277
|
conn = create_connection(site)
|
278
|
+
allow(conn).to receive(:started?).and_return(true)
|
261
279
|
expect(conn).to receive(:finish)
|
262
280
|
|
263
281
|
pool = create_pool_with_expired_connections(site, conn)
|
@@ -271,6 +289,7 @@ describe Puppet::Network::HTTP::Pool do
|
|
271
289
|
expect(Puppet).to receive(:log_exception).with(be_a(IOError), "Failed to close connection for #{site}: read timeout")
|
272
290
|
|
273
291
|
conn = create_connection(site)
|
292
|
+
expect(conn).to receive(:started?).and_return(true)
|
274
293
|
expect(conn).to receive(:finish).and_raise(IOError, 'read timeout')
|
275
294
|
|
276
295
|
pool = create_pool_with_expired_connections(site, conn)
|
@@ -319,10 +338,23 @@ describe Puppet::Network::HTTP::Pool do
|
|
319
338
|
|
320
339
|
it 'closes all cached connections' do
|
321
340
|
conn = create_connection(site)
|
341
|
+
allow(conn).to receive(:started?).and_return(true)
|
322
342
|
expect(conn).to receive(:finish)
|
323
343
|
|
324
344
|
pool = create_pool_with_connections(site, conn)
|
325
345
|
pool.close
|
326
346
|
end
|
347
|
+
|
348
|
+
it 'allows a connection to be closed multiple times safely' do
|
349
|
+
http = Net::HTTP.new(site.addr)
|
350
|
+
http.use_ssl = true
|
351
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
352
|
+
http.start
|
353
|
+
|
354
|
+
pool = create_pool
|
355
|
+
|
356
|
+
expect(pool.close_connection(site, http)).to eq(true)
|
357
|
+
expect(pool.close_connection(site, http)).to eq(false)
|
358
|
+
end
|
327
359
|
end
|
328
360
|
end
|
@@ -88,7 +88,8 @@ describe Puppet::Node::Facts, "when indirecting" do
|
|
88
88
|
@facts.sanitize
|
89
89
|
fact_value = @facts.values['test']
|
90
90
|
expect(fact_value).to eq(an_alien.to_s)
|
91
|
-
|
91
|
+
# JRuby 9.2.8 reports US-ASCII which is a subset of UTF-8
|
92
|
+
expect(fact_value.encoding).to eq(Encoding::UTF_8).or eq(Encoding::US_ASCII)
|
92
93
|
end
|
93
94
|
|
94
95
|
end
|
data/spec/unit/node_spec.rb
CHANGED
@@ -417,7 +417,9 @@ end
|
|
417
417
|
|
418
418
|
describe Puppet::Node, "when generating the list of names to search through" do
|
419
419
|
before do
|
420
|
-
|
420
|
+
Puppet[:strict_hostname_checking] = false
|
421
|
+
@node = Puppet::Node.new("foo.domain.com",
|
422
|
+
:parameters => {"hostname" => "yay", "domain" => "domain.com"})
|
421
423
|
end
|
422
424
|
|
423
425
|
it "returns an array of names" do
|
@@ -448,7 +450,6 @@ describe Puppet::Node, "when generating the list of names to search through" do
|
|
448
450
|
|
449
451
|
describe "and :node_name is set to 'cert'" do
|
450
452
|
before do
|
451
|
-
Puppet[:strict_hostname_checking] = false
|
452
453
|
Puppet[:node_name] = "cert"
|
453
454
|
end
|
454
455
|
|
@@ -457,8 +458,11 @@ describe Puppet::Node, "when generating the list of names to search through" do
|
|
457
458
|
end
|
458
459
|
|
459
460
|
describe "and strict hostname checking is enabled" do
|
460
|
-
|
461
|
+
before do
|
461
462
|
Puppet[:strict_hostname_checking] = true
|
463
|
+
end
|
464
|
+
|
465
|
+
it "only uses the passed-in key" do
|
462
466
|
expect(@node.names).to eq(["foo.domain.com"])
|
463
467
|
end
|
464
468
|
end
|
@@ -466,7 +470,6 @@ describe Puppet::Node, "when generating the list of names to search through" do
|
|
466
470
|
|
467
471
|
describe "and :node_name is set to 'facter'" do
|
468
472
|
before do
|
469
|
-
Puppet[:strict_hostname_checking] = false
|
470
473
|
Puppet[:node_name] = "facter"
|
471
474
|
end
|
472
475
|
|
@@ -296,10 +296,15 @@ module Serialization
|
|
296
296
|
expect(val2).to be_a(Types::PObjectTypeExtension)
|
297
297
|
expect(val2).to eql(val)
|
298
298
|
end
|
299
|
+
|
300
|
+
it 'with POjbectTypeExtension type being converted' do
|
301
|
+
val = { 'ObjectExtension' => type.create(34) }
|
302
|
+
expect(to_converter.convert(val))
|
303
|
+
.to eq({"ObjectExtension"=>{"__ptype"=>"MyType", "x"=>34}})
|
304
|
+
end
|
299
305
|
end
|
300
306
|
end
|
301
307
|
|
302
|
-
|
303
308
|
it 'Array of rich data' do
|
304
309
|
# Sensitive omitted because it doesn't respond to ==
|
305
310
|
val = [
|
@@ -486,10 +486,15 @@ describe "validating 4x" do
|
|
486
486
|
expect(acceptor).to have_issue(Puppet::Pops::Issues::EXPRESSION_NOT_SUPPORTED_WHEN_SCRIPTING)
|
487
487
|
end
|
488
488
|
|
489
|
-
it '
|
489
|
+
it 'allows node expressions' do
|
490
490
|
acceptor = validate(parse('apply("foo.example.com") { node default {} }'))
|
491
|
+
expect(acceptor.error_count).to eql(0)
|
492
|
+
end
|
493
|
+
|
494
|
+
it 'produces an error for node expressions nested in a block' do
|
495
|
+
acceptor = validate(parse('apply("foo.example.com") { if true { node default {} } }'))
|
491
496
|
expect(acceptor.error_count).to eql(1)
|
492
|
-
expect(acceptor).to have_issue(Puppet::Pops::Issues::
|
497
|
+
expect(acceptor).to have_issue(Puppet::Pops::Issues::NOT_TOP_LEVEL)
|
493
498
|
end
|
494
499
|
|
495
500
|
it 'produces an error for resource definitions' do
|
@@ -418,15 +418,29 @@ bin:2
|
|
418
418
|
end
|
419
419
|
|
420
420
|
describe '#ia_module_args' do
|
421
|
-
it 'returns no arguments if
|
421
|
+
it 'returns no arguments if ia_load_module parameter or forcelocal parameter are not specified' do
|
422
422
|
allow(provider.resource).to receive(:[]).with(:ia_load_module).and_return(nil)
|
423
|
+
allow(provider.resource).to receive(:[]).with(:forcelocal).and_return(nil)
|
423
424
|
expect(provider.ia_module_args).to eql([])
|
424
425
|
end
|
425
426
|
|
426
|
-
it 'returns the ia_load_module as a CLI argument' do
|
427
|
+
it 'returns the ia_load_module as a CLI argument when ia_load_module is specified' do
|
427
428
|
allow(provider.resource).to receive(:[]).with(:ia_load_module).and_return('module')
|
429
|
+
allow(provider.resource).to receive(:[]).with(:forcelocal).and_return(nil)
|
428
430
|
expect(provider.ia_module_args).to eql(['-R', 'module'])
|
429
431
|
end
|
432
|
+
|
433
|
+
it 'returns "files" as a CLI argument when forcelocal is specified' do
|
434
|
+
allow(provider.resource).to receive(:[]).with(:ia_load_module).and_return(nil)
|
435
|
+
allow(provider.resource).to receive(:[]).with(:forcelocal).and_return(true)
|
436
|
+
expect(provider.ia_module_args).to eql(['-R', 'files'])
|
437
|
+
end
|
438
|
+
|
439
|
+
it 'raises argument error when both ia_load_module and forcelocal parameters are set' do
|
440
|
+
allow(provider.resource).to receive(:[]).with(:ia_load_module).and_return('files')
|
441
|
+
allow(provider.resource).to receive(:[]).with(:forcelocal).and_return(true)
|
442
|
+
expect { provider.ia_module_args }.to raise_error(ArgumentError, "Cannot have both 'forcelocal' and 'ia_load_module' at the same time!")
|
443
|
+
end
|
430
444
|
end
|
431
445
|
|
432
446
|
describe '#lscmd' do
|
@@ -14,10 +14,11 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
|
|
14
14
|
|
15
15
|
let(:resource) { Puppet::Type.type(:group).new(:name => 'mygroup', :provider => provider) }
|
16
16
|
let(:provider) { described_class.new(:name => 'mygroup') }
|
17
|
+
let(:members) { ['user2', 'user1', 'user3'] }
|
17
18
|
|
18
19
|
describe "#create" do
|
19
20
|
before do
|
20
|
-
|
21
|
+
allow(provider).to receive(:exists?).and_return(false)
|
21
22
|
end
|
22
23
|
|
23
24
|
it "should add -o when allowdupe is enabled and the group is being created" do
|
@@ -42,77 +43,127 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
describe "on systems with
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
it "should use lgroupadd instead of groupadd" do
|
52
|
-
expect(provider).to receive(:execute).with(including('/usr/sbin/lgroupadd'), hash_including(:custom_environment => hash_including('LIBUSER_CONF')))
|
53
|
-
provider.create
|
54
|
-
end
|
46
|
+
describe "on systems with libuser" do
|
47
|
+
describe "with forcelocal=true" do
|
48
|
+
before do
|
49
|
+
described_class.has_feature(:manages_local_users_and_groups)
|
50
|
+
resource[:forcelocal] = :true
|
51
|
+
end
|
55
52
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
it "should use lgroupadd instead of groupadd" do
|
54
|
+
expect(provider).to receive(:execute).with(including('/usr/sbin/lgroupadd'), hash_including(:custom_environment => hash_including('LIBUSER_CONF')))
|
55
|
+
provider.create
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should NOT pass -o to lgroupadd" do
|
59
|
+
resource[:allowdupe] = :true
|
60
|
+
expect(provider).to receive(:execute).with(excluding('-o'), hash_including(:custom_environment => hash_including('LIBUSER_CONF')))
|
61
|
+
provider.create
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should raise an exception for duplicate GID if allowdupe is not set and duplicate GIDs exist" do
|
65
|
+
resource[:gid] = 505
|
66
|
+
allow(provider).to receive(:findgroup).and_return(true)
|
67
|
+
expect { provider.create }.to raise_error(Puppet::Error, "GID 505 already exists, use allowdupe to force group creation")
|
68
|
+
end
|
60
69
|
end
|
61
70
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
71
|
+
describe "with a list of members" do
|
72
|
+
before do
|
73
|
+
members.each { |m| allow(Etc).to receive(:getpwnam).with(m).and_return(true) }
|
74
|
+
|
75
|
+
described_class.has_feature(:manages_members)
|
76
|
+
resource[:forcelocal] = false
|
77
|
+
resource[:members] = members
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should use lgroupmod to add the members" do
|
81
|
+
allow(provider).to receive(:execute).with(['/usr/sbin/groupadd', 'mygroup'], hash_including({:failonfail => true, :combine => true, :custom_environment => {}})).and_return(true)
|
82
|
+
expect(provider).to receive(:execute).with(['/usr/sbin/lgroupmod', '-M', members.join(','), 'mygroup'], hash_including(:custom_environment => hash_including('LIBUSER_CONF')))
|
83
|
+
provider.create
|
84
|
+
end
|
85
|
+
end
|
67
86
|
end
|
68
87
|
end
|
69
88
|
|
70
89
|
describe "#modify" do
|
71
90
|
before do
|
72
|
-
|
91
|
+
allow(provider).to receive(:exists?).and_return(true)
|
73
92
|
end
|
74
93
|
|
75
|
-
describe "on systems with
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
94
|
+
describe "on systems with libuser" do
|
95
|
+
describe "with forcelocal=false" do
|
96
|
+
before do
|
97
|
+
described_class.has_feature(:manages_local_users_and_groups)
|
98
|
+
resource[:forcelocal] = :false
|
99
|
+
end
|
80
100
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
101
|
+
it "should use groupmod" do
|
102
|
+
expect(provider).to receive(:execute).with(['/usr/sbin/groupmod', '-g', 150, 'mygroup'], hash_including({:failonfail => true, :combine => true, :custom_environment => {}}))
|
103
|
+
provider.gid = 150
|
104
|
+
end
|
85
105
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
106
|
+
it "should pass -o to groupmod" do
|
107
|
+
resource[:allowdupe] = :true
|
108
|
+
expect(provider).to receive(:execute).with(['/usr/sbin/groupmod', '-g', 150, '-o', 'mygroup'], hash_including({:failonfail => true, :combine => true, :custom_environment => {}}))
|
109
|
+
provider.gid = 150
|
110
|
+
end
|
90
111
|
end
|
91
|
-
end
|
92
112
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
113
|
+
describe "with forcelocal=true" do
|
114
|
+
before do
|
115
|
+
described_class.has_feature(:manages_local_users_and_groups)
|
116
|
+
resource[:forcelocal] = :true
|
117
|
+
end
|
98
118
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
119
|
+
it "should use lgroupmod instead of groupmod" do
|
120
|
+
expect(provider).to receive(:execute).with(['/usr/sbin/lgroupmod', '-g', 150, 'mygroup'], hash_including(:custom_environment => hash_including('LIBUSER_CONF')))
|
121
|
+
provider.gid = 150
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should NOT pass -o to lgroupmod" do
|
125
|
+
resource[:allowdupe] = :true
|
126
|
+
expect(provider).to receive(:execute).with(['/usr/sbin/lgroupmod', '-g', 150, 'mygroup'], hash_including(:custom_environment => hash_including('LIBUSER_CONF')))
|
127
|
+
provider.gid = 150
|
128
|
+
end
|
103
129
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
130
|
+
it "should raise an exception for duplicate GID if allowdupe is not set and duplicate GIDs exist" do
|
131
|
+
resource[:gid] = 150
|
132
|
+
resource[:allowdupe] = :false
|
133
|
+
allow(provider).to receive(:findgroup).and_return(true)
|
134
|
+
expect { provider.gid = 150 }.to raise_error(Puppet::Error, "GID 150 already exists, use allowdupe to force group creation")
|
135
|
+
end
|
108
136
|
end
|
109
137
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
138
|
+
describe "with members=something" do
|
139
|
+
before do
|
140
|
+
described_class.has_feature(:manages_members)
|
141
|
+
allow(Etc).to receive(:getpwnam).and_return(true)
|
142
|
+
resource[:members] = members
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "with auth_membership on" do
|
146
|
+
before { resource[:auth_membership] = true }
|
147
|
+
|
148
|
+
it "should purge existing users before adding" do
|
149
|
+
allow(provider).to receive(:members).and_return(members)
|
150
|
+
expect(provider).to receive(:localmodify).with('-m', members.join(','), 'mygroup')
|
151
|
+
provider.modifycmd(:members, ['user1'])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "with auth_membership off" do
|
156
|
+
before { resource[:auth_membership] = false }
|
157
|
+
|
158
|
+
it "should add to the existing users" do
|
159
|
+
new_members = ['user1', 'user2', 'user3', 'user4']
|
160
|
+
allow(provider).to receive(:members).and_return(members)
|
161
|
+
expect(provider).not_to receive(:localmodify).with('-m', members.join(','), 'mygroup')
|
162
|
+
expect(provider).to receive(:execute).with(['/usr/sbin/lgroupmod', '-M', new_members.join(','), 'mygroup'], kind_of(Hash))
|
163
|
+
provider.members = new_members
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
116
167
|
end
|
117
168
|
end
|
118
169
|
|
@@ -124,6 +175,35 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
|
|
124
175
|
end
|
125
176
|
end
|
126
177
|
|
178
|
+
describe "#findgroup" do
|
179
|
+
before { allow(File).to receive(:read).with('/etc/group').and_return(content) }
|
180
|
+
|
181
|
+
let(:content) { "sample_group_name:sample_password:sample_gid:sample_user_list" }
|
182
|
+
let(:output) do
|
183
|
+
{
|
184
|
+
group_name: 'sample_group_name',
|
185
|
+
password: 'sample_password',
|
186
|
+
gid: 'sample_gid',
|
187
|
+
user_list: 'sample_user_list',
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
[:group_name, :password, :gid, :user_list].each do |key|
|
192
|
+
it "finds a group by #{key} when asked" do
|
193
|
+
expect(provider.send(:findgroup, key, "sample_#{key}")).to eq(output)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
it "returns false when specified key/value pair is not found" do
|
198
|
+
expect(provider.send(:findgroup, :group_name, 'invalid_group_name')).to eq(false)
|
199
|
+
end
|
200
|
+
|
201
|
+
it "reads the group file only once per resource" do
|
202
|
+
expect(File).to receive(:read).with('/etc/group').once
|
203
|
+
5.times { provider.send(:findgroup, :group_name, 'sample_group_name') }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
127
207
|
describe "#delete" do
|
128
208
|
before do
|
129
209
|
allow(provider).to receive(:exists?).and_return(true)
|
@@ -131,7 +211,7 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
|
|
131
211
|
|
132
212
|
describe "on systems with the libuser and forcelocal=false" do
|
133
213
|
before do
|
134
|
-
described_class.has_feature(:
|
214
|
+
described_class.has_feature(:manages_local_users_and_groups)
|
135
215
|
resource[:forcelocal] = :false
|
136
216
|
end
|
137
217
|
|
@@ -143,7 +223,7 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
|
|
143
223
|
|
144
224
|
describe "on systems with the libuser and forcelocal=true" do
|
145
225
|
before do
|
146
|
-
described_class.has_feature(:
|
226
|
+
described_class.has_feature(:manages_local_users_and_groups)
|
147
227
|
resource[:forcelocal] = :true
|
148
228
|
end
|
149
229
|
|
@@ -153,4 +233,35 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
|
|
153
233
|
end
|
154
234
|
end
|
155
235
|
end
|
236
|
+
|
237
|
+
describe "group type :members property helpers" do
|
238
|
+
describe "#member_valid?" do
|
239
|
+
it "should return true if a member exists" do
|
240
|
+
passwd = Struct::Passwd.new('existinguser', nil, 1100)
|
241
|
+
allow(Etc).to receive(:getpwnam).with('existinguser').and_return(passwd)
|
242
|
+
expect(provider.member_valid?('existinguser')).to eq(true)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "#members_to_s" do
|
247
|
+
it "should return an empty string on non-array input" do
|
248
|
+
[Object.new, {}, 1, :symbol, ''].each do |input|
|
249
|
+
expect(provider.members_to_s(input)).to be_empty
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should return an empty string on empty or nil users" do
|
254
|
+
expect(provider.members_to_s([])).to be_empty
|
255
|
+
expect(provider.members_to_s(nil)).to be_empty
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should return a user string for a single user" do
|
259
|
+
expect(provider.members_to_s(['user1'])).to eq('user1')
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should return a user string for multiple users" do
|
263
|
+
expect(provider.members_to_s(['user1', 'user2'])).to eq('user1,user2')
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
156
267
|
end
|