puppet 6.10.1 → 6.11.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/Gemfile.lock +20 -12
  4. data/ext/project_data.yaml +3 -2
  5. data/ext/regexp_nodes/regexp_nodes.rb +4 -4
  6. data/ext/windows/service/daemon.rb +33 -8
  7. data/install.rb +6 -6
  8. data/lib/puppet.rb +8 -0
  9. data/lib/puppet/application.rb +1 -1
  10. data/lib/puppet/application/agent.rb +3 -0
  11. data/lib/puppet/application/apply.rb +2 -2
  12. data/lib/puppet/application/describe.rb +3 -9
  13. data/lib/puppet/application/device.rb +3 -0
  14. data/lib/puppet/application/doc.rb +1 -1
  15. data/lib/puppet/application/lookup.rb +1 -1
  16. data/lib/puppet/application/script.rb +2 -2
  17. data/lib/puppet/application/ssl.rb +25 -21
  18. data/lib/puppet/configurer.rb +42 -0
  19. data/lib/puppet/configurer/downloader.rb +2 -6
  20. data/lib/puppet/context/trusted_information.rb +42 -4
  21. data/lib/puppet/defaults.rb +19 -4
  22. data/lib/puppet/face/module/list.rb +5 -5
  23. data/lib/puppet/face/module/search.rb +1 -1
  24. data/lib/puppet/face/module/uninstall.rb +1 -1
  25. data/lib/puppet/face/module/upgrade.rb +1 -1
  26. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  27. data/lib/puppet/file_system.rb +0 -8
  28. data/lib/puppet/file_system/memory_file.rb +1 -1
  29. data/lib/puppet/file_system/posix.rb +3 -2
  30. data/lib/puppet/forge.rb +3 -3
  31. data/lib/puppet/functions.rb +1 -2
  32. data/lib/puppet/gettext/module_translations.rb +1 -1
  33. data/lib/puppet/graph/rb_tree_map.rb +2 -2
  34. data/lib/puppet/graph/simple_graph.rb +4 -3
  35. data/lib/puppet/http.rb +29 -0
  36. data/lib/puppet/http/client.rb +156 -0
  37. data/lib/puppet/http/errors.rb +30 -0
  38. data/lib/puppet/http/redirector.rb +48 -0
  39. data/lib/puppet/http/resolver.rb +5 -0
  40. data/lib/puppet/http/resolver/settings.rb +5 -0
  41. data/lib/puppet/http/resolver/srv.rb +13 -0
  42. data/lib/puppet/http/response.rb +34 -0
  43. data/lib/puppet/http/retry_after_handler.rb +47 -0
  44. data/lib/puppet/http/service.rb +18 -0
  45. data/lib/puppet/http/service/ca.rb +49 -0
  46. data/lib/puppet/http/session.rb +55 -0
  47. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  48. data/lib/puppet/indirector/hiera.rb +2 -0
  49. data/lib/puppet/indirector/request.rb +1 -1
  50. data/lib/puppet/indirector/resource/ral.rb +1 -3
  51. data/lib/puppet/indirector/resource/validator.rb +1 -1
  52. data/lib/puppet/interface.rb +2 -1
  53. data/lib/puppet/interface/documentation.rb +1 -1
  54. data/lib/puppet/loaders.rb +0 -1
  55. data/lib/puppet/metatype/manager.rb +1 -1
  56. data/lib/puppet/module.rb +1 -1
  57. data/lib/puppet/module/task.rb +20 -4
  58. data/lib/puppet/module_tool/applications/installer.rb +1 -1
  59. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -3
  60. data/lib/puppet/module_tool/metadata.rb +1 -1
  61. data/lib/puppet/module_tool/shared_behaviors.rb +4 -4
  62. data/lib/puppet/module_tool/tar/mini.rb +1 -1
  63. data/lib/puppet/network/http.rb +2 -6
  64. data/lib/puppet/network/http/api/indirected_routes.rb +12 -11
  65. data/lib/puppet/network/http/connection.rb +10 -12
  66. data/lib/puppet/network/http/pool.rb +2 -0
  67. data/lib/puppet/network/http/site.rb +5 -1
  68. data/lib/puppet/network/resolver.rb +4 -4
  69. data/lib/puppet/node/environment.rb +4 -2
  70. data/lib/puppet/pal/pal_impl.rb +2 -2
  71. data/lib/puppet/parser/ast.rb +1 -1
  72. data/lib/puppet/parser/ast/resourceparam.rb +1 -1
  73. data/lib/puppet/parser/functions.rb +1 -1
  74. data/lib/puppet/parser/scope.rb +8 -7
  75. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +1 -1
  76. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +1 -1
  77. data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -2
  78. data/lib/puppet/pops/evaluator/runtime3_support.rb +4 -7
  79. data/lib/puppet/pops/loader/module_loaders.rb +1 -1
  80. data/lib/puppet/pops/loader/task_instantiator.rb +4 -0
  81. data/lib/puppet/pops/loaders.rb +1 -1
  82. data/lib/puppet/pops/lookup/hiera_config.rb +1 -0
  83. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  84. data/lib/puppet/pops/merge_strategy.rb +22 -18
  85. data/lib/puppet/pops/parser/heredoc_support.rb +1 -1
  86. data/lib/puppet/pops/parser/interpolation_support.rb +4 -4
  87. data/lib/puppet/pops/parser/locator.rb +1 -1
  88. data/lib/puppet/pops/parser/pn_parser.rb +17 -16
  89. data/lib/puppet/pops/puppet_stack.rb +52 -48
  90. data/lib/puppet/pops/types/p_sensitive_type.rb +1 -1
  91. data/lib/puppet/pops/types/p_uri_type.rb +1 -1
  92. data/lib/puppet/pops/types/string_converter.rb +10 -10
  93. data/lib/puppet/pops/types/types.rb +3 -3
  94. data/lib/puppet/property.rb +1 -1
  95. data/lib/puppet/property/ensure.rb +1 -1
  96. data/lib/puppet/provider/exec.rb +6 -2
  97. data/lib/puppet/provider/nameservice/directoryservice.rb +1 -1
  98. data/lib/puppet/provider/nameservice/pw.rb +2 -2
  99. data/lib/puppet/provider/package/apt.rb +5 -1
  100. data/lib/puppet/provider/package/dnfmodule.rb +87 -0
  101. data/lib/puppet/provider/package/dpkg.rb +31 -17
  102. data/lib/puppet/provider/package/openbsd.rb +1 -1
  103. data/lib/puppet/provider/package/pip.rb +34 -9
  104. data/lib/puppet/provider/package/portage.rb +1 -1
  105. data/lib/puppet/provider/package/rpm.rb +5 -5
  106. data/lib/puppet/provider/package/windows/package.rb +1 -1
  107. data/lib/puppet/provider/package/yum.rb +1 -1
  108. data/lib/puppet/provider/parsedfile.rb +1 -1
  109. data/lib/puppet/provider/service/daemontools.rb +9 -9
  110. data/lib/puppet/provider/service/openbsd.rb +1 -1
  111. data/lib/puppet/provider/service/rcng.rb +2 -2
  112. data/lib/puppet/provider/service/runit.rb +2 -8
  113. data/lib/puppet/provider/service/systemd.rb +10 -10
  114. data/lib/puppet/provider/user/directoryservice.rb +1 -1
  115. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  116. data/lib/puppet/provider/user/useradd.rb +22 -13
  117. data/lib/puppet/provider/user/windows_adsi.rb +4 -5
  118. data/lib/puppet/reference/indirection.rb +2 -2
  119. data/lib/puppet/reference/metaparameter.rb +1 -3
  120. data/lib/puppet/reference/providers.rb +1 -1
  121. data/lib/puppet/reference/type.rb +3 -9
  122. data/lib/puppet/reports.rb +1 -1
  123. data/lib/puppet/resource.rb +1 -1
  124. data/lib/puppet/resource/catalog.rb +1 -1
  125. data/lib/puppet/rest/errors.rb +1 -0
  126. data/lib/puppet/rest/response.rb +1 -0
  127. data/lib/puppet/rest/route.rb +1 -0
  128. data/lib/puppet/rest/routes.rb +3 -0
  129. data/lib/puppet/runtime.rb +25 -0
  130. data/lib/puppet/settings.rb +3 -3
  131. data/lib/puppet/settings/environment_conf.rb +1 -0
  132. data/lib/puppet/ssl/host.rb +1 -1
  133. data/lib/puppet/ssl/oids.rb +1 -1
  134. data/lib/puppet/ssl/state_machine.rb +23 -15
  135. data/lib/puppet/test/test_helper.rb +1 -1
  136. data/lib/puppet/transaction/report.rb +1 -1
  137. data/lib/puppet/trusted_external.rb +13 -0
  138. data/lib/puppet/type.rb +1 -3
  139. data/lib/puppet/type/exec.rb +7 -3
  140. data/lib/puppet/type/file.rb +1 -2
  141. data/lib/puppet/type/file/source.rb +2 -2
  142. data/lib/puppet/type/package.rb +10 -3
  143. data/lib/puppet/type/schedule.rb +1 -1
  144. data/lib/puppet/type/service.rb +1 -1
  145. data/lib/puppet/util.rb +2 -2
  146. data/lib/puppet/util/command_line/trollop.rb +1 -1
  147. data/lib/puppet/util/http_proxy.rb +2 -10
  148. data/lib/puppet/util/log.rb +2 -2
  149. data/lib/puppet/util/log/destinations.rb +2 -2
  150. data/lib/puppet/util/logging.rb +2 -2
  151. data/lib/puppet/util/metric.rb +2 -2
  152. data/lib/puppet/util/platform.rb +15 -4
  153. data/lib/puppet/util/provider_features.rb +2 -4
  154. data/lib/puppet/util/rdoc.rb +1 -1
  155. data/lib/puppet/util/reference.rb +1 -1
  156. data/lib/puppet/util/resource_template.rb +1 -1
  157. data/lib/puppet/util/selinux.rb +3 -1
  158. data/lib/puppet/util/windows/registry.rb +7 -5
  159. data/lib/puppet/vendor.rb +1 -1
  160. data/lib/puppet/vendor/require_vendored.rb +0 -1
  161. data/lib/puppet/version.rb +1 -1
  162. data/lib/puppet/x509/cert_provider.rb +4 -1
  163. data/locales/puppet.pot +279 -203
  164. data/man/man5/puppet.conf.5 +30 -8
  165. data/man/man8/puppet-agent.8 +4 -1
  166. data/man/man8/puppet-apply.8 +1 -1
  167. data/man/man8/puppet-catalog.8 +1 -1
  168. data/man/man8/puppet-config.8 +1 -1
  169. data/man/man8/puppet-describe.8 +1 -1
  170. data/man/man8/puppet-device.8 +1 -1
  171. data/man/man8/puppet-doc.8 +1 -1
  172. data/man/man8/puppet-epp.8 +1 -1
  173. data/man/man8/puppet-facts.8 +1 -1
  174. data/man/man8/puppet-filebucket.8 +1 -1
  175. data/man/man8/puppet-generate.8 +1 -1
  176. data/man/man8/puppet-help.8 +1 -1
  177. data/man/man8/puppet-key.8 +1 -1
  178. data/man/man8/puppet-lookup.8 +1 -1
  179. data/man/man8/puppet-man.8 +1 -1
  180. data/man/man8/puppet-module.8 +1 -1
  181. data/man/man8/puppet-node.8 +1 -1
  182. data/man/man8/puppet-parser.8 +1 -1
  183. data/man/man8/puppet-plugin.8 +1 -1
  184. data/man/man8/puppet-report.8 +1 -1
  185. data/man/man8/puppet-resource.8 +1 -1
  186. data/man/man8/puppet-script.8 +1 -1
  187. data/man/man8/puppet-ssl.8 +1 -1
  188. data/man/man8/puppet-status.8 +1 -1
  189. data/man/man8/puppet.8 +2 -2
  190. data/spec/fixtures/unit/provider/package/dnfmodule/dnf-module-list-installed.txt +11 -0
  191. data/spec/integration/configurer_spec.rb +52 -0
  192. data/spec/lib/puppet/certificate_factory.rb +2 -2
  193. data/spec/spec_helper.rb +24 -0
  194. data/spec/unit/application/device_spec.rb +6 -0
  195. data/spec/unit/application/ssl_spec.rb +4 -7
  196. data/spec/unit/configurer_spec.rb +1 -0
  197. data/spec/unit/context/trusted_information_spec.rb +41 -2
  198. data/spec/unit/http/client_spec.rb +440 -0
  199. data/spec/unit/http/resolver_spec.rb +45 -0
  200. data/spec/unit/http/service/ca_spec.rb +106 -0
  201. data/spec/unit/http/service_spec.rb +32 -0
  202. data/spec/unit/http/session_spec.rb +102 -0
  203. data/spec/unit/indirector/resource/ral_spec.rb +4 -4
  204. data/spec/unit/network/http/connection_spec.rb +119 -145
  205. data/spec/unit/network/http/site_spec.rb +7 -0
  206. data/spec/unit/parser/scope_spec.rb +10 -0
  207. data/spec/unit/pops/loaders/loaders_spec.rb +13 -2
  208. data/spec/unit/pops/loaders/module_loaders_spec.rb +37 -0
  209. data/spec/unit/provider/exec_spec.rb +209 -0
  210. data/spec/unit/provider/package/dnfmodule_spec.rb +186 -0
  211. data/spec/unit/provider/package/dpkg_spec.rb +238 -78
  212. data/spec/unit/provider/package/pip_spec.rb +51 -6
  213. data/spec/unit/provider/service/daemontools_spec.rb +24 -0
  214. data/spec/unit/provider/service/runit_spec.rb +24 -0
  215. data/spec/unit/provider/service/systemd_spec.rb +25 -25
  216. data/spec/unit/provider/user/useradd_spec.rb +46 -0
  217. data/spec/unit/ssl/host_spec.rb +0 -5
  218. data/spec/unit/ssl/state_machine_spec.rb +16 -10
  219. data/spec/unit/type/exec_spec.rb +6 -12
  220. data/spec/unit/type/file_spec.rb +9 -4
  221. data/spec/unit/type/package_spec.rb +5 -0
  222. data/spec/unit/util/execution_spec.rb +16 -0
  223. data/spec/unit/util/http_proxy_spec.rb +79 -27
  224. data/spec/unit/util/log/destinations_spec.rb +7 -3
  225. metadata +45 -22
  226. data/lib/puppet/pops/loader/null_loader.rb +0 -60
  227. data/lib/puppet/vendor/deep_merge/CHANGELOG +0 -45
  228. data/lib/puppet/vendor/deep_merge/Gemfile +0 -3
  229. data/lib/puppet/vendor/deep_merge/LICENSE +0 -21
  230. data/lib/puppet/vendor/deep_merge/PUPPET_README.md +0 -6
  231. data/lib/puppet/vendor/deep_merge/README.md +0 -113
  232. data/lib/puppet/vendor/deep_merge/Rakefile +0 -19
  233. data/lib/puppet/vendor/deep_merge/deep_merge.gemspec +0 -35
  234. data/lib/puppet/vendor/deep_merge/lib/deep_merge.rb +0 -2
  235. data/lib/puppet/vendor/deep_merge/lib/deep_merge/core.rb +0 -210
  236. data/lib/puppet/vendor/deep_merge/lib/deep_merge/deep_merge_hash.rb +0 -28
  237. data/lib/puppet/vendor/deep_merge/lib/deep_merge/rails_compat.rb +0 -27
  238. data/lib/puppet/vendor/deep_merge/test/test_deep_merge.rb +0 -608
  239. data/lib/puppet/vendor/load_deep_merge.rb +0 -1
  240. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +0 -24
  241. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +0 -24
  242. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +0 -24
