puppet 6.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +20 -20
  4. data/Guardfile.example +76 -0
  5. data/LICENSE +189 -4
  6. data/README.md +3 -3
  7. data/Rakefile +5 -2
  8. data/ext/solaris/smf/svc-puppetd +8 -1
  9. data/ext/solaris/smf/svc-puppetmasterd +8 -1
  10. data/lib/puppet/application/apply.rb +100 -59
  11. data/lib/puppet/application/cert.rb +4 -114
  12. data/lib/puppet/application/device.rb +48 -32
  13. data/lib/puppet/application/script.rb +1 -1
  14. data/lib/puppet/application/ssl.rb +135 -51
  15. data/lib/puppet/application.rb +5 -0
  16. data/lib/puppet/configurer.rb +2 -3
  17. data/lib/puppet/defaults.rb +33 -49
  18. data/lib/puppet/etc.rb +20 -0
  19. data/lib/puppet/face/config.rb +3 -3
  20. data/lib/puppet/face/key.rb +1 -1
  21. data/lib/puppet/face/node/clean.rb +0 -1
  22. data/lib/puppet/feature/base.rb +1 -1
  23. data/lib/puppet/file_bucket/dipper.rb +1 -1
  24. data/lib/puppet/file_serving/fileset.rb +1 -1
  25. data/lib/puppet/functions/abs.rb +1 -1
  26. data/lib/puppet/functions/new.rb +1 -1
  27. data/lib/puppet/module/task.rb +29 -38
  28. data/lib/puppet/pal/catalog_compiler.rb +96 -0
  29. data/lib/puppet/pal/compiler.rb +221 -0
  30. data/lib/puppet/pal/function_signature.rb +52 -0
  31. data/lib/puppet/pal/json_catalog_encoder.rb +67 -0
  32. data/lib/puppet/pal/pal_api.rb +15 -0
  33. data/lib/puppet/pal/pal_impl.rb +523 -0
  34. data/lib/puppet/pal/plan_signature.rb +71 -0
  35. data/lib/puppet/pal/script_compiler.rb +71 -0
  36. data/lib/puppet/pal/task_signature.rb +58 -0
  37. data/lib/puppet/parser/catalog_compiler.rb +24 -0
  38. data/lib/puppet/parser/compiler.rb +3 -1
  39. data/lib/puppet/parser/functions/generate.rb +7 -6
  40. data/lib/puppet/plugins/configuration.rb +5 -1
  41. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +3 -1
  42. data/lib/puppet/pops/evaluator/deferred_resolver.rb +3 -0
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -1
  44. data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -3
  45. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  46. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +19 -10
  47. data/lib/puppet/pops/loader/task_instantiator.rb +13 -70
  48. data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
  49. data/lib/puppet/pops/parser/lexer2.rb +1 -1
  50. data/lib/puppet/pops/pcore.rb +10 -33
  51. data/lib/puppet/pops/serialization/to_data_converter.rb +9 -1
  52. data/lib/puppet/pops/serialization.rb +1 -0
  53. data/lib/puppet/pops/types/p_timespan_type.rb +2 -2
  54. data/lib/puppet/pops/types/string_converter.rb +18 -4
  55. data/lib/puppet/pops/validation/checker4_0.rb +17 -2
  56. data/lib/puppet/provider/exec.rb +59 -57
  57. data/lib/puppet/provider/group/aix.rb +18 -2
  58. data/lib/puppet/provider/group/windows_adsi.rb +7 -3
  59. data/lib/puppet/provider/nameservice.rb +1 -25
  60. data/lib/puppet/provider/package/dnf.rb +2 -0
  61. data/lib/puppet/provider/package/pkgng.rb +37 -21
  62. data/lib/puppet/provider/package/portage.rb +2 -2
  63. data/lib/puppet/provider/package/windows/exe_package.rb +16 -10
  64. data/lib/puppet/provider/package/windows/msi_package.rb +8 -0
  65. data/lib/puppet/provider/package/windows/package.rb +9 -1
  66. data/lib/puppet/provider/package/windows.rb +2 -2
  67. data/lib/puppet/provider/package/yum.rb +1 -1
  68. data/lib/puppet/provider/parsedfile.rb +25 -4
  69. data/lib/puppet/provider/service/launchd.rb +19 -3
  70. data/lib/puppet/provider/service/smf.rb +54 -0
  71. data/lib/puppet/provider/service/systemd.rb +19 -0
  72. data/lib/puppet/provider/service/upstart.rb +1 -0
  73. data/lib/puppet/provider/service/windows.rb +22 -5
  74. data/lib/puppet/provider/user/aix.rb +48 -2
  75. data/lib/puppet/provider/user/useradd.rb +2 -10
  76. data/lib/puppet/provider/user/windows_adsi.rb +9 -1
  77. data/lib/puppet/resource/catalog.rb +1 -5
  78. data/lib/puppet/resource.rb +3 -1
  79. data/lib/puppet/ssl/host.rb +26 -16
  80. data/lib/puppet/syntax_checkers/epp.rb +34 -0
  81. data/lib/puppet/syntax_checkers/pp.rb +34 -0
  82. data/lib/puppet/transaction/event_manager.rb +13 -1
  83. data/lib/puppet/transaction/persistence.rb +1 -1
  84. data/lib/puppet/transaction/resource_harness.rb +3 -1
  85. data/lib/puppet/type/group.rb +29 -1
  86. data/lib/puppet/type/package.rb +5 -1
  87. data/lib/puppet/type/resources.rb +12 -2
  88. data/lib/puppet/type/schedule.rb +7 -0
  89. data/lib/puppet/type/service.rb +12 -0
  90. data/lib/puppet/type/user.rb +5 -2
  91. data/lib/puppet/type.rb +6 -0
  92. data/lib/puppet/util/command_line.rb +2 -3
  93. data/lib/puppet/util/execution.rb +15 -1
  94. data/lib/puppet/util/filetype.rb +56 -8
  95. data/lib/puppet/util/log/destinations.rb +3 -2
  96. data/lib/puppet/util/logging.rb +3 -2
  97. data/lib/puppet/util/posix.rb +15 -0
  98. data/lib/puppet/util/selinux.rb +1 -1
  99. data/lib/puppet/util/storage.rb +12 -0
  100. data/lib/puppet/util/windows/adsi.rb +79 -2
  101. data/lib/puppet/util/windows/api_types.rb +1 -1
  102. data/lib/puppet/util/windows/process.rb +23 -3
  103. data/lib/puppet/util/windows/registry.rb +29 -5
  104. data/lib/puppet/util/windows/security.rb +14 -0
  105. data/lib/puppet/util/windows/service.rb +294 -74
  106. data/lib/puppet/util/windows/user.rb +3 -5
  107. data/lib/puppet/util.rb +7 -3
  108. data/lib/puppet/version.rb +1 -1
  109. data/lib/puppet.rb +1 -0
  110. data/lib/puppet_pal.rb +5 -1099
  111. data/locales/ja/puppet.po +952 -986
  112. data/locales/puppet.pot +592 -347
  113. data/man/man5/puppet.conf.5 +26 -31
  114. data/man/man8/puppet-agent.8 +1 -1
  115. data/man/man8/puppet-apply.8 +1 -1
  116. data/man/man8/puppet-catalog.8 +1 -1
  117. data/man/man8/puppet-config.8 +4 -4
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +23 -19
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-filebucket.8 +1 -1
  124. data/man/man8/puppet-generate.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-key.8 +2 -2
  127. data/man/man8/puppet-lookup.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-module.8 +1 -1
  130. data/man/man8/puppet-node.8 +1 -1
  131. data/man/man8/puppet-parser.8 +1 -1
  132. data/man/man8/puppet-plugin.8 +1 -1
  133. data/man/man8/puppet-report.8 +1 -1
  134. data/man/man8/puppet-resource.8 +1 -1
  135. data/man/man8/puppet-script.8 +1 -1
  136. data/man/man8/puppet-ssl.8 +26 -3
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +2 -2
  139. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/bad_func_load.rb +11 -0
  140. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +7 -1
  141. data/spec/fixtures/unit/provider/package/pkgng/pkg.query.zsh +1 -0
  142. data/spec/fixtures/unit/provider/service/smf/svcs_fmri.out +6 -0
  143. data/spec/fixtures/unit/provider/service/smf/svcs_multiple_fmris.out +13 -0
  144. data/spec/integration/application/apply_spec.rb +4 -1
  145. data/spec/integration/parser/collection_spec.rb +4 -8
  146. data/spec/integration/provider/service/windows_spec.rb +5 -5
  147. data/spec/integration/ssl/key_spec.rb +0 -4
  148. data/spec/integration/transaction_spec.rb +559 -0
  149. data/spec/integration/type/file_spec.rb +6 -6
  150. data/spec/integration/util/windows/registry_spec.rb +39 -0
  151. data/spec/integration/util/windows/security_spec.rb +10 -7
  152. data/spec/integration/util/windows/user_spec.rb +37 -17
  153. data/spec/lib/puppet/test_ca.rb +1 -1
  154. data/spec/spec_helper.rb +1 -1
  155. data/spec/unit/agent_spec.rb +2 -2
  156. data/spec/unit/application/apply_spec.rb +55 -2
  157. data/spec/unit/application/device_spec.rb +10 -7
  158. data/spec/unit/application/face_base_spec.rb +1 -1
  159. data/spec/unit/application/lookup_spec.rb +2 -1
  160. data/spec/unit/application/ssl_spec.rb +178 -109
  161. data/spec/unit/application_spec.rb +29 -11
  162. data/spec/unit/configurer/downloader_spec.rb +1 -1
  163. data/spec/unit/configurer_spec.rb +16 -5
  164. data/spec/unit/etc_spec.rb +25 -0
  165. data/spec/unit/face/node_spec.rb +1 -3
  166. data/spec/unit/face/parser_spec.rb +15 -0
  167. data/spec/unit/file_serving/fileset_spec.rb +11 -11
  168. data/spec/unit/functions/logging_spec.rb +10 -3
  169. data/spec/unit/indirector/catalog/json_spec.rb +9 -3
  170. data/spec/unit/indirector/yaml_spec.rb +1 -1
  171. data/spec/unit/network/http/connection_spec.rb +2 -2
  172. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +36 -0
  173. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +22 -4
  174. data/spec/unit/pops/loaders/loader_spec.rb +9 -17
  175. data/spec/unit/pops/loaders/loaders_spec.rb +48 -0
  176. data/spec/unit/pops/loaders/module_loaders_spec.rb +7 -7
  177. data/spec/unit/pops/parser/parse_heredoc_spec.rb +16 -0
  178. data/spec/unit/pops/serialization/to_from_hr_spec.rb +9 -0
  179. data/spec/unit/pops/types/p_timespan_type_spec.rb +22 -0
  180. data/spec/unit/pops/types/p_timestamp_type_spec.rb +19 -0
  181. data/spec/unit/pops/types/string_converter_spec.rb +25 -1
  182. data/spec/unit/pops/types/task_spec.rb +42 -116
  183. data/spec/unit/pops/validator/validator_spec.rb +24 -10
  184. data/spec/unit/provider/exec/posix_spec.rb +24 -0
  185. data/spec/unit/provider/group/aix_spec.rb +20 -6
  186. data/spec/unit/provider/group/ldap_spec.rb +22 -25
  187. data/spec/unit/provider/group/pw_spec.rb +7 -10
  188. data/spec/unit/provider/group/windows_adsi_spec.rb +42 -33
  189. data/spec/unit/provider/nameservice/directoryservice_spec.rb +97 -103
  190. data/spec/unit/provider/package/aix_spec.rb +5 -8
  191. data/spec/unit/provider/package/apt_spec.rb +3 -6
  192. data/spec/unit/provider/package/dnf_spec.rb +38 -25
  193. data/spec/unit/provider/package/dpkg_spec.rb +18 -21
  194. data/spec/unit/provider/package/freebsd_spec.rb +4 -7
  195. data/spec/unit/provider/package/gem_spec.rb +41 -41
  196. data/spec/unit/provider/package/hpux_spec.rb +7 -10
  197. data/spec/unit/provider/package/macports_spec.rb +13 -15
  198. data/spec/unit/provider/package/nim_spec.rb +3 -10
  199. data/spec/unit/provider/package/openbsd_spec.rb +14 -17
  200. data/spec/unit/provider/package/pip3_spec.rb +3 -6
  201. data/spec/unit/provider/package/pip_spec.rb +45 -49
  202. data/spec/unit/provider/package/pkgin_spec.rb +13 -18
  203. data/spec/unit/provider/package/pkgng_spec.rb +32 -27
  204. data/spec/unit/provider/package/puppet_gem_spec.rb +6 -9
  205. data/spec/unit/provider/package/tdnf_spec.rb +9 -12
  206. data/spec/unit/provider/package/windows/exe_package_spec.rb +3 -3
  207. data/spec/unit/provider/package/windows_spec.rb +4 -4
  208. data/spec/unit/provider/package/yum_spec.rb +30 -16
  209. data/spec/unit/provider/package/zypper_spec.rb +17 -19
  210. data/spec/unit/provider/service/bsd_spec.rb +7 -9
  211. data/spec/unit/provider/service/daemontools_spec.rb +12 -16
  212. data/spec/unit/provider/service/debian_spec.rb +6 -10
  213. data/spec/unit/provider/service/freebsd_spec.rb +2 -2
  214. data/spec/unit/provider/service/launchd_spec.rb +19 -0
  215. data/spec/unit/provider/service/openbsd_spec.rb +13 -17
  216. data/spec/unit/provider/service/rcng_spec.rb +2 -4
  217. data/spec/unit/provider/service/redhat_spec.rb +12 -11
  218. data/spec/unit/provider/service/runit_spec.rb +7 -14
  219. data/spec/unit/provider/service/smf_spec.rb +77 -13
  220. data/spec/unit/provider/service/src_spec.rb +11 -16
  221. data/spec/unit/provider/service/systemd_spec.rb +39 -1
  222. data/spec/unit/provider/service/windows_spec.rb +39 -7
  223. data/spec/unit/provider/user/aix_spec.rb +43 -2
  224. data/spec/unit/provider/user/hpux_spec.rb +3 -5
  225. data/spec/unit/provider/user/ldap_spec.rb +29 -32
  226. data/spec/unit/provider/user/pw_spec.rb +10 -13
  227. data/spec/unit/provider/user/useradd_spec.rb +2 -2
  228. data/spec/unit/provider/user/windows_adsi_spec.rb +4 -4
  229. data/spec/unit/puppet_pal_2pec.rb +6 -6
  230. data/spec/unit/puppet_pal_catalog_spec.rb +58 -0
  231. data/spec/unit/resource/catalog_spec.rb +2 -2
  232. data/spec/unit/resource_spec.rb +31 -0
  233. data/spec/unit/ssl/host_spec.rb +22 -1
  234. data/spec/unit/ssl/key_spec.rb +2 -4
  235. data/spec/unit/task_spec.rb +50 -5
  236. data/spec/unit/transaction/event_manager_spec.rb +12 -1
  237. data/spec/unit/transaction/persistence_spec.rb +4 -4
  238. data/spec/unit/transaction/resource_harness_spec.rb +18 -0
  239. data/spec/unit/type/group_spec.rb +11 -3
  240. data/spec/unit/type/resources_spec.rb +18 -0
  241. data/spec/unit/type/service_spec.rb +27 -1
  242. data/spec/unit/util/execution_spec.rb +77 -0
  243. data/spec/unit/util/filetype_spec.rb +13 -5
  244. data/spec/unit/util/log/destinations_spec.rb +10 -0
  245. data/spec/unit/util/logging_spec.rb +58 -41
  246. data/spec/unit/util/monkey_patches_spec.rb +18 -5
  247. data/spec/unit/util/posix_spec.rb +28 -0
  248. data/spec/unit/util/selinux_spec.rb +4 -0
  249. data/spec/unit/util/storage_spec.rb +107 -0
  250. data/spec/unit/util/suidmanager_spec.rb +1 -3
  251. data/spec/unit/util/windows/adsi_spec.rb +95 -0
  252. data/spec/unit/util/windows/service_spec.rb +377 -131
  253. metadata +24 -11
  254. data/ext/autotest/Rakefile +0 -8
  255. data/ext/autotest/config +0 -43
  256. data/ext/autotest/readme.rst +0 -16
  257. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +0 -7
  258. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +0 -1
  259. data/spec/watchr.rb +0 -137
