Class: OctocatalogDiff::Facts::PuppetDB
- Inherits:
-
Object
- Object
- OctocatalogDiff::Facts::PuppetDB
- Defined in:
- lib/octocatalog-diff/facts/puppetdb.rb
Overview
Deal with facts in PuppetDB
Constant Summary collapse
- PUPPETDB_QUERY_FACTS_URL =
Supporting multiple versions of the PuppetDB API.
{ '3' => '/v3/nodes/<NODE>/facts', '4' => '/pdb/query/v4/nodes/<NODE>/facts' }.freeze
Class Method Summary collapse
-
.fact_retriever(options = {}, node) ⇒ Hash
Retrieve facts from PuppetDB for a specified node.
Class Method Details
.fact_retriever(options = {}, node) ⇒ Hash
Retrieve facts from PuppetDB for a specified node.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/octocatalog-diff/facts/puppetdb.rb', line 23 def self.fact_retriever( = {}, node) # Set up some variables from options raise ArgumentError, 'puppetdb_url is required' unless [:puppetdb_url].is_a?(String) raise ArgumentError, 'node must be a non-empty string' unless node.is_a?(String) && node != '' puppetdb_api_version = .fetch(:puppetdb_api_version, 4) uri = PUPPETDB_QUERY_FACTS_URL.fetch(puppetdb_api_version.to_s).gsub('<NODE>', node) retries = .fetch(:retry, 0).to_i # Construct puppetdb object and options opts = .merge(timeout: 5) puppetdb = OctocatalogDiff::PuppetDB.new(opts) # Use OctocatalogDiff::PuppetDB to pull facts exception_class = nil = nil obj_to_return = nil packages = nil (retries + 1).times do begin result = puppetdb.get(uri) facts = {} result.map { |x| facts[x['name']] = x['value'] } if facts.empty? = "Unable to retrieve facts for node #{node} from PuppetDB (empty or nil)!" raise OctocatalogDiff::Errors::FactRetrievalError, end # Create a structure compatible with YAML fact files. obj_to_return = { 'name' => node, 'values' => {} } facts.each { |k, v| obj_to_return['values'][k.sub(/^::/, '')] = v } break # Not return, to avoid LocalJumpError in Ruby 2.2 rescue OctocatalogDiff::Errors::PuppetDBConnectionError => exc exception_class = OctocatalogDiff::Errors::FactSourceError = "Fact retrieval failed (#{exc.class}) (#{exc.})" rescue OctocatalogDiff::Errors::PuppetDBNodeNotFoundError => exc exception_class = OctocatalogDiff::Errors::FactRetrievalError = "Node #{node} not found in PuppetDB (#{exc.})" rescue OctocatalogDiff::Errors::PuppetDBGenericError => exc exception_class = OctocatalogDiff::Errors::FactRetrievalError = "Fact retrieval failed for node #{node} from PuppetDB (#{exc.})" end end raise exception_class, if obj_to_return.nil? return obj_to_return if puppetdb_api_version < 4 || (![:puppetdb_package_inventory]) (retries + 1).times do begin result = puppetdb.get("/pdb/query/v4/package-inventory/#{node}") packages = {} result.each do |pkg| key = "#{pkg['package_name']}+#{pkg['provider']}" # Need to handle the situation where a package has multiple versions installed. # The _puppet_inventory_1 hash lists them separated by "; ". if packages.key?(key) packages[key]['version'] += "; #{pkg['version']}" else packages[key] = pkg end end break rescue OctocatalogDiff::Errors::PuppetDBConnectionError => exc exception_class = OctocatalogDiff::Errors::FactSourceError = "Package inventory retrieval failed (#{exc.class}) (#{exc.})" # This is not expected to occur, but we'll leave it just in case. A query to package-inventory # for a non-existant node returns a 200 OK with an empty list of packages: rescue OctocatalogDiff::Errors::PuppetDBNodeNotFoundError packages = {} rescue OctocatalogDiff::Errors::PuppetDBGenericError => exc exception_class = OctocatalogDiff::Errors::FactRetrievalError = "Package inventory retrieval failed for node #{node} from PuppetDB (#{exc.})" end end raise exception_class, if packages.nil? unless packages.empty? obj_to_return['values']['_puppet_inventory_1'] = { 'packages' => packages.values.map { |pkg| [pkg['package_name'], pkg['version'], pkg['provider']] } } end obj_to_return end |