@@ -210,8 +210,8 @@ Copyright (c) 2017 Puppet Inc., LLC Licensed under the Apache 2.0 License
210
210
 
211
211
  compiler.compile()
212
212
 
213
- rescue Puppet::ParseErrorWithIssue, Puppet::Error
214
- # already logged and handled by the compiler for these two cases
213
+ rescue Puppet::Error
214
+ # already logged and handled by the compiler, including Puppet::ParseErrorWithIssue
215
215
  exit(1)
216
216
  end
217
217
 
@@ -90,6 +90,7 @@ HELP
90
90
  @cert_provider = Puppet::X509::CertProvider.new
91
91
  @ssl_provider = Puppet::SSL::SSLProvider.new
92
92
  @machine = Puppet::SSL::StateMachine.new
93
+ @session = Puppet.runtime['http'].create_session
93
94
  end
94
95
 
95
96
  def setup_logs
@@ -160,14 +161,13 @@ HELP
160
161
  end
161
162
 
162
163
  csr = @cert_provider.create_request(Puppet[:certname], key)
163
- Puppet::Rest::Routes.put_certificate_request(csr.to_pem, Puppet[:certname], ssl_context)
164
+ route = create_route(ssl_context)
165
+ route.put_certificate_request(Puppet[:certname], csr, ssl_context: ssl_context)
164
166
  @cert_provider.save_request(Puppet[:certname], csr)