@@ -73,7 +73,7 @@ describe Puppet::Transaction::Persistence do
73
73
  it "should initialize with a clear internal state if the file does not contain valid YAML" do
74
74
  write_state_file('{ invalid')
75
75
 
76
- Puppet.expects(:err).with(regexp_matches(/Transaction store file .* is corrupt/))
76
+ Puppet.expects(:send_log).with(:err, regexp_matches(/Transaction store file .* is corrupt/))
77
77
 
78
78
  persistence = Puppet::Transaction::Persistence.new
79
79
  persistence.load
@@ -97,8 +97,8 @@ describe Puppet::Transaction::Persistence do
97
97
 
98
98
  File.expects(:rename).raises(SystemCallError)
99
99
 
100
- Puppet.expects(:err).with(regexp_matches(/Transaction store file .* is corrupt/))
101
- Puppet.expects(:err).with(regexp_matches(/Unable to rename/))
100
+ Puppet.expects(:send_log).with(:err, regexp_matches(/Transaction store file .* is corrupt/))
101
+ Puppet.expects(:send_log).with(:err, regexp_matches(/Unable to rename/))
102
102
 
103
103
  persistence = Puppet::Transaction::Persistence.new
104
104
  expect { persistence.load }.to raise_error(Puppet::Error, /Could not rename/)
