Module: Chef::EncryptedAttribute::SearchHelper
- Extended by:
- SearchHelper
- Included in:
- RemoteClients, RemoteNode, RemoteNodes, SearchHelper
- Defined in:
- lib/chef/encrypted_attribute/search_helper.rb
Overview
Search Helpers to do normal or partial searches.
Instance Method Summary collapse
-
#assert_normal_search_response(resp) ⇒ Object
private
Assert that the normal (no partial) search response is correct.
-
#assert_partial_search_response(resp) ⇒ Object
private
Assert that the partial search response is correct.
-
#assert_search_keys(keys) ⇒ Object
private
Assert that the search keys structure format is correct.
-
#catch_search_exceptions { ... } ⇒ Mixed
private
Translates Chef HTTP exceptions to search exceptions.
-
#empty_search?(query) ⇒ Boolean
private
Check if search query is empty.
-
#escape(str) ⇒ String
private
Escapes a search query string to be used in URLs.
-
#escape_query(query) ⇒ String
Escapes a search query array.
-
#filter_normal_search_response(resp, name) ⇒ Array
private
Filters normal search results that do not correspond to the searched node.
-
#filter_partial_search_response(resp, name) ⇒ Hash
private
Filters partial search results that do not correspond to the searched node.
-
#generate_partial_search_keys(keys) ⇒ Hash
private
Adds the
name
key to the search keys structure. -
#normal_search(type, name, query, keys, rows = 1000) ⇒ Array<Hash>
Does a normal (no partial) search in the Chef Server.
-
#parse_normal_search_response(resp, keys, name) ⇒ Array<Hash>
private
Parses a normal (no partial) full search search response.
-
#parse_normal_search_row_attribute(row, attr_ary) ⇒ Hash
private
Parses a normal (no partial) search response row.
-
#parse_partial_search_response(resp, name, keys) ⇒ Array<Hash>
private
Parses a partial full search search response.
-
#partial_search(type, name, query, keys, rows = 1000) ⇒ Array<Hash>
Does a partial search in the Chef Server.
-
#query ⇒ Chef::Search::Query
private
Gets a Chef Search Query object.
-
#search(type, query, keys, rows = 1000, partial_search = true) ⇒ Array<Hash>
Does a search in the Chef Server.
-
#search_by_name(type, name, keys, rows = 1000, partial_search = true) ⇒ Array<Hash>
Does a search in the Chef Server by node or client name.
-
#valid_search_keys?(keys) ⇒ Boolean
private
Checks if a search keys structure format is correct.
-
#valid_search_keys_key?(k) ⇒ Boolean
private
Checks if a Hash key from a search keys structure format is correct.
-
#valid_search_keys_value?(v) ⇒ Boolean
private
Checks if a Hash value from a search keys structure format is correct.
Instance Method Details
#assert_normal_search_response(resp) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Assert that the normal (no partial) search response is correct.
190 191 192 193 194 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 190 def assert_normal_search_response(resp) return if resp.is_a?(Array) fail SearchFatalError, "Wrong response received from Normal Search: #{resp.inspect}" end |
#assert_partial_search_response(resp) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Assert that the partial search response is correct.
288 289 290 291 292 293 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 288 def assert_partial_search_response(resp) return if resp.is_a?(Hash) && resp.key?('rows') && resp['rows'].is_a?(Array) fail SearchFatalError, "Wrong response received from Partial Search: #{resp.inspect}" end |
#assert_search_keys(keys) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Assert that the search keys structure format is correct.
108 109 110 111 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 108 def assert_search_keys(keys) return if valid_search_keys?(keys) fail InvalidSearchKeys, "Invalid search keys: #{keys.inspect}" end |
#catch_search_exceptions { ... } ⇒ Mixed
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Translates Chef HTTP exceptions to search exceptions.
128 129 130 131 132 133 134 135 136 137 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 128 def catch_search_exceptions(&block) block.call rescue Net::HTTPServerException => e unless e.response.is_a?(Net::HTTPResponse) && e.response.code == '404' raise SearchFailure, "Search exception #{e.class}: #{e}" end return [] rescue Net::HTTPFatalError => e raise SearchFailure, "Search exception #{e.class}: #{e}" end |
#empty_search?(query) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Check if search query is empty.
118 119 120 121 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 118 def empty_search?(query) query.is_a?(String) && query.empty? || query.is_a?(Array) && query.count == 0 end |
#escape(str) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Escapes a search query string to be used in URLs.
43 44 45 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 43 def escape(str) URI.escape(str.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) end |
#escape_query(query) ⇒ String
Escapes a search query array.
When multiple queries are provided, the result will be OR-ed.
53 54 55 56 57 58 59 60 61 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 53 def escape_query(query) query_s = if query.is_a?(Array) query.map { |item| "( #{item} )" }.compact.join(' OR ') else query.to_s end escape(query_s) end |
#filter_normal_search_response(resp, name) ⇒ Array
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Filters normal search results that do not correspond to the searched node.
Used when searching by node name.
224 225 226 227 228 229 230 231 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 224 def filter_normal_search_response(resp, name) return resp if name.nil? resp.select { |row| row.name == name }.tap do |r| fail SearchFatalError, 'Multiple responses received from Partial Search:'\ " #{r.inspect}" if r.count > 1 end end |
#filter_partial_search_response(resp, name) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Filters partial search results that do not correspond to the searched node.
Used when searching by node name.
322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 322 def filter_partial_search_response(resp, name) return resp if name.nil? filtered_resp = resp.select do |row| row['data']['name'] == name end filtered_resp.tap do |r| fail SearchFatalError, 'Multiple responses received from Partial Search:'\ " #{r.inspect}" if r.count > 1 end end |
#generate_partial_search_keys(keys) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Adds the name
key to the search keys structure.
Used to get the node name when searching nodes by name.
306 307 308 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 306 def generate_partial_search_keys(keys) keys.merge('name' => %w(name)) end |
#normal_search(type, name, query, keys, rows = 1000) ⇒ Array<Hash>
Does a normal (no partial) search in the Chef Server.
269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 269 def normal_search(type, name, query, keys, rows = 1000) escaped_query = escape_query(query) Chef::Log.info( "Normal Search query: #{escaped_query}, keys: #{keys.inspect}" ) assert_search_keys(keys) resp = self.query.search(type, escaped_query, nil, 0, rows)[0] assert_normal_search_response(resp) parse_normal_search_response(resp, keys, name) end |
#parse_normal_search_response(resp, keys, name) ⇒ Array<Hash>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Parses a normal (no partial) full search search response.
244 245 246 247 248 249 250 251 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 244 def parse_normal_search_response(resp, keys, name) filter_normal_search_response(resp, name).map do |row| Hash[keys.map do |key_name, attr_ary| value = parse_normal_search_row_attribute(row, attr_ary) [key_name, value] end] end end |
#parse_normal_search_row_attribute(row, attr_ary) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Parses a normal (no partial) search response row.
203 204 205 206 207 208 209 210 211 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 203 def parse_normal_search_row_attribute(row, attr_ary) attr_ary.reduce(row) do |r, attr| if r.respond_to?(attr) r.send(attr) elsif r.respond_to?(:key?) r[attr.to_s] if r.key?(attr.to_s) end end end |
#parse_partial_search_response(resp, name, keys) ⇒ Array<Hash>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Parses a partial full search search response.
345 346 347 348 349 350 351 352 353 354 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 345 def parse_partial_search_response(resp, name, keys) filter_partial_search_response(resp['rows'], name).map do |row| if row.is_a?(Hash) && row['data'].is_a?(Hash) row['data'].tap { |r| r.delete('name') unless keys.key?('name') } else fail SearchFatalError, "Wrong row format received from Partial Search: #{row.inspect}" end end.compact end |
#partial_search(type, name, query, keys, rows = 1000) ⇒ Array<Hash>
Does a partial search in the Chef Server.
371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 371 def partial_search(type, name, query, keys, rows = 1000) escaped_query = "search/#{escape(type)}?q=#{escape_query(query)}&start=0&rows=#{rows}" Chef::Log.info( "Partial Search query: #{escaped_query}, keys: #{keys.inspect}" ) assert_search_keys(keys) rest = Chef::ServerAPI.new(Chef::Config[:chef_server_url]) resp = rest.post(escaped_query, generate_partial_search_keys(keys)) assert_partial_search_response(resp) parse_partial_search_response(resp, name, keys) end |
#query ⇒ Chef::Search::Query
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Gets a Chef Search Query object.
34 35 36 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 34 def query Chef::Search::Query.new end |
#search(type, query, keys, rows = 1000, partial_search = true) ⇒ Array<Hash>
Does a search in the Chef Server.
155 156 157 158 159 160 161 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 155 def search(type, query, keys, rows = 1000, partial_search = true) return [] if empty_search?(query) # avoid empty searches search_method = partial_search ? :partial_search : :normal_search catch_search_exceptions do send(search_method, type, nil, query, keys, rows) end end |
#search_by_name(type, name, keys, rows = 1000, partial_search = true) ⇒ Array<Hash>
Does a search in the Chef Server by node or client name.
177 178 179 180 181 182 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 177 def search_by_name(type, name, keys, rows = 1000, partial_search = true) search_method = partial_search ? :partial_search : :normal_search catch_search_exceptions do send(search_method, type, name, "name:#{name}", keys, rows) end end |
#valid_search_keys?(keys) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks if a search keys structure format is correct.
This is an example of a correct search structure:
{
ipaddress: %w(ipaddress),
mysql_version: %w(mysql version)
}
96 97 98 99 100 101 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 96 def valid_search_keys?(keys) return false unless keys.is_a?(Hash) keys.reduce(true) do |r, (k, v)| r && valid_search_keys_key?(k) && valid_search_keys_value?(v) end end |
#valid_search_keys_key?(k) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks if a Hash key from a search keys structure format is correct.
68 69 70 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 68 def valid_search_keys_key?(k) k.is_a?(String) || k.is_a?(Symbol) end |
#valid_search_keys_value?(v) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks if a Hash value from a search keys structure format is correct.
77 78 79 80 |
# File 'lib/chef/encrypted_attribute/search_helper.rb', line 77 def valid_search_keys_value?(v) return false unless v.is_a?(Array) v.reduce(true) { |a, e| a && e.is_a?(String) } end |