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
@@ -624,8 +624,7 @@ module Puppet::Functions
624
624
  # Get location to use in case of error - this produces ruby filename and where call to 'type' occurred
625
625
  # but strips off the rest of the internal "where" as it is not meaningful to user.
626
626
  #
627
- rb_location = caller[0]
628
-
627
+ rb_location = caller(1, 1).first
629
628
  begin
630
629
  result = parser.parse_string("type #{assignment_string}", nil)
631
630
  rescue StandardError => e
@@ -11,7 +11,7 @@ module Puppet::ModuleTranslations
11
11
  modules.each do |mod|
12
12
  next unless mod.forge_name && mod.has_translations?(Puppet::GettextConfig.current_locale)
13
13
 
14
- module_name = mod.forge_name.gsub('/', '-')
14
+ module_name = mod.forge_name.tr('/', '-')
15
15
  if Puppet::GettextConfig.load_translations(module_name, mod.locale_directory, :po)
16
16
  Puppet.debug "Loaded translations for #{module_name}."
17
17
  elsif Puppet::GettextConfig.gettext_loaded?
@@ -213,8 +213,8 @@ class Puppet::Graph::RbTreeMap
213
213
  :color => @color,
214
214
  }
215
215
  }
216
- h.merge!(:left => left.to_hash) if @left
217
- h.merge!(:right => right.to_hash) if @right
216
+ h[:left] = left.to_hash if @left
217
+ h[:right] = right.to_hash if @right
218
218
  h
219
219
  end
220
220
 
@@ -133,11 +133,12 @@ class Puppet::Graph::SimpleGraph
133
133
  else
134
134
  if s[:lowlink][vertex] == s[:index][vertex] then
135
135
  this_scc = []
136
- begin
136
+ loop do
137
137
  top = s[:stack].pop
138
138
  s[:seen][top] = false
139
139
  this_scc << top
140
- end until top == vertex
140
+ break if top == vertex
141
+ end
141
142
  s[:scc] << this_scc
142
143
  end
143
144
  recur.pop # done with this node, finally.
@@ -438,7 +439,7 @@ class Puppet::Graph::SimpleGraph
438
439
  # rdot.rb. If an edge or vertex label is a kind of Hash then the keys
439
440
  # which match +dot+ properties will be used as well.
440
441
  def to_dot_graph(params = {})
441
- params['name'] ||= self.class.name.gsub(/:/,'_')
442
+ params['name'] ||= self.class.name.tr(':','_')
442
443
  fontsize = params['fontsize'] ? params['fontsize'] : '8'
443
444
  graph = (directed? ? DOT::DOTDigraph : DOT::DOTSubgraph).new(params)
444
445
  edge_klass = directed? ? DOT::DOTDirectedEdge : DOT::DOTEdge