@@ -109,7 +109,7 @@ describe Puppet::Transaction::Persistence do
109
109
 
110
110
  File.expects(:rename).at_least_once
111
111
 
112
- Puppet.expects(:err).with(regexp_matches(/Transaction store file .* is corrupt/))
112
+ Puppet.expects(:send_log).with(:err, regexp_matches(/Transaction store file .* is corrupt/))
113
113
 
114
114
  persistence = Puppet::Transaction::Persistence.new
115
115
  persistence.load
@@ -173,6 +173,10 @@ describe Puppet::Transaction::ResourceHarness do
173
173
  def insync?(value)
174
174
  @resource.behaviors[:ensure_insync?]
175
175
  end
176
+
177
+ def should_to_s(value)
178
+ (@resource.behaviors[:on_should_to_s] || proc { "'#{value}'" }).call
179
+ end
176
180
  end
177
181
 
178
182
  newparam(:name) do
@@ -266,6 +270,20 @@ describe Puppet::Transaction::ResourceHarness do
266
270
 
267
271
  expect(status.events).to be_empty
268
272
  end
273
+
274
+ it "ensure errors in message still get a log entry" do
275
+ resource = an_ensurable_resource_reacting_as(:ensure_insync? => false, :on_ensure => proc { raise StandardError }, :on_should_to_s => proc { raise StandardError }, :present? => true)
276
+
277
+ status = @harness.evaluate(resource)
278
+
279
+ expect(status.events.length).to eq(2)
280
+ testing_errors = status.events.find_all { |x| x.name.to_s == "Testing_created" }
281
+ resource_errors = status.events.find_all { |x| x.name.to_s == "resource_error" }
282
+ expect(testing_errors.length).to eq(1)
283
+ expect(resource_errors.length).to eq(1)
284
+ expect(testing_errors[0].message).not_to be_nil
285
+ expect(resource_errors[0].message).not_to eq("Puppet::Util::Log requires a message")
286
+ end
269
287
  end
