puppet 6.19.0 → 6.22.1

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.

Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -16
  3. data/Gemfile +3 -1
  4. data/Gemfile.lock +50 -39
  5. data/ext/project_data.yaml +2 -2
  6. data/lib/puppet/application.rb +10 -6
  7. data/lib/puppet/application/agent.rb +1 -0
  8. data/lib/puppet/application/apply.rb +3 -2
  9. data/lib/puppet/application/device.rb +1 -0
  10. data/lib/puppet/application/filebucket.rb +2 -2
  11. data/lib/puppet/application/script.rb +1 -0
  12. data/lib/puppet/application/ssl.rb +11 -0
  13. data/lib/puppet/application_support.rb +7 -0
  14. data/lib/puppet/configurer.rb +28 -18
  15. data/lib/puppet/defaults.rb +46 -20
  16. data/lib/puppet/environments.rb +54 -55
  17. data/lib/puppet/face/config.rb +10 -0
  18. data/lib/puppet/face/epp.rb +12 -2
  19. data/lib/puppet/face/facts.rb +158 -0
  20. data/lib/puppet/ffi/posix.rb +10 -0
  21. data/lib/puppet/ffi/posix/constants.rb +14 -0
  22. data/lib/puppet/ffi/posix/functions.rb +24 -0
  23. data/lib/puppet/file_system/memory_file.rb +8 -1
  24. data/lib/puppet/file_system/windows.rb +2 -0
  25. data/lib/puppet/functions/epp.rb +1 -0
  26. data/lib/puppet/functions/inline_epp.rb +1 -0
  27. data/lib/puppet/functions/partition.rb +8 -0
  28. data/lib/puppet/indirector/fact_search.rb +60 -0
  29. data/lib/puppet/indirector/facts/facter.rb +24 -3
  30. data/lib/puppet/indirector/facts/json.rb +27 -0
  31. data/lib/puppet/indirector/facts/yaml.rb +3 -58
  32. data/lib/puppet/indirector/json.rb +5 -1
  33. data/lib/puppet/indirector/node/json.rb +8 -0
  34. data/lib/puppet/indirector/report/json.rb +34 -0
  35. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  36. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  37. data/lib/puppet/network/formats.rb +69 -1
  38. data/lib/puppet/network/http/factory.rb +4 -0
  39. data/lib/puppet/pal/pal_impl.rb +70 -17
  40. data/lib/puppet/parser/ast/leaf.rb +3 -2
  41. data/lib/puppet/parser/templatewrapper.rb +1 -1
  42. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
  44. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  45. data/lib/puppet/property/list.rb +1 -1
  46. data/lib/puppet/provider/group/groupadd.rb +13 -8
  47. data/lib/puppet/provider/package/apt.rb +34 -2
  48. data/lib/puppet/provider/package/aptitude.rb +6 -0
  49. data/lib/puppet/provider/package/dnfmodule.rb +1 -1
  50. data/lib/puppet/provider/service/debian.rb +2 -0
  51. data/lib/puppet/provider/service/systemd.rb +1 -1
  52. data/lib/puppet/provider/user/aix.rb +2 -2
  53. data/lib/puppet/provider/user/useradd.rb +62 -8
  54. data/lib/puppet/reference/configuration.rb +6 -5
  55. data/lib/puppet/settings.rb +43 -15
  56. data/lib/puppet/settings/alias_setting.rb +37 -0
  57. data/lib/puppet/settings/base_setting.rb +26 -2
  58. data/lib/puppet/settings/environment_conf.rb +1 -0
  59. data/lib/puppet/type/package.rb +3 -3
  60. data/lib/puppet/util/autoload.rb +1 -8
  61. data/lib/puppet/util/fact_dif.rb +81 -0
  62. data/lib/puppet/util/monkey_patches.rb +7 -0
  63. data/lib/puppet/util/posix.rb +54 -5
  64. data/lib/puppet/util/rubygems.rb +5 -1
  65. data/lib/puppet/util/windows/adsi.rb +46 -0
  66. data/lib/puppet/util/windows/api_types.rb +1 -1
  67. data/lib/puppet/util/windows/principal.rb +9 -2
  68. data/lib/puppet/util/windows/service.rb +1 -1
  69. data/lib/puppet/util/windows/sid.rb +4 -2
  70. data/lib/puppet/version.rb +1 -1
  71. data/locales/puppet.pot +295 -219
  72. data/man/man5/puppet.conf.5 +15 -7
  73. data/man/man8/puppet-agent.8 +2 -2
  74. data/man/man8/puppet-apply.8 +2 -2
  75. data/man/man8/puppet-catalog.8 +1 -1
  76. data/man/man8/puppet-config.8 +1 -1
  77. data/man/man8/puppet-describe.8 +1 -1
  78. data/man/man8/puppet-device.8 +2 -2
  79. data/man/man8/puppet-doc.8 +1 -1
  80. data/man/man8/puppet-epp.8 +1 -1
  81. data/man/man8/puppet-facts.8 +90 -1
  82. data/man/man8/puppet-filebucket.8 +3 -3
  83. data/man/man8/puppet-generate.8 +1 -1
  84. data/man/man8/puppet-help.8 +1 -1
  85. data/man/man8/puppet-key.8 +1 -1
  86. data/man/man8/puppet-lookup.8 +1 -1
  87. data/man/man8/puppet-man.8 +1 -1
  88. data/man/man8/puppet-module.8 +1 -1
  89. data/man/man8/puppet-node.8 +4 -1
  90. data/man/man8/puppet-parser.8 +1 -1
  91. data/man/man8/puppet-plugin.8 +1 -1
  92. data/man/man8/puppet-report.8 +4 -1
  93. data/man/man8/puppet-resource.8 +1 -1
  94. data/man/man8/puppet-script.8 +2 -2
  95. data/man/man8/puppet-ssl.8 +5 -1
  96. data/man/man8/puppet-status.8 +1 -1
  97. data/man/man8/puppet.8 +2 -2
  98. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  99. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services_vendor_preset +9 -0
  100. data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
  101. data/spec/integration/application/agent_spec.rb +160 -3
  102. data/spec/integration/application/apply_spec.rb +19 -0
  103. data/spec/integration/application/plugin_spec.rb +1 -1
  104. data/spec/integration/defaults_spec.rb +0 -7
  105. data/spec/integration/environments/setting_hooks_spec.rb +1 -1
  106. data/spec/integration/http/client_spec.rb +12 -0
  107. data/spec/integration/indirector/direct_file_server_spec.rb +1 -3
  108. data/spec/integration/resource/type_collection_spec.rb +2 -6
  109. data/spec/integration/transaction_spec.rb +4 -9
  110. data/spec/integration/util/windows/adsi_spec.rb +21 -1
  111. data/spec/integration/util/windows/principal_spec.rb +21 -0
  112. data/spec/integration/util/windows/registry_spec.rb +6 -10
  113. data/spec/lib/puppet_spec/settings.rb +6 -1
  114. data/spec/spec_helper.rb +12 -5
  115. data/spec/unit/agent_spec.rb +8 -6
  116. data/spec/unit/application/agent_spec.rb +0 -1
  117. data/spec/unit/application/config_spec.rb +224 -4
  118. data/spec/unit/application/facts_spec.rb +482 -3
  119. data/spec/unit/application/filebucket_spec.rb +0 -2
  120. data/spec/unit/application/ssl_spec.rb +23 -0
  121. data/spec/unit/application_spec.rb +51 -9
  122. data/spec/unit/confine/feature_spec.rb +1 -1
  123. data/spec/unit/confine_spec.rb +8 -2
  124. data/spec/unit/defaults_spec.rb +36 -1
  125. data/spec/unit/environments_spec.rb +221 -68
  126. data/spec/unit/face/config_spec.rb +27 -32
  127. data/spec/unit/face/facts_spec.rb +4 -0
  128. data/spec/unit/face/node_spec.rb +0 -11
  129. data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
  130. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  131. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  132. data/spec/unit/file_system_spec.rb +9 -0
  133. data/spec/unit/forge/module_release_spec.rb +2 -7
  134. data/spec/unit/functions/inline_epp_spec.rb +26 -1
  135. data/spec/unit/http/service/compiler_spec.rb +49 -0
  136. data/spec/unit/http/service_spec.rb +1 -1
  137. data/spec/unit/indirector/face_spec.rb +0 -1
  138. data/spec/unit/indirector/facts/facter_spec.rb +95 -1
  139. data/spec/unit/indirector/facts/json_spec.rb +255 -0
  140. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  141. data/spec/unit/indirector/indirection_spec.rb +8 -12
  142. data/spec/unit/indirector/key/file_spec.rb +0 -1
  143. data/spec/unit/indirector/node/json_spec.rb +33 -0
  144. data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
  145. data/spec/unit/indirector/report/yaml_spec.rb +72 -8
  146. data/spec/unit/indirector_spec.rb +2 -2
  147. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  148. data/spec/unit/network/authconfig_spec.rb +0 -3
  149. data/spec/unit/network/formats_spec.rb +41 -0
  150. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
  151. data/spec/unit/network/http/factory_spec.rb +19 -0
  152. data/spec/unit/network/http/handler_spec.rb +0 -5
  153. data/spec/unit/parser/compiler_spec.rb +3 -19
  154. data/spec/unit/parser/resource_spec.rb +14 -8
  155. data/spec/unit/parser/templatewrapper_spec.rb +4 -3
  156. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  157. data/spec/unit/property_spec.rb +1 -0
  158. data/spec/unit/provider/group/groupadd_spec.rb +5 -2
  159. data/spec/unit/provider/nameservice_spec.rb +66 -65
  160. data/spec/unit/provider/package/apt_spec.rb +28 -23
  161. data/spec/unit/provider/package/aptitude_spec.rb +1 -1
  162. data/spec/unit/provider/package/base_spec.rb +6 -5
  163. data/spec/unit/provider/package/dnfmodule_spec.rb +10 -1
  164. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  165. data/spec/unit/provider/package/pip_spec.rb +6 -11
  166. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  167. data/spec/unit/provider/service/systemd_spec.rb +11 -0
  168. data/spec/unit/provider/user/aix_spec.rb +5 -0
  169. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  170. data/spec/unit/provider/user/pw_spec.rb +2 -0
  171. data/spec/unit/provider/user/useradd_spec.rb +71 -3
  172. data/spec/unit/provider_spec.rb +8 -10
  173. data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
  174. data/spec/unit/resource/capability_finder_spec.rb +6 -1
  175. data/spec/unit/resource/catalog_spec.rb +1 -1
  176. data/spec/unit/resource/type_spec.rb +1 -1
  177. data/spec/unit/resource_spec.rb +11 -10
  178. data/spec/unit/settings_spec.rb +543 -228
  179. data/spec/unit/ssl/base_spec.rb +0 -1
  180. data/spec/unit/ssl/host_spec.rb +0 -5
  181. data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
  182. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -7
  183. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  184. data/spec/unit/transaction_spec.rb +13 -4
  185. data/spec/unit/type/file/content_spec.rb +0 -1
  186. data/spec/unit/type/file/selinux_spec.rb +0 -2
  187. data/spec/unit/type/file_spec.rb +0 -6
  188. data/spec/unit/type/group_spec.rb +13 -6
  189. data/spec/unit/type/resources_spec.rb +7 -7
  190. data/spec/unit/type/service_spec.rb +1 -1
  191. data/spec/unit/type/tidy_spec.rb +0 -1
  192. data/spec/unit/type_spec.rb +2 -2
  193. data/spec/unit/util/at_fork_spec.rb +2 -2
  194. data/spec/unit/util/autoload_spec.rb +5 -1
  195. data/spec/unit/util/backups_spec.rb +1 -2
  196. data/spec/unit/util/execution_spec.rb +15 -11
  197. data/spec/unit/util/inifile_spec.rb +6 -14
  198. data/spec/unit/util/log_spec.rb +8 -7
  199. data/spec/unit/util/logging_spec.rb +3 -3
  200. data/spec/unit/util/posix_spec.rb +363 -15
  201. data/spec/unit/util/rubygems_spec.rb +2 -2
  202. data/spec/unit/util/selinux_spec.rb +76 -52
  203. data/spec/unit/util/storage_spec.rb +3 -1
  204. data/spec/unit/util/suidmanager_spec.rb +44 -41
  205. data/spec/unit/util/windows/sid_spec.rb +6 -0
  206. data/spec/unit/util_spec.rb +13 -6
  207. metadata +23 -14
  208. data/spec/integration/application/config_spec.rb +0 -74
  209. data/spec/lib/matchers/include.rb +0 -27
  210. data/spec/lib/matchers/include_spec.rb +0 -32
  211. data/spec/unit/face/catalog_spec.rb +0 -6
  212. data/spec/unit/face/module_spec.rb +0 -3