165
- Puppet.notice _("Submitted certificate request for '%{name}' to https://%{server}:%{port}") % {
166
- name: Puppet[:certname], server: Puppet[:ca_server], port: Puppet[:ca_port]
167
- }
168
- rescue Puppet::Rest::ResponseError => e
169
- if e.response.code.to_i == 400
170
- raise Puppet::Error.new(_("Could not submit certificate request for '%{name}' to https://%{server}:%{port} due to a conflict on the server") % { name: Puppet[:certname], server: Puppet[:ca_server], port: Puppet[:ca_port] })
167
+ Puppet.notice _("Submitted certificate request for '%{name}' to %{url}") % { name: Puppet[:certname], url: route.url }
168
+ rescue Puppet::HTTP::ResponseError => e
169
+ if e.response.code == 400
170
+ raise Puppet::Error.new(_("Could not submit certificate request for '%{name}' to %{url} due to a conflict on the server") % { name: Puppet[:certname], url: route.url })
171
171
  else
172
172
  raise Puppet::Error.new(_("Failed to submit certificate request: %{message}") % { message: e.message }, e)
173
173
  end
@@ -178,27 +178,23 @@ HELP
178
178
  def download_cert(ssl_context)
179
179
  key = @cert_provider.load_private_key(Puppet[:certname])
