Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions lib/puppet/configurer/fact_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ def encode_facts(facts)
# > 1024 characters sent in POST data, additionally x-www-form-urlencoded
# so it's only important that encoding method here return original values
# correctly when CGI.unescape called against it (in compiler code)
if Puppet[:preferred_serialization_format] == "pson"
{ :facts_format => :pson, :facts => Puppet::Util.uri_query_encode(facts.render(:pson)) }
else
{ :facts_format => 'application/json', :facts => Puppet::Util.uri_query_encode(facts.render(:json)) }
end
{ :facts_format => 'application/json', :facts => Puppet::Util.uri_query_encode(facts.render(:json)) }
end
end
15 changes: 0 additions & 15 deletions lib/puppet/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1744,21 +1744,6 @@ def self.initialize_default_settings!(settings)
instances will be serialized using this method, since not all classes
can be guaranteed to support this format, but it will be used for all
classes that support it.",
:hook => proc { |value|
if value == "pson" && !Puppet.features.pson?
raise(Puppet::Settings::ValidationError, "The 'puppet-pson' gem must be installed to use the PSON serialization format.")
end
}
},
:allow_pson_serialization => {
:default => false,
:type => :boolean,
:desc => "Whether to allow PSON serialization. When unable to serialize to
JSON or other formats, Puppet falls back to PSON. This option affects the
configuration management service responses of Puppet Server and the process by
which the agent saves its cached catalog. With a default value of `false`, this
option is useful in preventing the loss of data because rich data cannot be
serialized via PSON.",
},
:agent_catalog_run_lockfile => {
:default => "$statedir/agent_catalog_run.lock",
Expand Down
4 changes: 2 additions & 2 deletions lib/puppet/feature/pson.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

require_relative '../../puppet/util/feature'

# PSON is deprecated, use JSON instead
Puppet.features.add(:pson, :libs => ['puppet/external/pson'])
# PSON has been removed. This feature is always false.
Puppet.features.add(:pson) { false }
10 changes: 2 additions & 8 deletions lib/puppet/http/service/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,8 @@ def get_node(name, environment:, configured_environment: nil, transaction_uuid:
#
# @api public
def post_catalog(name, facts:, environment:, configured_environment: nil, check_environment: false, transaction_uuid: nil, job_uuid: nil, static_catalog: true, checksum_type: Puppet[:supported_checksum_types])
if Puppet[:preferred_serialization_format] == "pson"
formatter = Puppet::Network::FormatHandler.format_for(:pson)
# must use 'pson' instead of 'text/pson'
facts_format = 'pson'
else
formatter = Puppet::Network::FormatHandler.format_for(:json)
facts_format = formatter.mime
end
formatter = Puppet::Network::FormatHandler.format_for(:json)
facts_format = formatter.mime

facts_as_string = serialize(formatter, facts)

Expand Down
4 changes: 0 additions & 4 deletions lib/puppet/indirector/catalog/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ def require_environment?
# @api private
def convert_wire_facts(facts, format)
case format
when 'pson'
# We unescape here because the corresponding code in Puppet::Configurer::FactHandler encodes with Puppet::Util.uri_query_encode
# PSON is deprecated, but continue to accept from older agents
Puppet::Node::Facts.convert_from('pson', CGI.unescape(facts))
when 'application/json'
Puppet::Node::Facts.convert_from('json', CGI.unescape(facts))
else
Expand Down
18 changes: 1 addition & 17 deletions lib/puppet/indirector/catalog/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,11 @@ class Puppet::Resource::Catalog::Json < Puppet::Indirector::JSON
desc "Store catalogs as flat files, serialized using JSON."

def from_json(text)
utf8 = text.force_encoding(Encoding::UTF_8)

if utf8.valid_encoding?
model.convert_from(json_format, utf8)
else
Puppet.info(_("Unable to deserialize catalog from json, retrying with pson"))
model.convert_from('pson', text.force_encoding(Encoding::BINARY))
end
model.convert_from(json_format, text.force_encoding(Encoding::UTF_8))
end

def to_json(object)
object.render(json_format)
rescue Puppet::Network::FormatHandler::FormatError => err
if Puppet[:allow_pson_serialization]
Puppet.info(_("Unable to serialize catalog to json, retrying with pson. PSON is deprecated and will be removed in a future release"))
Puppet.log_exception(err, err.message, level: :debug)
object.render('pson').force_encoding(Encoding::BINARY)
else
Puppet.info(_("Unable to serialize catalog to json, no other acceptable format"))
Puppet.log_exception(err, err.message, level: :err)
end
end

private
Expand Down
5 changes: 0 additions & 5 deletions lib/puppet/network/format_support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,6 @@ def to_msgpack(*args)
to_data_hash.to_msgpack(*args)
end

# @deprecated, use to_json
def to_pson(*args)
to_data_hash.to_pson(*args)
end

def to_json(*args)
Puppet::Util::Json.dump(to_data_hash, *args)
end
Expand Down
34 changes: 0 additions & 34 deletions lib/puppet/network/formats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,38 +87,6 @@ def supported?(klass)
:required_methods => [:render_method, :intern_method]) do
end

# PSON is deprecated
Puppet::Network::FormatHandler.create_serialized_formats(:pson, :weight => 10, :required_methods => [:render_method, :intern_method], :intern_method => :from_data_hash) do
confine :feature => :pson

def intern(klass, text)
data_to_instance(klass, PSON.parse(text))
end

def intern_multiple(klass, text)
PSON.parse(text).collect do |data|
data_to_instance(klass, data)
end
end

# PSON monkey-patches Array, so this works.
def render_multiple(instances)
instances.to_pson
end

# If they pass class information, we want to ignore it.
# This is required for compatibility with Puppet 3.x
def data_to_instance(klass, data)
d = data['data'] if data.is_a?(Hash)
if d
data = d
end
return data if data.is_a?(klass)

klass.from_data_hash(data)
end
end

Puppet::Network::FormatHandler.create_serialized_formats(:json, :mime => 'application/json', :charset => Encoding::UTF_8, :weight => 15, :required_methods => [:render_method, :intern_method], :intern_method => :from_data_hash) do
def intern(klass, text)
data_to_instance(klass, Puppet::Util::Json.load(text))
Expand All @@ -134,8 +102,6 @@ def render_multiple(instances)
Puppet::Util::Json.dump(instances)
end

# Unlike PSON, we do not need to unwrap the data envelope, because legacy 3.x agents
# have never supported JSON
def data_to_instance(klass, data)
return data if data.is_a?(klass)

Expand Down
7 changes: 1 addition & 6 deletions lib/puppet/network/http/api/indirected_routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,7 @@ def first_response_formatter_for(model, request, key, &block)
rescue Puppet::Network::FormatHandler::FormatError => err
msg = _("Failed to serialize %{model} for '%{key}': %{detail}") %
{ model: model, key: key, detail: err }
if Puppet[:allow_pson_serialization]
Puppet.warning(msg)
else
raise Puppet::Network::FormatHandler::FormatError, msg
end
false
raise Puppet::Network::FormatHandler::FormatError, msg
end

return formatter if formatter
Expand Down
72 changes: 0 additions & 72 deletions spec/integration/network/formats_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,6 @@

require 'puppet/network/formats'

class PsonIntTest
attr_accessor :string
def ==(other)
other.class == self.class and string == other.string
end

def self.from_data_hash(data)
new(data[0])
end

def initialize(string)
@string = string
end

def to_pson(*args)
{
'type' => self.class.name,
'data' => [@string]
}.to_pson(*args)
end

def self.canonical_order(s)
s.gsub(/\{"data":\[(.*?)\],"type":"PsonIntTest"\}/,'{"type":"PsonIntTest","data":[\1]}')
end

end

describe Puppet::Network::FormatHandler.format(:s) do
before do
@format = Puppet::Network::FormatHandler.format(:s)
Expand All @@ -43,48 +16,3 @@ def self.canonical_order(s)
end
end

describe Puppet::Network::FormatHandler.format(:pson), if: Puppet.features.pson? do
before do
@pson = Puppet::Network::FormatHandler.format(:pson)
end

it "should be able to render an instance to pson" do
instance = PsonIntTest.new("foo")
expect(PsonIntTest.canonical_order(@pson.render(instance))).to eq(PsonIntTest.canonical_order('{"type":"PsonIntTest","data":["foo"]}' ))
end

it "should be able to render arrays to pson" do
expect(@pson.render([1,2])).to eq('[1,2]')
end

it "should be able to render arrays containing hashes to pson" do
expect(@pson.render([{"one"=>1},{"two"=>2}])).to eq('[{"one":1},{"two":2}]')
end

it "should be able to render multiple instances to pson" do
one = PsonIntTest.new("one")
two = PsonIntTest.new("two")

expect(PsonIntTest.canonical_order(@pson.render([one,two]))).to eq(PsonIntTest.canonical_order('[{"type":"PsonIntTest","data":["one"]},{"type":"PsonIntTest","data":["two"]}]'))
end

it "should be able to intern pson into an instance" do
expect(@pson.intern(PsonIntTest, '{"type":"PsonIntTest","data":["foo"]}')).to eq(PsonIntTest.new("foo"))
end

it "should be able to intern pson with no class information into an instance" do
expect(@pson.intern(PsonIntTest, '["foo"]')).to eq(PsonIntTest.new("foo"))
end

it "should be able to intern multiple instances from pson" do
expect(@pson.intern_multiple(PsonIntTest, '[{"type": "PsonIntTest", "data": ["one"]},{"type": "PsonIntTest", "data": ["two"]}]')).to eq([
PsonIntTest.new("one"), PsonIntTest.new("two")
])
end

it "should be able to intern multiple instances from pson with no class information" do
expect(@pson.intern_multiple(PsonIntTest, '[["one"],["two"]]')).to eq([
PsonIntTest.new("one"), PsonIntTest.new("two")
])
end
end
30 changes: 0 additions & 30 deletions spec/unit/configurer/fact_handler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,36 +79,6 @@ def reload_facter
{ :hash => { 'afact' => "A\u06FF\u16A0\u{2070E}" }, :encoded => '%22values%22%3A%7B%22afact%22%3A%22' + 'A%DB%BF%E1%9A%A0%F0%A0%9C%8E' + '%22%7D' },
]