@@ -123,7 +123,7 @@ 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
126
+ it "should just enable the module if it has no default profile(missing groups or modules)" do
127
127
  dnf_exception = Puppet::ExecutionFailure.new("Error: Problems in request:\nmissing groups or modules: #{resource[:name]}")
128
128
  allow(provider).to receive(:execute).with(array_including('install')).and_raise(dnf_exception)
129
129
  resource[:ensure] = :present
@@ -132,6 +132,15 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
132
132
  provider.install
133
133
  end
134
134
 
135
+ it "should just enable the module if it has no default profile(broken groups or modules)" do
136
+ dnf_exception = Puppet::ExecutionFailure.new("Error: Problems in request:\nbroken groups or modules: #{resource[:name]}")
137
+ allow(provider).to receive(:execute).with(array_including('install')).and_raise(dnf_exception)
138
+ resource[:ensure] = :present
139
+ expect(provider).to receive(:execute).with(array_including('install')).ordered
140
+ expect(provider).to receive(:execute).with(array_including('enable')).ordered
141
+ provider.install
142
+ end
143
+
135
144
  it "should just enable the module if enable_only = true" do
136
145
  resource[:ensure] = :present
137
146
  resource[:enable_only] = true
@@ -32,10 +32,12 @@ describe Puppet::Type.type(:package).provider(:pacman) do
32
32
  end