180
180
 
181
- Puppet.info _("Downloading certificate '%{name}' from https://%{server}:%{port}") % {
182
- name: Puppet[:certname], server: Puppet[:ca_server], port: Puppet[:ca_port]
183
- }
184
-
185
181
  # try to download cert
186
- x509 = Puppet::Rest::Routes.get_certificate(Puppet[:certname], ssl_context)
182
+ route = create_route(ssl_context)
183
+ Puppet.info _("Downloading certificate '%{name}' from %{url}") % { name: Puppet[:certname], url: route.url }
184
+
185
+ x509 = route.get_certificate(Puppet[:certname], ssl_context: ssl_context)
187
186
  cert = OpenSSL::X509::Certificate.new(x509)
188
187
  Puppet.notice _("Downloaded certificate '%{name}' with fingerprint %{fingerprint}") % { name: Puppet[:certname], fingerprint: fingerprint(cert) }
188
+
189
189
  # verify client cert before saving
190
190
  @ssl_provider.create_context(
191
191
  cacerts: ssl_context.cacerts, crls: ssl_context.crls, private_key: key, client_cert: cert
192
192
  )
193
193
  @cert_provider.save_client_cert(Puppet[:certname], cert)
194
194
  @cert_provider.delete_request(Puppet[:certname])