context "as pson", if: Puppet.features.pson? do
before :each do
Puppet[:preferred_serialization_format] = 'pson'
end

it "should serialize and CGI escape the fact values for uploading" do
facts = Puppet::Node::Facts.new(Puppet[:node_name_value], 'my_name_fact' => 'other_node_name')
Puppet::Node::Facts.indirection.save(facts)
text = Puppet::Util.uri_query_encode(facthandler.find_facts.render(:pson))

expect(text).to include('%22values%22%3A%7B%22my_name_fact%22%3A%22other_node_name%22%7D')
expect(facthandler.facts_for_uploading).to eq({:facts_format => :pson, :facts => text})
end

facts_with_special_characters.each do |test_fact|
it "should properly accept the fact #{test_fact[:hash]}" do
facts = Puppet::Node::Facts.new(Puppet[:node_name_value], test_fact[:hash])
Puppet::Node::Facts.indirection.save(facts)
text = Puppet::Util.uri_query_encode(facthandler.find_facts.render(:pson))

to_upload = facthandler.facts_for_uploading
expect(to_upload).to eq({:facts_format => :pson, :facts => text})
expect(text).to include(test_fact[:encoded])

# this is not sufficient to test whether these values are sent via HTTP GET or HTTP POST in actual catalog request
expect(JSON.parse(Puppet::Util.uri_unescape(to_upload[:facts]))['values']).to eq(test_fact[:hash])
end
end
end