33
33
 
34
34
  it "should call yaourt to install the right package quietly when yaourt is installed" do
35
- allow(described_class).to receive(:yaourt?).and_return(true)
36
- args = ['--noconfirm', '--needed', '--noprogressbar', '-S', resource[:name]]
37
- expect(provider).to receive(:yaourt).at_least(:once).with(*args).and_return('')
38
- provider.install
35
+ without_partial_double_verification do
36
+ allow(described_class).to receive(:yaourt?).and_return(true)
37
+ args = ['--noconfirm', '--needed', '--noprogressbar', '-S', resource[:name]]
38
+ expect(provider).to receive(:yaourt).at_least(:once).with(*args).and_return('')
39
+ provider.install
40
+ end
39
41
  end
40
42
 
41
43
  it "should raise an Puppet::Error if the installation failed" do
@@ -74,10 +76,12 @@ describe Puppet::Type.type(:package).provider(:pacman) do
74
76
  end
75
77
 
76
78
  it "should call yaourt to install the right package quietly when yaourt is installed" do
77
- expect(described_class).to receive(:yaourt?).and_return(true)
78
- args = ['--noconfirm', '--needed', '--noprogressbar', '-x', '--arg=value', '-S', resource[:name]]
79
- expect(provider).to receive(:yaourt).at_least(:once).with(*args).and_return('')
80
- provider.install
79
+ without_partial_double_verification do
80
+ expect(described_class).to receive(:yaourt?).and_return(true)
81
+ args = ['--noconfirm', '--needed', '--noprogressbar', '-x', '--arg=value', '-S', resource[:name]]
82
+ expect(provider).to receive(:yaourt).at_least(:once).with(*args).and_return('')
83
+ provider.install
84
+ end
81
85
  end