195
-
196
- Puppet.notice _("Downloaded certificate '%{name}' with fingerprint %{fingerprint}") % {
197
- name: Puppet[:certname], fingerprint: fingerprint(cert)
198
- }
199
195
  cert
200
- rescue Puppet::Rest::ResponseError => e
201
- if e.response.code.to_i == 404
196
+ rescue Puppet::HTTP::ResponseError => e
197
+ if e.response.code == 404
202
198
  return nil
203
199
  else
204
200
  raise Puppet::Error.new(_("Failed to download certificate: %{message}") % { message: e.message }, e)
@@ -229,8 +225,9 @@ HELP
229
225
 
230
226
  begin
231
227
  ssl_context = @machine.ensure_ca_certificates
232
- cert = Puppet::Rest::Routes.get_certificate(certname, ssl_context)
233
- rescue Puppet::Rest::ResponseError => e
228
+ route = create_route(ssl_context)
229
+ cert = route.get_certificate(certname, ssl_context: ssl_context)
230
+ rescue Puppet::HTTP::ResponseError => e
234
231
  if e.response.code.to_i != 404
235
232
  raise Puppet::Error.new(_("Failed to connect to the CA to determine if certificate %{certname} has been cleaned") % { certname: certname }, e)
236
233
  end
@@ -255,7 +252,10 @@ END
255
252
  'certificate' => Puppet[:hostcert],
256
253
  'private key password file' => Puppet[:passfile]
257
254
  }
258
- paths.merge!('local CA certificate' => Puppet[:localcacert], 'local CRL' => Puppet[:hostcrl]) if options[:localca]
255
+ if options[:localca]
256
+ paths['local CA certificate'] = Puppet[:localcacert]
257
+ paths['local CRL'] = Puppet[:hostcrl]
258
+ end
259
259
  paths.each_pair do |label, path|
260
260
  if Puppet::FileSystem.exist?(path)
261
261
  Puppet::FileSystem.unlink(path)
@@ -269,4 +269,8 @@ END
269
269
  def fingerprint(cert)
270
270
  Puppet::SSL::Digest.new(nil, cert.to_der)
271
271
  end
272
+
273
+ def create_route(ssl_context)
274
+ @session.route_to(:ca, ssl_context: ssl_context)
275
+ end
272
276
  end
@@ -387,6 +387,14 @@ class Puppet::Configurer
387
387
  execute_postrun_command or return nil
388
388
  end
389
389
  ensure
390
+ if Puppet[:resubmit_facts]
391
+ # TODO: Should mark the report as "failed" if an error occurs and
392
+ # resubmit_facts returns false. There is currently no API for this.
393
+ resubmit_facts_time = thinmark { resubmit_facts }
394
+
395
+ report.add_times(:resubmit_facts, resubmit_facts_time)
396
+ end
397
+
390
398
  report.cached_catalog_status ||= @cached_catalog_status
391
399
  report.add_times(:total, Time.now - start)
392
400
  report.finalize_report
@@ -434,6 +442,40 @@ class Puppet::Configurer
434
442
  Puppet.log_exception(detail, _("Could not save last run local report: %{detail}") % { detail: detail })
435
443
  end
436
444
 
445
+ # Submit updated facts to the Puppet Server
446
+ #
447
+ # This method will clear all current fact values, load a fresh set of
448
+ # fact data, and then submit it to the Puppet Server.
449
+ #
450
+ # @return [true] If fact submission succeeds.
451
+ # @return [false] If an exception is raised during fact generation or
452
+ # submission.
453
+ def resubmit_facts
454
+ ::Facter.clear
455
+ facts = find_facts
456
+
457
+ saved_fact_terminus = Puppet::Node::Facts.indirection.terminus_class
458
+ begin
459
+ Puppet::Node::Facts.indirection.terminus_class = :rest
460
+
461
+ server = Puppet::Node::Facts::Rest.server
462
+ Puppet.info(_("Uploading facts for %{node} to %{server}") % {
463
+ node: facts.name,
464
+ server: server})
465
+
466
+ Puppet::Node::Facts.indirection.save(facts, nil, :environment => Puppet::Node::Environment.remote(@environment))
467
+
468
+ return true
469
+ ensure
470
+ Puppet::Node::Facts.indirection.terminus_class = saved_fact_terminus
471
+ end
472
+ rescue => detail
473
+ Puppet.log_exception(detail, _("Failed to submit facts: %{detail}") %
474
+ { detail: detail })
475
+
476
+ return false
477
+ end
478
+
437
479
  private
