Skip to content

json --fact-file data straight from puppetdb fails #257

Open
@elfchief

Description

@elfchief

Description

When octocatalog-diff (version 2.1.0) is provided a set of facts via --facts-file, it will fail if that file contains a json array straight out of puppetdb. Being able to use facts straight from puppetdb like this is useful for (e.g.) providing simple offline caching of facts.

For example:

$ curl -s http://puppetdb/pdb/query/v4/nodes/somehost.internal/facts > /tmp/somehost_facts.json
$ jq . /tmp/somehost_facts.json  | head
[
  {
    "certname": "somehost.internal",
    "environment": "production",
    "name": "id",
    "value": "root"
  },
  (etc)

and then:

$ octocatalog-diff --hostname somehost.internal --fact-file /tmp/somehost_facts.json
Traceback (most recent call last):
	17: from /opt/puppetlabs/puppet/bin/octocatalog-diff:23:in `<main>'
	16: from /opt/puppetlabs/puppet/bin/octocatalog-diff:23:in `load'
	15: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/bin/octocatalog-diff:34:in `<top (required)>'
	14: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/cli.rb:69:in `cli'
	13: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/cli.rb:168:in `parse_opts'
	12: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/cli/options.rb:66:in `parse_options'
	11: from /opt/puppetlabs/puppet/lib/ruby/2.7.0/optparse.rb:1691:in `parse!'
	10: from /opt/puppetlabs/puppet/lib/ruby/2.7.0/optparse.rb:1666:in `permute!'
	 9: from /opt/puppetlabs/puppet/lib/ruby/2.7.0/optparse.rb:1569:in `order!'
	 8: from /opt/puppetlabs/puppet/lib/ruby/2.7.0/optparse.rb:1575:in `parse_in_order'
	 7: from /opt/puppetlabs/puppet/lib/ruby/2.7.0/optparse.rb:1575:in `catch'
	 6: from /opt/puppetlabs/puppet/lib/ruby/2.7.0/optparse.rb:1589:in `block in parse_in_order'
	 5: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/cli/options.rb:128:in `block in option_globally_or_per_branch_string'
	 4: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/cli/options.rb:238:in `translate_option'
	 3: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/cli/options/fact_file.rb:23:in `block in parse'
	 2: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/cli/options/fact_file.rb:23:in `new'
	 1: from /opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/facts.rb:27:in `initialize'
/opt/puppetlabs/puppet/lib/ruby/gems/2.7.0/gems/octocatalog-diff-2.1.0/lib/octocatalog-diff/facts/json.rb:18:in `fact_retriever': undefined method `keys' for #<Array:0x00000000024a04c8> (NoMethodError)

Possible Fix

One possible fix would be to add something similar to the following immediately after the JSON::parse call in self.fact_retriever, inside facts/json.rb:

        if facts.is_a?(Array) && facts[0].is_a?(Hash) && facts[0].keys.include?('certname')
            # you probably gave us the raw puppetdb output
            fixed_facts = {}
            facts.map { |x| fixed_facts[x['name']] = x['value'] }
            facts = fixed_facts
        end

This works, and allows catalogs to be built using that straight-from-puppetdb json goodness.

I am not submitting this as a pull request because 1-- I don't really know ruby but the above feels a bit sloppy to me and I suspect there might be a more ruby-like way to handle this, and 2-- getting myself a test environment that can actually run and pass the entire octocatalog-diff unit test suite has been... challenging. I'll be happy to submit the above as a PR if that is your desire, though.

Environment

Although it is unlikely to matter in this specific case:

  • OS: CentOS Linux release 8.2.2004
  • Ruby version: ruby 2.7.3p183 (2021-04-05 revision 6847ee089d) [x86_64-linux] (the bundled ruby from the puppet agent)
  • Puppet version: puppet-agent-7.10.0-1.el8.x86_64 (official PuppetLabs puppet-agent RPM)
  • octocatalog-diff version: octocatalog-diff 2.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions