class ChefZero::Endpoints::SearchEndpoint

/search/INDEX

Public Instance Methods

get(request) click to toggle source
# File lib/chef_zero/endpoints/search_endpoint.rb, line 12
def get(request)
  orgname = request.rest_path[1]
  results = search(request, orgname)

  results["rows"] = results["rows"].map { |name, uri, value, search_value| value }

  json_response(200, results)
rescue ChefZero::Solr::ParseError
  bad_search_request(request)
end
post(request) click to toggle source
# File lib/chef_zero/endpoints/search_endpoint.rb, line 23
def post(request)
  orgname = request.rest_path[1]
  full_results = search(request, orgname)
  keys = FFI_Yajl::Parser.parse(request.body)
  partial_results = full_results["rows"].map do |name, uri, doc, search_value|
    data = {}
    keys.each_pair do |key, path|
      if path.size > 0
        value = search_value
        path.each do |path_part|
          value = value[path_part] if !value.nil?
        end
        data[key] = value
      else
        data[key] = nil
      end
    end
    {
      "url" => uri,
      "data" => data,
    }
  end
  json_response(200, {
    "rows" => partial_results,
    "start" => full_results["start"],
    "total" => full_results["total"],
  })
rescue ChefZero::Solr::ParseError
  bad_search_request(request)
end

Private Instance Methods

bad_search_request(request) click to toggle source
# File lib/chef_zero/endpoints/search_endpoint.rb, line 56
def bad_search_request(request)
  query_string = request.query_params["q"]
  resp = { "error" => ["invalid search query: '#{query_string}'"] }
  json_response(400, resp)
end
deep_merge!(source, dest) click to toggle source

Deep Merge core documentation. deep_merge! method permits merging of arbitrary child elements. The two top level elements must be hashes. These hashes can contain unlimited (to stack limit) levels of child elements. These child elements to not have to be of the same types. Where child elements are of the same type, deep_merge will attempt to merge them together. Where child elements are not of the same type, deep_merge will skip or optionally overwrite the destination element with the contents of the source element at that level. So if you have two hashes like this:

source = {:x => [1,2,3], :y => 2}
dest =   {:x => [4,5,'6'], :y => [7,8,9]}
dest.deep_merge!(source)
Results: {:x => [1,2,3,4,5,'6'], :y => 2}

By default, “deep_merge!” will overwrite any unmergeables and merge everything else. To avoid this, use “deep_merge” (no bang/exclamation mark)

# File lib/chef_zero/endpoints/search_endpoint.rb, line 172
def deep_merge!(source, dest)
  # if dest doesn't exist, then simply copy source to it
  if dest.nil?
    dest = source; return dest
  end

  case source
  when nil
    dest
  when Hash
    source.each do |src_key, src_value|
      if dest.kind_of?(Hash)
        if dest[src_key]
          dest[src_key] = deep_merge!(src_value, dest[src_key])
        else # dest[src_key] doesn't exist so we take whatever source has
          dest[src_key] = src_value
        end
      else # dest isn't a hash, so we overwrite it completely
        dest = source
      end
    end
  when Array
    if dest.kind_of?(Array)
      dest |= source
    else
      dest = source
    end
  when String
    dest = source
  else # src_hash is not an array or hash, so we'll have to overwrite dest
    dest = source
  end
  dest
end
expand_for_indexing(value, index, id) click to toggle source
# File lib/chef_zero/endpoints/search_endpoint.rb, line 83
def expand_for_indexing(value, index, id)
  if index == "node"
    result = {}
    deep_merge!(value["default"] || {}, result)
    deep_merge!(value["normal"] || {}, result)
    deep_merge!(value["override"] || {}, result)
    deep_merge!(value["automatic"] || {}, result)
    result["recipe"] = []
    result["role"] = []
    if value["run_list"]
      value["run_list"].each do |run_list_entry|
        if run_list_entry =~ /^(recipe|role)\[(.*)\]/
          result[$1] << $2
        end
      end
    end
    value.each_pair do |key, val|
      result[key] = val unless %w{default normal override automatic}.include?(key)
    end
    result

  elsif !%w{client environment role}.include?(index)
    ChefData::DataNormalizer.normalize_data_bag_item(value, index, id, "GET")
  else
    value
  end
end
search_container(request, index, orgname) click to toggle source
# File lib/chef_zero/endpoints/search_endpoint.rb, line 62
def search_container(request, index, orgname)
  relative_parts, normalize_proc =
    case index
    when "client"
      [ ["clients"], Proc.new { |client, name| ChefData::DataNormalizer.normalize_client(client, name, orgname) } ]
    when "node"
      [ ["nodes"], Proc.new { |node, name| ChefData::DataNormalizer.normalize_node(node, name) } ]
    when "environment"
      [ ["environments"], Proc.new { |environment, name| ChefData::DataNormalizer.normalize_environment(environment, name) } ]
    when "role"
      [ ["roles"], Proc.new { |role, name| ChefData::DataNormalizer.normalize_role(role, name) } ]
    else
      [ ["data", index], Proc.new { |data_bag_item, id| ChefData::DataNormalizer.normalize_data_bag_item(data_bag_item, index, id, "DELETE") } ]
    end

  [
    request.rest_path[0..1] + relative_parts,
    normalize_proc,
  ]
end