diff --git a/lib/octocatalog-diff/facts/json.rb b/lib/octocatalog-diff/facts/json.rb index 76f89d9f..2c535b63 100644 --- a/lib/octocatalog-diff/facts/json.rb +++ b/lib/octocatalog-diff/facts/json.rb @@ -14,8 +14,19 @@ class JSON # @return [Hash] Facts def self.fact_retriever(options = {}, node = '') facts = ::JSON.parse(options.fetch(:fact_file_string)) - node = facts.fetch('fqdn', 'unknown.node') if node.empty? - { 'name' => node, 'values' => facts } + + if facts.keys.include?('name') && facts.keys.include?('values') && facts['values'].is_a?(Hash) + # If you saved the output of something like + # `puppet facts find $(hostname)` the structure will already be a + # {'name' => , 'values' => }. We do nothing + # here because we don't want to double-encode. + else + facts = { 'name' => node, 'values' => facts } + end + + facts['name'] = node unless node.empty? + facts['name'] = facts['values'].fetch('fqdn', 'unknown.node') if facts['name'].empty? + facts end end end diff --git a/spec/octocatalog-diff/fixtures/facts/encoded-facts.json b/spec/octocatalog-diff/fixtures/facts/encoded-facts.json new file mode 100644 index 00000000..d3d3386a --- /dev/null +++ b/spec/octocatalog-diff/fixtures/facts/encoded-facts.json @@ -0,0 +1,10 @@ +{ + "name":"rspec-node.abc.github.net", + "values":{ + "apt_update_last_success":1458162123, + "architecture":"amd64", + "datacenter":"xyz", + "fqdn":"rspec-node.xyz.github.net", + "_timestamp":"2014-12-02 14:56:20 -0600" + } +} diff --git a/spec/octocatalog-diff/tests/facts/json_spec.rb b/spec/octocatalog-diff/tests/facts/json_spec.rb index 28004293..d3f9d18e 100644 --- a/spec/octocatalog-diff/tests/facts/json_spec.rb +++ b/spec/octocatalog-diff/tests/facts/json_spec.rb @@ -39,5 +39,30 @@ expect(result['name']).to eq('override.node') expect(result['values']['fqdn']).to eq('rspec-node.xyz.github.net') end + + it 'should fill in a missing name from hash with name/values' do + fact_file = OctocatalogDiff::Spec.fixture_path('facts/encoded-facts.json') + data = JSON.parse(File.read(fact_file)) + data['name'] = '' + options = { + fact_file_string: JSON.generate(data) + } + result = OctocatalogDiff::Facts::JSON.fact_retriever(options) + expect(result).to be_a_kind_of(Hash) + expect(result['name']).to eq('rspec-node.xyz.github.net') + expect(result['values']['fqdn']).to eq('rspec-node.xyz.github.net') + end + + it 'should not double-encode hash already containing name and values' do + fact_file = OctocatalogDiff::Spec.fixture_path('facts/encoded-facts.json') + options = { + fact_file_string: File.read(fact_file) + } + result = OctocatalogDiff::Facts::JSON.fact_retriever(options) + expect(result).to be_a_kind_of(Hash) + expect(result.keys).to match_array(%w(name values)) + expect(result['name']).to eq('rspec-node.abc.github.net') + expect(result['values']['fqdn']).to eq('rspec-node.xyz.github.net') + end end end