270
288
 
271
289
  describe "when a caught error occurs" do
@@ -72,7 +72,15 @@ describe Puppet::Type.type(:group) do
72
72
 
73
73
  describe "should delegate :members implementation to the provider:" do
74
74
 
75
- let (:provider) { @class.provide(:testing) { has_features :manages_members } }
75
+ let (:provider) do
76
+ @class.provide(:testing) do
77
+ has_features :manages_members
78
+
79
+ def members
80
+ []
81
+ end
82
+ end
83
+ end
76
84
  let (:provider_instance) { provider.new }
77
85
  let (:type) { @class.new(:name => "group", :provider => provider_instance, :members => ['user1']) }
78
86
 
@@ -82,11 +90,11 @@ describe Puppet::Type.type(:group) do
82
90
  end
83
91
 
84
92
  it "is_to_s and should_to_s call members_to_s" do
85
- provider_instance.expects(:members_to_s).with(['user2', 'user1']).returns "user2 (), user1 ()"
93
+ provider_instance.expects(:members_to_s).with(['user1', 'user2']).returns "user1 (), user2 ()"
86
94
  provider_instance.expects(:members_to_s).with(['user1']).returns "user1 ()"
87
95
 
88
96
  expect(type.property(:members).is_to_s('user1')).to eq('user1 ()')
89
- expect(type.property(:members).should_to_s('user2,user1')).to eq('user2 (), user1 ()')
97
+ expect(type.property(:members).should_to_s('user1,user2')).to eq('user1 (), user2 ()')
90
98
  end
91
99
  end
92
100
  end
@@ -100,6 +100,24 @@ describe resources do
100
100
  user.stubs(:retrieve_resource).returns Puppet::Resource.new("user", user_hash[:name], :parameters => user_hash)
101
101
  expect(res.user_check(user)).to be_falsey
102
102
  end