82
86
  end
83
87
 
@@ -172,10 +176,12 @@ describe Puppet::Type.type(:package).provider(:pacman) do
172
176
  end
173
177
 
174
178
  it "should call yaourt to remove the right package quietly" do
175
- allow(described_class).to receive(:yaourt?).and_return(true)
176
- args = ["--noconfirm", "--noprogressbar", "-R", resource[:name]]
177
- expect(provider).to receive(:yaourt).with(*args)
178
- provider.uninstall
179
+ without_partial_double_verification do
180
+ allow(described_class).to receive(:yaourt?).and_return(true)
181
+ args = ["--noconfirm", "--noprogressbar", "-R", resource[:name]]
182
+ expect(provider).to receive(:yaourt).with(*args)
183
+ provider.uninstall
184
+ end
179
185
  end
180
186
 
181
187
  it "adds any uninstall_options" do
@@ -14,9 +14,8 @@ describe Puppet::Type.type(:package).provider(:pip) do
14
14
  it { is_expected.to be_version_ranges }
15
15
 
16
16
  before do
17
- @resource = Puppet::Resource.new(:package, "fake_package")
18
- allow(@resource).to receive(:original_parameters).and_return({})
19
- @provider = described_class.new(@resource)
17
+ @resource = Puppet::Type.type(:package).new(name: "fake_package", provider: :pip)
18
+ @provider = @resource.provider
20
19
  @client = double('client')
21
20
  allow(@client).to receive(:call).with('package_releases', 'real_package').and_return(["1.3", "1.2.5", "1.2.4"])
22
21
  allow(@client).to receive(:call).with('package_releases', 'fake_package').and_return([])
@@ -335,7 +334,6 @@ describe Puppet::Type.type(:package).provider(:pip) do
335
334
 
336
335
  it "should install" do
337
336
  @resource[:ensure] = :installed
338
- @resource[:source] = nil
339
337
  expect(@provider).to receive(:execute).with(["/fake/bin/pip", ["install", "-q", "fake_package"]])
