logstash-filter-elastic_integration 0.0.1-java

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9c797a3d5774cab43738ee098605fcba0a8df86d104b5334d38b27f882e7b086
4
+ data.tar.gz: 43d2a785e22bf742e3e3fb9ba0ae93a7b2ede62ed6a25fae590fbd6c869eb729
5
+ SHA512:
6
+ metadata.gz: 2ed848a542bf89c151122bdf98d7ca7c85573ee3d81e5019632f2a1be2c61941d704e21342f28c1e52680956a862a823939e43c61d682e59a877bbedd198c0e6
7
+ data.tar.gz: 3d2231665a2277b8bed047b1fbf412e56d3e84926893769e69277d1e3d400781d41c2e0551b8d21e3b0ba9eaab1621c7514f497c87ea07f402b740d90b1e2fc4
data/LICENSE.md ADDED
@@ -0,0 +1,93 @@
1
+ Elastic License 2.0
2
+
3
+ URL: https://www.elastic.co/licensing/elastic-license
4
+
5
+ ## Acceptance
6
+
7
+ By using the software, you agree to all of the terms and conditions below.
8
+
9
+ ## Copyright License
10
+
11
+ The licensor grants you a non-exclusive, royalty-free, worldwide,
12
+ non-sublicensable, non-transferable license to use, copy, distribute, make
13
+ available, and prepare derivative works of the software, in each case subject to
14
+ the limitations and conditions below.
15
+
16
+ ## Limitations
17
+
18
+ You may not provide the software to third parties as a hosted or managed
19
+ service, where the service provides users with access to any substantial set of
20
+ the features or functionality of the software.
21
+
22
+ You may not move, change, disable, or circumvent the license key functionality
23
+ in the software, and you may not remove or obscure any functionality in the
24
+ software that is protected by the license key.
25
+
26
+ You may not alter, remove, or obscure any licensing, copyright, or other notices
27
+ of the licensor in the software. Any use of the licensor’s trademarks is subject
28
+ to applicable law.
29
+
30
+ ## Patents
31
+
32
+ The licensor grants you a license, under any patent claims the licensor can
33
+ license, or becomes able to license, to make, have made, use, sell, offer for
34
+ sale, import and have imported the software, in each case subject to the
35
+ limitations and conditions in this license. This license does not cover any
36
+ patent claims that you cause to be infringed by modifications or additions to
37
+ the software. If you or your company make any written claim that the software
38
+ infringes or contributes to infringement of any patent, your patent license for
39
+ the software granted under these terms ends immediately. If your company makes
40
+ such a claim, your patent license ends immediately for work on behalf of your
41
+ company.
42
+
43
+ ## Notices
44
+
45
+ You must ensure that anyone who gets a copy of any part of the software from you
46
+ also gets a copy of these terms.
47
+
48
+ If you modify the software, you must include in any modified copies of the
49
+ software prominent notices stating that you have modified the software.
50
+
51
+ ## No Other Rights
52
+
53
+ These terms do not imply any licenses other than those expressly granted in
54
+ these terms.
55
+
56
+ ## Termination
57
+
58
+ If you use the software in violation of these terms, such use is not licensed,
59
+ and your licenses will automatically terminate. If the licensor provides you
60
+ with a notice of your violation, and you cease all violation of this license no
61
+ later than 30 days after you receive that notice, your licenses will be
62
+ reinstated retroactively. However, if you violate these terms after such
63
+ reinstatement, any additional violation of these terms will cause your licenses
64
+ to terminate automatically and permanently.
65
+
66
+ ## No Liability
67
+
68
+ *As far as the law allows, the software comes as is, without any warranty or
69
+ condition, and the licensor will not be liable to you for any damages arising
70
+ out of these terms or the use or nature of the software, under any kind of
71
+ legal claim.*
72
+
73
+ ## Definitions
74
+
75
+ The **licensor** is the entity offering these terms, and the **software** is the
76
+ software the licensor makes available under these terms, including any portion
77
+ of it.
78
+
79
+ **you** refers to the individual or entity agreeing to these terms.
80
+
81
+ **your company** is any legal entity, sole proprietorship, or other kind of
82
+ organization that you work for, plus all organizations that have control over,
83
+ are under the control of, or are under common control with that
84
+ organization. **control** means ownership of substantially all the assets of an
85
+ entity, or the power to direct its management and policies by vote, contract, or
86
+ otherwise. Control can be direct or indirect.
87
+
88
+ **your licenses** are all the licenses granted to you for the software under
89
+ these terms.
90
+
91
+ **use** means anything you do with the software requiring one of your licenses.
92
+
93
+ **trademark** means trademarks, service marks, and similar rights.
data/NOTICE.txt ADDED
@@ -0,0 +1,5 @@
1
+ Elastic Integration filter for Logstash
2
+ Copyright (c) 2023 Elastic, N.V.
3
+
4
+ Distributable artifacts of this product include software developed
5
+ by The Apache Software Foundation (http://www.apache.org/).
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ ########################################################################
4
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V.
5
+ # under one or more contributor license agreements. Licensed under the
6
+ # Elastic License 2.0; you may not use this file except in compliance
7
+ # with the Elastic License 2.0.
8
+ ########################################################################
9
+
10
+ ##
11
+ # This module contains methods for bridging the gap between the
12
+ # Ruby-API [LogStash::Event] and its Java-API [co.elastic.logstash.api.Event]
13
+ # counterpart, producing bidirectional zero-copy _views_ of one API for use
14
+ # with the other API.
15
+ module LogStash::Filters::ElasticIntegration::EventApiBridge
16
+
17
+ ##
18
+ # Converts a collection of Ruby-API events into a collection
19
+ # of Java-API events.
20
+ #
21
+ # @param ruby_events [Array[LogStash::Event]]
22
+ # @return [Array[co.elastic.logstash.api.Event]]
23
+ def ruby_events_as_java(ruby_events)
24
+ ruby_events.map do |ruby_event|
25
+ mutable_java_view_of_ruby_event(ruby_event)
26
+ end
27
+ end
28
+
29
+ ##
30
+ # Converts a collection of Java-API events into a collection
31
+ # of Ruby-API events.
32
+ #
33
+ # @param java_events [Array[co.elastic.logstash.api.Event]]
34
+ # @return [Array[LogStash::Event]]
35
+ def java_events_as_ruby(java_events)
36
+ java_events.map do |java_event|
37
+ mutable_ruby_view_of_java_event(java_event)
38
+ end
39
+ end
40
+
41
+ ##
42
+ # Returns the Java-API event that backs the provided Ruby-API event.
43
+ # Mutations to the Java-API event are reflected by the Ruby-API event.
44
+ #
45
+ # @param ruby_api_event [LogStash::Event]
46
+ # @return [co.elastic.logstash.api.Event]
47
+ def mutable_java_view_of_ruby_event(ruby_api_event)
48
+ ruby_api_event.to_java
49
+ end
50
+
51
+ # Because LS Core's RubyEvent.newRubyEvent(Runtime, Event)
52
+ # requires the ruby runtime which is constant-once-defined,
53
+ # we look it up and memoize it once.
54
+ RUBY_RUNTIME = self.to_java.getMetaClass().to_java.getClassRuntime()
55
+ private_constant :RUBY_RUNTIME
56
+
57
+ ##
58
+ # Returns a Ruby-API event that is backed by the provided Java-API event.
59
+ # Mutations to the Ruby-API event directly modify the underlying Java-API event.
60
+ #
61
+ # @param java_api_event [co.elastic.logstash.api.Event]
62
+ # @return [LogStash::Event]
63
+ def mutable_ruby_view_of_java_event(java_api_event)
64
+ org.logstash.ext.JrubyEventExtLibrary::RubyEvent.newRubyEvent(RUBY_RUNTIME, java_api_event)
65
+ end
66
+ end
@@ -0,0 +1,11 @@
1
+ # AUTOGENERATED BY THE GRADLE SCRIPT. DO NOT EDIT.
2
+
3
+ ########################################################################
4
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V.
5
+ # under one or more contributor license agreements. Licensed under the
6
+ # Elastic License 2.0; you may not use this file except in compliance
7
+ # with the Elastic License 2.0.
8
+ ########################################################################
9
+
10
+ require 'jar_dependencies'
11
+ require_jar('co.elastic.logstash.plugins.filter.elasticintegration', 'logstash-filter-elastic_integration', '0.0.1')
@@ -0,0 +1,369 @@
1
+ # encoding: utf-8
2
+
3
+ ########################################################################
4
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V.
5
+ # under one or more contributor license agreements. Licensed under the
6
+ # Elastic License 2.0; you may not use this file except in compliance
7
+ # with the Elastic License 2.0.
8
+ ########################################################################
9
+
10
+ require "logstash/filters/base"
11
+ require "logstash/namespace"
12
+
13
+ require_relative "elastic_integration/jar_dependencies"
14
+
15
+ class LogStash::Filters::ElasticIntegration < LogStash::Filters::Base
16
+
17
+ require_relative "elastic_integration/event_api_bridge"
18
+ include EventApiBridge
19
+
20
+ config_name "elastic_integration"
21
+
22
+ java_import('co.elastic.logstash.filters.elasticintegration.PluginConfiguration')
23
+ java_import('co.elastic.logstash.filters.elasticintegration.EventProcessor')
24
+ java_import('co.elastic.logstash.filters.elasticintegration.EventProcessorBuilder')
25
+ java_import('co.elastic.logstash.filters.elasticintegration.ElasticsearchRestClientBuilder')
26
+ java_import('co.elastic.logstash.filters.elasticintegration.PreflightCheck')
27
+
28
+ ELASTICSEARCH_DEFAULT_PORT = 9200.freeze
29
+ ELASTICSEARCH_DEFAULT_PATH = '/'.freeze
30
+ HTTP_PROTOCOL = "http".freeze
31
+ HTTPS_PROTOCOL = "https".freeze
32
+
33
+ # Sets the host(s) of the remote instance. If given an array it will load balance
34
+ # requests across the hosts specified in the `hosts` parameter. Hosts can be any of
35
+ # the forms:
36
+ # `"127.0.0.1"`
37
+ # `["127.0.0.1:9200","127.0.0.2:9200"]`
38
+ # `["http://127.0.0.1"]`
39
+ # `["https://127.0.0.1:9200"]`
40
+ # `["https://127.0.0.1:9200/mypath"]` (If using a proxy on a subpath)
41
+ # If the protocol is unspecified, this plugin assumes `https` when `ssl => true` (default)
42
+ # or `http` when `ssl => false`.
43
+ #
44
+ # It is important to exclude http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html[dedicated master nodes] from the `hosts` list
45
+ # to prevent LS from overloading the master nodes. So this parameter should only reference either data or client nodes in Elasticsearch.
46
+ #
47
+ # Any special characters present in the URLs here MUST be URL escaped! This means `#` should be put in as `%23` for instance.
48
+ config :hosts, :validate => :uri, :list => true
49
+
50
+ # Cloud ID, from the Elastic Cloud web console. If set `hosts` should not be used.
51
+ #
52
+ # For more details, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_id[cloud documentation]
53
+ config :cloud_id, :validate => :string
54
+
55
+ # Enable SSL/TLS secured communication to Elasticsearch cluster
56
+ config :ssl_enabled, :validate => :boolean
57
+
58
+ # Determines how much to verify a presented SSL certificate when `ssl => true`
59
+ # - none: no validation
60
+ # - certificate: trustworthy certificate (identity claims NOT validated)
61
+ # - full (default): trustworthy certificate WITH validated identity claims
62
+ config :ssl_verification_mode, :validate => %w(full certificate none)
63
+
64
+ # A path to truststore, used to _override_ the system truststore
65
+ config :ssl_truststore_path, :validate => :path
66
+
67
+ # A password for truststore
68
+ config :ssl_truststore_password, :validate => :password
69
+
70
+ # list of paths for SSL certificate authorities, used to _override_ the system truststore
71
+ config :ssl_certificate_authorities, :validate => :path, :list => true
72
+
73
+ # a path for SSL certificate which will be used when SSL is enabled
74
+ config :ssl_certificate, :validate => :path
75
+
76
+ # a path for SSL certificate key
77
+ config :ssl_key, :validate => :path
78
+
79
+ # SSL keyphrase
80
+ config :ssl_key_passphrase, :validate => :password
81
+
82
+ # The keystore used to present a certificate to the server
83
+ config :ssl_keystore_path, :validate => :path
84
+
85
+ # A password for SSL keystore
86
+ config :ssl_keystore_password, :validate => :password
87
+
88
+ # Username for basic authentication
89
+ config :auth_basic_username, :validate => :string
90
+
91
+ # Password for basic authentication
92
+ config :auth_basic_password, :validate => :password
93
+
94
+ # Cloud authentication string ("<username>:<password>" format) to connect to Elastic cloud.
95
+ #
96
+ # For more details, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_auth[cloud documentation]
97
+ config :cloud_auth, :validate => :password
98
+
99
+ # A key to authenticate when connecting to Elasticsearch
100
+ config :api_key, :validate => :password
101
+
102
+ # A directory containing one or more Maxmind Datbase files in *.mmdb format
103
+ config :geoip_database_directory, :validate => :path
104
+
105
+
106
+ def initialize(*a, &b)
107
+ # This Elastic-licensed plugin needs to run in a _complete_ distro of Logstash that
108
+ # has non-OSS features active. Runtime detection mechanism relies on LogStash::OSS,
109
+ # which is set in the prelude to LogStash::Runner, and is bypassed when LogStash::OSS
110
+ # is not defined (such as when running specs from source)
111
+ if defined?(LogStash::OSS) && LogStash::OSS
112
+ raise_config_error! <<~ERR
113
+ The Elastic Integration filter for Logstash is an Elastic-licensed plugin
114
+ that REQUIRES the complete Logstash distribution, including non-OSS features.
115
+ ERR
116
+ end
117
+
118
+ super
119
+ end
120
+
121
+ def register
122
+ @logger.debug("Registering `filter-elastic_integration` plugin.", :params => original_params)
123
+
124
+ validate_connection_settings!
125
+ @ssl_enabled = infer_ssl_from_connection_settings if @ssl_enabled.nil?
126
+
127
+ validate_ssl_settings!
128
+ validate_auth_settings!
129
+ validate_and_normalize_hosts
130
+
131
+ initialize_elasticsearch_rest_client!
132
+ initialize_geoip_database_provider!
133
+ initialize_event_processor!
134
+
135
+ perform_preflight_check!
136
+ end # def register
137
+
138
+ def filter(event)
139
+ fail "#{self.class}#filter is not allowed. Use #{self.class}#multi_filter"
140
+ end
141
+
142
+ def multi_filter(ruby_api_events)
143
+ LogStash::Util.set_thread_plugin(self)
144
+
145
+ incoming_java_api_events = ruby_events_as_java(ruby_api_events)
146
+
147
+ outgoing_java_api_events = @event_processor.process_events(incoming_java_api_events)
148
+
149
+ java_events_as_ruby(outgoing_java_api_events)
150
+ end
151
+
152
+ def filter_matched_java(java_event)
153
+ filter_matched(mutable_ruby_view_of_java_event(java_event))
154
+ end
155
+
156
+ def close
157
+ @elasticsearch_rest_client&.close
158
+ @geoip_database_provider&.close
159
+ @event_processor&.close
160
+ end
161
+
162
+ private
163
+
164
+ def validate_connection_settings!
165
+ @cloud_id = @cloud_id&.freeze
166
+
167
+ raise_config_error! "`hosts` and `cloud_id` cannot be used together." if @hosts && @cloud_id
168
+ raise_config_error! "Either `hosts` or `cloud_id` is required" unless @hosts || @cloud_id
169
+ raise_config_error! "Empty `cloud_id` is not allowed" if @cloud_id && @cloud_id.empty?
170
+ raise_config_error! "Empty `hosts` is not allowed" if @hosts && @hosts.size == 0 # let's also catch [""]
171
+ end
172
+
173
+ def infer_ssl_from_connection_settings
174
+ return true if @cloud_id
175
+ return true if @hosts.all? { |host| host.scheme.to_s.empty? }
176
+ return true if @hosts.all? { |host| host.scheme == HTTPS_PROTOCOL }
177
+ return false if @hosts.all? { |host| host.scheme == HTTP_PROTOCOL }
178
+
179
+ raise_config_error! "`hosts` contains entries with mixed protocols, which are unsupported; when any entry includes a protocol, the protocols of all must match each other"
180
+ end
181
+
182
+ def validate_and_normalize_hosts
183
+ return if @hosts.nil? || @hosts.size == 0
184
+
185
+ # host normalization expects `ssl_enabled` to be resolved (not nil)
186
+ # let's add a safeguard to make sure we don't break the behavior in the future
187
+ raise_config_error! "`hosts` cannot be normalized with `ssl_enabled => nil`" if @ssl_enabled.nil?
188
+
189
+ root_path = @hosts[0].path.empty? ? ELASTICSEARCH_DEFAULT_PATH : @hosts[0].path
190
+ scheme = @ssl_enabled ? HTTPS_PROTOCOL : HTTP_PROTOCOL
191
+
192
+ @hosts = @hosts.each do |host_uri|
193
+ # no need to validate hostname, uri validates it at initialize
194
+ host_uri.port=(ELASTICSEARCH_DEFAULT_PORT) if host_uri.port.nil?
195
+ host_uri.path=(ELASTICSEARCH_DEFAULT_PATH) if host_uri.path.to_s.empty?
196
+ agree_with = host_uri.path == root_path
197
+ raise_config_error! "All hosts must use same path." unless agree_with
198
+
199
+ host_uri.update(:scheme, scheme) if host_uri.scheme.to_s.empty?
200
+ agree_with = host_uri.scheme == scheme
201
+ raise_config_error! "All hosts must agree with #{scheme} schema when#{@ssl_enabled ? '' : ' NOT'} using `ssl_enabled`." unless agree_with
202
+
203
+ host_uri.freeze
204
+ end.freeze
205
+ end
206
+
207
+ def validate_auth_settings!
208
+ @cloud_auth = @cloud_auth&.freeze
209
+ @api_key = @api_key&.freeze
210
+ @auth_basic_username = @auth_basic_username&.freeze
211
+ @auth_basic_password = @auth_basic_password&.freeze
212
+
213
+ raise_config_error! "`auth_basic_username` requires `auth_basic_password`" if @auth_basic_username && !@auth_basic_password
214
+ raise_config_error! "`auth_basic_password` is not allowed unless `auth_basic_username` is specified" if !@auth_basic_username && @auth_basic_password
215
+ if @auth_basic_username && @auth_basic_password
216
+ raise_config_error! "Empty `auth_basic_username` or `auth_basic_password` is not allowed" if @auth_basic_username.empty? || @auth_basic_password.value.empty?
217
+ end
218
+
219
+ possible_auth_options = original_params.keys & %w(auth_basic_password cloud_auth api_key)
220
+ raise_config_error!("Multiple authentication #{possible_auth_options} options cannot be used together. Please provide ONLY one.") if possible_auth_options.size > 1
221
+
222
+ raise_config_error! "Empty `cloud_auth` is not allowed" if @cloud_auth && @cloud_auth.value.empty?
223
+ raise_config_error! "Empty `api_key` is not allowed" if @api_key && @api_key.value.empty?
224
+
225
+ @logger.warn("Credentials are being sent over unencrypted HTTP. This may bring security risk.") if possible_auth_options.size == 1 && !@ssl_enabled
226
+ end
227
+
228
+ def validate_ssl_settings!
229
+ @ssl_enabled = @ssl_enabled&.freeze
230
+ @ssl_verification_mode = @ssl_verification_mode&.freeze
231
+ @ssl_certificate = @ssl_certificate&.freeze
232
+ @ssl_key = @ssl_key&.freeze
233
+ @ssl_key_passphrase = @ssl_key_passphrase&.freeze
234
+ @ssl_truststore_path = @ssl_truststore_path&.freeze
235
+ @ssl_truststore_password = @ssl_truststore_password&.freeze
236
+ @ssl_keystore_path = @ssl_keystore_path&.freeze
237
+ @ssl_keystore_password = @ssl_keystore_password&.freeze
238
+ @ssl_certificate_authorities = @ssl_certificate_authorities&.freeze
239
+
240
+ if @ssl_enabled
241
+ # when SSL is enabled, the default ssl_verification_mode is "full"
242
+ @ssl_verification_mode = "full".freeze if @ssl_verification_mode.nil?
243
+
244
+ # optional: presenting our identity
245
+ raise_config_error! "`ssl_certificate` and `ssl_keystore_path` cannot be used together." if @ssl_certificate && @ssl_keystore_path
246
+ raise_config_error! "`ssl_certificate` requires `ssl_key`" if @ssl_certificate && !@ssl_key
247
+ ensure_readable_and_non_writable! "ssl_certificate", @ssl_certificate if @ssl_certificate
248
+
249
+ raise_config_error! "`ssl_key` is not allowed unless `ssl_certificate` is specified" if @ssl_key && !@ssl_certificate
250
+ raise_config_error! "`ssl_key` requires `ssl_key_passphrase`" if @ssl_key && !@ssl_key_passphrase
251
+ ensure_readable_and_non_writable! "ssl_key", @ssl_key if @ssl_key
252
+
253
+ raise_config_error! "`ssl_key_passphrase` is not allowed unless `ssl_key` is specified" if @ssl_key_passphrase && !@ssl_key
254
+ raise_config_error! "`ssl_key_passphrase` cannot be empty" if @ssl_key_passphrase && @ssl_key_passphrase.value.empty?
255
+
256
+ raise_config_error! "`ssl_keystore_path` requires `ssl_keystore_password`" if @ssl_keystore_path && !@ssl_keystore_password
257
+ raise_config_error! "`ssl_keystore_password` is not allowed unless `ssl_keystore_path` is specified" if @ssl_keystore_password && !@ssl_keystore_path
258
+ raise_config_error! "`ssl_keystore_password` cannot be empty" if @ssl_keystore_password && @ssl_keystore_password.value.empty?
259
+ ensure_readable_and_non_writable! "ssl_keystore_path", @ssl_keystore_path if @ssl_keystore_path
260
+
261
+ # establishing trust of the server we connect to
262
+ # system-provided trust requires verification mode enabled
263
+ if @ssl_verification_mode == "none"
264
+ raise_config_error! "`ssl_truststore_path` requires `ssl_verification_mode` to be either `full` or `certificate`" if @ssl_truststore_path
265
+ raise_config_error! "`ssl_truststore_password` requires `ssl_truststore_path` and `ssl_verification_mode` (either `full` or `certificate`)" if @ssl_truststore_password
266
+ raise_config_error! "`ssl_certificate_authorities` requires `ssl_verification_mode` to be either `full` or `certificate`" if @ssl_certificate_authorities
267
+ end
268
+
269
+ raise_config_error! "`ssl_truststore_path` and `ssl_certificate_authorities` cannot be used together." if @ssl_truststore_path && @ssl_certificate_authorities
270
+ raise_config_error! "`ssl_truststore_path` requires `ssl_truststore_password`" if @ssl_truststore_path && !@ssl_truststore_password
271
+ ensure_readable_and_non_writable! "ssl_truststore_path", @ssl_truststore_path if @ssl_truststore_path
272
+
273
+ raise_config_error! "`ssl_truststore_password` is not allowed unless `ssl_truststore_path` is specified" if !@ssl_truststore_path && @ssl_truststore_password
274
+ raise_config_error! "`ssl_truststore_password` cannot be empty" if @ssl_truststore_password && @ssl_truststore_password.value.empty?
275
+
276
+ if !@ssl_truststore_path && @ssl_certificate_authorities&.empty?
277
+ raise_config_error! "`ssl_certificate_authorities` cannot be empty"
278
+ end
279
+ @ssl_certificate_authorities&.each do |certificate_authority|
280
+ ensure_readable_and_non_writable! "ssl_certificate_authorities", certificate_authority
281
+ end
282
+ else
283
+ # Disabled SSL does not allow to set SSL related configs
284
+ ssl_config_provided = original_params.keys.select {|k| k.start_with?("ssl_", "cloud_id") && k != "ssl_enabled" }
285
+ if ssl_config_provided.any?
286
+ raise_config_error! "When SSL is disabled, the following provided parameters are not allowed: #{ssl_config_provided}"
287
+ end
288
+ end
289
+ end
290
+
291
+ def ensure_readable_and_non_writable!(name, path)
292
+ raise_config_error! "Specified #{name} #{path} path must be readable." unless File.readable?(path)
293
+ raise_config_error! "Specified #{name} #{path} path must not be writable." if File.writable?(path)
294
+ end
295
+
296
+ ##
297
+ # @param message [String]
298
+ # @raise [LogStash::ConfigurationError]
299
+ def raise_config_error!(message)
300
+ raise LogStash::ConfigurationError, message
301
+ end
302
+
303
+ ##
304
+ # Builds a `PluginConfiguration` from the previously-validated config
305
+ def extract_immutable_config
306
+ builder = PluginConfiguration::Builder.new
307
+
308
+ builder.setId @id
309
+
310
+ builder.setHosts @hosts&.map(&:to_s)
311
+ builder.setCloudId @cloud_id
312
+
313
+ builder.setSslEnabled @ssl_enabled
314
+
315
+ # ssl trust
316
+ builder.setSslVerificationMode @ssl_verification_mode
317
+ builder.setSslTruststorePath @ssl_truststore_path
318
+ builder.setSslTruststorePassword @ssl_truststore_password
319
+ builder.setSslCertificateAuthorities @ssl_certificate_authorities
320
+
321
+ # ssl identity
322
+ builder.setSslKeystorePath @keystore
323
+ builder.setSslKeystorePassword @ssl_keystore_password
324
+ builder.setSslCertificate @ssl_certificate
325
+ builder.setSslKey @ssl_key
326
+ builder.setSslKeyPassphrase @ssl_key_passphrase
327
+
328
+ # request auth
329
+ builder.setAuthBasicUsername @auth_basic_username
330
+ builder.setAuthBasicPassword @auth_basic_password
331
+ builder.setCloudAuth @cloud_auth
332
+ builder.setApiKey @api_key
333
+
334
+ builder.build
335
+ end
336
+
337
+ def initialize_elasticsearch_rest_client!
338
+ @elasticsearch_rest_client = ElasticsearchRestClientBuilder.fromPluginConfiguration(extract_immutable_config)
339
+ .map(&:build)
340
+ .orElseThrow() # todo: ruby/java bridge better exception
341
+ end
342
+
343
+ def initialize_event_processor!
344
+ java_import('co.elastic.logstash.filters.elasticintegration.EventProcessorBuilder')
345
+ java_import('co.elastic.logstash.filters.elasticintegration.geoip.GeoIpProcessorFactory')
346
+
347
+ @event_processor = EventProcessorBuilder.fromElasticsearch(@elasticsearch_rest_client)
348
+ .setFilterMatchListener(method(:filter_matched_java).to_proc)
349
+ .addProcessor("geoip") { GeoIpProcessorFactory.new(@geoip_database_provider) }
350
+ .build("logstash.filter.elastic_integration.#{id}.#{__id__}")
351
+ rescue => exception
352
+ raise_config_error!("configuration did not produce an EventProcessor: #{exception}")
353
+ end
354
+
355
+ def initialize_geoip_database_provider!
356
+ java_import('co.elastic.logstash.filters.elasticintegration.geoip.GeoIpDatabaseProvider')
357
+ java_import('co.elastic.logstash.filters.elasticintegration.geoip.StaticGeoIpDatabase')
358
+
359
+ @geoip_database_provider ||= GeoIpDatabaseProvider::Builder.new.tap do |builder|
360
+ builder.setDatabases(java.io.File.new(@geoip_database_directory)) if @geoip_database_directory
361
+ end.build
362
+ end
363
+
364
+ def perform_preflight_check!
365
+ PreflightCheck.new(@elasticsearch_rest_client).check
366
+ rescue => e
367
+ raise_config_error!(e.message)
368
+ end
369
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ ELASTIC_INTEGRATION_VERSION = File.read(File.expand_path(File.join(File.dirname(__FILE__), "VERSION"))).strip unless defined?(ELASTIC_INTEGRATION_VERSION)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'logstash-filter-elastic_integration'
6
+ s.version = ELASTIC_INTEGRATION_VERSION
7
+ s.licenses = ['ELv2']
8
+ s.summary = "Processes Elastic Integrations"
9
+ 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"
10
+ s.authors = ["Elastic"]
11
+ s.email = 'info@elastic.co'
12
+ s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
13
+ s.require_paths = ["lib", "vendor/jar-dependencies"]
14
+
15
+ # Files to be included in package
16
+ s.files = Dir[*%w{
17
+ lib/**/*.*
18
+ *.gemspec
19
+ vendor/jar-dependencies/**/*.jar
20
+ VERSION
21
+ LICENSE.md
22
+ NOTICE.txt
23
+ }]
24
+
25
+ # Special flag to let us know this is actually a logstash plugin
26
+ s.metadata = {
27
+ "logstash_plugin" => "true",
28
+ "logstash_group" => "filter",
29
+ "source_code_uri" => "https://github.com/elastic/logstash-filter-elastic_integration",
30
+ }
31
+
32
+ # Gem dependencies
33
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
34
+ s.add_runtime_dependency "logstash-core", ">= 8.7.0"
35
+
36
+ s.add_development_dependency 'logstash-devutils'
37
+
38
+ s.platform = "java"
39
+
40
+ s.post_install_message = <<~NOTICES
41
+ This Logstash plugin embeds a subset of Elasticsearch (https://elastic.co/)
42
+ and packages from Apache Lucene, including software developed by The Apache
43
+ Software Foundation (http://www.apache.org/).
44
+ NOTICES
45
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-filter-elastic_integration
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: java
6
+ authors:
7
+ - Elastic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-04-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.60'
19
+ - - "<="
20
+ - !ruby/object:Gem::Version
21
+ version: '2.99'
22
+ name: logstash-core-plugin-api
23
+ prerelease: false
24
+ type: :runtime
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.60'
30
+ - - "<="
31
+ - !ruby/object:Gem::Version
32
+ version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 8.7.0
39
+ name: logstash-core
40
+ prerelease: false
41
+ type: :runtime
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 8.7.0
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ name: logstash-devutils
54
+ prerelease: false
55
+ type: :development
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ description: This gem is a Logstash plugin required to be installed on top of the
62
+ Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
63
+ gem is not a stand-alone program
64
+ email: info@elastic.co
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - LICENSE.md
70
+ - NOTICE.txt
71
+ - VERSION
72
+ - lib/logstash/filters/elastic_integration.rb
73
+ - lib/logstash/filters/elastic_integration/event_api_bridge.rb
74
+ - lib/logstash/filters/elastic_integration/jar_dependencies.rb
75
+ - logstash-filter-elastic_integration.gemspec
76
+ - vendor/jar-dependencies/co/elastic/logstash/plugins/filter/elasticintegration/logstash-filter-elastic_integration/0.0.1/logstash-filter-elastic_integration-0.0.1.jar
77
+ homepage: http://www.elastic.co/guide/en/logstash/current/index.html
78
+ licenses:
79
+ - ELv2
80
+ metadata:
81
+ logstash_plugin: 'true'
82
+ logstash_group: filter
83
+ source_code_uri: https://github.com/elastic/logstash-filter-elastic_integration
84
+ post_install_message: |
85
+ This Logstash plugin embeds a subset of Elasticsearch (https://elastic.co/)
86
+ and packages from Apache Lucene, including software developed by The Apache
87
+ Software Foundation (http://www.apache.org/).
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ - vendor/jar-dependencies
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 3.2.33
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Processes Elastic Integrations
107
+ test_files: []