103
+
104
+ it "should not purge Windows system users" do
105
+ res = Puppet::Type.type(:resources).new :name => :user, :purge => true
106
+ res.catalog = Puppet::Resource::Catalog.new
107
+ user_hash = {:name => 'Administrator', :uid => 'S-1-5-21-12345-500'}
108
+ user = Puppet::Type.type(:user).new(user_hash)
109
+ user.stubs(:retrieve_resource).returns Puppet::Resource.new("user", user_hash[:name], :parameters => user_hash)
110
+ expect(res.user_check(user)).to be_falsey
111
+ end
112
+
113
+ it "should not purge Windows system users" do
114
+ res = Puppet::Type.type(:resources).new :name => :user, :purge => true
115
+ res.catalog = Puppet::Resource::Catalog.new
116
+ user_hash = {:name => 'other', :uid => 'S-1-5-21-12345-1001'}
117
+ user = Puppet::Type.type(:user).new(user_hash)
118
+ user.stubs(:retrieve_resource).returns Puppet::Resource.new("user", user_hash[:name], :parameters => user_hash)
119
+ expect(res.user_check(user)).to be_truthy
120
+ end
103
121
  end
104
122
 
105
123
  %w(FreeBSD OpenBSD).each do |os|
@@ -29,7 +29,7 @@ end
29
29
  describe test_title, "when validating attributes" do
30
30
  safely_load_service_type
31
31
 
32
- [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart, :control].each do |param|
32
+ [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart, :control, :timeout].each do |param|
33
33
  it "should have a #{param} parameter" do
34
34
  expect(Puppet::Type.type(:service).attrtype(param)).to eq(:param)
35
35
  end
@@ -103,6 +103,32 @@ describe test_title, "when validating attribute values" do
103
103
  end
104
104
  end
105
105
 
106
+ describe "the timeout parameter" do
107
+ before do
108
+ provider_class_with_timeout = Puppet::Type.type(:service).provide(:simple) do
109
+ has_features :configurable_timeout
110
+ end
111
+ Puppet::Type.type(:service).stubs(:defaultprovider).returns provider_class_with_timeout
112
+ end
113
+
114
+ it "should fail when timeout is not an integer" do
115
+ expect { Puppet::Type.type(:service).new(:name => "yay", :timeout => 'foobar') }.to raise_error(Puppet::Error)
116
+ end
117
+
118
+ [-999, -1, 0].each do |int|
119
+ it "should not support #{int} as a value to :timeout" do
120
+ expect { Puppet::Type.type(:service).new(:name => "yay", :timeout => int) }.to raise_error(Puppet::Error)
121
+ end
122
+ end
123
+
124
+ [1, 30, 999].each do |int|
125
+ it "should support #{int} as a value to :timeout" do
126
+ srv = Puppet::Type.type(:service).new(:name => "yay", :timeout => int)
127
+ expect(srv[:timeout]).to eq(int)
128
+ end
129
+ end
130
+ end
131
+
106
132
  it "should support :true as a value to :hasstatus" do
107
133
  srv = Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :true)
108
134
  expect(srv[:hasstatus]).to eq(:true)
@@ -119,6 +119,17 @@ describe Puppet::Util::Execution, if: !Puppet::Util::Platform.jruby? do
119
119
  call_exec_posix("/bin/echo 'foo' ; \n /bin/echo 'bar' ;", {:uid => 50, :gid => 55}, @stdin, @stdout, @stderr)
120
120
  end
121
121
 
122
+ context 'cwd option' do
123
+ let(:cwd) { 'cwd' }
124
+
125
+ it 'should run the command in the specified working directory' do
126
+ Dir.expects(:chdir).with(cwd)
127
+ Kernel.expects(:exec).with('test command')
128
+
129
+ call_exec_posix('test command', { :cwd => cwd }, @stdin, @stdout, @stderr)
130
+ end
131
+ end
132
+
122
133
  it "should return the pid of the child process" do
123
134
  expect(call_exec_posix('test command', {}, @stdin, @stdout, @stderr)).to eq(pid)
124
135
  end
@@ -144,6 +155,42 @@ describe Puppet::Util::Execution, if: !Puppet::Util::Platform.jruby? do
144
155
  call_exec_windows('test command', {}, @stdin, @stdout, @stderr)
145
156
  end
146
157
 
158
+ context 'cwd option' do
159
+ let(:cwd) { 'cwd' }
160
+ it "should execute the command in the specified working directory" do
161
+ Dir.expects(:chdir).with(cwd).yields
162
+ Process.expects(:create).with(
163
+ :command_line => "test command",
164
+ :startup_info => {
165
+ :stdin => @stdin,
166
+ :stdout => @stdout,
167
+ :stderr => @stderr
168
+ },
169
+ :close_handles => false
170
+ )
171
+
172
+ call_exec_windows('test command', { :cwd => cwd }, @stdin, @stdout, @stderr)
173
+ end
174
+ end
175
+
176
+ context 'suppress_window option' do
177
+ let(:cwd) { 'cwd' }
178
+ it "should execute the command in the specified working directory" do
179
+ Process.expects(:create).with(
180
+ :command_line => "test command",
181
+ :startup_info => {
182
+ :stdin => @stdin,
183
+ :stdout => @stdout,
184
+ :stderr => @stderr
185
+ },
186
+ :close_handles => false,
187
+ :creation_flags => Puppet::Util::Windows::Process::CREATE_NO_WINDOW
188
+ )
189
+
190
+ call_exec_windows('test command', { :suppress_window => true }, @stdin, @stdout, @stderr)
191
+ end
192
+ end
193
+
147
194
  it "should return the process info of the child process" do
148
195
  expect(call_exec_windows('test command', {}, @stdin, @stdout, @stderr)).to eq(proc_info_stub)
149
196
  end
@@ -219,6 +266,36 @@ describe Puppet::Util::Execution, if: !Puppet::Util::Platform.jruby? do
219
266
  end
220
267
  end
221
268
 
