puppet 6.13.0 → 6.14.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +7 -13
  3. data/Gemfile.lock +6 -6
  4. data/README.md +15 -22
  5. data/lib/puppet.rb +1 -1
  6. data/lib/puppet/application/agent.rb +9 -11
  7. data/lib/puppet/application/describe.rb +7 -5
  8. data/lib/puppet/application/device.rb +2 -2
  9. data/lib/puppet/application/filebucket.rb +14 -1
  10. data/lib/puppet/application/ssl.rb +1 -1
  11. data/lib/puppet/configurer.rb +30 -41
  12. data/lib/puppet/configurer/plugin_handler.rb +10 -1
  13. data/lib/puppet/defaults.rb +7 -1
  14. data/lib/puppet/face/plugin.rb +1 -1
  15. data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
  16. data/lib/puppet/http.rb +1 -0
  17. data/lib/puppet/http/client.rb +69 -34
  18. data/lib/puppet/http/resolver/server_list.rb +2 -2
  19. data/lib/puppet/http/resolver/settings.rb +1 -1
  20. data/lib/puppet/http/resolver/srv.rb +1 -1
  21. data/lib/puppet/http/response.rb +6 -1
  22. data/lib/puppet/http/service.rb +30 -11
  23. data/lib/puppet/http/service/ca.rb +8 -8
  24. data/lib/puppet/http/service/compiler.rb +41 -10
  25. data/lib/puppet/http/service/file_server.rb +40 -20
  26. data/lib/puppet/http/service/report.rb +12 -15
  27. data/lib/puppet/http/session.rb +39 -1
  28. data/lib/puppet/indirector/catalog/rest.rb +33 -0
  29. data/lib/puppet/indirector/facts/rest.rb +41 -0
  30. data/lib/puppet/indirector/file_content/rest.rb +30 -0
  31. data/lib/puppet/indirector/file_metadata/rest.rb +50 -0
  32. data/lib/puppet/indirector/node/rest.rb +23 -0
  33. data/lib/puppet/indirector/report/rest.rb +19 -0
  34. data/lib/puppet/indirector/rest.rb +6 -0
  35. data/lib/puppet/indirector/status/rest.rb +17 -0
  36. data/lib/puppet/loaders.rb +6 -0
  37. data/lib/puppet/network/http/base_pool.rb +1 -1
  38. data/lib/puppet/network/http/pool.rb +6 -1
  39. data/lib/puppet/provider/group/groupadd.rb +9 -4
  40. data/lib/puppet/runtime.rb +8 -1
  41. data/lib/puppet/settings.rb +2 -0
  42. data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
  43. data/lib/puppet/ssl/state_machine.rb +4 -0
  44. data/lib/puppet/test/test_helper.rb +3 -1
  45. data/lib/puppet/type/file.rb +13 -0
  46. data/lib/puppet/type/file/source.rb +47 -58
  47. data/lib/puppet/version.rb +1 -1
  48. data/locales/puppet.pot +167 -160
  49. data/man/man5/puppet.conf.5 +11 -3
  50. data/man/man8/puppet-agent.8 +6 -6
  51. data/man/man8/puppet-apply.8 +1 -1
  52. data/man/man8/puppet-catalog.8 +1 -1
  53. data/man/man8/puppet-config.8 +1 -1
  54. data/man/man8/puppet-describe.8 +1 -1
  55. data/man/man8/puppet-device.8 +2 -2
  56. data/man/man8/puppet-doc.8 +1 -1
  57. data/man/man8/puppet-epp.8 +1 -1
  58. data/man/man8/puppet-facts.8 +1 -1
  59. data/man/man8/puppet-filebucket.8 +17 -2
  60. data/man/man8/puppet-generate.8 +1 -1
  61. data/man/man8/puppet-help.8 +1 -1
  62. data/man/man8/puppet-key.8 +1 -1
  63. data/man/man8/puppet-lookup.8 +1 -1
  64. data/man/man8/puppet-man.8 +1 -1
  65. data/man/man8/puppet-module.8 +1 -1
  66. data/man/man8/puppet-node.8 +1 -1
  67. data/man/man8/puppet-parser.8 +1 -1
  68. data/man/man8/puppet-plugin.8 +1 -1
  69. data/man/man8/puppet-report.8 +1 -1
  70. data/man/man8/puppet-resource.8 +1 -1
  71. data/man/man8/puppet-script.8 +1 -1
  72. data/man/man8/puppet-ssl.8 +2 -2
  73. data/man/man8/puppet-status.8 +1 -1
  74. data/man/man8/puppet.8 +2 -2
  75. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +1 -67
  76. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +1 -69
  77. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -69
  78. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +1 -67
  79. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -65
  80. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +1 -67
  81. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +1 -67
  82. data/spec/integration/faces/plugin_spec.rb +3 -1
  83. data/spec/integration/http/client_spec.rb +11 -0
  84. data/spec/integration/network/http_pool_spec.rb +9 -1
  85. data/spec/unit/application/describe_spec.rb +88 -50
  86. data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
  87. data/spec/unit/configurer_spec.rb +16 -14
  88. data/spec/unit/face/plugin_spec.rb +12 -10
  89. data/spec/unit/functions/lookup_spec.rb +13 -0
  90. data/spec/unit/http/client_spec.rb +172 -1
  91. data/spec/unit/http/resolver_spec.rb +14 -2
  92. data/spec/unit/http/response_spec.rb +69 -0
  93. data/spec/unit/http/service/ca_spec.rb +28 -9
  94. data/spec/unit/http/service/compiler_spec.rb +151 -24
  95. data/spec/unit/http/service/file_server_spec.rb +65 -8
  96. data/spec/unit/http/service/report_spec.rb +17 -8
  97. data/spec/unit/http/service_spec.rb +92 -3
  98. data/spec/unit/http/session_spec.rb +104 -1
  99. data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
  100. data/spec/unit/indirector/facts/rest_spec.rb +79 -24
  101. data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
  102. data/spec/unit/indirector/file_metadata/rest_spec.rb +109 -2
  103. data/spec/unit/indirector/node/rest_spec.rb +57 -2
  104. data/spec/unit/indirector/report/rest_spec.rb +58 -51
  105. data/spec/unit/indirector/resource/ral_spec.rb +7 -8
  106. data/spec/unit/indirector/status/rest_spec.rb +43 -2
  107. data/spec/unit/network/http/pool_spec.rb +57 -11
  108. data/spec/unit/provider/group/groupadd_spec.rb +22 -8
  109. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  110. data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
  111. data/spec/unit/ssl/state_machine_spec.rb +10 -0
  112. data/spec/unit/transaction_spec.rb +0 -2
  113. data/spec/unit/type/file/ensure_spec.rb +1 -2
  114. data/spec/unit/type/file/source_spec.rb +86 -35
  115. data/spec/unit/util/at_fork_spec.rb +1 -0
  116. data/spec/unit/util/pidlock_spec.rb +36 -24
  117. metadata +7 -3
  118. data/COMMITTERS.md +0 -244