context "as json" do
it "should serialize and CGI escape the fact values for uploading" do
facts = Puppet::Node::Facts.new(Puppet[:node_name_value], 'my_name_fact' => 'other_node_name')
Expand Down
7 changes: 0 additions & 7 deletions spec/unit/defaults_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,4 @@
end
end

describe "#preferred_serialization_format" do
it 'raises if PSON is not available', unless: Puppet.features.pson? do
expect {
Puppet.settings[:preferred_serialization_format] = "pson"
}.to raise_error(Puppet::Settings::ValidationError, "The 'puppet-pson' gem must be installed to use the PSON serialization format.")
end
end
end
12 changes: 0 additions & 12 deletions spec/unit/http/service/compiler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,6 @@
subject.post_catalog(certname, environment: environment, facts: facts)
end

it 'submits facts as pson if set as the preferred format', if: Puppet.features.pson? do
Puppet[:preferred_serialization_format] = "pson"

stub_request(:post, uri)
.with(body: hash_including("facts_format" => /pson/))
.to_return(**catalog_response)

subject.post_catalog(certname, environment: environment, facts: facts)
end

it 'includes environment as a query parameter AND in the POST body' do
stub_request(:post, uri)
.with(query: {"environment" => "outerspace"},
Expand Down Expand Up @@ -145,7 +135,6 @@
.to_return(**catalog_response)

allow(Puppet.features).to receive(:msgpack?).and_return(false)
allow(Puppet.features).to receive(:pson?).and_return(false)

subject.post_catalog(certname, environment: environment, facts: facts)
end
Expand All @@ -156,7 +145,6 @@
.to_return(**catalog_response)

allow(Puppet.features).to receive(:msgpack?).and_return(true)
allow(Puppet.features).to receive(:pson?).and_return(false)

subject.post_catalog(certname, environment: environment, facts: facts)
end
Expand Down
9 changes: 1 addition & 8 deletions spec/unit/indirector/catalog/compiler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def set_facts(fact_hash)
Puppet::Node::Facts.indirection.save(facts)
end

def a_legacy_request_that_contains(facts, format = :pson)
def a_legacy_request_that_contains(facts, format = :yaml)
request = Puppet::Indirector::Request.new(:catalog, :find, "hostname", nil)
request.options[:facts_format] = format.to_s
request.options[:facts] = Puppet::Util.uri_query_encode(facts.render(format))
Expand Down Expand Up @@ -338,13 +338,6 @@ def a_request_that_contains(facts)
expect(facts.timestamp).to eq(time)
end

it "accepts PSON facts from older agents", :if => Puppet.features.pson? do
request = a_legacy_request_that_contains(facts)

facts = compiler.extract_facts_from_request(request)
expect(facts).to eq(facts)
end

it "rejects YAML facts" do
request = a_legacy_request_that_contains(facts, :yaml)

Expand Down
Loading