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 +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: []
|