Skip to content

Commit fe63c90

Browse files
authored
Merge pull request #9049 from AriaXLi/PUP-10928/allow_pson_serialization_setting
(PUP-10928) Add allow_pson_serialization setting
2 parents affec3c + 1066460 commit fe63c90

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed

lib/puppet/defaults.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,6 +1711,15 @@ def self.initialize_default_settings!(settings)
17111711
can be guaranteed to support this format, but it will be used for all
17121712
classes that support it.",
17131713
},
1714+
:allow_pson_serialization => {
1715+
:default => true,
1716+
:type => :boolean,
1717+
:desc => "Whether when unable to serialize to JSON or other formats,
1718+
Puppet falls back to PSON. This option affects both puppetserver's
1719+
configuration management service responses and when the agent saves its
1720+
cached catalog. This option is useful in preventing the loss of data because
1721+
rich data cannot be serialized via PSON.",
1722+
},
17141723
:agent_catalog_run_lockfile => {
17151724
:default => "$statedir/agent_catalog_run.lock",
17161725
:type => :string, # (#2888) Ensure this file is not added to the settings catalog.

lib/puppet/indirector/catalog/json.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ def from_json(text)
1818
def to_json(object)
1919
object.render(json_format)
2020
rescue Puppet::Network::FormatHandler::FormatError => err
21-
Puppet.info(_("Unable to serialize catalog to json, retrying with pson"))
22-
Puppet.log_exception(err, err.message, level: :debug)
23-
object.render('pson').force_encoding(Encoding::BINARY)
21+
if Puppet[allow_pson_serialization]
22+
Puppet.info(_("Unable to serialize catalog to json, retrying with pson. PSON is deprecated and will be removed in a future release"))
23+
Puppet.log_exception(err, err.message, level: :debug)
24+
object.render('pson').force_encoding(Encoding::BINARY)
25+
else
26+
Puppet.info(_("Unable to serialize catalog to json, no other acceptable format"))
27+
Puppet.log_exception(err, err.message, level: :err)
28+
end
2429
end
2530

2631
private

lib/puppet/network/http/api/indirected_routes.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,13 @@ def first_response_formatter_for(model, request, key, &block)
192192
yield format
193193
true
194194
rescue Puppet::Network::FormatHandler::FormatError => err
195-
Puppet.warning(_("Failed to serialize %{model} for '%{key}': %{detail}") %
196-
{model: model, key: key, detail: err})
195+
msg = _("Failed to serialize %{model} for '%{key}': %{detail}") %
196+
{model: model, key: key, detail: err}
197+
if Puppet[:allow_pson_serialization]
198+
Puppet.warning(msg)
199+
else
200+
raise Puppet::Network::FormatHandler::FormatError.new(msg)
201+
end
197202
false
198203
end
199204
end

spec/unit/network/http/api/indirected_routes_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,19 @@
210210
handler.call(request, response)
211211
}.to raise_error(not_found_error)
212212
end
213+
214+
it "should raise FormatError if tries to fallback and pson serialization is not allowed" do
215+
Puppet[:allow_pson_serialization] = false
216+
data = Puppet::IndirectorTesting.new("my data")
217+
indirection.save(data, "my data")
218+
request = a_request_that_finds(data, :accept_header => "unknown, text/pson")
219+
allow(data).to receive(:to_pson).and_raise(Puppet::Network::FormatHandler::FormatError, 'Could not render to Puppet::Network::Format[pson]: source sequence is illegal/malformed utf-8')
220+
221+
expect {
222+
handler.call(request, response)
223+
}.to raise_error(Puppet::Network::FormatHandler::FormatError,
224+
%r{Failed to serialize Puppet::IndirectorTesting for 'my data': Could not render to Puppet::Network::Format\[pson\]})
225+
end
213226
end
214227

215228
describe "when searching for model instances" do
@@ -250,6 +263,19 @@
250263
%r{No supported formats are acceptable \(Accept: application/json, text/pson\)})
251264
end
252265

266+
it "raises FormatError if tries to fallback and pson serialization is not allowed" do
267+
Puppet[:allow_pson_serialization] = false
268+
data = Puppet::IndirectorTesting.new("my data")
269+
indirection.save(data, "my data")
270+
request = a_request_that_searches(Puppet::IndirectorTesting.new("my"), :accept_header => "unknown, text/pson")
271+
allow(data).to receive(:to_pson).and_raise(Puppet::Network::FormatHandler::FormatError, 'Could not render to Puppet::Network::Format[pson]: source sequence is illegal/malformed utf-8')
272+
273+
expect {
274+
handler.call(request, response)
275+
}.to raise_error(Puppet::Network::FormatHandler::FormatError,
276+
%r{Failed to serialize Puppet::IndirectorTesting for 'my': Could not render_multiple to Puppet::Network::Format\[pson\]})
277+
end
278+
253279
it "should return [] when searching returns an empty array" do
254280
request = a_request_that_searches(Puppet::IndirectorTesting.new("nothing"), :accept_header => "unknown, application/json")
255281

0 commit comments

Comments
 (0)