438
480
 
439
481
  def execute_from_setting(setting)
@@ -55,12 +55,8 @@ class Puppet::Configurer::Downloader
55
55
  :noop => false
56
56
  }
57
57
  if !Puppet::Util::Platform.windows?
58
- defargs.merge!(
59
- {
60
- :owner => Process.uid,
61
- :group => Process.gid
62
- }
63
- )
58
+ defargs[:owner] = Process.uid
59
+ defargs[:group] = Process.gid
64
60
  end
65
61
  return defargs
66
62
  end
@@ -1,3 +1,5 @@
1
+ require 'puppet/trusted_external'
2
+
1
3
  # @api private
2
4
  class Puppet::Context::TrustedInformation
3
5
  # one of 'remote', 'local', or false, where 'remote' is authenticated via cert,
@@ -27,7 +29,12 @@ class Puppet::Context::TrustedInformation
27
29
  # @return [String]
28
30
  attr_reader :hostname
29
31
 
30
- def initialize(authenticated, certname, extensions)
32
+ # Additional external facts loaded through `trusted_external_command`.
33
+ #
34
+ # @return [Hash]
35
+ attr_reader :external
36
+
37
+ def initialize(authenticated, certname, extensions, external = {})
31
38
  @authenticated = authenticated.freeze
32
39
  @certname = certname.freeze
33
40
  @extensions = extensions.freeze
@@ -39,9 +46,12 @@ class Puppet::Context::TrustedInformation
39
46
  end
40
47
  @hostname = hostname.freeze
41
48
  @domain = domain.freeze
49
+ @external = external.freeze
42
50
  end
43
51
 
44
52
  def self.remote(authenticated, node_name, certificate)
53
+ external = retrieve_trusted_external(node_name)
54
+
45
55
  if authenticated
46
56
  extensions = {}
47
57
  if certificate.nil?
@@ -51,9 +61,9 @@ class Puppet::Context::TrustedInformation
51
61
  [ext['oid'].freeze, ext['value'].freeze]
52
62
  end]
53
63
  end
54
- new('remote', node_name, extensions)
64
+ new('remote', node_name, extensions, external)
55
65
  else
56
- new(false, nil, {})
66
+ new(false, nil, {}, external)
57
67
  end
58
68
  end
59
69
 
@@ -61,8 +71,35 @@ class Puppet::Context::TrustedInformation
61
71
  # Always trust local data by picking up the available parameters.
62
72
  client_cert = node ? node.parameters['clientcert'] : nil
63
73
 
64
- new('local', client_cert, {})
74
+ new('local', client_cert, {}, retrieve_trusted_external(client_cert))
75
+ end
76
+
77
+ def self.retrieve_trusted_external(certname)
78
+ deep_freeze(Puppet::TrustedExternal.retrieve(certname) || {})
79
+ end
80
+ private_class_method :retrieve_trusted_external
81
+
82
+ # Deeply freezes the given object. The object and its content must be of the types:
83
+ # Array, Hash, Numeric, Boolean, Regexp, NilClass, or String. All other types raises an Error.
84
+ # (i.e. if they are assignable to Puppet::Pops::Types::Data type).
85
+ def self.deep_freeze(object)
86
+ case object
87
+ when Array
88
+ object.each {|v| deep_freeze(v) }
89
+ object.freeze
90
+ when Hash
91
+ object.each {|k, v| deep_freeze(k); deep_freeze(v) }
92
+ object.freeze
93
+ when NilClass, Numeric, TrueClass, FalseClass
94
+ # do nothing
95
+ when String
96
+ object.freeze
97
+ else
98
+ raise Puppet::Error, _("Unsupported data type: '%{klass}'") % { klass: object.class }
99
+ end
100
+ object
65
101
  end
102
+ private_class_method :deep_freeze
66
103
 
67
104
  def to_h
68
105
  {
@@ -71,6 +108,7 @@ class Puppet::Context::TrustedInformation
71
108
  'extensions'.freeze => extensions,
72
109
  'hostname'.freeze => hostname,
73
110
  'domain'.freeze => domain,
111
+ 'external'.freeze => external,
74
112
  }.freeze
75
113
  end
76
114
  end
@@ -306,7 +306,6 @@ module Puppet
306
306
  :default => ! Puppet::Util::Platform.windows?,
307
307
  :type => :boolean,
308
308
  :desc => "Whether Puppet should manage the owner, group, and mode of files it uses internally.
309
-
310
309
  **Note**: For Windows agents, the default is `false` for versions 4.10.13 and greater, versions 5.5.6 and greater, and versions 6.0 and greater.",
311
310
  },
312
311
  :onetime => {
@@ -536,6 +535,16 @@ module Puppet
536
535
  :default => 'facter',
537
536
  :desc => "The node facts terminus.",
538
537
  },