269
+ describe "cwd option" do
270
+ def expect_cwd_to_be(cwd)
271
+ Puppet::Util::Execution.expects(executor).with(
272
+ anything,
273
+ has_entries(:cwd => cwd),
274
+ anything,
275
+ anything,
276
+ anything
277
+ ).returns(rval)
278
+ end
279
+
280
+ it 'should raise an ArgumentError if the specified working directory does not exist' do
281
+ cwd = 'cwd'
282
+ Puppet::FileSystem.stubs(:directory?).with(cwd).returns(false)
283
+
284
+ expect {
285
+ Puppet::Util::Execution.execute('test command', cwd: cwd)
286
+ }.to raise_error do |error|
287
+ expect(error).to be_a(ArgumentError)
288
+ expect(error.message).to match(cwd)
289
+ end
290
+ end
291
+
292
+ it "should set the cwd to the user-specified one" do
293
+ Puppet::FileSystem.stubs(:directory?).with('cwd').returns(true)
294
+ expect_cwd_to_be('cwd')
295
+ Puppet::Util::Execution.execute('test command', cwd: 'cwd')
296
+ end
297
+ end
298
+
222
299
  describe "on POSIX", :if => Puppet.features.posix? do
223
300
  describe "when squelch is not set" do
224
301
  it "should set stdout to a pipe" do
@@ -107,6 +107,10 @@ describe Puppet::Util::FileType do
107
107
  end
108
108
 
109
109
  describe "#read" do
110
+ before(:each) do
111
+ Puppet::Util.stubs(:uid).with(uid).returns 9000
112
+ end
113
+
110
114
  it "should run crontab -l as the target user" do
111
115
  Puppet::Util::Execution.expects(:execute)
112
116
  .with(['crontab', '-l'], user_options)
@@ -115,7 +119,7 @@ describe Puppet::Util::FileType do
115
119
  end
116
120
 
117
121
  it "should not switch user if current user is the target user" do
118
- Puppet::Util.expects(:uid).with(uid).returns 9000
122
+ Puppet::Util.expects(:uid).with(uid).twice.returns 9000
119
123
  Puppet::Util::SUIDManager.expects(:uid).returns 9000
120
124
  Puppet::Util::Execution
121
125
  .expects(:execute).with(['crontab', '-l'], options)
@@ -128,11 +132,15 @@ describe Puppet::Util::FileType do
128
132
  expect(cron.read).to eq('')
129
133
  end
130
134
 
131
- it "should raise an error if the user is not authorized to use cron" do
135
+ it "should treat a nonexistent user's crontab as empty" do
136
+ Puppet::Util.expects(:uid).with(uid).returns nil
137
+
138
+ expect(cron.read).to eq('')
139
+ end
140
+
141
+ it "should return empty if the user is not authorized to use cron" do
132
142
  Puppet::Util::Execution.expects(:execute).with(['crontab', '-l'], user_options).raises(Puppet::ExecutionFailure, unauthorized_crontab)
133
- expect {
134
- cron.read
135
- }.to raise_error Puppet::Error, /User #{uid} not authorized to use cron/
143
+ expect(cron.read).to eq('')
136
144
  end
137
145
  end
138
146
 
@@ -54,6 +54,7 @@ describe Puppet::Util::Log.desttypes[:file] do
54
54
  it_behaves_like "file destination"
55
55
 
56
56
  it "logs an error if it can't chown the file owner & group" do
57
+ File.expects(:exists?).with(abspath).returns(false)
57
58
  FileUtils.expects(:chown).with(Puppet[:user], Puppet[:group], abspath).raises(Errno::EPERM)
58
59
  Puppet.features.expects(:root?).returns(true)
59
60
  Puppet.expects(:err).with("Unable to set ownership to #{Puppet[:user]}:#{Puppet[:group]} for log file: #{abspath}")
@@ -62,11 +63,20 @@ describe Puppet::Util::Log.desttypes[:file] do
62
63
  end
63
64
 
64
65
  it "doesn't attempt to chown when running as non-root" do
66
+ File.expects(:exists?).with(abspath).returns(false)
65
67
  FileUtils.expects(:chown).with(Puppet[:user], Puppet[:group], abspath).never
66
68
  Puppet.features.expects(:root?).returns(false)
67
69
 
68
70
  @class.new(abspath)
69
71
  end
72
+
73
+ it "doesn't attempt to chown when file already exists" do
74
+ File.expects(:exists?).with(abspath).returns(true)
75
+ FileUtils.expects(:chown).with(Puppet[:user], Puppet[:group], abspath).never
76
+ Puppet.features.expects(:root?).returns(true)
77
+
78
+ @class.new(abspath)
79
+ end
70
80
  end
71
81
 
72
82
  describe "with a JSON file" do
@@ -99,6 +99,64 @@ describe Puppet::Util::Logging do
99
99
  end
100
100
  end
101
101
 