340
338
  @provider.install
341
339
  end
@@ -368,7 +366,6 @@ describe Puppet::Type.type(:package).provider(:pip) do
368
366
 
369
367
  it "should install a particular version" do
370
368
  @resource[:ensure] = "0.0.0"
371
- @resource[:source] = nil
372
369
  # TJK
373
370
  expect(@provider).to receive(:execute).with(["/fake/bin/pip", ["install", "-q", "fake_package==0.0.0"]])
374
371
  @provider.install
@@ -376,7 +373,6 @@ describe Puppet::Type.type(:package).provider(:pip) do
376
373
 
377
374
  it "should upgrade" do
378
375
  @resource[:ensure] = :latest
379
- @resource[:source] = nil
380
376
  # TJK
381
377
  expect(@provider).to receive(:execute).with(["/fake/bin/pip", ["install", "-q", "--upgrade", "fake_package"]])
382
378
  @provider.install
@@ -384,7 +380,6 @@ describe Puppet::Type.type(:package).provider(:pip) do
384
380
 
385
381
  it "should handle install options" do
386
382
  @resource[:ensure] = :installed
387
- @resource[:source] = nil
388
383
  @resource[:install_options] = [{"--timeout" => "10"}, "--no-index"]
389
384
  expect(@provider).to receive(:execute).with(["/fake/bin/pip", ["install", "-q", "--timeout=10", "--no-index", "fake_package"]])
390
385
  @provider.install
@@ -415,7 +410,7 @@ describe Puppet::Type.type(:package).provider(:pip) do
415
410
  let(:pip) { '/fake/bin/pip' }
416
411
 
417
412
  it "should look up version if pip is present" do
418
- allow(described_class).to receive(:pip_cmd).and_return(pip)
413
+ allow(described_class).to receive(:cmd).and_return(pip)
419
414
  process = ['pip 8.0.2 from /usr/local/lib/python2.7/dist-packages (python 2.7)']
420
415
  allow(described_class).to receive(:execpipe).with([pip, '--version']).and_yield(process)
421
416
 
@@ -423,7 +418,7 @@ describe Puppet::Type.type(:package).provider(:pip) do
423
418
  end
424
419
 
425
420
  it "parses multiple lines of output" do
426
- allow(described_class).to receive(:pip_cmd).and_return(pip)
421
+ allow(described_class).to receive(:cmd).and_return(pip)
427
422
  process = [
428
423
  "/usr/local/lib/python2.7/dist-packages/urllib3/contrib/socks.py:37: DependencyWarning: SOCKS support in urllib3 requires the installation of optional dependencies: specifically, PySocks. For more information, see https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies",
429
424
  " DependencyWarning",
@@ -435,7 +430,7 @@ describe Puppet::Type.type(:package).provider(:pip) do
435
430
  end
436
431
 
437
432
  it "raises if there isn't a version string" do
438
- allow(described_class).to receive(:pip_cmd).and_return(pip)
433
+ allow(described_class).to receive(:cmd).and_return(pip)
439
434
  allow(described_class).to receive(:execpipe).with([pip, '--version']).and_yield([""])
440
435
  expect {
441
436
  described_class.pip_version(pip)
@@ -444,7 +439,7 @@ describe Puppet::Type.type(:package).provider(:pip) do
444
439
 
445
440
  it "quotes commands with spaces" do
446
441
  pip = 'C:\Program Files\Python27\Scripts\pip.exe'
447
- allow(described_class).to receive(:pip_cmd).and_return(pip)
442
+ allow(described_class).to receive(:cmd).and_return(pip)
448
443
  process = ["pip 18.1 from c:\program files\python27\lib\site-packages\pip (python 2.7)\r\n"]
449
444
  allow(described_class).to receive(:execpipe).with(["\"#{pip}\"", '--version']).and_yield(process)
450
445
 
@@ -8,10 +8,6 @@ describe Puppet::Type.type(:package).provider(:pkgdmg) do
8
8
  it { is_expected.not_to be_uninstallable }
9
9
 
10
10
  describe "when installing it should fail when" do
11
- before :each do
12
- expect(Puppet::Util).not_to receive(:execute)
13
- end
14
-
15
11
  it "no source is specified" do
16
12
  expect { provider.install }.to raise_error(Puppet::Error, /must specify a package source/)
17
13
  end
@@ -200,6 +200,17 @@ describe 'Puppet::Type::Service::Provider::Systemd',
200
200
  })
