diff --git a/lib/puppet/catalog-diff/searchfacts.rb b/lib/puppet/catalog-diff/searchfacts.rb index 3e33d8f..9214dcb 100644 --- a/lib/puppet/catalog-diff/searchfacts.rb +++ b/lib/puppet/catalog-diff/searchfacts.rb @@ -21,14 +21,14 @@ def find_nodes(options = {}) active_nodes end - def find_nodes_puppetdb(env) - require 'puppet/util/puppetdb' - server_url = Puppet::Util::Puppetdb.config.server_urls[0] - port = server_url.port - use_ssl = port != 8080 - connection = Puppet::Network::HttpPool.http_instance(server_url.host, port, use_ssl) + def build_query(env, version) base_query = ['and', ['=', ['node', 'active'], true]] - base_query.concat([['=', 'catalog_environment', env]]) if env + if version == 'latest' + query_field_catalog_environment = 'catalog_environment' + else + query_field_catalog_environment = 'catalog-environment' + end + base_query.concat([['=', query_field_catalog_environment, env]]) if env real_facts = @facts.reject { |_k, v| v.nil? } query = base_query.concat(real_facts.map { |k, v| ['=', ['fact', k], v] }) classes = Hash[@facts.select { |_k, v| v.nil? }].keys @@ -43,9 +43,28 @@ def find_nodes_puppetdb(env) ['=', 'title', capit]]]]]], ) end - json_query = URI.encode_www_form_component(query.to_json) + query + end + + def find_nodes_puppetdb(env) + require 'puppet/util/puppetdb' + puppetdb_version = 'latest' + server_url = Puppet::Util::Puppetdb.config.server_urls[0] + port = server_url.port + use_ssl = port != 8080 + connection = Puppet::Network::HttpPool.http_instance(server_url.host, port, use_ssl) + query = build_query(env, puppetdb_version) + json_query = URI.escape(query.to_json) begin - filtered = PSON.parse(connection.request_get("/pdb/query/v4/nodes?query=#{json_query}", 'Accept' => 'application/json').body) + result = connection.request_get("/pdb/query/v4/nodes?query=#{json_query}", 'Accept' => 'application/json') + if result.code.to_i >= 400 + puppetdb_version = '2.3' + Puppet::debug("Query returned HTTP code #{result.code}. Falling back to older version of API used in PuppetDB version #{puppetdb_version}.") + query = build_query(env, puppetdb_version) + json_query = URI.escape(query.to_json) + result = connection.request_get("/v4/nodes/?query=#{json_query}", 'Accept' => 'application/json') + end + filtered = PSON.parse(result.body) rescue PSON::ParserError => e raise "Error parsing json output of puppet search: #{e.message}" end