102
+ describe "log_exception" do
103
+ context "when requesting a debug level it is logged at debug" do
104
+ it "the exception is a ParseErrorWithIssue and message is :default" do
105
+ Puppet::Util::Log.expects(:create).with do |args|
106
+ expect(args[:message]).to eq("Test")
107
+ expect(args[:level]).to eq(:debug)
108
+ end
109
+
110
+ begin
111
+ raise Puppet::ParseErrorWithIssue, "Test"
112
+ rescue Puppet::ParseErrorWithIssue => err
113
+ Puppet.log_exception(err, :default, level: :debug)
114
+ end
115
+ end
116
+
117
+ it "the exception is something else" do
118
+ Puppet::Util::Log.expects(:create).with do |args|
119
+ expect(args[:message]).to eq("Test")
120
+ expect(args[:level]).to eq(:debug)
121
+ end
122
+
123
+ begin
124
+ raise Puppet::Error, "Test"
125
+ rescue Puppet::Error => err
126
+ Puppet.log_exception(err, :default, level: :debug)
127
+ end
128
+ end
129
+ end
130
+
131
+ context "no log level is requested it defaults to err" do
132
+ it "the exception is a ParseErrorWithIssue and message is :default" do
133
+ Puppet::Util::Log.expects(:create).with do |args|
134
+ expect(args[:message]).to eq("Test")
135
+ expect(args[:level]).to eq(:err)
136
+ end
137
+
138
+ begin
139
+ raise Puppet::ParseErrorWithIssue, "Test"
140
+ rescue Puppet::ParseErrorWithIssue => err
141
+ Puppet.log_exception(err)
142
+ end
143
+ end
144
+
145
+ it "the exception is something else" do
146
+ Puppet::Util::Log.expects(:create).with do |args|
147
+ expect(args[:message]).to eq("Test")
148
+ expect(args[:level]).to eq(:err)
149
+ end
150
+
151
+ begin
152
+ raise Puppet::Error, "Test"
153
+ rescue Puppet::Error => err
154
+ Puppet.log_exception(err)
155
+ end
156
+ end
157
+ end
158
+ end
159
+
102
160
  describe "when sending a deprecation warning" do
103
161
  it "does not log a message when deprecation warnings are disabled" do
104
162
  Puppet.expects(:[]).with(:disable_warnings).returns %w[deprecations]
@@ -302,21 +360,6 @@ original
302
360
  Facter.unstub(:debugging)
303
361
  end
304
362
 
305
- describe 'does not support debugging' do
306
- before :each do
307
- Facter.stubs(:respond_to?).with(:debugging).returns false
308
- Facter.stubs(:debugging).never
309
- end
310
-
311
- it 'does not enable Facter debugging for debug level' do
312
- Puppet::Util::Log.level = :debug
313
- end
314
-
315
- it 'does not enable Facter debugging non-debug level' do
316
- Puppet::Util::Log.level = :info
317
- end
318
- end
319
-
320
363
  describe 'does support debugging' do
321
364
  before :each do
322
365
  Facter.stubs(:respond_to?).with(:debugging).returns true
@@ -333,21 +376,6 @@ original
333
376
  end
334
377
  end
335
378
 
336
- describe 'does not support trace' do
337
- before :each do
338
- Facter.stubs(:respond_to?).with(:trace).returns false
339
- Facter.stubs(:trace).never
340
- end
341
-
342
- it 'does not enable Facter trace when enabled' do
343
- Puppet[:trace] = true
344
- end
345
-
346
- it 'does not enable Facter trace when disabled' do
347
- Puppet[:trace] = false
348
- end
349
- end
350
-
351
379
  describe 'does support trace' do
352
380
  before :each do
353
381
  Facter.stubs(:respond_to?).with(:trace).returns true
@@ -364,17 +392,6 @@ original
364
392
  end
365
393
  end
366
394
 
367
- describe 'does not support on_message' do
368
- before :each do
369
- Facter.stubs(:respond_to?).with(:on_message).returns false
370
- Facter.stubs(:on_message).never
371
- end
372
-
373
- it 'does not call Facter.on_message' do
374
- expect(Puppet::Util::Logging::setup_facter_logging!).to be_falsey
375
- end
376
- end
377
-
378
395
  describe 'does support on_message' do
379
396
  before :each do
380
397
  Facter.stubs(:respond_to?).with(:on_message).returns true
@@ -101,13 +101,26 @@ describe OpenSSL::X509::Store, :if => Puppet::Util::Platform.windows? do
101
101
  store.set_default_paths
102
102
  end
103
103
 
104
- it "warns when adding a certificate that already exists" do
105
- with_root_certs([cert])
106
- store.add_cert(cert)
104
+ # openssl 1.1.1 ignores duplicate certs
105
+ # https://github.com/openssl/openssl/commit/c0452248ea1a59a41023a4765ef7d9825e80a62b
106
+ if OpenSSL::OPENSSL_VERSION_NUMBER < 0x10101000
107
+ it "warns when adding a certificate that already exists" do
108
+ with_root_certs([cert])
109
+ store.add_cert(cert)
107
110
 
108
- store.expects(:warn).with('Failed to add /DC=com/DC=microsoft/CN=Microsoft Root Certificate Authority')
111
+ store.expects(:warn).with('Failed to add /DC=com/DC=microsoft/CN=Microsoft Root Certificate Authority')
109
112
 
110
- store.set_default_paths
113
+ store.set_default_paths
114
+ end
115
+ else
116
+ it "doesn't warn when adding a duplicate cert" do
117
+ with_root_certs([cert])
118
+ store.add_cert(cert)
119
+
120
+ store.expects(:warn).never
121
+
122
+ store.set_default_paths
123
+ end
111
124
  end
112
125
 
113
126
  it "raises when adding an invalid certificate" do
@@ -12,6 +12,34 @@ describe Puppet::Util::POSIX do
12
12
  @posix = PosixTest.new
13
13
  end
14
14
 