@@ -29,8 +29,17 @@ class Puppet::Configurer::PluginHandler
29
29
  result += plugin_fact_downloader.evaluate
30
30
  result += plugin_downloader.evaluate
31
31
 
32
+ # until file metadata/content are using the rest client, we need to check
33
+ # both :server_agent_version and the session to see if the server supports
34
+ # the "locales" mount
32
35
  server_agent_version = Puppet.lookup(:server_agent_version) { "0.0" }
33
- if Gem::Version.new(server_agent_version) >= SUPPORTED_LOCALES_MOUNT_AGENT_VERSION
36
+ locales = Gem::Version.new(server_agent_version) >= SUPPORTED_LOCALES_MOUNT_AGENT_VERSION
37
+ unless locales
38
+ session = Puppet.lookup(:http_session)
39
+ locales = session.supports?(:puppet, 'locales')
40
+ end
41
+
42
+ if locales
34
43
  locales_downloader = Puppet::Configurer::Downloader.new(
35
44
  "locales",
36
45
  Puppet[:localedest],
@@ -1167,7 +1167,7 @@ EOT
1167
1167
  the request.
1168
1168
 
1169
1169
  For info on autosign configuration files, see
1170
- [the guide to Puppet's config files](https://puppet.com/docs/puppet/latest/config_about_settings.html).",
1170
+ [the guide to Puppet's config files](https://puppet.com/docs/puppet/latest/config_file_autosign.html).",
1171
1171
  },
1172
1172
  :allow_duplicate_certs => {
1173
1173
  :default => false,
@@ -1633,6 +1633,12 @@ EOT
1633
1633
  :default => lambda { Puppet::Settings.domain_fact },
1634
1634
  :desc => "The domain which will be queried to find the SRV records of servers to use.",
1635
1635
  },
1636
+ :http_extra_headers => {
1637
+ :default => [],
1638
+ :type => :http_extra_headers,
1639
+ :desc => "The list of extra headers that will be sent with http requests to the master.
1640
+ The header definition consists of a name and a value separated by a colon."
1641
+ },
1636
1642
  :ignoreschedules => {
1637
1643
  :default => false,
1638
1644
  :type => :boolean,
@@ -41,7 +41,7 @@ Puppet::Face.define(:plugin, '0.0.1') do
41
41
  when_invoked do |options|
42
42
  remote_environment_for_plugins = Puppet::Node::Environment.remote(Puppet[:environment])
43
43
 
44
- pool = Puppet::Network::HTTP::Pool.new(Puppet[:http_keepalive_timeout])
44
+ pool = Puppet.runtime['http'].pool
45
45
  Puppet.override(:http_pool => pool) do
46
46
  begin
47
47
  handler = Puppet::Configurer::PluginHandler.new()
@@ -39,7 +39,7 @@ Puppet::Functions.create_function(:eyaml_lookup_key) do
39
39
  context.cache(nil, raw_data)
40
40
  end
41
41
  context.not_found unless raw_data.include?(key)
42
- context.cache(key, decrypt_value(raw_data[key], context, options))
42
+ context.cache(key, decrypt_value(raw_data[key], context, options, key))
43
43
  end
44
44
 
45
45
  def load_data_hash(options, context)
@@ -62,22 +62,22 @@ Puppet::Functions.create_function(:eyaml_lookup_key) do
62
62
  end
63
63
  end
64
64
 
65
- def decrypt_value(value, context, options)
65
+ def decrypt_value(value, context, options, key)
66
66
  case value
67
67
  when String
68
- decrypt(value, context, options)
68
+ decrypt(value, context, options, key)
69
69
  when Hash
70
70
  result = {}
71
- value.each_pair { |k, v| result[context.interpolate(k)] = decrypt_value(v, context, options) }
71
+ value.each_pair { |k, v| result[context.interpolate(k)] = decrypt_value(v, context, options, key) }
72
72
  result
73
73
  when Array
74
- value.map { |v| decrypt_value(v, context, options) }
74
+ value.map { |v| decrypt_value(v, context, options, key) }
75
75
  else
76
76
  value
77
77
  end
78
78
  end
79
79
 
80
- def decrypt(data, context, options)
80
+ def decrypt(data, context, options, key)
81
81
  if encrypted?(data)
82
82
  # Options must be set prior to each call to #parse since they end up as static variables in
83
83
  # the Options class. They cannot be set once before #decrypt_value is called, since each #decrypt
@@ -85,8 +85,13 @@ Puppet::Functions.create_function(:eyaml_lookup_key) do
85
85
  # config.
86
86
  #
87
87
  Hiera::Backend::Eyaml::Options.set(options)
88
- tokens = Hiera::Backend::Eyaml::Parser::ParserFactory.hiera_backend_parser.parse(data)
89
- data = tokens.map(&:to_plain_text).join.chomp
88
+ begin
89
+ tokens = Hiera::Backend::Eyaml::Parser::ParserFactory.hiera_backend_parser.parse(data)
90
+ data = tokens.map(&:to_plain_text).join.chomp
91
+ rescue StandardError => ex
92
+ raise Puppet::DataBinding::LookupError,
93
+ _("hiera-eyaml backend error decrypting %{data} when looking up %{key} in %{path}. Error was %{message}") % { data: data, key: key, path: options['path'], message: ex.message }
94
+ end
90
95
  end
91
96
  context.interpolate(data)
92
97
  end
@@ -13,6 +13,7 @@ module Puppet
13
13
 
14
14
  module HTTP
15
15
  ACCEPT_ENCODING = "gzip;q=1.0,deflate;q=0.6,identity;q=0.3".freeze
16
+ HEADER_PUPPET_VERSION = "X-Puppet-Version".freeze
16
17
 
17
18
  require 'puppet/http/errors'
18
19
  require 'puppet/http/response'
@@ -1,11 +1,14 @@
1
1
  class Puppet::HTTP::Client
2
- def initialize(pool: Puppet::Network::HTTP::Pool.new, ssl_context: nil, redirect_limit: 10, retry_limit: 100)
2
+ attr_reader :pool
3
+
4
+ def initialize(pool: Puppet::Network::HTTP::Pool.new, ssl_context: nil, system_ssl_context: nil, redirect_limit: 10, retry_limit: 100)
3
5
  @pool = pool
4
6
  @default_headers = {
5
7
  'X-Puppet-Version' => Puppet.version,
6
8
  'User-Agent' => Puppet[:http_user_agent],
7
9
  }.freeze
8
10
  @default_ssl_context = ssl_context
11
+ @default_system_ssl_context = system_ssl_context
9
12
  @redirector = Puppet::HTTP::Redirector.new(redirect_limit)
10
13
  @retry_after_handler = Puppet::HTTP::RetryAfterHandler.new(retry_limit, Puppet[:runinterval])
11
14
  @resolvers = build_resolvers
@@ -15,11 +18,15 @@ class Puppet::HTTP::Client
15
18
  Puppet::HTTP::Session.new(self, @resolvers)
16
19
  end
17
20
 
18
- def connect(uri, ssl_context: nil, &block)
21
+ def connect(uri, ssl_context: nil, include_system_store: false, &block)
19
22
  start = Time.now
20
- ctx = ssl_context ? ssl_context : default_ssl_context
23
+ ctx = resolve_ssl_context(ssl_context, include_system_store)
21
24
  site = Puppet::Network::HTTP::Site.from_uri(uri)
22
- verifier = Puppet::SSL::Verifier.new(site.host, ctx)
25
+ verifier = if site.use_ssl?
26
+ Puppet::SSL::Verifier.new(site.host, ctx)
27
+ else
28
+ nil
29
+ end
23
30
  connected = false
24
31
 
25
32
  @pool.with_connection(site, verifier) do |http|
@@ -43,7 +50,7 @@ class Puppet::HTTP::Client
43
50
  {uri: uri, elapsed: elapsed(start), message: e.message}, e, connected)
44
51
  end
45
52
 
46
- def get(url, headers: {}, params: {}, ssl_context: nil, user: nil, password: nil, &block)
53
+ def get(url, headers: {}, params: {}, user: nil, password: nil, ssl_context: nil, include_system_store: false, &block)
47
54
  query = encode_params(params)
48
55
  unless query.empty?
49
56
  url = url.dup
@@ -52,16 +59,16 @@ class Puppet::HTTP::Client
52
59
 
53
60
  request = Net::HTTP::Get.new(url, @default_headers.merge(headers))
54
61
 
55
- execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
62
+ execute_streaming(request, user: user, password: password, ssl_context: ssl_context, include_system_store: include_system_store) do |response|
56
63
  if block_given?
57
64
  yield response
58
65
  else
59
- response.read_body
66
+ response.body
60
67
  end
61
68
  end
62
69
  end
63
70
 
64
- def head(url, headers: {}, params: {}, ssl_context: nil, user: nil, password: nil)
71
+ def head(url, headers: {}, params: {}, user: nil, password: nil, ssl_context: nil, include_system_store: false)
65
72
  query = encode_params(params)
66
73
  unless query.empty?
67
74
  url = url.dup
@@ -70,12 +77,12 @@ class Puppet::HTTP::Client
70
77
 
71
78
  request = Net::HTTP::Head.new(url, @default_headers.merge(headers))
72
79
 
73
- execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
74
- response.read_body
80
+ execute_streaming(request, user: user, password: password, ssl_context: ssl_context, include_system_store: include_system_store) do |response|
81
+ response.body
75
82
  end
76
83
  end
77
84
 
78
- def put(url, headers: {}, params: {}, content_type:, body:, ssl_context: nil, user: nil, password: nil)
85
+ def put(url, headers: {}, params: {}, content_type:, body:, user: nil, password: nil, ssl_context: nil, include_system_store: false)
79
86
  query = encode_params(params)
80
87
  unless query.empty?
81
88
  url = url.dup
@@ -87,12 +94,12 @@ class Puppet::HTTP::Client
87
94
  request['Content-Length'] = body.bytesize
88
95
  request['Content-Type'] = content_type
89
96
 
90
- execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
91
- response.read_body
97
+ execute_streaming(request, user: user, password: password, ssl_context: ssl_context, include_system_store: include_system_store) do |response|
98
+ response.body
92
99
  end
93
100
  end
94
101
 
95
- def post(url, headers: {}, params: {}, content_type:, body:, ssl_context: nil, user: nil, password: nil, &block)
102
+ def post(url, headers: {}, params: {}, content_type:, body:, user: nil, password: nil, ssl_context: nil, include_system_store: false, &block)
96
103
  query = encode_params(params)
97
104
  unless query.empty?
98
105
  url = url.dup
@@ -104,16 +111,16 @@ class Puppet::HTTP::Client
104
111
  request['Content-Length'] = body.bytesize
105
112
  request['Content-Type'] = content_type
106
113
 
107
- execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
114
+ execute_streaming(request, user: user, password: password, ssl_context: ssl_context, include_system_store: include_system_store) do |response|
108
115
  if block_given?
109
116
  yield response
110
117
  else
111
- response.read_body
118
+ response.body
112
119
  end
113
120
  end
114
121
  end
115
122
 
116
- def delete(url, headers: {}, params: {}, ssl_context: nil, user: nil, password: nil)
123
+ def delete(url, headers: {}, params: {}, user: nil, password: nil, ssl_context: nil, include_system_store: false)
117
124
  query = encode_params(params)
118
125
  unless query.empty?
119
126
  url = url.dup
@@ -122,8 +129,8 @@ class Puppet::HTTP::Client
122
129
 
123
130
  request = Net::HTTP::Delete.new(url, @default_headers.merge(headers))
124
131
 
125
- execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
126
- response.read_body
132
+ execute_streaming(request, user: user, password: password, ssl_context: ssl_context, include_system_store: include_system_store) do |response|
133
+ response.body
127
134
  end
128
135
  end
129
136
 
@@ -133,16 +140,19 @@ class Puppet::HTTP::Client
133
140
 
134
141
  private
135
142
 
136
- def execute_streaming(request, ssl_context:, user: nil, password: nil, &block)
143
+ def execute_streaming(request, user: nil, password: nil, ssl_context:, include_system_store:, &block)
137
144
  redirects = 0
138
145
  retries = 0
146
+ response = nil
147
+ done = false
139
148
 
140
- loop do
141
- connect(request.uri, ssl_context: ssl_context) do |http|
149
+ while !done do
150
+ connect(request.uri, ssl_context: ssl_context, include_system_store: include_system_store) do |http|
142
151
  apply_auth(request, user, password)
143
152
 
153
+ # don't call return within the `request` block
144
154
  http.request(request) do |nethttp|
145
- response = Puppet::HTTP::Response.new(nethttp)
155
+ response = Puppet::HTTP::Response.new(nethttp, request.uri)
146
156
  begin
147
157
  Puppet.debug("HTTP #{request.method.upcase} #{request.uri} returned #{response.code} #{response.reason}")
148
158
 
@@ -154,6 +164,10 @@ class Puppet::HTTP::Client
154
164
  interval = @retry_after_handler.retry_after_interval(request, response, retries)
155
165
  retries += 1
156
166
  if interval
167
+ if http.started?
168
+ Puppet.debug("Closing connection for #{Puppet::Network::HTTP::Site.from_uri(request.uri)}")
169
+ http.finish
170
+ end
157
171
  Puppet.warning(_("Sleeping for %{interval} seconds before retrying the request") % { interval: interval })
158
172
  ::Kernel.sleep(interval)
159
173
  next
@@ -165,10 +179,12 @@ class Puppet::HTTP::Client
165
179
  response.drain
166
180
  end
167
181
 
168
- return response
182
+ done = true
169
183
  end
170
184
  end
171
185
  end
186
+
187
+ response
172
188
  end
173
189
 
174
190
  def expand_into_parameters(data)
@@ -219,8 +235,25 @@ class Puppet::HTTP::Client
219
235
  end
220
236
  end
221
237
 
222
- def default_ssl_context
223
- @default_ssl_context || Puppet.lookup(:ssl_context)
238
+ def resolve_ssl_context(ssl_context, include_system_store)
239
+ if ssl_context
240
+ raise Puppet::HTTP::HTTPError, "The ssl_context and include_system_store parameters are mutually exclusive" if include_system_store
241
+ ssl_context
242
+ elsif include_system_store
243
+ system_ssl_context
244
+ else
245
+ @default_ssl_context || Puppet.lookup(:ssl_context)
246
+ end
247
+ end
248
+
249
+ def system_ssl_context
250
+ return @default_system_ssl_context if @default_system_ssl_context
251
+
252
+ cert_provider = Puppet::X509::CertProvider.new
253
+ cacerts = cert_provider.load_cacerts || []
254
+
255
+ ssl = Puppet::SSL::SSLProvider.new
256
+ @default_system_ssl_context = ssl.create_system_context(cacerts: cacerts)
224
257
  end
225
258
 
226
259
  def apply_auth(request, user, password)
@@ -238,14 +271,16 @@ class Puppet::HTTP::Client
238
271
 
239
272
  server_list_setting = Puppet.settings.setting(:server_list)
240
273
  if server_list_setting.value && !server_list_setting.value.empty?
241
- services = [:puppet]
242
-
243
- # If we have not explicitly set :ca_server either on the command line or
244
- # in puppet.conf, we want to be able to try the servers defined by
245
- # :server_list when resolving the :ca service. Otherwise, :server_list
246
- # should only be used with the :puppet service.
247
- if !Puppet.settings.set_by_config?(:ca_server)
248
- services << :ca
274
+ # use server list to resolve all services
275
+ services = Puppet::HTTP::Service::SERVICE_NAMES.dup
276
+
277
+ # except if it's been explicitly set
278
+ if Puppet.settings.set_by_config?(:ca_server)
279
+ services.delete(:ca)
280
+ end
281
+
282
+ if Puppet.settings.set_by_config?(:report_server)
283
+ services.delete(:report)
249
284
  end
250
285
 
251
286
  resolvers << Puppet::HTTP::Resolver::ServerList.new(self, server_list_setting: server_list_setting, default_port: Puppet[:masterport], services: services)
@@ -13,7 +13,7 @@ class Puppet::HTTP::Resolver::ServerList < Puppet::HTTP::Resolver
13
13
  port = server[1] || @default_port
14
14
  uri = URI("https://#{host}:#{port}/status/v1/simple/master")
15
15
  if get_success?(uri, session, ssl_context: ssl_context)
16
- return Puppet::HTTP::Service.create_service(@client, name, host, port)
16
+ return Puppet::HTTP::Service.create_service(@client, session, name, host, port)
17
17
  end
18
18
  end
19
19
  raise Puppet::Error, _("Could not select a functional puppet master from server_list: '%{server_list}'") % { server_list: @server_list_setting.print(@server_list_setting.value) }
@@ -27,7 +27,7 @@ class Puppet::HTTP::Resolver::ServerList < Puppet::HTTP::Resolver
27
27
  return true if response.success?
28
28
 
29
29
  Puppet.debug(_("Puppet server %{host}:%{port} is unavailable: %{code} %{reason}") %
30
- { host: host, port: port, code: response.code, reason: response.message })
30
+ { host: uri.host, port: uri.port, code: response.code, reason: response.reason })
31
31
  return false
32
32
  rescue => detail
33
33
  session.add_exception(detail)
@@ -1,6 +1,6 @@
1
1
  class Puppet::HTTP::Resolver::Settings < Puppet::HTTP::Resolver
2
2
  def resolve(session, name, ssl_context: nil)
3
- service = Puppet::HTTP::Service.create_service(@client, name)
3
+ service = Puppet::HTTP::Service.create_service(@client, session, name)
4
4
  check_connection?(session, service, ssl_context: ssl_context) ? service : nil
5
5
  end
6
6
  end
@@ -10,7 +10,7 @@ class Puppet::HTTP::Resolver::SRV < Puppet::HTTP::Resolver
10
10
  # This is fine for :ca, but note that :puppet and :file are handled
11
11
  # specially in `each_srv_record`.
12
12
  @delegate.each_srv_record(@srv_domain, name) do |server, port|
13
- service = Puppet::HTTP::Service.create_service(@client, name, server, port)
13
+ service = Puppet::HTTP::Service.create_service(@client, session, name, server, port)
14
14
  return service if check_connection?(session, service, ssl_context: ssl_context)
15
15
  end
16
16
 
@@ -1,6 +1,9 @@
1
1
  class Puppet::HTTP::Response
2
- def initialize(nethttp)
2
+ attr_reader :nethttp, :url
3
+
4
+ def initialize(nethttp, url)
3
5
  @nethttp = nethttp
6
+ @url = url
4
7
  end
5
8
 
6
9
  def code
@@ -16,6 +19,8 @@ class Puppet::HTTP::Response
16
19
  end
17
20
 
18
21
  def read_body(&block)
22
+ raise ArgumentError, "A block is required" unless block_given?
23
+
19
24
  @nethttp.read_body(&block)
20
25
  end
21
26
 
@@ -4,16 +4,16 @@ class Puppet::HTTP::Service
4
4
  SERVICE_NAMES = [:ca, :fileserver, :puppet, :report].freeze
5
5
  EXCLUDED_FORMATS = [:yaml, :b64_zlib_yaml, :dot].freeze
6
6
 
7
- def self.create_service(client, name, server = nil, port = nil)
7
+ def self.create_service(client, session, name, server = nil, port = nil)
8
8
  case name
9
9
  when :ca
10
- Puppet::HTTP::Service::Ca.new(client, server, port)
10
+ Puppet::HTTP::Service::Ca.new(client, session, server, port)
11
11
  when :fileserver
12
- Puppet::HTTP::Service::FileServer.new(client, server, port)
12
+ Puppet::HTTP::Service::FileServer.new(client, session, server, port)
13
13
  when :puppet
14
- ::Puppet::HTTP::Service::Compiler.new(client, server, port)
14
+ ::Puppet::HTTP::Service::Compiler.new(client, session, server, port)
15
15
  when :report
16
- Puppet::HTTP::Service::Report.new(client, server, port)
16
+ Puppet::HTTP::Service::Report.new(client, session, server, port)
17
17
  else
18
18
  raise ArgumentError, "Unknown service #{name}"
19
19
  end
@@ -23,8 +23,9 @@ class Puppet::HTTP::Service
23
23
  SERVICE_NAMES.include?(name)
24
24
  end
25
25
 
26
- def initialize(client, url)
26
+ def initialize(client, session, url)
27
27
  @client = client
28
+ @session = session
28
29
  @url = url
29
30
  end
30
31
 
@@ -42,7 +43,22 @@ class Puppet::HTTP::Service
42
43
 
43
44
  def add_puppet_headers(headers)
44
45
  modified_headers = headers.dup
46
+
47
+ # Add 'X-Puppet-Profiling' to enable performance profiling if turned on
45
48
  modified_headers['X-Puppet-Profiling'] = 'true' if Puppet[:profile]
49
+
50
+ # Add additional user-defined headers if they are defined
51
+ Puppet[:http_extra_headers].each do |name, value|
52
+ if modified_headers.keys.find { |key| key.casecmp(name) == 0 }
53
+ Puppet.warning(_('Ignoring extra header "%{name}" as it was previously set.') % { name: name })
54
+ else
55
+ if value.nil? || value.empty?
56
+ Puppet.warning(_('Ignoring extra header "%{name}" as it has no value.') % { name: name })
57
+ else
58
+ modified_headers[name] = value
59
+ end
60
+ end
61
+ end
46
62
  modified_headers
47
63
  end
48
64
 
@@ -54,11 +70,8 @@ class Puppet::HTTP::Service
54
70
  end
55
71
 
56
72
  def get_mime_types(model)
57
- unless @mime_types
58
- network_formats = model.supported_formats - EXCLUDED_FORMATS
59
- @mime_types = network_formats.map { |f| model.get_format(f).mime }
60
- end
61
- @mime_types
73
+ network_formats = model.supported_formats - EXCLUDED_FORMATS
74
+ network_formats.map { |f| model.get_format(f).mime }
62
75
  end
63
76
 
64
77
  def formatter_for_response(response)
@@ -106,4 +119,10 @@ class Puppet::HTTP::Service
106
119
  raise Puppet::HTTP::SerializationError.new("Failed to deserialize multiple #{model} from #{formatter.name}: #{err.message}", err)
107
120
  end
108
121
  end
122
+
123
+ def process_response(response)
124
+ @session.process_response(response)
125
+
126
+ raise Puppet::HTTP::ResponseError.new(response) unless response.success?
127
+ end
109
128
  end