elastic-transport 8.5.2 → 8.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -6
- data/lib/elastic/transport/client.rb +8 -29
- data/lib/elastic/transport/transport/base.rb +11 -9
- data/lib/elastic/transport/transport/ca_fingerprint.rb +131 -0
- data/lib/elastic/transport/transport/connections/connection.rb +0 -2
- data/lib/elastic/transport/transport/http/curb.rb +3 -0
- data/lib/elastic/transport/transport/http/manticore.rb +8 -0
- data/lib/elastic/transport/version.rb +1 -1
- data/lib/elastic/transport.rb +1 -0
- metadata +8 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d020bb42e417e2c6ac4a2f45502217df668c4d8d22d41ff2e420a3e4e816b95
|
|
4
|
+
data.tar.gz: 2944d994083d8d36b6b8f212c05516b34bf5bd6c985402496af9c2200a0f9f6f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 166ba90d59e3239807a0f3ba9329ab1d0f844a59a17aac1607c5541789dbb9760367191f0c2ab0e716cb9abc9386284b32a713fd5255af847fb65e7653545368
|
|
7
|
+
data.tar.gz: 8fb41bdd95ca8163c0e6f736105b91d1f484706c19caa682b8caefdfa97ad37c7190e640907fca0a7eae9c4278450895d5c82d38154515167f3609f8ad75b51b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
## 8.
|
|
1
|
+
## 8.6.0
|
|
2
2
|
|
|
3
|
-
-
|
|
4
|
-
-
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
3
|
+
- **Breaking:** fixes `ca_fingerprint` so it secures the connections used for requests. The certificate matching the fingerprint is fetched from the server's chain and used as the only trusted certificate on every connection, with chain and expiry verification left on. Host names aren't checked (a pinned intermediate can't be used on JRuby, and the certificate is fetched without a proxy), so a cluster reached by a name or IP that isn't in its certificate works (Faraday 1 and Manticore still check them). Previously the fingerprint was checked on a separate socket and matched any certificate the server sent, without checking that the server's certificate was signed by it.
|
|
4
|
+
- `ca_fingerprint` raises an `ArgumentError` when combined with `verify: false` (or Manticore's `:none`/`:disable`), `ca_file`, `ca_path`, `cert_store` or `truststore`, in `transport_options[:ssl]` or `:ssl`. Remove `verify: false` if you followed the previous docs.
|
|
5
|
+
- The Curb transport now reads `ca_file` and `verify: false` from `transport_options[:ssl]`.
|
|
6
|
+
- `ca_fingerprint` raises an `ArgumentError` when combined with a custom `:transport` instance.
|
|
7
|
+
- Removes `Connection#verified`.
|
|
8
8
|
|
|
9
9
|
## 8.5.1
|
|
10
10
|
|
|
@@ -117,7 +117,11 @@ module Elastic
|
|
|
117
117
|
#
|
|
118
118
|
# @option enable_meta_header [Boolean] :enable_meta_header Enable sending the meta data header to Cloud.
|
|
119
119
|
# (Default: true)
|
|
120
|
-
# @option
|
|
120
|
+
# @option arguments [String] :ca_fingerprint SHA256 fingerprint of a certificate in the server's chain (usually
|
|
121
|
+
# the CA). Before the first request, the matching certificate is fetched from the server and becomes the only
|
|
122
|
+
# trusted certificate for every connection. Chain and expiry are verified, host names aren't (except on
|
|
123
|
+
# Faraday 1 and Manticore). Requires https
|
|
124
|
+
# hosts and the client-built transport (can't be combined with `:transport`).
|
|
121
125
|
#
|
|
122
126
|
# @yield [faraday] Access and configure the `Faraday::Connection` instance directly with a block
|
|
123
127
|
#
|
|
@@ -136,13 +140,14 @@ module Elastic
|
|
|
136
140
|
|
|
137
141
|
@hosts ||= extract_hosts
|
|
138
142
|
@send_get_body_as = @arguments[:send_get_body_as] || 'GET'
|
|
139
|
-
@ca_fingerprint = @arguments.delete(:ca_fingerprint)
|
|
140
143
|
|
|
141
144
|
if @arguments[:request_timeout]
|
|
142
145
|
@arguments[:transport_options][:request] = { timeout: @arguments[:request_timeout] }
|
|
143
146
|
end
|
|
144
147
|
|
|
145
148
|
if @arguments[:transport]
|
|
149
|
+
raise ArgumentError, 'ca_fingerprint can\'t be used with a custom :transport instance' if @arguments[:ca_fingerprint]
|
|
150
|
+
|
|
146
151
|
@transport = @arguments[:transport]
|
|
147
152
|
else
|
|
148
153
|
@transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
|
|
@@ -168,8 +173,7 @@ module Elastic
|
|
|
168
173
|
#
|
|
169
174
|
def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {})
|
|
170
175
|
method = @send_get_body_as if method == 'GET' && body
|
|
171
|
-
|
|
172
|
-
if @otel
|
|
176
|
+
if defined?(@otel) && !@otel.nil?
|
|
173
177
|
# If no endpoint is specified in the opts, use the HTTP method name
|
|
174
178
|
span_name = opts[:endpoint] || method
|
|
175
179
|
@otel.tracer.in_span(span_name) do |span|
|
|
@@ -196,31 +200,6 @@ module Elastic
|
|
|
196
200
|
|
|
197
201
|
private
|
|
198
202
|
|
|
199
|
-
def validate_ca_fingerprints
|
|
200
|
-
transport.connections.connections.each do |connection|
|
|
201
|
-
unless connection.host[:scheme] == 'https'
|
|
202
|
-
raise Elastic::Transport::Transport::Error, 'CA fingerprinting can\'t be configured over http'
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
next if connection.verified
|
|
206
|
-
|
|
207
|
-
ctx = OpenSSL::SSL::SSLContext.new
|
|
208
|
-
socket = TCPSocket.new(connection.host[:host], connection.host[:port])
|
|
209
|
-
ssl = OpenSSL::SSL::SSLSocket.new(socket, ctx)
|
|
210
|
-
ssl.connect
|
|
211
|
-
cert_store = ssl.peer_cert_chain
|
|
212
|
-
matching_certs = cert_store.select do |cert|
|
|
213
|
-
OpenSSL::Digest::SHA256.hexdigest(cert.to_der).upcase == @ca_fingerprint.gsub(':', '').upcase
|
|
214
|
-
end
|
|
215
|
-
if matching_certs.empty?
|
|
216
|
-
raise Elastic::Transport::Transport::Error,
|
|
217
|
-
'Server certificate CA fingerprint does not match the value configured in ca_fingerprint'
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
connection.verified = true
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
|
|
224
203
|
def add_header(header)
|
|
225
204
|
headers = @arguments[:transport_options]&.[](:headers) || {}
|
|
226
205
|
headers.merge!(header)
|
|
@@ -22,6 +22,7 @@ module Elastic
|
|
|
22
22
|
#
|
|
23
23
|
module Base
|
|
24
24
|
include Loggable
|
|
25
|
+
include CaFingerprint
|
|
25
26
|
|
|
26
27
|
DEFAULT_PORT = 9200
|
|
27
28
|
DEFAULT_PROTOCOL = 'http'.freeze
|
|
@@ -48,6 +49,7 @@ module Elastic
|
|
|
48
49
|
#
|
|
49
50
|
def initialize(arguments = {}, &block)
|
|
50
51
|
@state_mutex = Mutex.new
|
|
52
|
+
@ca_pin_mutex = Mutex.new
|
|
51
53
|
|
|
52
54
|
@hosts = arguments[:hosts] || []
|
|
53
55
|
@options = arguments[:options] || {}
|
|
@@ -55,6 +57,7 @@ module Elastic
|
|
|
55
57
|
@options[:retry_on_status] ||= []
|
|
56
58
|
@options[:delay_on_retry] ||= 0
|
|
57
59
|
|
|
60
|
+
validate_ca_fingerprint_options! if @options[:ca_fingerprint]
|
|
58
61
|
@block = block
|
|
59
62
|
@compression = !!@options[:compression]
|
|
60
63
|
@connections = __build_connections
|
|
@@ -166,6 +169,9 @@ module Elastic
|
|
|
166
169
|
host[:password] ||= options[:password] || options[:http][:password]
|
|
167
170
|
end
|
|
168
171
|
|
|
172
|
+
# Hosts added after the pin (reload, sniffing) would otherwise get no protection
|
|
173
|
+
raise Error, 'CA fingerprinting can\'t be configured over http' if @ca_file && host[:protocol] != 'https'
|
|
174
|
+
|
|
169
175
|
__build_connection(host, (options[:transport_options] || {}), @block)
|
|
170
176
|
end
|
|
171
177
|
end
|
|
@@ -273,6 +279,7 @@ module Elastic
|
|
|
273
279
|
def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {}, &block)
|
|
274
280
|
raise NoMethodError, 'Implement this method in your transport class' unless block_given?
|
|
275
281
|
|
|
282
|
+
pin_ca_certificate! if options[:ca_fingerprint]
|
|
276
283
|
start = Time.now
|
|
277
284
|
tries = 0
|
|
278
285
|
reload_on_failure = opts.fetch(:reload_on_failure, @options[:reload_on_failure])
|
|
@@ -356,15 +363,10 @@ module Elastic
|
|
|
356
363
|
end
|
|
357
364
|
|
|
358
365
|
if response.body &&
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
# Prevent Float value from automatically becoming BigDecimal when using Oj
|
|
364
|
-
load_options = {}
|
|
365
|
-
load_options[:mode] = :compat if ::MultiJson.adapter.to_s == "MultiJson::Adapters::Oj"
|
|
366
|
-
|
|
367
|
-
json = serializer.load(response.body, load_options)
|
|
366
|
+
!response.body.empty? &&
|
|
367
|
+
response.headers &&
|
|
368
|
+
response.headers['content-type'] =~ /json/
|
|
369
|
+
json = serializer.load(response.body)
|
|
368
370
|
end
|
|
369
371
|
took = (json['took'] ? sprintf('%.3fs', json['took'] / 1000.0) : 'n/a') rescue 'n/a'
|
|
370
372
|
__log_response(method, path, params, body, url, response, json, took, duration) unless ignore.include?(response.status.to_i)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
require 'openssl'
|
|
19
|
+
require 'socket'
|
|
20
|
+
require 'tempfile'
|
|
21
|
+
require 'timeout'
|
|
22
|
+
|
|
23
|
+
module Elastic
|
|
24
|
+
module Transport
|
|
25
|
+
module Transport
|
|
26
|
+
# Makes the certificate matching the `ca_fingerprint` option the only trust anchor of every connection.
|
|
27
|
+
#
|
|
28
|
+
# Before the first request, the server's certificate chain is fetched once without verification. Only the
|
|
29
|
+
# certificate whose fingerprint matches is kept, so the fetch itself needs no trust. The connections are then
|
|
30
|
+
# rebuilt with that certificate as their only trusted certificate, and the HTTP library verifies the chain and
|
|
31
|
+
# expiry on every connection. Host names aren't checked where the adapter allows that.
|
|
32
|
+
#
|
|
33
|
+
module CaFingerprint
|
|
34
|
+
TRUST_SETTINGS = %i[ca_file ca_path cert_store truststore].freeze
|
|
35
|
+
VERIFY_OFF = [false, :none, :disable].freeze
|
|
36
|
+
FETCH_TIMEOUT = 10
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# The pinned certificate must be the only trust anchor. Other trust settings would be trusted next to it,
|
|
41
|
+
# or silently replaced by it, and turning verification off would turn the pin off too.
|
|
42
|
+
def validate_ca_fingerprint_options!
|
|
43
|
+
[options[:ssl], options.dig(:transport_options, :ssl)].compact.each do |ssl|
|
|
44
|
+
ssl = ssl.to_h
|
|
45
|
+
if VERIFY_OFF.include?(ssl[:verify]) || TRUST_SETTINGS.any? { |key| ssl[key] }
|
|
46
|
+
raise ArgumentError,
|
|
47
|
+
"ca_fingerprint can't be combined with :verify off or with #{TRUST_SETTINGS.join(', ')}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def pin_ca_certificate!
|
|
53
|
+
return if @ca_file
|
|
54
|
+
|
|
55
|
+
@ca_pin_mutex.synchronize do
|
|
56
|
+
return if @ca_file
|
|
57
|
+
|
|
58
|
+
ca = fetch_pinned_certificate
|
|
59
|
+
store = OpenSSL::X509::Store.new
|
|
60
|
+
# Without PARTIAL_CHAIN, OpenSSL only trusts a chain that ends in a self-signed root in the store. With it,
|
|
61
|
+
# the pinned certificate is a trust anchor even when it is an intermediate. ponytail: jruby-openssl lacks
|
|
62
|
+
# the flag, so on JRuby the fingerprint has to be the root CA's.
|
|
63
|
+
store.flags = OpenSSL::X509::V_FLAG_PARTIAL_CHAIN if defined?(OpenSSL::X509::V_FLAG_PARTIAL_CHAIN)
|
|
64
|
+
store.add_cert(ca)
|
|
65
|
+
# The Tempfile is deleted when garbage collected, so @ca_file keeps a reference to it.
|
|
66
|
+
# Curb, Manticore and libcurl-based Faraday adapters only accept a CA file
|
|
67
|
+
ca_file = Tempfile.new(['ca_fingerprint', '.pem'])
|
|
68
|
+
ca_file.write(ca.to_pem)
|
|
69
|
+
ca_file.flush
|
|
70
|
+
|
|
71
|
+
pin = { cert_store: store, ca_file: ca_file.path }
|
|
72
|
+
# The pin is the trust decision, host names add nothing (elastic/security#6842), and clusters reached by
|
|
73
|
+
# a container service name or IP must work. ponytail: Faraday 1 and Manticore have no host-name-only
|
|
74
|
+
# switch, so they still check host names.
|
|
75
|
+
pin[:verify_hostname] = false if !is_a?(HTTP::Faraday) || ::Faraday::SSLOptions.members.include?(:verify_hostname)
|
|
76
|
+
# New hashes, so the caller's option hashes aren't changed
|
|
77
|
+
transport_options = options[:transport_options] || {}
|
|
78
|
+
options[:transport_options] = transport_options.merge(ssl: (transport_options[:ssl] || {}).merge(pin))
|
|
79
|
+
options[:ssl] = (options[:ssl] || {}).merge(ca_file: ca_file.path) # Manticore reads top-level :ssl
|
|
80
|
+
__rebuild_pinned_connections
|
|
81
|
+
@ca_file = ca_file
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Replaces every connection, so none built before the pin stays in use.
|
|
86
|
+
def __rebuild_pinned_connections
|
|
87
|
+
@state_mutex.synchronize do
|
|
88
|
+
__close_connections
|
|
89
|
+
@connections = __build_connections
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def fetch_pinned_certificate
|
|
94
|
+
unless hosts.all? { |host| host[:protocol] == 'https' }
|
|
95
|
+
raise Error, 'CA fingerprinting can\'t be configured over http'
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
fingerprint = options[:ca_fingerprint].delete(':').upcase
|
|
99
|
+
chain = reachable_peer_cert_chain
|
|
100
|
+
ca = chain.find { |cert| OpenSSL::Digest::SHA256.hexdigest(cert.to_der).upcase == fingerprint }
|
|
101
|
+
ca or raise Error, 'Server certificate CA fingerprint does not match the value configured in ca_fingerprint'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Takes the chain of the first host that answers. Every other host must chain to the same certificate, or
|
|
105
|
+
# its connections fail verification.
|
|
106
|
+
def reachable_peer_cert_chain
|
|
107
|
+
error = nil
|
|
108
|
+
hosts.each do |host|
|
|
109
|
+
return peer_cert_chain(host)
|
|
110
|
+
rescue SystemCallError, SocketError, IOError, OpenSSL::SSL::SSLError, Timeout::Error => e
|
|
111
|
+
error = e
|
|
112
|
+
end
|
|
113
|
+
raise Error, "Couldn't fetch the server certificate for ca_fingerprint: #{error.message}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def peer_cert_chain(host)
|
|
117
|
+
context = OpenSSL::SSL::SSLContext.new
|
|
118
|
+
context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
119
|
+
socket = Socket.tcp(host[:host], host[:port], connect_timeout: FETCH_TIMEOUT)
|
|
120
|
+
ssl = OpenSSL::SSL::SSLSocket.new(socket, context)
|
|
121
|
+
ssl.hostname = host[:host]
|
|
122
|
+
Timeout.timeout(FETCH_TIMEOUT) { ssl.connect }
|
|
123
|
+
ssl.peer_cert_chain
|
|
124
|
+
ensure
|
|
125
|
+
ssl&.close
|
|
126
|
+
socket&.close
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -33,7 +33,6 @@ module Elastic
|
|
|
33
33
|
DEFAULT_RESURRECT_TIMEOUT = 60
|
|
34
34
|
|
|
35
35
|
attr_reader :host, :connection, :options, :failures, :dead_since
|
|
36
|
-
attr_accessor :verified
|
|
37
36
|
|
|
38
37
|
# @option arguments [Hash] :host Host information (example: `{host: 'localhost', port: 9200}`)
|
|
39
38
|
# @option arguments [Object] :connection The transport-specific physical connection or "session"
|
|
@@ -43,7 +42,6 @@ module Elastic
|
|
|
43
42
|
@host = arguments[:host].is_a?(Hash) ? Redacted.new(arguments[:host]) : arguments[:host]
|
|
44
43
|
@connection = arguments[:connection]
|
|
45
44
|
@options = arguments[:options] || {}
|
|
46
|
-
@verified = false
|
|
47
45
|
@state_mutex = Mutex.new
|
|
48
46
|
|
|
49
47
|
@options[:resurrect_timeout] ||= DEFAULT_RESURRECT_TIMEOUT
|
|
@@ -83,6 +83,9 @@ module Elastic
|
|
|
83
83
|
|
|
84
84
|
apply_headers(client, options)
|
|
85
85
|
client.url = __full_url(host)
|
|
86
|
+
client.cacert = options.dig(:ssl, :ca_file) if options.dig(:ssl, :ca_file)
|
|
87
|
+
client.ssl_verify_peer = false if options.dig(:ssl, :verify) == false
|
|
88
|
+
client.ssl_verify_host = 0 if options.dig(:ssl, :verify) == false || options.dig(:ssl, :verify_hostname) == false
|
|
86
89
|
|
|
87
90
|
if host[:user]
|
|
88
91
|
client.http_auth_types = host[:auth_type] || :basic
|
|
@@ -158,6 +158,14 @@ module Elastic
|
|
|
158
158
|
|
|
159
159
|
private
|
|
160
160
|
|
|
161
|
+
# Faraday and Curb read the pinned CA when a connection is built, so rebuilding connections is enough.
|
|
162
|
+
# Manticore reads it once, when the Manticore::Client is built in initialize, so the client is built again.
|
|
163
|
+
def __rebuild_pinned_connections
|
|
164
|
+
@manticore.close
|
|
165
|
+
build_client(options)
|
|
166
|
+
super
|
|
167
|
+
end
|
|
168
|
+
|
|
161
169
|
def parse_headers(headers)
|
|
162
170
|
request_headers = @request_options.fetch(:headers, {})
|
|
163
171
|
headers = request_headers.merge(headers || {})
|
data/lib/elastic/transport.rb
CHANGED
|
@@ -26,6 +26,7 @@ require 'elastic/transport/transport/serializer/multi_json'
|
|
|
26
26
|
require 'elastic/transport/transport/sniffer'
|
|
27
27
|
require 'elastic/transport/transport/response'
|
|
28
28
|
require 'elastic/transport/transport/errors'
|
|
29
|
+
require 'elastic/transport/transport/ca_fingerprint'
|
|
29
30
|
require 'elastic/transport/transport/base'
|
|
30
31
|
require 'elastic/transport/transport/connections/selector'
|
|
31
32
|
require 'elastic/transport/transport/connections/connection'
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: elastic-transport
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.
|
|
4
|
+
version: 8.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Elastic Client Library Maintainers
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-11-10 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: faraday
|
|
@@ -242,8 +243,8 @@ email:
|
|
|
242
243
|
executables: []
|
|
243
244
|
extensions: []
|
|
244
245
|
extra_rdoc_files:
|
|
245
|
-
- LICENSE
|
|
246
246
|
- README.md
|
|
247
|
+
- LICENSE
|
|
247
248
|
files:
|
|
248
249
|
- CHANGELOG.md
|
|
249
250
|
- CONTRIBUTING.md
|
|
@@ -256,6 +257,7 @@ files:
|
|
|
256
257
|
- lib/elastic/transport/opentelemetry.rb
|
|
257
258
|
- lib/elastic/transport/redacted.rb
|
|
258
259
|
- lib/elastic/transport/transport/base.rb
|
|
260
|
+
- lib/elastic/transport/transport/ca_fingerprint.rb
|
|
259
261
|
- lib/elastic/transport/transport/connections/collection.rb
|
|
260
262
|
- lib/elastic/transport/transport/connections/connection.rb
|
|
261
263
|
- lib/elastic/transport/transport/connections/selector.rb
|
|
@@ -276,6 +278,7 @@ metadata:
|
|
|
276
278
|
changelog_uri: https://github.com/elastic/elastic-transport-ruby/blob/master/CHANGELOG.md
|
|
277
279
|
source_code_uri: https://github.com/elastic/elastic-transport-ruby
|
|
278
280
|
bug_tracker_uri: https://github.com/elastic/elastic-transport-ruby/issues
|
|
281
|
+
post_install_message:
|
|
279
282
|
rdoc_options:
|
|
280
283
|
- "--charset=UTF-8"
|
|
281
284
|
require_paths:
|
|
@@ -291,7 +294,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
291
294
|
- !ruby/object:Gem::Version
|
|
292
295
|
version: '0'
|
|
293
296
|
requirements: []
|
|
294
|
-
rubygems_version:
|
|
297
|
+
rubygems_version: 3.5.22
|
|
298
|
+
signing_key:
|
|
295
299
|
specification_version: 4
|
|
296
300
|
summary: Low level Ruby client for Elastic services.
|
|
297
301
|
test_files: []
|