201
201
  end
202
202
 
203
+ it "correctly parses services when list-unit-files has an additional column" do
204
+ expect(provider_class).to receive(:systemctl).with('list-unit-files', '--type', 'service', '--full', '--all', '--no-pager').and_return(File.read(my_fixture('list_unit_files_services_vendor_preset')))
205
+ expect(provider_class.instances.map(&:name)).to match_array(%w{
206
+ arp-ethers.service
207
+ auditd.service
208
+ dbus.service
209
+ umountnfs.service
210
+ urandom.service
211
+ })
212
+ end
213
+
203
214
  it "should print a debug message when a service with the state `bad` is found" do
204
215
  expect(provider_class).to receive(:systemctl).with('list-unit-files', '--type', 'service', '--full', '--all', '--no-pager').and_return(File.read(my_fixture('list_unit_files_services')))
205
216
  expect(Puppet).to receive(:debug).with("apparmor.service marked as bad by `systemctl`. It is recommended to be further checked.")
@@ -143,6 +143,11 @@ describe 'Puppet::Type::User::Provider::Aix' do
143
143
  it "returns the user's password" do
144
144
  expect(call_parse_password).to eql('some_password')
145
145
  end
146
+
147
+ it "returns the user's password with tabs" do
148
+ resource[:name] = 'tab_password_user'
149
+ expect(call_parse_password).to eql('some_password')
150
+ end
146
151
  end
147
152
 
148
153
  # TODO: If we move from using Mocha to rspec's mocks,
@@ -33,7 +33,7 @@ describe Puppet::Type.type(:user).provider(:hpuxuseradd),
33
33
  before :each do
34
34
  allow(Etc).to receive(:getpwent).and_return(pwent)
35
35
  allow(Etc).to receive(:getpwnam).and_return(pwent)
36
- allow(resource).to receive(:command).with(:modify).and_return('/usr/sam/lbin/usermod.sam')
36
+ allow(provider).to receive(:command).with(:modify).and_return('/usr/sam/lbin/usermod.sam')
37
37
  end
38
38
 
39
39
  it "should have feature manages_passwords" do
@@ -53,12 +53,14 @@ describe Puppet::Type.type(:user).provider(:pw) do
53
53
 
54
54
  it "should use -G with the correct argument when the groups property is set" do
55
55
  resource[:groups] = "group1"
56
+ allow(Puppet::Util::POSIX).to receive(:groups_of).with('testuser').and_return([])
56
57
  expect(provider).to receive(:execute).with(include("-G").and(include("group1")), kind_of(Hash))
57
58
  provider.create
58
59
  end
59
60
 
60
61
  it "should use -G with all the given groups when the groups property is set to an array" do
61
62
  resource[:groups] = ["group1", "group2"]
63
+ allow(Puppet::Util::POSIX).to receive(:groups_of).with('testuser').and_return([])
62
64
  expect(provider).to receive(:execute).with(include("-G").and(include("group1,group2")), kind_of(Hash))
63
65
  provider.create
64
66
  end
@@ -4,6 +4,7 @@ RSpec::Matchers.define_negated_matcher :excluding, :include
4
4
 
5
5
  describe Puppet::Type.type(:user).provider(:useradd) do
6
6
  before :each do
7
+ allow(Puppet::Util::POSIX).to receive(:groups_of).and_return([])
7
8
  allow(described_class).to receive(:command).with(:password).and_return('/usr/bin/chage')
8
9
  allow(described_class).to receive(:command).with(:localpassword).and_return('/usr/sbin/lchage')
9
10
  allow(described_class).to receive(:command).with(:add).and_return('/usr/sbin/useradd')
@@ -151,6 +152,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
151
152
 
152
153
  it "should not use -G for luseradd and should call usermod with -G after luseradd when groups property is set" do
153
154
  resource[:groups] = ['group1', 'group2']
155
+ allow(provider).to receive(:localgroups)
154
156
  expect(provider).to receive(:execute).with(include('/usr/sbin/luseradd').and(excluding('-G')), hash_including(custom_environment: hash_including('LIBUSER_CONF')))
155
157
  expect(provider).to receive(:execute).with(include('/usr/sbin/usermod').and(include('-G')), hash_including(custom_environment: hash_including('LIBUSER_CONF')))
156
158
  provider.create
@@ -336,7 +338,8 @@ describe Puppet::Type.type(:user).provider(:useradd) do
336
338
 
337
339
  it "should return the local comment string when forcelocal is true" do
338
340
  resource[:forcelocal] = true