15
+ describe '.groups_of' do
16
+ let(:mock_groups) do
17
+ [
18
+ ['group1', ['user1', 'user2']],
19
+ ['group2', ['user2']],
20
+ ['group1', ['user1', 'user2']],
21
+ ['group3', ['user1']],
22
+ ['group4', ['user2']]
23
+ ].map do |(name, members)|
24
+ group_struct = stub("Group #{name}")
25
+ group_struct.stubs(:name).returns(name)
26
+ group_struct.stubs(:mem).returns(members)
27
+
28
+ group_struct
29
+ end
30
+ end
31
+
32
+ before(:each) do
33
+ Puppet::Etc.stubs(:group).multiple_yields(*mock_groups)
34
+ end
35
+
36
+ it 'returns the groups of the given user' do
37
+ expect(Puppet::Util::POSIX.groups_of('user1')).to eql(
38
+ ['group1', 'group3']
39
+ )
40
+ end
41
+ end
42
+
15
43
  [:group, :gr].each do |name|
16
44
  it "should return :gid as the field for #{name}" do
17
45
  expect(@posix.idfield(name)).to eq(:gid)
@@ -73,6 +73,10 @@ describe Puppet::Util::SELinux do
73
73
  expect(selinux_label_support?('/etc/puppetlabs/puppet/testfile')).to be_truthy
74
74
  end
75
75
 
76
+ it "should return true if tmpfs" do
77
+ expect(selinux_label_support?('/dev/shm/testfile')).to be_truthy
78
+ end
79
+
76
80
  it "should return false for a noncapable filesystem" do
77
81
  expect(selinux_label_support?('/mnt/nfs/testfile')).to be_falsey
78
82
  end
@@ -225,5 +225,112 @@ describe Puppet::Util::Storage do
225
225
 
226
226
  expect(Puppet::Util::Storage.state).to eq({:yayness=>{}})
227
227
  end
228
+
229
+ it "expires entries with a :checked older than statettl seconds ago" do
230
+ Puppet[:statettl] = '1d'
231
+ recent_checked = Time.now.round
232
+ stale_checked = recent_checked - (Puppet[:statettl] + 10)
233
+ Puppet::Util::Storage.cache(:yayness)[:checked] = recent_checked
234
+ Puppet::Util::Storage.cache(:stale)[:checked] = stale_checked
235
+ expect(Puppet::Util::Storage.state).to eq(
236
+ {
237
+ :yayness => {
238
+ :checked => recent_checked
239
+ },
240
+ :stale => {
241
+ :checked => stale_checked
242
+ }
243
+ }
244
+ )
245
+
246
+ Puppet::Util::Storage.store
247
+ Puppet::Util::Storage.clear
248
+
249
+ expect(Puppet::Util::Storage.state).to eq({})
250
+
251
+ Puppet::Util::Storage.load
252
+
253
+ expect(Puppet::Util::Storage.state).to eq(
254
+ {
255
+ :yayness => {
256
+ :checked => recent_checked
257
+ }
258
+ }
259
+ )
260
+ end
261
+
262
+
263
+ it "does not expire entries when statettl is 0" do
264
+ Puppet[:statettl] = '0'
265
+ recent_checked = Time.now.round
266
+ older_checked = recent_checked - 10_000_000
267
+ Puppet::Util::Storage.cache(:yayness)[:checked] = recent_checked
268
+ Puppet::Util::Storage.cache(:older)[:checked] = older_checked
269
+ expect(Puppet::Util::Storage.state).to eq(
270
+ {
271
+ :yayness => {
272
+ :checked => recent_checked
273
+ },
274
+ :older => {
275
+ :checked => older_checked
276
+ }
277
+ }
278
+ )
279
+
280
+ Puppet::Util::Storage.store
281
+ Puppet::Util::Storage.clear
282
+
283
+ expect(Puppet::Util::Storage.state).to eq({})
284
+
285
+ Puppet::Util::Storage.load
286
+
287
+ expect(Puppet::Util::Storage.state).to eq(
288
+ {
289
+ :yayness => {
290
+ :checked => recent_checked
291
+ },
292
+ :older => {
293
+ :checked => older_checked
294
+ }
295
+ }
296
+ )
297
+ end
298
+
299
+
300
+ it "does not expire entries when statettl is 'unlimited'" do
301
+ Puppet[:statettl] = 'unlimited'
302
+ recent_checked = Time.now
303
+ older_checked = Time.now - 10_000_000
304
+ Puppet::Util::Storage.cache(:yayness)[:checked] = recent_checked
305
+ Puppet::Util::Storage.cache(:older)[:checked] = older_checked
306
+ expect(Puppet::Util::Storage.state).to eq(
307
+ {
308
+ :yayness => {
309
+ :checked => recent_checked
310
+ },
311
+ :older => {
312
+ :checked => older_checked
313
+ }
314
+ }
315
+ )
316
+
317
+ Puppet::Util::Storage.store
318
+ Puppet::Util::Storage.clear
319
+
320
+ expect(Puppet::Util::Storage.state).to eq({})
321
+
322
+ Puppet::Util::Storage.load
323
+
324
+ expect(Puppet::Util::Storage.state).to eq(
325
+ {
326
+ :yayness => {
327
+ :checked => recent_checked
328
+ },
329
+ :older => {
330
+ :checked => older_checked
331
+ }
332
+ }
333
+ )
334
+ end
228
335
  end
229
336
  end
@@ -121,9 +121,7 @@ describe Puppet::Util::SUIDManager do
121
121
  end
122
122
  end
123
123
 
124
- it "should not get or set euid/egid on Windows" do
125
- Puppet::Util::Platform.stubs(:windows?).returns false
126
-
124
+ it "should not get or set euid/egid on Windows", if: Puppet::Util::Platform.windows? do
127
125
  Puppet::Util::SUIDManager.asuser(user[:uid], user[:gid]) {}
128
126
 
129
127
  expect(xids).to be_empty