538
+ :trusted_external_command => {
539
+ :default => nil,
540
+ :desc => "The external trusted facts script to use.
541
+ This setting's value can be set to the path to an executable command that
542
+ can produce external trusted facts. The command must:
543
+
544
+ * Take the name of a node as a command-line argument.
545
+ * Return a JSON hash with the external trusted facts for this node.
546
+ * For unknown or invalid nodes, exit with a non-zero exit code.",
547
+ },
539
548
  :default_file_terminus => {
540
549
  :type => :terminus,
541
550
  :default => "rest",
@@ -546,9 +555,10 @@ module Puppet
546
555
  },
547
556
  :http_proxy_host => {
548
557
  :default => "none",
549
- :desc => "The HTTP proxy host to use for outgoing connections. Note: You
558
+ :desc => "The HTTP proxy host to use for outgoing connections. The proxy will be bypassed if
559
+ the server's hostname matches the NO_PROXY environment variable or `no_proxy` setting. Note: You
550
560
  may need to use a FQDN for the server hostname when using a proxy. Environment variable
551
- http_proxy or HTTP_PROXY will override this value",
561
+ http_proxy or HTTP_PROXY will override this value. ",
552
562
  },
553
563
  :http_proxy_port => {
554
564
  :default => 3128,
@@ -574,7 +584,7 @@ module Puppet
574
584
  },
575
585
  :no_proxy => {
576
586
  :default => "localhost, 127.0.0.1",
577
- :desc => "List of domain names that should not go through `http_proxy_host`. Environment variable no_proxy or NO_PROXY will override this value.",
587
+ :desc => "List of host or domain names that should not go through `http_proxy_host`. Environment variable no_proxy or NO_PROXY will override this value. Names can be specified as an FQDN `host.example.com`, wildcard `*.example.com`, dotted domain `.example.com`, or suffix `example.com`.",
578
588
  },
579
589
  :http_keepalive_timeout => {
580
590
  :default => "4s",
@@ -1706,6 +1716,11 @@ EOT
1706
1716
  :type => :boolean,
1707
1717
  :desc => "Whether to send reports after every transaction.",
1708
1718
  },