339
- allow(File).to receive(:read).with('/etc/passwd').and_return(content)
341
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/passwd').and_return(true)
342
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').and_yield(content)
340
343
  expect(provider.comment).to eq('local comment')
341
344
  end
342
345
 
@@ -348,8 +351,73 @@ describe Puppet::Type.type(:user).provider(:useradd) do
348
351
  end
349
352
  end
350
353
 
354
+ describe "#gid" do
355
+ before { described_class.has_feature :manages_local_users_and_groups }
356
+
357
+ let(:content) { "myuser:x:x:999:x:x:x" }
358
+
359
+ it "should return the local GID when forcelocal is true" do
360
+ resource[:forcelocal] = true
361
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/passwd').and_return(true)
362
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').and_yield(content)
363
+ expect(provider.gid).to eq(999)
364
+ end
365
+
366
+ it "should fall back to nameservice GID when forcelocal is false" do
367
+ resource[:forcelocal] = false
368
+ allow(provider).to receive(:get).with(:gid).and_return(1234)
369
+ expect(provider).not_to receive(:localgid)
370
+ expect(provider.gid).to eq(1234)
371
+ end
372
+ end
373
+
374
+ describe "#groups" do
375
+ before { described_class.has_feature :manages_local_users_and_groups }
376
+
377
+ let(:content) do
378
+ StringIO.new(<<~EOF)
379
+ group1:x:0:myuser
380
+ group2:x:999:
381
+ group3:x:998:myuser
382
+ EOF
383
+ end
384
+
385
+ let(:content_with_empty_line) do
386
+ StringIO.new(<<~EOF)
387
+ group1:x:0:myuser
388
+ group2:x:999:
389
+ group3:x:998:myuser
390
+
391
+ EOF
392
+ end
393
+
394
+ it "should return the local groups string when forcelocal is true" do
395
+ resource[:forcelocal] = true
396
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/group').and_return(true)
397
+ allow(File).to receive(:open).with(Pathname.new('/etc/group')).and_yield(content)
398
+ expect(provider.groups).to eq(['group1', 'group3'])
399
+ end
400
+
401
+ it "does not raise when parsing empty lines in /etc/group" do
402
+ resource[:forcelocal] = true
403
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/group').and_return(true)
404
+ allow(File).to receive(:open).with(Pathname.new('/etc/group')).and_yield(content_with_empty_line)
405
+ expect { provider.groups }.not_to raise_error
406
+ end
407
+
408
+ it "should fall back to nameservice groups when forcelocal is false" do
409
+ resource[:forcelocal] = false
410
+ allow(Puppet::Util::POSIX).to receive(:groups_of).with('myuser').and_return(['remote groups'])
411
+ expect(provider).not_to receive(:localgroups)
412
+ expect(provider.groups).to eq('remote groups')
413
+ end
414
+ end
415
+
351
416
  describe "#finduser" do
352
- before { allow(File).to receive(:read).with('/etc/passwd').and_return(content) }
417
+ before do
418
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/passwd').and_return(true)
419
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').and_yield(content)
420
+ end
353
421
 
354
422
  let(:content) { "sample_account:sample_password:sample_uid:sample_gid:sample_gecos:sample_directory:sample_shell" }
355
423
  let(:output) do
@@ -375,7 +443,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
375
443
  end
376
444
 
377
445
  it "reads the user file only once per resource" do
378
- expect(File).to receive(:read).with('/etc/passwd').once
446
+ expect(Puppet::FileSystem).to receive(:each_line).with('/etc/passwd').once
379
447
  5.times { provider.finduser(:account, 'sample_account') }
380
448
  end
381
449
  end
@@ -648,39 +648,37 @@ describe Puppet::Provider do
648
648
  it "delegates instance execute to Puppet::Util::Execution" do
649
649
  expect(Puppet::Util::Execution).to receive(:execute).with("a_command", { :option => "value" })
650
650
 
651
- provider.new.send(:execute, "a_command", { :option => "value" })
651
+ provider.new.execute("a_command", { :option => "value" })
652
652
  end
653
653
 
654
654
  it "delegates class execute to Puppet::Util::Execution" do
655
655
  expect(Puppet::Util::Execution).to receive(:execute).with("a_command", { :option => "value" })
656
656
 
657
- provider.send(:execute, "a_command", { :option => "value" })
657
+ provider.execute("a_command", { :option => "value" })
658
658
  end
659
659
 
660
660
  it "delegates instance execpipe to Puppet::Util::Execution" do
