Skip to content

Commit e91e775

Browse files
authored
Merge pull request #8993 from joshcooper/dig_legacy_facts_11717
(PUP-11717) Protect against facter returning a Hash subclass
2 parents 50cac10 + 9f520a9 commit e91e775

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

lib/puppet/indirector/facts/facter.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ def find(request)
4040
Puppet::Node::Facts.new(request.key, Puppet.runtime[:facter].to_hash)
4141
else
4242
# resolve does not return legacy facts unless requested
43-
Puppet::Node::Facts.new(request.key, Puppet.runtime[:facter].resolve(''))
43+
facts = Puppet.runtime[:facter].resolve('')
44+
# some versions of Facter 4 return a Facter::FactCollection instead of
45+
# a Hash, breaking API compatibility, so force a hash using `to_h`
46+
Puppet::Node::Facts.new(request.key, facts.to_h)
4447
end
4548

4649
result.add_local_facts unless request.options[:resolve_options]

spec/unit/indirector/facts/facter_spec.rb

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
require 'spec_helper'
22
require 'puppet/indirector/facts/facter'
33

4+
class Puppet::Node::Facts::Facter::MyCollection < Hash; end
5+
46
describe Puppet::Node::Facts::Facter do
57
FS = Puppet::FileSystem
68

@@ -87,11 +89,24 @@
8789
it "can exclude legacy facts" do
8890
Puppet[:include_legacy_facts] = false
8991

90-
facts = Puppet::Node::Facts.new("foo")
91-
expect(Puppet::Node::Facts).to receive(:new).and_return(facts)
9292
expect(Puppet.runtime[:facter]).to receive(:resolve).with('')
93+
.and_return({'kernelversion' => '1.2.3'})
9394

94-
@facter.find(@request)
95+
values = @facter.find(@request).values
96+
expect(values).to be_an_instance_of(Hash)
97+
expect(values).to include({'kernelversion' => '1.2.3'})
98+
end
99+
100+
it "can exclude legacy facts using buggy facter implementations that return a Hash subclass" do
101+
Puppet[:include_legacy_facts] = false
102+
103+
collection = Puppet::Node::Facts::Facter::MyCollection["kernelversion" => '1.2.3']
104+
expect(Puppet.runtime[:facter]).to receive(:resolve).with('')
105+
.and_return(collection)
106+
107+
values = @facter.find(@request).values
108+
expect(values).to be_an_instance_of(Hash)
109+
expect(values).to include({'kernelversion' => '1.2.3'})
95110
end
96111
end
97112

0 commit comments

Comments
 (0)