1719
+ :resubmit_facts => {
1720
+ :default => false,
1721
+ :type => :boolean,
1722
+ :desc => "Whether to send updated facts after every transaction.",
1723
+ },
1709
1724
  :lastrunfile => {
1710
1725
  :default => "$statedir/last_run_summary.yaml",
1711
1726
  :type => :file,
@@ -123,10 +123,10 @@ Puppet::Face.define(:module, '1.0.0') do
123
123
  unmet_grouped.each do |type, deps|
124
124
  unless deps.empty?
125
125
  unmet_grouped[type].sort_by { |dep| dep[:name] }.each do |dep|
126
- dep_name = dep[:name].gsub('/', '-')
126
+ dep_name = dep[:name].tr('/', '-')
127
127
  installed_version = dep[:mod_details][:installed_version]
128
128
  version_constraint = dep[:version_constraint]
129
- parent_name = dep[:parent][:name].gsub('/', '-')
129
+ parent_name = dep[:parent][:name].tr('/', '-')
130
130
  parent_version = dep[:parent][:version]
131
131
 
132
132
  msg = _("'%{parent_name}' (%{parent_version}) requires '%{dependency_name}' (%{dependency_version})") % { parent_name: parent_name, parent_version: parent_version, dependency_name: dep_name, dependency_version: version_constraint }
@@ -146,7 +146,7 @@ Puppet::Face.define(:module, '1.0.0') do
146
146
  error_display_order.each do |type|
147
147
  unless @unmet_deps[type].empty?
148
148
  @unmet_deps[type].keys.sort.each do |dep|
149
- name = dep.gsub('/', '-')
149
+ name = dep.tr('/', '-')
150
150
  errors = @unmet_deps[type][dep][:errors]
151
151
  version = @unmet_deps[type][dep][:version]
152
152
 
@@ -214,7 +214,7 @@ Puppet::Face.define(:module, '1.0.0') do
214
214
  dep[:reason] == :missing
215
215
  end
216
216
  missing_deps.map do |mis_mod|
217
- str = "#{colorize(:bg_red, _('UNMET DEPENDENCY'))} #{mis_mod[:name].gsub('/', '-')} "
217
+ str = "#{colorize(:bg_red, _('UNMET DEPENDENCY'))} #{mis_mod[:name].tr('/', '-')} "
218
218
  str << "(#{colorize(:cyan, mis_mod[:version_constraint])})"
219
219
  node[:dependencies] << { :text => str }
220
220
  end
@@ -239,7 +239,7 @@ Puppet::Face.define(:module, '1.0.0') do
239
239
  #
240
240
  def list_build_node(mod, parent, params)
241
241
  str = ''
242
- str << (mod.forge_name ? mod.forge_name.gsub('/', '-') : mod.name)
242
+ str << (mod.forge_name ? mod.forge_name.tr('/', '-') : mod.name)
243
243
  str << ' (' + colorize(:cyan, mod.version ? "v#{mod.version}" : '???') + ')'
244
244
 
245
245
  unless File.dirname(mod.path) == params[:path]
@@ -81,7 +81,7 @@ Puppet::Face.define(:module, '1.0.0') do
81
81
 
82
82
  highlight = proc do |s|
83
83
  s = s.gsub(term, colorize(:green, term))
84
- s = s.gsub(term.gsub('/', '-'), colorize(:green, term.gsub('/', '-'))) if term =~ /\//
84
+ s = s.gsub(term.tr('/', '-'), colorize(:green, term.tr('/', '-'))) if term =~ /\//
85
85
  s = s.gsub(' DEPRECATED', colorize(:red, ' DEPRECATED'))
86
86
  s
87
87
  end
@@ -57,7 +57,7 @@ Puppet::Face.define(:module, '1.0.0') do
57
57
  end
58
58
 
59
59
  when_invoked do |name, options|
60
- name = name.gsub('/', '-')
60
+ name = name.tr('/', '-')
61
61
 
62
62
  Puppet::ModuleTool.set_option_defaults options
63
63
  message = if options[:version]
@@ -63,7 +63,7 @@ Puppet::Face.define(:module, '1.0.0') do
63
63
  end
64
64
 
65
65
  when_invoked do |name, options|
66
- name = name.gsub('/', '-')
66
+ name = name.tr('/', '-')
67
67
  Puppet.notice _("Preparing to upgrade '%{name}' ...") % { name: name }
68
68
  Puppet::ModuleTool.set_option_defaults options
69
69
  Puppet::ModuleTool::Applications::Upgrader.new(name, options).run
@@ -42,7 +42,7 @@ class Puppet::FileServing::HttpMetadata < Puppet::FileServing::Metadata
42
42
  [ @checksum_type, :md5, :sha256, :sha384, :sha512, :sha224, :mtime ].each do |type|
43
43
  @checksum_type = type
44
44
  @checksum = @checksums[type]
45
- return if @checksum
45
+ break if @checksum
46
46
  end
47
47
  end
48
48
  end
@@ -92,14 +92,6 @@ module Puppet::FileSystem
92
92
  @impl.path_string(@impl.basename(assert_path(path)))
93
93
  end
94
94
 
95
- # @return [Integer] the size of the file
96
- #
97
- # @api public
98
- #
99
- def self.size(path)
100
- @impl.size(assert_path(path))
101
- end
102
-
103
95
  # Allows exclusive updates to a file to be made by excluding concurrent
104
96
  # access using flock. This means that if the file is on a filesystem that
105
97
  # does not support flock, this method will provide no protection.
@@ -61,6 +61,6 @@ class Puppet::FileSystem::MemoryFile
61
61
  end
62
62
 
63
63
  def inspect
64
- "<Puppet::FileSystem::MemoryFile:#{to_s}>"
64
+ "<Puppet::FileSystem::MemoryFile:#{self}>"
65
65
  end
66
66
  end
@@ -14,11 +14,12 @@ class Puppet::FileSystem::Posix < Puppet::FileSystem::FileImpl
14
14
  bsize = stream_blksize(this, stream)
15
15
  sa = "".force_encoding('ASCII-8BIT')
16
16
  sb = "".force_encoding('ASCII-8BIT')
17
- begin
17
+ loop do
18
18
  this.read(bsize, sa)
19
19
  stream.read(bsize, sb)
20
20
  return true if sa.empty? && sb.empty?
21
- end while sa == sb
21
+ break if sa != sb
22
+ end
22
23
  false
23
24
  end
24
25
  end
@@ -58,7 +58,7 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source
58
58
  matches = []
59
59
  uri = "/v3/modules?query=#{term}"
60
60
  if Puppet[:module_groups]
61
- uri += "&module_groups=#{Puppet[:module_groups].gsub('+', ' ')}"
61
+ uri += "&module_groups=#{Puppet[:module_groups].tr('+', ' ')}"
62
62
  end
63
63
 
64
64
  while uri
@@ -94,7 +94,7 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source
94
94
  name = input.tr('/', '-')
95
95
  uri = "/v3/releases?module=#{name}&sort_by=version&exclude_fields=#{MODULE_RELEASE_EXCLUSIONS}"
96
96
  if Puppet[:module_groups]
97
- uri += "&module_groups=#{Puppet[:module_groups].gsub('+', ' ')}"
97
+ uri += "&module_groups=#{Puppet[:module_groups].tr('+', ' ')}"
98
98
  end
99
99
  releases = []
100
100
 
@@ -254,6 +254,6 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source
254
254
  def decode_uri(uri)
255
255
  return if uri.nil?
256
256
 
257
- URI.decode(uri.gsub('+', ' '))
257
+ URI.decode(uri.tr('+', ' '))
258
258
  end
259
259
  end