Method: Puppet::Node::Facts::DiffPuppetdb#search

Defined in:
lib/puppet/indirector/facts/diff_puppetdb.rb

#search(request) ⇒ Object

Search for nodes matching a set of fact constraints. The constraints are specified as a hash of the form:

‘=> value`

The only accepted ‘type` is ’facts’.

‘name` must be the fact name to query against.

‘operator` may be one of {eq, ne, lt, gt, le, ge, and will default to ’eq’ if unspecified.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/puppet/indirector/facts/diff_puppetdb.rb', line 102

def search(request)
  profile('facts#search', [:puppetdb, :facts, :search, request.key]) do
    return [] unless request.options
    operator_map = {
      'eq' => '=',
      'gt' => '>',
      'lt' => '<',
      'ge' => '>=',
      'le' => '<=',
    }
    filters = request.options.sort.map do |key,value|
      type, name, operator = key.to_s.split('.')
      operator ||= 'eq'
      raise Puppet::Error, "Fact search against keys of type '#{type}' is unsupported" unless type == 'facts'
      if operator == 'ne'
        ['not', ['=', ['fact', name], value]]
      else
        [operator_map[operator], ['fact', name], value]
      end
    end

    query = ['and'] + filters
    query_param = CGI.escape(query.to_json)

    begin
      url = Puppet::Util::Puppetdb.url_path("/v3/nodes?query=#{query_param}")
      response = profile("Fact query request: #{URI.unescape(url)}",
                         [:puppetdb, :facts, :search, :query_request, request.key]) do
        http_get(request, url, headers)
      end
      log_x_deprecation_header(response)

      if response.is_a? Net::HTTPSuccess
        profile("Parse fact query response (size: #{response.body.size})",
                [:puppetdb, :facts, :search, :parse_query_response, request.key,]) do
          JSON.parse(response.body).collect {|s| s['name']}
        end
      else
        # Newline characters cause an HTTP error, so strip them
        raise "[#{response.code} #{response.message}] #{response.body.gsub(/[\r\n]/, '')}"
      end
    rescue => e
      raise Puppet::Error, "Could not perform inventory search from PuppetDB at #{self.class.server}:#{self.class.port}: #{e}"
    end
  end
end