Skip to content

Commit

Permalink
(PUP-10861) Don't JSON.dump single fact values
Browse files Browse the repository at this point in the history
The `puppet facts show --value-only` option prints just the value for a single
fact. Previously, the value was pretty printed using JSON.dump, which emitted a
quoted string. Now just print the string, so that the value can be parsed via
automation, like export OSFAMILY=`puppet facts show os.family --value-only`

Also add a test for multiple fact names as the `--value-only` option.
  • Loading branch information
joshcooper committed Jan 29, 2021
1 parent 3a8626f commit 6c53d26
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
16 changes: 11 additions & 5 deletions lib/puppet/face/facts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,23 @@
options[:resolve_options] = true
result = Puppet::Node::Facts.indirection.find(Puppet.settings[:certname], options)

facts = result.values

if options[:value_only]
facts.values.first
result.values.values.first
else
facts
result.values
end
end

when_rendering :console do |result|
Puppet::Util::Json.dump(result, :pretty => true)
# VALID_TYPES = [Integer, Float, TrueClass, FalseClass, NilClass, Symbol, String, Array, Hash].freeze
# from https://github.com/puppetlabs/facter/blob/4.0.49/lib/facter/custom_facts/util/normalization.rb#L8

case result
when Array, Hash
Puppet::Util::Json.dump(result, :pretty => true)
else # Integer, Float, TrueClass, FalseClass, NilClass, Symbol, String
result
end
end
end
end
Expand Down
41 changes: 41 additions & 0 deletions spec/unit/application/facts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,47 @@
}.to exit_with(0)
.and output(expected).to_stdout
end

it 'displays a single fact value' do
app.command_line.args << 'filesystems' << '--value-only'
expect {
app.run
}.to exit_with(0)
.and output("apfs,autofs,devfs\n").to_stdout
end

it "warns and ignores value-only when multiple fact names are specified" do
app.command_line.args << 'filesystems' << 'macaddress' << '--value-only'
expect {
app.run
}.to exit_with(0)
.and output(expected).to_stdout
.and output(/it can only be used when querying for a single fact/).to_stderr
end

facts = {
"type_hash" => [{}, "{\n}"],
"type_array" => [[], "[\n\n]"],
"type_string" => ["str", "str"],
"type_int" => [1, "1"],
"type_float" => [1.0, "1.0"],
"type_true" => [true, "true"],
"type_false" => [false, "false"],
"type_nil" => [nil, ""],
"type_sym" => [:sym, "sym"]
}.each_pair do |name, values|
it "renders '#{name}' as '#{values.last}'" do
fact_value = values.first
fact_output = values.last

allow(Facter).to receive(:resolve).and_return({name => fact_value})

app.command_line.args << name << '--value-only'
expect {
app.run
}.to exit_with(0)
.and output("#{fact_output}\n").to_stdout
end
end
end

Expand Down

0 comments on commit 6c53d26

Please sign in to comment.