@@ -0,0 +1,29 @@
1
+ module Puppet
2
+ module Network
3
+ module HTTP
4
+ require 'puppet/network/http/site'
5
+ require 'puppet/network/http/session'
6
+ require 'puppet/network/http/factory'
7
+ require 'puppet/network/http/base_pool'
8
+ require 'puppet/network/http/nocache_pool'
9
+ require 'puppet/network/http/pool'
10
+ require 'puppet/network/resolver'
11
+ end
12
+ end
13
+
14
+ module HTTP
15
+ ACCEPT_ENCODING = "gzip;q=1.0,deflate;q=0.6,identity;q=0.3".freeze
16
+
17
+ require 'puppet/http/errors'
18
+ require 'puppet/http/response'
19
+ require 'puppet/http/service'
20
+ require 'puppet/http/service/ca'
21
+ require 'puppet/http/session'
22
+ require 'puppet/http/resolver'
23
+ require 'puppet/http/resolver/settings'
24
+ require 'puppet/http/resolver/srv'
25
+ require 'puppet/http/client'
26
+ require 'puppet/http/redirector'
27
+ require 'puppet/http/retry_after_handler'
28
+ end
29
+ end
@@ -0,0 +1,156 @@
1
+ class Puppet::HTTP::Client
2
+ def initialize(pool: Puppet::Network::HTTP::Pool.new, ssl_context: nil, redirect_limit: 10, retry_limit: 100)
3
+ @pool = pool
4
+ @default_headers = {
5
+ 'X-Puppet-Version' => Puppet.version,
6
+ 'User-Agent' => Puppet[:http_user_agent],
7
+ }.freeze
8
+ @default_ssl_context = ssl_context
9
+ @redirector = Puppet::HTTP::Redirector.new(redirect_limit)
10
+ @retry_after_handler = Puppet::HTTP::RetryAfterHandler.new(retry_limit, Puppet[:runinterval])
11
+ @resolvers = build_resolvers
12
+ end
13
+
14
+ def create_session
15
+ Puppet::HTTP::Session.new(self, @resolvers)
16
+ end
17
+
18
+ def connect(uri, ssl_context: nil, &block)
19
+ ctx = ssl_context ? ssl_context : default_ssl_context
20
+ site = Puppet::Network::HTTP::Site.from_uri(uri)
21
+ verifier = Puppet::SSL::Verifier.new(site.host, ctx)
22
+
23
+ @pool.with_connection(site, verifier) do |http|
24
+ if block_given?
25
+ handle_post_connect(uri, http, &block)
26
+ end
27
+ end
28
+ rescue Puppet::HTTP::HTTPError
29
+ raise
30
+ rescue => e
31
+ raise Puppet::HTTP::ConnectionError.new(_("Failed to connect to %{uri}: %{message}") % {uri: uri, message: e.message}, e)
32
+ end
33
+
34
+ def get(url, headers: {}, params: {}, ssl_context: nil, user: nil, password: nil, &block)
35
+ query = encode_params(params)
36
+ unless query.empty?
37
+ url = url.dup
38
+ url.query = query
39
+ end
40
+
41
+ request = Net::HTTP::Get.new(url, @default_headers.merge(headers))
42
+
43
+ execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
44
+ if block_given?
45
+ yield response
46
+ else
47
+ response.read_body
48
+ end
49
+ end
50
+ end
51
+
52
+ def put(url, headers: {}, params: {}, content_type:, body:, ssl_context: nil, user: nil, password: nil)
53
+ query = encode_params(params)
54
+ unless query.empty?
55
+ url = url.dup
56
+ url.query = query
57
+ end
58
+
59
+ request = Net::HTTP::Put.new(url, @default_headers.merge(headers))
60
+ request.body = body
61
+ request['Content-Length'] = body.bytesize
62
+ request['Content-Type'] = content_type
63
+
64
+ execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
65
+ response.read_body
66
+ end
67
+ end
68
+
69
+ def close
70
+ @pool.close
71
+ end
72
+
73
+ private
74
+
75
+ def execute_streaming(request, ssl_context:, user: nil, password: nil, &block)
76
+ redirects = 0
77
+ retries = 0
78
+
79
+ loop do
80
+ connect(request.uri, ssl_context: ssl_context) do |http|
81
+ apply_auth(request, user, password)
82
+
83
+ http.request(request) do |nethttp|
84
+ response = Puppet::HTTP::Response.new(nethttp)
85
+ begin
86
+ Puppet.debug("HTTP #{request.method.upcase} #{request.uri} returned #{response.code} #{response.reason}")
87
+
88
+ if @redirector.redirect?(request, response)
89
+ request = @redirector.redirect_to(request, response, redirects)
90
+ redirects += 1
91
+ next
92
+ elsif @retry_after_handler.retry_after?(request, response)
93
+ interval = @retry_after_handler.retry_after_interval(request, response, retries)
94
+ retries += 1
95
+ if interval
96
+ Puppet.warning(_("Sleeping for %{interval} seconds before retrying the request") % { interval: interval })
97
+ ::Kernel.sleep(interval)
98
+ next
99
+ end
100
+ end
101
+
102
+ yield response
103
+ ensure
104
+ response.drain
105
+ end
106
+
107
+ return response
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ def encode_params(params)
114
+ params.map do |key, value|
115
+ "#{key}=#{Puppet::Util.uri_query_encode(value.to_s)}"
116
+ end.join('&')
117
+ end
118
+
119
+ def handle_post_connect(uri, http, &block)
120
+ start = Time.now
121
+ yield http
122
+ rescue Puppet::HTTP::HTTPError
123
+ raise
124
+ rescue EOFError => e
125
+ raise Puppet::HTTP::HTTPError.new(_("Request to %{uri} interrupted after %{elapsed} seconds") % {uri: uri, elapsed: elapsed(start)}, e)
126
+ rescue Timeout::Error => e
127
+ raise Puppet::HTTP::HTTPError.new(_("Request to %{uri} timed out after %{elapsed} seconds") % {uri: uri, elapsed: elapsed(start)}, e)
128
+ rescue => e
129
+ raise Puppet::HTTP::HTTPError.new(_("Request to %{uri} failed after %{elapsed} seconds: %{message}") % {uri: uri, elapsed: elapsed(start), message: e.message}, e)
130
+ end
131
+
132
+ def elapsed(start)
133
+ (Time.now - start).to_f.round(3)
134
+ end
135
+
136
+ def default_ssl_context
137
+ @default_ssl_context || Puppet.lookup(:ssl_context)
138
+ end
139
+
140
+ def apply_auth(request, user, password)
141
+ if user && password
142
+ request.basic_auth(user, password)
143
+ end
144
+ end
145
+
146
+ def build_resolvers
147
+ resolvers = []
148
+
149
+ if Puppet[:use_srv_records]
150
+ resolvers << Puppet::HTTP::Resolver::SRV.new(domain: Puppet[:srv_domain])
151
+ end
152
+
153
+ resolvers << Puppet::HTTP::Resolver::Settings.new
154
+ resolvers.freeze
155
+ end
156
+ end
@@ -0,0 +1,30 @@
1
+ module Puppet::HTTP
2
+ class HTTPError < Puppet::Error; end
3
+
4
+ class ConnectionError < HTTPError; end
5
+
6
+ class RouteError < HTTPError; end
7
+
8
+ class ProtocolError < HTTPError; end
9
+
10
+ class ResponseError < HTTPError
11
+ attr_reader :response
12
+
13
+ def initialize(response)
14
+ super(response.reason)
15
+ @response = response
16
+ end
17
+ end
18
+
19
+ class TooManyRedirects < HTTPError
20
+ def initialize(addr)
21
+ super(_("Too many HTTP redirections for %{addr}") % { addr: addr})
22
+ end
23
+ end
24
+
25
+ class TooManyRetryAfters < HTTPError
26
+ def initialize(addr)
27
+ super(_("Too many HTTP retries for %{addr}") % { addr: addr})
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,48 @@
1
+ class Puppet::HTTP::Redirector
2
+ def initialize(redirect_limit)
3
+ @redirect_limit = redirect_limit
4
+ end
5
+
6
+ def redirect?(request, response)
7
+ # Net::HTTPRedirection is not used because historically puppet
8
+ # has only handled these, and we're not a browser
9
+ case response.code
10
+ when 301, 302, 307
11
+ true
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ def redirect_to(request, response, redirects)
18
+ raise Puppet::HTTP::TooManyRedirects.new(request.uri) if redirects >= @redirect_limit
19
+
20
+ location = parse_location(response)
21
+ if location.relative?
22
+ url = request.uri.dup
23
+ url.path = location.path
24
+ else
25
+ url = location.dup
26
+ end
27
+ url.query = request.uri.query
28
+
29
+ new_request = request.class.new(url)
30
+ new_request.body = request.body
31
+ request.each do |header, value|
32
+ new_request[header] = value
33
+ end
34
+
35
+ new_request
36
+ end
37
+
38
+ private
39
+
40
+ def parse_location(response)
41
+ location = response['location']
42
+ raise Puppet::HTTP::ProtocolError.new(_("Location response header is missing")) unless location
43
+
44
+ URI.parse(location)
45
+ rescue URI::InvalidURIError => e
46
+ raise Puppet::HTTP::ProtocolError.new(_("Location URI is invalid: %{detail}") % { detail: e.message}, e)
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ class Puppet::HTTP::Resolver
2
+ def resolve(session, name, &block)
3
+ raise NotImplementedError
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Puppet::HTTP::Resolver::Settings < Puppet::HTTP::Resolver
2
+ def resolve(session, name, &block)
3
+ yield session.create_service(name)
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ class Puppet::HTTP::Resolver::SRV < Puppet::HTTP::Resolver
2
+ def initialize(domain: srv_domain, dns: Resolv::DNS.new)
3
+ @srv_domain = domain
4
+ @delegate = Puppet::Network::Resolver.new(dns)
5
+ end
6
+
7
+ def resolve(session, name, &block)
8
+ # This assumes the route name is the same as the DNS SRV name
9
+ @delegate.each_srv_record(@srv_domain, name) do |server, port|
10
+ yield session.create_service(name, server, port)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ class Puppet::HTTP::Response
2
+ def initialize(nethttp)
3
+ @nethttp = nethttp
4
+ end
5
+
6
+ def code
7
+ @nethttp.code.to_i
8
+ end
9
+
10
+ def reason
11
+ @nethttp.message
12
+ end
13
+
14
+ def body
15
+ @nethttp.body
16
+ end
17
+
18
+ def read_body(&block)
19
+ @nethttp.read_body(&block)
20
+ end
21
+
22
+ def success?
23
+ @nethttp.is_a?(Net::HTTPSuccess)
24
+ end
25
+
26
+ def [](name)
27
+ @nethttp[name]
28
+ end
29
+
30
+ def drain
31
+ body
32
+ true
33
+ end
34
+ end
@@ -0,0 +1,47 @@
1
+ require 'date'
2
+ require 'time'
3
+
4
+ class Puppet::HTTP::RetryAfterHandler
5
+ def initialize(retry_limit, max_sleep)
6
+ @retry_limit = retry_limit
7
+ @max_sleep = max_sleep
8
+ end
9
+
10
+ def retry_after?(request, response)
11
+ case response.code
12
+ when 429, 503
13
+ true
14
+ else
15
+ false
16
+ end
17
+ end
18
+
19
+ def retry_after_interval(request, response, retries)
20
+ raise Puppet::HTTP::TooManyRetryAfters.new(request.uri) if retries >= @retry_limit
21
+
22
+ retry_after = response['Retry-After']
23
+ return nil unless retry_after
24
+
25
+ seconds = parse_retry_after(retry_after)
26
+
27
+ # if retry-after is far in the future, we could end up sleeping repeatedly
28
+ # for 30 minutes, effectively waiting indefinitely, seems like we should wait
29
+ # in total for 30 minutes, in which case this upper limit needs to be enforced
30
+ # by the client.
31
+ [seconds, @max_sleep].min
32
+ end
33
+
34
+ private
35
+
36
+ def parse_retry_after(retry_after)
37
+ Integer(retry_after)
38
+ rescue TypeError, ArgumentError
39
+ begin
40
+ tm = DateTime.rfc2822(retry_after)
41
+ seconds = (tm.to_time - DateTime.now.to_time).to_i
42
+ [seconds, 0].max
43
+ rescue ArgumentError
44
+ raise Puppet::HTTP::ProtocolError.new(_("Failed to parse Retry-After header '%{retry_after}' as an integer or RFC 2822 date") % { retry_after: retry_after })
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,18 @@
1
+ class Puppet::HTTP::Service
2
+ attr_reader :url
3
+
4
+ def initialize(client, url)
5
+ @client = client
6
+ @url = url
7
+ end
8
+
9
+ def with_base_url(path)
10
+ u = @url.dup
11
+ u.path += path
12
+ u
13
+ end
14
+
15
+ def connect(ssl_context: nil)
16
+ @client.connect(@url, ssl_context: ssl_context)
17
+ end
18
+ end