puppet 5.5.19-x64-mingw32 → 5.5.20-x64-mingw32
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 +11 -11
- data/lib/puppet/agent.rb +2 -10
- data/lib/puppet/functions/reduce.rb +2 -4
- data/lib/puppet/provider/group/windows_adsi.rb +3 -3
- data/lib/puppet/provider/package/aix.rb +17 -2
- data/lib/puppet/provider/package/dnfmodule.rb +39 -12
- data/lib/puppet/provider/package/pkgdmg.rb +1 -1
- data/lib/puppet/provider/package/pkgng.rb +16 -4
- data/lib/puppet/provider/package/yum.rb +18 -15
- data/lib/puppet/provider/selmodule/semodule.rb +43 -26
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/type/package.rb +20 -0
- data/lib/puppet/util/pidlock.rb +12 -6
- data/lib/puppet/util/windows/adsi.rb +2 -2
- data/lib/puppet/util/windows/process.rb +16 -15
- 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 +103 -95
- data/man/man5/puppet.conf.5 +2 -2
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-ca.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-cert.8 +1 -1
- data/man/man8/puppet-certificate.8 +1 -1
- data/man/man8/puppet-certificate_request.8 +1 -1
- data/man/man8/puppet-certificate_revocation_list.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-master.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-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- 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/integration/util/windows/adsi_spec.rb +1 -1
- data/spec/unit/agent_spec.rb +33 -25
- data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
- data/spec/unit/provider/package/aix_spec.rb +29 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +33 -14
- data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
- data/spec/unit/provider/package/pkgng_spec.rb +36 -0
- data/spec/unit/provider/package/yum_spec.rb +10 -1
- data/spec/unit/provider/selmodule_spec.rb +118 -47
- data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
- data/spec/unit/util/pidlock_spec.rb +67 -40
- data/spec/unit/util/windows/adsi_spec.rb +4 -4
- data/spec/unit/util/windows/sid_spec.rb +2 -2
- metadata +6 -4
@@ -33,13 +33,18 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
33
33
|
let(:user1) { double(:account => 'user1', :domain => '.', :sid => 'user1sid') }
|
34
34
|
let(:user2) { double(:account => 'user2', :domain => '.', :sid => 'user2sid') }
|
35
35
|
let(:user3) { double(:account => 'user3', :domain => '.', :sid => 'user3sid') }
|
36
|
+
let(:user_without_domain) { double(:account => 'user_without_domain', :domain => nil, :sid => 'user_without_domain_sid') }
|
37
|
+
|
36
38
|
let(:invalid_user) { SecureRandom.uuid }
|
39
|
+
let(:invalid_user_principal) { double(:account => "#{invalid_user}", :domain => nil, :sid => "#{invalid_user}") }
|
37
40
|
|
38
41
|
before :each do
|
39
|
-
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user1').and_return(user1)
|
40
|
-
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2').and_return(user2)
|
41
|
-
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user3').and_return(user3)
|
42
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user1', any_args).and_return(user1)
|
43
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2', any_args).and_return(user2)
|
44
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user3', any_args).and_return(user3)
|
45
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user_without_domain', any_args).and_return(user_without_domain)
|
42
46
|
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with(invalid_user).and_return(nil)
|
47
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with(invalid_user, true).and_return(invalid_user_principal)
|
43
48
|
end
|
44
49
|
|
45
50
|
describe "#members_insync?" do
|
@@ -199,7 +204,15 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
199
204
|
]
|
200
205
|
expect(provider.members_insync?(current, ['user2','user1'])).to be_truthy
|
201
206
|
end
|
207
|
+
|
208
|
+
it "should return true even if a current user is unresolvable if should is included" do
|
209
|
+
current = [
|
210
|
+
"#{invalid_user}",
|
211
|
+
'user2',
|
212
|
+
]
|
213
|
+
expect(provider.members_insync?(current, ['user2'])).to be_truthy
|
202
214
|
end
|
215
|
+
end
|
203
216
|
end
|
204
217
|
|
205
218
|
describe "#members_to_s" do
|
@@ -222,8 +235,8 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
222
235
|
expect(provider.members_to_s(['user1', 'user2'])).to eq('.\user1,.\user2')
|
223
236
|
end
|
224
237
|
|
225
|
-
it "should return
|
226
|
-
expect(provider.members_to_s([
|
238
|
+
it "should return a user string without domain if domain is not set" do
|
239
|
+
expect(provider.members_to_s(['user_without_domain'])).to eq('user_without_domain')
|
227
240
|
end
|
228
241
|
|
229
242
|
it "should return the username when it cannot be resolved to a SID (for the sake of resource_harness error messages)" do
|
@@ -237,10 +250,14 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
237
250
|
let(:user2) { double(:account => 'user2', :domain => '.', :sid => 'user2sid') }
|
238
251
|
let(:user3) { double(:account => 'user3', :domain => '.', :sid => 'user3sid') }
|
239
252
|
|
253
|
+
let(:invalid_user) { SecureRandom.uuid }
|
254
|
+
let(:invalid_user_principal) { double(:account => "#{invalid_user}", :domain => nil, :sid => "#{invalid_user}") }
|
255
|
+
|
240
256
|
before :each do
|
241
|
-
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user1').and_return(user1)
|
242
|
-
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2').and_return(user2)
|
243
|
-
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user3').and_return(user3)
|
257
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user1', any_args).and_return(user1)
|
258
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2', any_args).and_return(user2)
|
259
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user3', any_args).and_return(user3)
|
260
|
+
allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with(invalid_user, true).and_return(invalid_user_principal)
|
244
261
|
|
245
262
|
resource[:auth_membership] = true
|
246
263
|
end
|
@@ -261,6 +278,22 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
261
278
|
expect(provider.members).to match_array(expected_members)
|
262
279
|
end
|
263
280
|
|
281
|
+
it "should be able to handle unresolvable SID in list of members" do
|
282
|
+
allow(provider.group).to receive(:members).and_return([
|
283
|
+
'user1',
|
284
|
+
"#{invalid_user}",
|
285
|
+
'user3',
|
286
|
+
])
|
287
|
+
|
288
|
+
expected_member_sids = [user1.sid, invalid_user_principal.sid, user3.sid]
|
289
|
+
expected_members = ['user1', "#{invalid_user}", 'user3']
|
290
|
+
allow(provider).to receive(:members_to_s)
|
291
|
+
.with(expected_member_sids)
|
292
|
+
.and_return(expected_members.join(','))
|
293
|
+
|
294
|
+
expect(provider.members).to match_array(expected_members)
|
295
|
+
end
|
296
|
+
|
264
297
|
it "should be able to set group members" do
|
265
298
|
allow(provider.group).to receive(:members).and_return(['user1', 'user2'])
|
266
299
|
|
@@ -272,8 +305,8 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
272
305
|
|
273
306
|
allow(provider.group).to receive(:member_sids).and_return(member_sids[0..1])
|
274
307
|
|
275
|
-
expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2').and_return(member_sids[1])
|
276
|
-
expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user3').and_return(member_sids[2])
|
308
|
+
expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2', any_args).and_return(member_sids[1])
|
309
|
+
expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user3', any_args).and_return(member_sids[2])
|
277
310
|
|
278
311
|
expect(provider.group).to receive(:remove_member_sids).with(member_sids[0])
|
279
312
|
expect(provider.group).to receive(:add_member_sids).with(member_sids[2])
|
@@ -22,16 +22,26 @@ describe Puppet::Type.type(:package).provider(:aix) do
|
|
22
22
|
|
23
23
|
context "when installing" do
|
24
24
|
it "should install a package" do
|
25
|
+
allow(@provider).to receive(:query).and_return({:name => 'mypackage', :ensure => 'present', :status => :committed})
|
25
26
|
expect(@provider).to receive(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage')
|
26
27
|
@provider.install
|
27
28
|
end
|
28
29
|
|
29
30
|
it "should install a specific package version" do
|
30
31
|
allow(@resource).to receive(:should).with(:ensure).and_return("1.2.3.4")
|
32
|
+
allow(@provider).to receive(:query).and_return({:name => 'mypackage', :ensure => '1.2.3.4', :status => :committed})
|
31
33
|
expect(@provider).to receive(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage 1.2.3.4')
|
32
34
|
@provider.install
|
33
35
|
end
|
34
36
|
|
37
|
+
[:broken, :inconsistent].each do |state|
|
38
|
+
it "should fail if the installation resulted in a '#{state}' state" do
|
39
|
+
allow(@provider).to receive(:query).and_return({:name => 'mypackage', :ensure => 'present', :status => state})
|
40
|
+
expect(@provider).to receive(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage')
|
41
|
+
expect { @provider.install }.to raise_error(Puppet::Error, "Package 'mypackage' is in a #{state} state and requires manual intervention")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
35
45
|
it "should fail if the specified version is superseded" do
|
36
46
|
@resource[:ensure] = '1.2.3.3'
|
37
47
|
allow(@provider).to receive(:installp).and_return(<<-OUTPUT)
|
@@ -126,4 +136,23 @@ END
|
|
126
136
|
expect(described_class).to receive(:execute).and_return('mypackage:mypackage.rte:1.8.6.4::I:T:::::N:A Super Cool Package::::0::\n')
|
127
137
|
described_class.prefetch({ 'mypackage' => latest, 'otherpackage' => absent })
|
128
138
|
end
|
139
|
+
|
140
|
+
context "when querying instances" do
|
141
|
+
before(:each) do
|
142
|
+
allow(described_class).to receive(:execute).and_return(<<-END.chomp)
|
143
|
+
sysmgt.cim.providers:sysmgt.cim.providers.metrics:2.12.1.1: : :B: :Metrics Providers for AIX OS: : : : : : :1:0:/:
|
144
|
+
sysmgt.cim.providers:sysmgt.cim.providers.osbase:2.12.1.1: : :C: :Base Providers for AIX OS: : : : : : :1:0:/:
|
145
|
+
openssl.base:openssl.base:1.0.2.1800: : :?: :Open Secure Socket Layer: : : : : : :0:0:/:
|
146
|
+
END
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should treat installed packages in broken and inconsistent state as absent" do
|
150
|
+
installed_packages = described_class.instances.map { |package| package.properties }
|
151
|
+
expected_packages = [{:name => 'sysmgt.cim.providers.metrics', :ensure => :absent, :status => :broken, :provider => :aix},
|
152
|
+
{:name => 'sysmgt.cim.providers.osbase', :ensure => '2.12.1.1', :status => :committed, :provider => :aix},
|
153
|
+
{:name => 'openssl.base', :ensure => :absent, :status => :inconsistent, :provider => :aix}]
|
154
|
+
|
155
|
+
expect(installed_packages).to eql(expected_packages)
|
156
|
+
end
|
157
|
+
end
|
129
158
|
end
|
@@ -18,7 +18,7 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
|
|
18
18
|
{:failonfail => true, :combine => true, :custom_environment => {}}
|
19
19
|
end
|
20
20
|
|
21
|
-
let(:packages) { File.read(my_fixture("dnf-module-list-
|
21
|
+
let(:packages) { File.read(my_fixture("dnf-module-list-enabled.txt")) }
|
22
22
|
let(:dnf_path) { '/usr/bin/dnf' }
|
23
23
|
|
24
24
|
before(:each) { allow(Puppet::Util).to receive(:which).with('/usr/bin/dnf').and_return(dnf_path) }
|
@@ -123,6 +123,23 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
|
|
123
123
|
provider.install
|
124
124
|
end
|
125
125
|
|
126
|
+
it "should just enable the module if it has no default profile" do
|
127
|
+
dnf_exception = Puppet::ExecutionFailure.new("Error: Problems in request:\nmissing groups or modules: #{resource[:name]}")
|
128
|
+
allow(provider).to receive(:execute).with(array_including('install')).and_raise(dnf_exception)
|
129
|
+
resource[:ensure] = :present
|
130
|
+
expect(provider).to receive(:execute).with(array_including('install')).ordered
|
131
|
+
expect(provider).to receive(:execute).with(array_including('enable')).ordered
|
132
|
+
provider.install
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should just enable the module if enable_only = true" do
|
136
|
+
resource[:ensure] = :present
|
137
|
+
resource[:enable_only] = true
|
138
|
+
expect(provider).to receive(:execute).with(array_including('enable'))
|
139
|
+
expect(provider).not_to receive(:execute).with(array_including('install'))
|
140
|
+
provider.install
|
141
|
+
end
|
142
|
+
|
126
143
|
it "should install the default stream and flavor" do
|
127
144
|
resource[:ensure] = :present
|
128
145
|
expect(provider).to receive(:execute).with(array_including('baz'))
|
@@ -185,24 +202,26 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
|
|
185
202
|
end
|
186
203
|
end
|
187
204
|
|
188
|
-
context "parsing the output of module list --
|
205
|
+
context "parsing the output of module list --enabled" do
|
189
206
|
before { allow(described_class).to receive(:command).with(:dnf).and_return(dnf_path) }
|
190
207
|
|
191
|
-
it "returns an array of
|
208
|
+
it "returns an array of enabled modules" do
|
192
209
|
allow(Puppet::Util::Execution).to receive(:execute)
|
193
|
-
.with("/usr/bin/dnf module list --
|
210
|
+
.with("/usr/bin/dnf module list --enabled -d 0 -e 1")
|
194
211
|
.and_return(packages)
|
195
212
|
|
196
|
-
|
197
|
-
expected_packages = [{name: "
|
198
|
-
{name: "
|
199
|
-
{name: "
|
200
|
-
{name: "
|
201
|
-
{name: "
|
202
|
-
{name: "
|
203
|
-
{name: "
|
204
|
-
|
205
|
-
|
213
|
+
enabled_packages = described_class.instances.map { |package| package.properties }
|
214
|
+
expected_packages = [{name: "389-ds", ensure: "1.4", flavor: :absent, provider: :dnfmodule},
|
215
|
+
{name: "gimp", ensure: "2.8", flavor: "devel", provider: :dnfmodule},
|
216
|
+
{name: "mariadb", ensure: "10.3", flavor: "client", provider: :dnfmodule},
|
217
|
+
{name: "nodejs", ensure: "10", flavor: "minimal", provider: :dnfmodule},
|
218
|
+
{name: "perl", ensure: "5.26", flavor: "minimal", provider: :dnfmodule},
|
219
|
+
{name: "postgresql", ensure: "10", flavor: "server", provider: :dnfmodule},
|
220
|
+
{name: "ruby", ensure: "2.5", flavor: :absent, provider: :dnfmodule},
|
221
|
+
{name: "rust-toolset", ensure: "rhel8", flavor: "common", provider: :dnfmodule},
|
222
|
+
{name: "subversion", ensure: "1.10", flavor: "server", provider: :dnfmodule}]
|
223
|
+
|
224
|
+
expect(enabled_packages).to eql(expected_packages)
|
206
225
|
end
|
207
226
|
end
|
208
227
|
end
|
@@ -45,7 +45,7 @@ describe Puppet::Type.type(:package).provider(:pkgdmg) do
|
|
45
45
|
it "should call hdiutil to mount and eject the disk image" do
|
46
46
|
allow(Dir).to receive(:entries).and_return([])
|
47
47
|
expect(provider.class).to receive(:hdiutil).with("eject", fake_mountpoint).and_return(0)
|
48
|
-
expect(provider.class).to receive(:hdiutil).with("mount", "-plist", "-nobrowse", "-readonly", "-
|
48
|
+
expect(provider.class).to receive(:hdiutil).with("mount", "-plist", "-nobrowse", "-readonly", "-mountrandom", "/tmp", '/tmp/foo').and_return('a plist')
|
49
49
|
expect(Puppet::Util::Plist).to receive(:parse_plist).with('a plist').and_return(fake_hdiutil_plist)
|
50
50
|
provider.install
|
51
51
|
end
|
@@ -110,6 +110,30 @@ describe Puppet::Type.type(:package).provider(:pkgng) do
|
|
110
110
|
end
|
111
111
|
resource.provider.install
|
112
112
|
end
|
113
|
+
|
114
|
+
it "should call pkg with the specified install options string" do
|
115
|
+
resource = Puppet::Type.type(:package).new(
|
116
|
+
:name => 'curl',
|
117
|
+
:provider => :pkgng,
|
118
|
+
:install_options => ['--foo', '--bar']
|
119
|
+
)
|
120
|
+
expect(resource.provider).to receive(:pkg) do |arg|
|
121
|
+
expect(arg).to include('--foo', '--bar')
|
122
|
+
end
|
123
|
+
resource.provider.install
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should call pkg with the specified install options hash" do
|
127
|
+
resource = Puppet::Type.type(:package).new(
|
128
|
+
:name => 'curl',
|
129
|
+
:provider => :pkgng,
|
130
|
+
:install_options => ['--foo', { '--bar' => 'baz', '--baz' => 'foo' }]
|
131
|
+
)
|
132
|
+
expect(resource.provider).to receive(:pkg) do |arg|
|
133
|
+
expect(arg).to include('--foo', '--bar=baz', '--baz=foo')
|
134
|
+
end
|
135
|
+
resource.provider.install
|
136
|
+
end
|
113
137
|
end
|
114
138
|
|
115
139
|
context "#prefetch" do
|
@@ -169,6 +193,18 @@ describe Puppet::Type.type(:package).provider(:pkgng) do
|
|
169
193
|
bash_comp_latest_version = described_class.get_latest_version('shells/bash-completion', version_list)
|
170
194
|
expect(bash_comp_latest_version).to eq('2.1_3')
|
171
195
|
end
|
196
|
+
|
197
|
+
it "should return nil when the package is orphaned" do
|
198
|
+
version_list = File.read(my_fixture('pkg.version'))
|
199
|
+
orphan_latest_version = described_class.get_latest_version('sysutils/orphan', version_list)
|
200
|
+
expect(orphan_latest_version).to be_nil
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should return nil when the package is broken" do
|
204
|
+
version_list = File.read(my_fixture('pkg.version'))
|
205
|
+
broken_latest_version = described_class.get_latest_version('sysutils/broken', version_list)
|
206
|
+
expect(broken_latest_version).to be_nil
|
207
|
+
end
|
172
208
|
end
|
173
209
|
|
174
210
|
describe "confine" do
|
@@ -55,7 +55,7 @@ describe Puppet::Type.type(:package).provider(:yum) do
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
describe 'with install_options' do
|
58
|
+
describe 'with install_options' do
|
59
59
|
it 'can parse disable-repo with array of strings' do
|
60
60
|
resource[:install_options] = ['--disable-repo=dev*', '--disable-repo=prod*']
|
61
61
|
expect(provider).to receive(:execute) do | arr|
|
@@ -194,5 +194,14 @@ describe Puppet::Type.type(:package).provider(:yum) do
|
|
194
194
|
expect(output).not_to include("Random plugin")
|
195
195
|
end
|
196
196
|
end
|
197
|
+
|
198
|
+
context "with subscription manager enabled " do
|
199
|
+
let(:check_update) { File.read(my_fixture("yum-check-update-subscription-manager.txt")) }
|
200
|
+
let(:output) { described_class.parse_updates(check_update) }
|
201
|
+
|
202
|
+
it "parses correctly formatted entries" do
|
203
|
+
expect(output['curl.x86_64']).to eq([{:name => 'curl', :epoch => '0', :version => '7.32.0', :release => '10.fc20', :arch => 'x86_64'}])
|
204
|
+
end
|
205
|
+
end
|
197
206
|
end
|
198
207
|
end
|
@@ -6,78 +6,149 @@
|
|
6
6
|
require 'spec_helper'
|
7
7
|
require 'stringio'
|
8
8
|
|
9
|
-
|
9
|
+
describe Puppet::Type.type(:selmodule).provider(:semodule) do
|
10
|
+
let(:resource) { instance_double('resource', name: name) }
|
11
|
+
let(:provider) { described_class.new(resource) }
|
10
12
|
|
11
|
-
describe provider_class do
|
12
13
|
before :each do
|
13
|
-
|
14
|
-
allow(@resource).to receive(:[]).and_return("foo")
|
15
|
-
@provider = provider_class.new(@resource)
|
14
|
+
allow(resource).to receive(:[]).and_return name
|
16
15
|
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
def loaded_modules
|
18
|
+
{
|
19
|
+
'bar' => '1.2.3',
|
20
|
+
'foo' => '4.4.4',
|
21
|
+
'bang' => '1.0.0',
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def semodule_list_output
|
26
|
+
loaded_modules.map{|k,v| "#{k}\t#{v}"}.join("\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'selmodules_loaded' do
|
30
|
+
let(:name) { 'foo' }
|
31
|
+
|
32
|
+
it 'should return raise an exception when running selmodule raises an exception' do
|
33
|
+
provider.class.loaded_modules = nil # Reset loaded_modules before test
|
34
|
+
allow(provider.class).to receive(:command).with(:semodule).and_return '/usr/sbin/semodule'
|
35
|
+
allow(provider.class).to receive(:execpipe).with('/usr/sbin/semodule --list')
|
36
|
+
.and_yield(StringIO.new("this is\nan error")).and_raise(Puppet::ExecutionFailure, 'it failed')
|
37
|
+
expect { provider.selmodules_loaded }
|
38
|
+
.to raise_error(Puppet::Error, /Could not list policy modules: ".*" failed with "this is an error"/)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should return empty hash if no modules are loaded' do
|
42
|
+
provider.class.loaded_modules = nil # Reset loaded_modules before test
|
43
|
+
allow(provider.class).to receive(:command).with(:semodule).and_return '/usr/sbin/semodule'
|
44
|
+
allow(provider.class).to receive(:execpipe).with('/usr/sbin/semodule --list').and_yield StringIO.new('')
|
45
|
+
expect(provider.selmodules_loaded).to eq(Hash.new())
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should return hash of loaded modules' do
|
49
|
+
provider.class.loaded_modules = nil # Reset loaded_modules before test
|
50
|
+
allow(provider.class).to receive(:command).with(:semodule).and_return '/usr/sbin/semodule'
|
51
|
+
allow(provider.class).to receive(:execpipe).with('/usr/sbin/semodule --list').and_yield StringIO.new(semodule_list_output)
|
52
|
+
expect(provider.selmodules_loaded).to eq(loaded_modules)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should return cached hash of loaded modules' do
|
56
|
+
allow(provider.class).to receive(:loaded_modules).and_return loaded_modules
|
57
|
+
allow(provider.class).to receive(:command).with(:semodule).and_return '/usr/sbin/semodule'
|
58
|
+
allow(provider.class).to receive(:execpipe).with('/usr/sbin/semodule --list').and_yield StringIO.new("test\t1.0.0")
|
59
|
+
expect(provider.selmodules_loaded).to eq(loaded_modules)
|
23
60
|
end
|
24
61
|
|
25
|
-
it
|
26
|
-
|
27
|
-
|
28
|
-
|
62
|
+
it 'should return cached hash of loaded modules and not raise an exception' do
|
63
|
+
allow(provider.class).to receive(:loaded_modules).and_return loaded_modules
|
64
|
+
allow(provider.class).to receive(:command).with(:semodule).and_return '/usr/sbin/semodule'
|
65
|
+
allow(provider.class).to receive(:execpipe).with('/usr/sbin/semodule --list')
|
66
|
+
.and_yield(StringIO.new('this should not be called')).and_raise(Puppet::ExecutionFailure, 'it failed')
|
67
|
+
expect(provider.selmodules_loaded).to eq(loaded_modules)
|
29
68
|
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'exists? method' do
|
72
|
+
context 'with name foo' do
|
73
|
+
let(:name) { 'foo' }
|
74
|
+
|
75
|
+
it 'should return false if no modules are loaded' do
|
76
|
+
allow(provider).to receive(:selmodules_loaded).and_return Hash.new()
|
77
|
+
expect(provider.exists?).to eq(false)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should find a module if it is already loaded' do
|
81
|
+
allow(provider).to receive(:selmodules_loaded).and_return loaded_modules
|
82
|
+
expect(provider.exists?).to eq(true)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'with name foobar' do
|
87
|
+
let(:name) { 'foobar' }
|
30
88
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
89
|
+
it 'should return false if not loaded' do
|
90
|
+
allow(provider).to receive(:selmodules_loaded).and_return loaded_modules
|
91
|
+
expect(provider.exists?).to eq(false)
|
92
|
+
end
|
35
93
|
end
|
36
94
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
95
|
+
context 'with name myfoo' do
|
96
|
+
let(:name) { 'myfoo' }
|
97
|
+
|
98
|
+
it 'should return false if module with same suffix is loaded' do
|
99
|
+
allow(provider).to receive(:selmodules_loaded).and_return loaded_modules
|
100
|
+
expect(provider.exists?).to eq(false)
|
101
|
+
end
|
41
102
|
end
|
42
103
|
end
|
43
104
|
|
44
|
-
describe
|
45
|
-
|
46
|
-
|
47
|
-
|
105
|
+
describe 'selmodversion_file' do
|
106
|
+
let(:name) { 'foo' }
|
107
|
+
|
108
|
+
it 'should return 1.5.0 for the example policy file' do
|
109
|
+
allow(provider).to receive(:selmod_name_to_filename).and_return "#{File.dirname(__FILE__)}/selmodule-example.pp"
|
110
|
+
expect(provider.selmodversion_file).to eq('1.5.0')
|
48
111
|
end
|
49
112
|
end
|
50
113
|
|
51
|
-
describe
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
114
|
+
describe 'syncversion' do
|
115
|
+
let(:name) { 'foo' }
|
116
|
+
|
117
|
+
it 'should return :true if loaded and file modules are in sync' do
|
118
|
+
allow(provider).to receive(:selmodversion_loaded).and_return '1.5.0'
|
119
|
+
allow(provider).to receive(:selmodversion_file).and_return '1.5.0'
|
120
|
+
expect(provider.syncversion).to eq(:true)
|
56
121
|
end
|
57
122
|
|
58
|
-
it
|
59
|
-
|
60
|
-
|
61
|
-
expect(
|
123
|
+
it 'should return :false if loaded and file modules are not in sync' do
|
124
|
+
allow(provider).to receive(:selmodversion_loaded).and_return '1.4.0'
|
125
|
+
allow(provider).to receive(:selmodversion_file).and_return '1.5.0'
|
126
|
+
expect(provider.syncversion).to eq(:false)
|
62
127
|
end
|
63
128
|
|
64
|
-
it
|
65
|
-
|
66
|
-
expect(
|
129
|
+
it 'should return before checking file version if no loaded policy' do
|
130
|
+
allow(provider).to receive(:selmodversion_loaded).and_return nil
|
131
|
+
expect(provider.syncversion).to eq(:false)
|
67
132
|
end
|
68
133
|
end
|
69
134
|
|
70
|
-
describe
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
135
|
+
describe 'selmodversion_loaded' do
|
136
|
+
context 'with name foo' do
|
137
|
+
let(:name) { 'foo' }
|
138
|
+
|
139
|
+
it 'should return the version of a loaded module' do
|
140
|
+
allow(provider).to receive(:selmodules_loaded).and_return loaded_modules
|
141
|
+
expect(provider.selmodversion_loaded).to eq('4.4.4')
|
142
|
+
end
|
75
143
|
end
|
76
144
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
145
|
+
context 'with name foobar' do
|
146
|
+
let(:name) { 'foobar' }
|
147
|
+
|
148
|
+
it 'should return nil if module is not loaded' do
|
149
|
+
allow(provider).to receive(:selmodules_loaded).and_return loaded_modules
|
150
|
+
expect(provider.selmodversion_loaded).to be_nil
|
151
|
+
end
|
81
152
|
end
|
82
153
|
end
|
83
154
|
end
|