logstash-filter-elasticsearch 3.19.0 → 3.19.1
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 +3 -0
- data/docs/index.asciidoc +6 -2
- data/lib/logstash/filters/elasticsearch/client.rb +30 -2
- data/lib/logstash/filters/elasticsearch.rb +2 -1
- data/logstash-filter-elasticsearch.gemspec +2 -2
- data/spec/filters/elasticsearch_spec.rb +43 -6
- data/version +1 -0
- metadata +14 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9a0e21ee3a328a2c9f6ad6a7cba6035f09fdc3a760787441efc9746b0db53a00
|
|
4
|
+
data.tar.gz: 66facd522d9a822e62529bd6fc99207db46070232f13558fef87565002c24a9c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: baebe8460aaaa98b3c84da38a52e344a840beed5cfe6ae7359a07b4a86e2403d01ed693755b5e7750c6f8c56586be0ad51aac306e7f5a112c03398ffe4138015
|
|
7
|
+
data.tar.gz: 97afa7a8436f4a27472c60670230ed6746f84c12e7daeff3ff08723cddcf57402e1918ef4dca1d8fe0b51aa9fb2318d0f529f89fd148b29bf4d9aec146502ec6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
## 3.19.1
|
|
2
|
+
- Support base64-encoded and Elastic Cloud (`essu_`-prefixed) API keys in the `api_key` option; reject unrecognized formats at startup. [#229](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/229)
|
|
3
|
+
|
|
1
4
|
## 3.19.0
|
|
2
5
|
- ES|QL support [#199](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/199)
|
|
3
6
|
|
data/docs/index.asciidoc
CHANGED
|
@@ -305,8 +305,12 @@ Example:
|
|
|
305
305
|
Authenticate using Elasticsearch API key. Note that this option also requires
|
|
306
306
|
enabling the <<plugins-{type}s-{plugin}-ssl_enabled>> option.
|
|
307
307
|
|
|
308
|
-
|
|
309
|
-
Elasticsearch
|
|
308
|
+
The format is `id:api_key`, where `id` and `api_key` are as returned by the
|
|
309
|
+
Elasticsearch
|
|
310
|
+
{ref}/security-api-create-api-key.html[Create
|
|
311
|
+
API key API]. The base64-encoded form of that pair is also accepted, as is an
|
|
312
|
+
https://www.elastic.co/docs/deploy-manage/api-keys/elastic-cloud-api-keys[Elastic Cloud API key]
|
|
313
|
+
(prefixed with `essu_`), which is used as-is.
|
|
310
314
|
|
|
311
315
|
[id="plugins-{type}s-{plugin}-ca_trusted_fingerprint"]
|
|
312
316
|
===== `ca_trusted_fingerprint`
|
|
@@ -101,12 +101,40 @@ module LogStash
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
def setup_api_key(api_key)
|
|
104
|
-
return {} unless (api_key
|
|
104
|
+
return {} unless (api_key&.value)
|
|
105
105
|
|
|
106
|
-
token =
|
|
106
|
+
token = resolve_api_key(api_key.value)
|
|
107
107
|
{ 'Authorization' => "ApiKey #{token}" }
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
+
# Resolves the `api_key` value into the credential used in the
|
|
111
|
+
# `Authorization: ApiKey` header. An already base64-encoded key and an Elastic
|
|
112
|
+
# Cloud API key are used as-is; a raw `id:api_key` pair is base64-encoded. An
|
|
113
|
+
# unrecognized value is rejected so a malformed key surfaces at startup rather
|
|
114
|
+
# than as a later authentication failure.
|
|
115
|
+
def resolve_api_key(key_value)
|
|
116
|
+
if base64?(key_value) || cloud_api_key?(key_value)
|
|
117
|
+
key_value
|
|
118
|
+
elsif key_value.match?(/\A[^:]+:[^:]+\z/)
|
|
119
|
+
Base64.strict_encode64(key_value)
|
|
120
|
+
else
|
|
121
|
+
raise LogStash::ConfigurationError, "Invalid api_key format. Expected a base64-encoded key, an 'id:api_key' pair, or a Cloud API key (essu_ prefix)."
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Elastic Cloud API keys (such as the unified Serverless keys) are opaque
|
|
126
|
+
# tokens prefixed with `essu_` that Elasticsearch accepts verbatim in the
|
|
127
|
+
# `Authorization: ApiKey` header, with no base64 encoding.
|
|
128
|
+
def cloud_api_key?(string)
|
|
129
|
+
string.match?(/\Aessu_.+/)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def base64?(string)
|
|
133
|
+
string == Base64.strict_encode64(Base64.strict_decode64(string))
|
|
134
|
+
rescue ArgumentError
|
|
135
|
+
false
|
|
136
|
+
end
|
|
137
|
+
|
|
110
138
|
def get_transport_client_class
|
|
111
139
|
# LS-core includes `elasticsearch` gem. The gem is composed of two separate gems: `elasticsearch-api` and `elasticsearch-transport`
|
|
112
140
|
# And now `elasticsearch-transport` is old, instead we have `elastic-transport`.
|
|
@@ -73,7 +73,8 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
|
73
73
|
config :cloud_auth, :validate => :password
|
|
74
74
|
|
|
75
75
|
# Authenticate using Elasticsearch API key.
|
|
76
|
-
#
|
|
76
|
+
# Format is either the `id:api_key` pair (as returned by https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html[Create API key]),
|
|
77
|
+
# its base64-encoded form, or an https://www.elastic.co/docs/deploy-manage/api-keys/elastic-cloud-api-keys[Elastic Cloud API key] (prefixed with `essu_`) can be used.
|
|
77
78
|
config :api_key, :validate => :password
|
|
78
79
|
|
|
79
80
|
# Set the address of a forward HTTP proxy.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
|
|
3
3
|
s.name = 'logstash-filter-elasticsearch'
|
|
4
|
-
s.version = '
|
|
4
|
+
s.version = ::File.read('version').split("\n").first
|
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
|
6
6
|
s.summary = "Copies fields from previous log events in Elasticsearch to current events "
|
|
7
7
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
|
11
11
|
s.require_paths = ["lib"]
|
|
12
12
|
|
|
13
13
|
# Files
|
|
14
|
-
s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
|
|
14
|
+
s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "version", "docs/**/*"]
|
|
15
15
|
|
|
16
16
|
# Tests
|
|
17
17
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
|
@@ -4,6 +4,7 @@ require "logstash/plugin"
|
|
|
4
4
|
require "logstash/filters/elasticsearch"
|
|
5
5
|
require "logstash/json"
|
|
6
6
|
require "cabin"
|
|
7
|
+
require "manticore"
|
|
7
8
|
require "webrick"
|
|
8
9
|
require "uri"
|
|
9
10
|
|
|
@@ -324,14 +325,50 @@ describe LogStash::Filters::Elasticsearch do
|
|
|
324
325
|
end
|
|
325
326
|
|
|
326
327
|
context "with ssl" do
|
|
327
|
-
let(:
|
|
328
|
+
let(:api_key_value) { nil }
|
|
329
|
+
let(:config) { super().merge("ssl_enabled" => true, 'api_key' => LogStash::Util::Password.new(api_key_value)) }
|
|
330
|
+
let(:encoded_api_key) { Base64.strict_encode64('foo:bar') }
|
|
328
331
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
332
|
+
shared_examples "a plugin that sets the ApiKey authorization header" do
|
|
333
|
+
it "correctly sets the Authorization header" do
|
|
334
|
+
plugin.register
|
|
335
|
+
client = plugin.send(:get_client).client
|
|
336
|
+
auth_header = extract_transport(client).options[:transport_options][:headers]['Authorization']
|
|
337
|
+
|
|
338
|
+
expect(auth_header).to eql("ApiKey #{encoded_api_key}")
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
context "with a non-encoded API key" do
|
|
343
|
+
let(:api_key_value) { "foo:bar" }
|
|
344
|
+
it_behaves_like "a plugin that sets the ApiKey authorization header"
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
context "with an encoded API key" do
|
|
348
|
+
let(:api_key_value) { encoded_api_key }
|
|
349
|
+
it_behaves_like "a plugin that sets the ApiKey authorization header"
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
context "with an Elastic Cloud API key (essu_ prefix)" do
|
|
353
|
+
# The suffix is intentionally not canonical base64: a Cloud key is opaque
|
|
354
|
+
# and must be forwarded verbatim regardless of its payload encoding.
|
|
355
|
+
let(:api_key_value) { "essu_VFZGblZreFhTekJ4ZDB4M2NHUnZRMEU2YzNWd1pYSnpaV055WlhRPQ==AAAAAAAA" }
|
|
356
|
+
|
|
357
|
+
it "sets the Authorization header verbatim without re-encoding" do
|
|
358
|
+
plugin.register
|
|
359
|
+
client = plugin.send(:get_client).client
|
|
360
|
+
auth_header = extract_transport(client).options[:transport_options][:headers]['Authorization']
|
|
361
|
+
|
|
362
|
+
expect(auth_header).to eql("ApiKey #{api_key_value}")
|
|
363
|
+
end
|
|
364
|
+
end
|
|
333
365
|
|
|
334
|
-
|
|
366
|
+
context "with an unrecognized api_key format" do
|
|
367
|
+
let(:api_key_value) { "not-a-valid-key" }
|
|
368
|
+
|
|
369
|
+
it "fails registration with a configuration error" do
|
|
370
|
+
expect { plugin.register }.to raise_error(LogStash::ConfigurationError, /Invalid api_key format/)
|
|
371
|
+
end
|
|
335
372
|
end
|
|
336
373
|
|
|
337
374
|
context 'user also set' do
|
data/version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.19.1
|
metadata
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logstash-filter-elasticsearch
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.19.
|
|
4
|
+
version: 3.19.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Elastic
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-07-17 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: logstash-core-plugin-api
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
@@ -19,7 +19,6 @@ dependencies:
|
|
|
19
19
|
- - "<="
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
21
|
version: '2.99'
|
|
22
|
-
name: logstash-core-plugin-api
|
|
23
22
|
type: :runtime
|
|
24
23
|
prerelease: false
|
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -31,6 +30,7 @@ dependencies:
|
|
|
31
30
|
- !ruby/object:Gem::Version
|
|
32
31
|
version: '2.99'
|
|
33
32
|
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: elasticsearch
|
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
|
35
35
|
requirements:
|
|
36
36
|
- - ">="
|
|
@@ -39,7 +39,6 @@ dependencies:
|
|
|
39
39
|
- - "<"
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
41
|
version: '9'
|
|
42
|
-
name: elasticsearch
|
|
43
42
|
type: :runtime
|
|
44
43
|
prerelease: false
|
|
45
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -51,12 +50,12 @@ dependencies:
|
|
|
51
50
|
- !ruby/object:Gem::Version
|
|
52
51
|
version: '9'
|
|
53
52
|
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: manticore
|
|
54
54
|
requirement: !ruby/object:Gem::Requirement
|
|
55
55
|
requirements:
|
|
56
56
|
- - ">="
|
|
57
57
|
- !ruby/object:Gem::Version
|
|
58
58
|
version: 0.7.1
|
|
59
|
-
name: manticore
|
|
60
59
|
type: :runtime
|
|
61
60
|
prerelease: false
|
|
62
61
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -65,12 +64,12 @@ dependencies:
|
|
|
65
64
|
- !ruby/object:Gem::Version
|
|
66
65
|
version: 0.7.1
|
|
67
66
|
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: logstash-mixin-ecs_compatibility_support
|
|
68
68
|
requirement: !ruby/object:Gem::Requirement
|
|
69
69
|
requirements:
|
|
70
70
|
- - "~>"
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
72
|
version: '1.3'
|
|
73
|
-
name: logstash-mixin-ecs_compatibility_support
|
|
74
73
|
type: :runtime
|
|
75
74
|
prerelease: false
|
|
76
75
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -79,12 +78,12 @@ dependencies:
|
|
|
79
78
|
- !ruby/object:Gem::Version
|
|
80
79
|
version: '1.3'
|
|
81
80
|
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: logstash-mixin-ca_trusted_fingerprint_support
|
|
82
82
|
requirement: !ruby/object:Gem::Requirement
|
|
83
83
|
requirements:
|
|
84
84
|
- - "~>"
|
|
85
85
|
- !ruby/object:Gem::Version
|
|
86
86
|
version: '1.0'
|
|
87
|
-
name: logstash-mixin-ca_trusted_fingerprint_support
|
|
88
87
|
type: :runtime
|
|
89
88
|
prerelease: false
|
|
90
89
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -93,12 +92,12 @@ dependencies:
|
|
|
93
92
|
- !ruby/object:Gem::Version
|
|
94
93
|
version: '1.0'
|
|
95
94
|
- !ruby/object:Gem::Dependency
|
|
95
|
+
name: logstash-mixin-normalize_config_support
|
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
|
97
97
|
requirements:
|
|
98
98
|
- - "~>"
|
|
99
99
|
- !ruby/object:Gem::Version
|
|
100
100
|
version: '1.0'
|
|
101
|
-
name: logstash-mixin-normalize_config_support
|
|
102
101
|
type: :runtime
|
|
103
102
|
prerelease: false
|
|
104
103
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -107,12 +106,12 @@ dependencies:
|
|
|
107
106
|
- !ruby/object:Gem::Version
|
|
108
107
|
version: '1.0'
|
|
109
108
|
- !ruby/object:Gem::Dependency
|
|
109
|
+
name: logstash-mixin-validator_support
|
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
|
111
111
|
requirements:
|
|
112
112
|
- - "~>"
|
|
113
113
|
- !ruby/object:Gem::Version
|
|
114
114
|
version: '1.0'
|
|
115
|
-
name: logstash-mixin-validator_support
|
|
116
115
|
type: :runtime
|
|
117
116
|
prerelease: false
|
|
118
117
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -121,12 +120,12 @@ dependencies:
|
|
|
121
120
|
- !ruby/object:Gem::Version
|
|
122
121
|
version: '1.0'
|
|
123
122
|
- !ruby/object:Gem::Dependency
|
|
123
|
+
name: cabin
|
|
124
124
|
requirement: !ruby/object:Gem::Requirement
|
|
125
125
|
requirements:
|
|
126
126
|
- - "~>"
|
|
127
127
|
- !ruby/object:Gem::Version
|
|
128
128
|
version: '0.6'
|
|
129
|
-
name: cabin
|
|
130
129
|
type: :development
|
|
131
130
|
prerelease: false
|
|
132
131
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -135,12 +134,12 @@ dependencies:
|
|
|
135
134
|
- !ruby/object:Gem::Version
|
|
136
135
|
version: '0.6'
|
|
137
136
|
- !ruby/object:Gem::Dependency
|
|
137
|
+
name: webrick
|
|
138
138
|
requirement: !ruby/object:Gem::Requirement
|
|
139
139
|
requirements:
|
|
140
140
|
- - ">="
|
|
141
141
|
- !ruby/object:Gem::Version
|
|
142
142
|
version: '0'
|
|
143
|
-
name: webrick
|
|
144
143
|
type: :development
|
|
145
144
|
prerelease: false
|
|
146
145
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -149,12 +148,12 @@ dependencies:
|
|
|
149
148
|
- !ruby/object:Gem::Version
|
|
150
149
|
version: '0'
|
|
151
150
|
- !ruby/object:Gem::Dependency
|
|
151
|
+
name: logstash-devutils
|
|
152
152
|
requirement: !ruby/object:Gem::Requirement
|
|
153
153
|
requirements:
|
|
154
154
|
- - ">="
|
|
155
155
|
- !ruby/object:Gem::Version
|
|
156
156
|
version: '0'
|
|
157
|
-
name: logstash-devutils
|
|
158
157
|
type: :development
|
|
159
158
|
prerelease: false
|
|
160
159
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -213,13 +212,13 @@ files:
|
|
|
213
212
|
- spec/filters/fixtures/test_certs/ls.key
|
|
214
213
|
- spec/filters/integration/elasticsearch_esql_spec.rb
|
|
215
214
|
- spec/filters/integration/elasticsearch_spec.rb
|
|
215
|
+
- version
|
|
216
216
|
homepage: https://elastic.co/logstash
|
|
217
217
|
licenses:
|
|
218
218
|
- Apache License (2.0)
|
|
219
219
|
metadata:
|
|
220
220
|
logstash_plugin: 'true'
|
|
221
221
|
logstash_group: filter
|
|
222
|
-
post_install_message:
|
|
223
222
|
rdoc_options: []
|
|
224
223
|
require_paths:
|
|
225
224
|
- lib
|
|
@@ -234,8 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
234
233
|
- !ruby/object:Gem::Version
|
|
235
234
|
version: '0'
|
|
236
235
|
requirements: []
|
|
237
|
-
rubygems_version: 3.3
|
|
238
|
-
signing_key:
|
|
236
|
+
rubygems_version: 3.6.3
|
|
239
237
|
specification_version: 4
|
|
240
238
|
summary: Copies fields from previous log events in Elasticsearch to current events
|
|
241
239
|
test_files:
|