661
- block = Proc.new { }
662
- expect(Puppet::Util::Execution).to receive(:execpipe).with("a_command", true, block)
661
+ allow(Puppet::Util::Execution).to receive(:execpipe).with("a_command", true).and_yield('some output')
663
662
 
664
- provider.new.send(:execpipe, "a_command", true, block)
663
+ expect { |b| provider.new.execpipe("a_command", true, &b) }.to yield_with_args('some output')
665
664
  end
666
665
 
667
666
  it "delegates class execpipe to Puppet::Util::Execution" do
668
- block = Proc.new { }
669
- expect(Puppet::Util::Execution).to receive(:execpipe).with("a_command", true, block)
667
+ allow(Puppet::Util::Execution).to receive(:execpipe).with("a_command", true).and_yield('some output')
670
668
 
671
- provider.send(:execpipe, "a_command", true, block)
669
+ expect { |b| provider.execpipe("a_command", true, &b) }.to yield_with_args('some output')
672
670
  end
673
671
 
674
672
  it "delegates instance execfail to Puppet::Util::Execution" do
675
673
  expect(Puppet::Util::Execution).to receive(:execfail).with("a_command", "an exception to raise")
676
674
 
677
- provider.new.send(:execfail, "a_command", "an exception to raise")
675
+ provider.new.execfail("a_command", "an exception to raise")
678
676
  end
679
677
 
680
678
  it "delegates class execfail to Puppet::Util::Execution" do
681
679
  expect(Puppet::Util::Execution).to receive(:execfail).with("a_command", "an exception to raise")
682
680
 
683
- provider.send(:execfail, "a_command", "an exception to raise")
681
+ provider.execfail("a_command", "an exception to raise")
684
682
  end
685
683
  end
686
684
 
@@ -69,6 +69,51 @@ describe 'Puppet Pal' do
69
69
  }.to raise_error(/manifest_file or code_string cannot be given when configured_by_env is true/)
70
70
  end
71
71
 
72
+ it 'shadows target variables that collide with plan variables' do
73
+ facts = { 'var' => 'fact' }
74
+ target_vars = { 'var' => 'target' }
75
+
76
+ expect(Puppet).to receive(:warning).with(/Target variable \$var will be overridden by fact of the same name/)
77
+
78
+ result = Puppet::Pal.in_tmp_environment('pal_env', facts: {}) do |ctx|
79
+ ctx.with_catalog_compiler(facts: facts, target_variables: target_vars ) do |c|
80
+ c.evaluate_string('$var')
81
+ end
82
+ end
83
+
84
+ expect(result).to eq('fact')
85
+ end
86
+
87
+ it 'shadows target variables that collide with facts' do
88
+ plan_vars = { 'var' => 'plan' }
89
+ target_vars = { 'var' => 'target' }
90
+
91
+ expect(Puppet).to receive(:warning).with(/Target variable \$var will be overridden by plan variable of the same name/)
92
+
93
+ result = Puppet::Pal.in_tmp_environment('pal_env', facts: {}) do |ctx|
94
+ ctx.with_catalog_compiler(variables: plan_vars, target_variables: target_vars ) do |c|
95
+ c.evaluate_string('$var')
96
+ end
97
+ end
98
+
99
+ expect(result).to eq('plan')
100
+ end
101
+
102
+ it 'shadows plan variables that collide with facts' do
103
+ facts = { 'var' => 'fact' }
104
+ plan_vars = { 'var' => 'plan' }
105
+
106
+ expect(Puppet).to receive(:warning).with(/Plan variable \$var will be overridden by fact of the same name/)
107
+
108
+ result = Puppet::Pal.in_tmp_environment('pal_env', facts: {}) do |ctx|
109
+ ctx.with_catalog_compiler(facts: facts, variables: plan_vars ) do |c|
110
+ c.evaluate_string('$var')
111
+ end
112
+ end
113
+
114
+ expect(result).to eq('fact')
115
+ end
116
+
72
117
  context "evaluate_string method" do
73
118
  it 'evaluates code string in a given tmp environment' do
74
119
  result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
@@ -16,7 +16,12 @@ describe Puppet::Resource::CapabilityFinder do
16
16
  Puppet.push_context({:loaders => loaders, :current_environment => env})
17
17
  if mock_pdb
18
18
  module Puppet::Util::Puppetdb
19
- class Http; end
19
+ def query_puppetdb(query); end
20
+ module_function :query_puppetdb
21
+
22
+ class Http
23
+ def self.action(url); end
24
+ end
20
25
  end
21
26
  end
22
27
  make_cap_type