logstash-filter-elastic_integration 0.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.md +93 -0
- data/NOTICE.txt +5 -0
- data/VERSION +1 -0
- data/lib/logstash/filters/elastic_integration/event_api_bridge.rb +66 -0
- data/lib/logstash/filters/elastic_integration/jar_dependencies.rb +11 -0
- data/lib/logstash/filters/elastic_integration.rb +369 -0
- data/logstash-filter-elastic_integration.gemspec +45 -0
- data/vendor/jar-dependencies/co/elastic/logstash/plugins/filter/elasticintegration/logstash-filter-elastic_integration/0.0.1/logstash-filter-elastic_integration-0.0.1.jar +0 -0
- metadata +107 -0
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
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: []
|