class Elasticsearch::Client
This is the stateful Elasticsearch::Client
, using an instance of elastic-transport.
Constants
- DEFAULT_CLOUD_PORT
The default port to use if connecting using a Cloud ID. Updated from 9243 to 443 in client version 7.10.1
@since 7.2.0
Public Class Methods
Create a client connected to an Elasticsearch
cluster.
@param [Hash] arguments - initializer arguments @option arguments [String] :cloud_id - The Cloud ID to connect to Elastic
Cloud @option arguments [String, Hash] :api_key Use API Key Authentication, either the base64 encoding of ‘id` and `api_key`
joined by a colon as a String, or a hash with the `id` and `api_key` values.
@option arguments [String] :opaque_id_prefix set a prefix for X-Opaque-Id when initializing the client.
This will be prepended to the id you set before each request if you're using X-Opaque-Id
@option arguments [Hash] :headers Custom HTTP Request Headers
# File lib/elasticsearch.rb, line 47 def initialize(arguments = {}, &block) @verified = false @warned = false @opaque_id_prefix = arguments[:opaque_id_prefix] || nil api_key(arguments) if arguments[:api_key] setup_cloud(arguments) if arguments[:cloud_id] set_user_agent!(arguments) unless sent_user_agent?(arguments) @transport = Elastic::Transport::Client.new(arguments, &block) end
Public Instance Methods
# File lib/elasticsearch.rb, line 57 def method_missing(name, *args, &block) if methods.include?(name) super elsif name == :perform_request # The signature for perform_request is: # method, path, params, body, headers, opts if (opaque_id = args[2]&.delete(:opaque_id)) headers = args[4] || {} opaque_id = @opaque_id_prefix ? "#{@opaque_id_prefix}#{opaque_id}" : opaque_id args[4] = headers.merge('X-Opaque-Id' => opaque_id) end unless @verified verify_elasticsearch(*args, &block) else @transport.perform_request(*args, &block) end else @transport.send(name, *args, &block) end end
# File lib/elasticsearch.rb, line 78 def respond_to_missing?(method_name, *args) @transport.respond_to?(method_name) || super end
Private Instance Methods
# File lib/elasticsearch.rb, line 123 def api_key(arguments) api_key = if arguments[:api_key].is_a? Hash encode(arguments[:api_key]) else arguments[:api_key] end arguments.delete(:user) arguments.delete(:password) authorization = { 'Authorization' => "ApiKey #{api_key}" } if (headers = arguments.dig(:transport_options, :headers)) headers.merge!(authorization) else arguments[:transport_options] ||= {} arguments[:transport_options].merge!({ headers: authorization }) end end
# File lib/elasticsearch.rb, line 157 def elasticsearch_validation_request @transport.perform_request('GET', '/') end
Encode credentials for the Authorization Header Credentials is the base64 encoding of id and api_key
joined by a colon @see www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html
# File lib/elasticsearch.rb, line 152 def encode(api_key) credentials = [api_key[:id], api_key[:api_key]].join(':') [credentials].pack('m0') end
# File lib/elasticsearch.rb, line 161 def sent_user_agent?(arguments) return unless (headers = arguments&.[](:transport_options)&.[](:headers)) !!headers.keys.detect { |h| h =~ /user-?_?agent/ } end
# File lib/elasticsearch.rb, line 167 def set_user_agent!(arguments) user_agent = [ "elasticsearch-ruby/#{Elasticsearch::VERSION}", "elastic-transport-ruby/#{Elastic::Transport::VERSION}", "RUBY_VERSION: #{RUBY_VERSION}" ] if RbConfig::CONFIG && RbConfig::CONFIG['host_os'] user_agent << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}" end arguments[:transport_options] ||= {} arguments[:transport_options][:headers] ||= {} arguments[:transport_options][:headers].merge!({ user_agent: user_agent.join('; ')}) end
# File lib/elasticsearch.rb, line 140 def setup_cloud(arguments) arguments[:hosts] = setup_cloud_host( arguments[:cloud_id], arguments[:user], arguments[:password], arguments[:port] ) end
# File lib/elasticsearch.rb, line 108 def setup_cloud_host(cloud_id, user, password, port) name = cloud_id.split(':')[0] base64_decoded = cloud_id.gsub("#{name}:", '').unpack1('m') cloud_url, elasticsearch_instance = base64_decoded.split('$') if cloud_url.include?(':') url, port = cloud_url.split(':') host = "#{elasticsearch_instance}.#{url}" else host = "#{elasticsearch_instance}.#{cloud_url}" port ||= DEFAULT_CLOUD_PORT end [{ scheme: 'https', user: user, password: password, host: host, port: port.to_i }] end
# File lib/elasticsearch.rb, line 84 def verify_elasticsearch(*args, &block) begin response = @transport.perform_request(*args, &block) rescue Elastic::Transport::Transport::Errors::Unauthorized, Elastic::Transport::Transport::Errors::Forbidden, Elastic::Transport::Transport::Errors::RequestEntityTooLarge => e warn(SECURITY_PRIVILEGES_VALIDATION_WARNING) @verified = true raise e rescue Elastic::Transport::Transport::Error => e unless @warned warn(VALIDATION_WARNING) @warned = true end raise e rescue StandardError => e warn(VALIDATION_WARNING) raise e end raise Elasticsearch::UnsupportedProductError unless response.headers['x-elastic-product'] == 'Elasticsearch' @verified = true response end