logstash-output-opensearch 1.3.0-java → 2.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/COMPATIBILITY.md +5 -3
  4. data/README.md +51 -34
  5. data/docs/ecs_compatibility.md +42 -0
  6. data/lib/logstash/outputs/opensearch/http_client/manticore_adapter.rb +27 -12
  7. data/lib/logstash/outputs/opensearch/http_client/pool.rb +11 -2
  8. data/lib/logstash/outputs/opensearch/http_client.rb +10 -3
  9. data/lib/logstash/outputs/opensearch/http_client_builder.rb +4 -2
  10. data/lib/logstash/outputs/opensearch/template_manager.rb +6 -5
  11. data/lib/logstash/outputs/opensearch/templates/ecs-disabled/1x_index.json +66 -0
  12. data/lib/logstash/outputs/opensearch/templates/ecs-disabled/2x_index.json +66 -0
  13. data/lib/logstash/outputs/opensearch/templates/ecs-disabled/7x_index.json +66 -0
  14. data/lib/logstash/outputs/opensearch/templates/ecs-v1/1x.json +3629 -0
  15. data/lib/logstash/outputs/opensearch/templates/ecs-v1/1x_index.json +3631 -0
  16. data/lib/logstash/outputs/opensearch/templates/ecs-v1/2x.json +3629 -0
  17. data/lib/logstash/outputs/opensearch/templates/ecs-v1/2x_index.json +3631 -0
  18. data/lib/logstash/outputs/opensearch/templates/ecs-v1/7x.json +3629 -0
  19. data/lib/logstash/outputs/opensearch/templates/ecs-v1/7x_index.json +3631 -0
  20. data/lib/logstash/outputs/opensearch/templates/ecs-v8/1x_index.json +5254 -0
  21. data/lib/logstash/outputs/opensearch/templates/ecs-v8/2x_index.json +5254 -0
  22. data/lib/logstash/outputs/opensearch/templates/ecs-v8/7x_index.json +5254 -0
  23. data/lib/logstash/outputs/opensearch.rb +7 -0
  24. data/logstash-output-opensearch.gemspec +2 -2
  25. data/spec/unit/outputs/opensearch/http_client/manticore_adapter_spec.rb +13 -0
  26. data/spec/unit/outputs/opensearch/http_client_spec.rb +20 -0
  27. data/spec/unit/outputs/opensearch/template_manager_spec.rb +8 -20
  28. data.tar.gz.sig +0 -0
  29. metadata +31 -23
  30. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bbe40e1f039f2d91a4adfb8b8fb9a28fd877156bf270060fa1d294986a769983
4
- data.tar.gz: 9c2bd44c3e32cbf31d3ffac173a5e9b0ff2e4bcb9c4bd27267ac70a3a88ee6da
3
+ metadata.gz: 567e7fbd1e9d9e3ca660d5b40c2bfd12e6f7e9504e65f26beeef04834e5c636a
4
+ data.tar.gz: d1d6c1bf7eb003d32cea988c5ed7bea367213fd8e344e987a9989bc414e22192
5
5
  SHA512:
6
- metadata.gz: ed114d31a8dd15ebe57cba0d87c278efe3be2a47743aa2cdfe99bf861e0934edb2772d09aa59eda0d9428b119dde77a16c82371ce19ca1cbfb5c6ce736692690
7
- data.tar.gz: df6263f5109d5834bc19fa9804c082c95dc1867eed7926be99b7682c4c1cfb3abffa0ff23b16f123f55f196e353527d31d8d5a61f3011bbf56805f43fa890fdc
6
+ metadata.gz: 1c1ba6f915936dde9d654b5883645bd818cb46fad5c821ec4cf7c87cd250a5bf489957f6f4308aa29ed4e5b0f214b2ae1a4f9195d5d022835610ff8f6e21e3c3
7
+ data.tar.gz: d585a0bafbe30f63411eaa9a733505a49990f86c092e2a6a0a36170d017ff3bc3cc088dc2cd11e77204d5d921867158c258146c6ce0cad10ee25622c703cd2a6
checksums.yaml.gz.sig CHANGED
Binary file
data/COMPATIBILITY.md CHANGED
@@ -5,23 +5,25 @@
5
5
  | logstash-output-opensearch | Logstash OSS|
6
6
  | ------------- | ------------- |
7
7
  | 1.0.0+ | 7.13.2 |
8
+ | 2.0.0+ | 7.13.2 |
8
9
 
9
10
  ### Matrix for OpenSearch
10
11
 
11
12
  | logstash-output-opensearch | OpenSearch |
12
13
  | ------------- | ------------- |
13
- | 1.0.0+ | 1.0.0 |
14
-
14
+ | 1.0.0+ | 1.0.0 |
15
+ | 2.0.0+ | 1.0.0 |
15
16
 
16
17
  ### Matrix for ODFE
17
18
 
18
19
  | logstash-output-opensearch | ODFE |
19
20
  | ------------- | ------------- |
20
21
  | 1.0.0+ | 1.x - 1.13.2 |
21
-
22
+ | 2.0.0+ | 1.x - 1.13.2 |
22
23
 
23
24
  ### Matrix for Elasticsearch OSS
24
25
 
25
26
  | logstash-output-opensearch | Elasticsearch OSS|
26
27
  | ------------- | ------------- |
27
28
  | 1.0.0+ | 7.x - 7.10.2 |
29
+ | 2.0.0+ | 7.x - 7.10.2 |
data/README.md CHANGED
@@ -18,7 +18,8 @@ The logstash-output-opensearch plugin helps to ship events from Logstash to Open
18
18
  ## Project Resources
19
19
 
20
20
  * [Project Website](https://opensearch.org/)
21
- * [Documentation](https://opensearch.org/docs/clients/logstash/index/)
21
+ * [Detailed Documentation](https://opensearch.org/docs/latest/clients/logstash/ship-to-opensearch/#opensearch-output-plugin)
22
+ * [Logstash Overview](https://opensearch.org/docs/clients/logstash/index/)
22
23
  * [Developer Guide](DEVELOPER_GUIDE.md)
23
24
  * Need help? Try [Forums](https://discuss.opendistrocommunity.dev/)
24
25
  * [Project Principles](https://opensearch.org/#principles)
@@ -44,17 +45,17 @@ output {
44
45
 
45
46
  To run the Logstash Output Opensearch plugin using aws_iam authentication, refer to the sample configuration shown below:
46
47
  ```
47
- output {
48
- opensearch {
49
- hosts => ["hostname:port"]
50
- auth_type => {
51
- type => 'aws_iam'
52
- aws_access_key_id => 'ACCESS_KEY'
53
- aws_secret_access_key => 'SECRET_KEY'
54
- region => 'us-west-2'
55
- }
56
- index => "logstash-logs-%{+YYYY.MM.dd}"
57
- }
48
+ output {
49
+ opensearch {
50
+ hosts => ["hostname:port"]
51
+ auth_type => {
52
+ type => 'aws_iam'
53
+ aws_access_key_id => 'ACCESS_KEY'
54
+ aws_secret_access_key => 'SECRET_KEY'
55
+ region => 'us-west-2'
56
+ }
57
+ index => "logstash-logs-%{+YYYY.MM.dd}"
58
+ }
58
59
  }
59
60
  ```
60
61
 
@@ -62,37 +63,53 @@ In addition to the existing authentication mechanisms, if we want to add new aut
62
63
 
63
64
  Example Configuration for basic authentication:
64
65
  ```
65
- output {
66
- opensearch {
67
- hosts => ["hostname:port"]
68
- auth_type => {
69
- type => 'basic'
70
- user => 'admin'
71
- password => 'admin'
72
- }
73
- index => "logstash-logs-%{+YYYY.MM.dd}"
74
- }
75
- }
66
+ output {
67
+ opensearch {
68
+ hosts => ["hostname:port"]
69
+ auth_type => {
70
+ type => 'basic'
71
+ user => 'admin'
72
+ password => 'admin'
73
+ }
74
+ index => "logstash-logs-%{+YYYY.MM.dd}"
75
+ }
76
+ }
76
77
  ```
77
78
 
78
79
  To ingest data into a `data stream` through logstash, we need to create the data stream and specify the name of data stream and the `op_type` of `create` in the output configuration. The sample configuration is shown below:
79
80
 
80
81
  ```yml
81
- output {
82
- opensearch {
83
- hosts => ["https://hostname:port"]
84
- auth_type => {
85
- type => 'basic'
86
- user => 'admin'
87
- password => 'admin'
82
+ output {
83
+ opensearch {
84
+ hosts => ["https://hostname:port"]
85
+ auth_type => {
86
+ type => 'basic'
87
+ user => 'admin'
88
+ password => 'admin'
88
89
  }
89
90
  index => "my-data-stream"
90
91
  action => "create"
91
- }
92
- }
92
+ }
93
+ }
94
+ ```
95
+
96
+ Starting in 2.0.0, the aws sdk version is bumped to v3. In order for all other AWS plugins to work together, please remove pre-installed aws plugins and install logstash-integration-aws plugin as follows. See also https://github.com/logstash-plugins/logstash-mixin-aws/issues/38
97
+ ```
98
+ # Remove existing logstash aws plugins and install logstash-integration-aws to keep sdk dependency the same
99
+ # https://github.com/logstash-plugins/logstash-mixin-aws/issues/38
100
+ /usr/share/logstash/bin/logstash-plugin remove logstash-input-s3
101
+ /usr/share/logstash/bin/logstash-plugin remove logstash-input-sqs
102
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-s3
103
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-sns
104
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-sqs
105
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-cloudwatch
106
+
107
+ /usr/share/logstash/bin/logstash-plugin install --version 0.1.0.pre logstash-integration-aws
108
+ bin/logstash-plugin install --version 2.0.0 logstash-output-opensearch
93
109
  ```
110
+ ## ECS Compatibility
111
+ [Elastic Common Schema(ECS)](https://www.elastic.co/guide/en/ecs/current/index.html]) compatibility for V8 was added in 1.3.0. For more details on ECS support refer to this [documentation](docs/ecs_compatibility.md).
94
112
 
95
- For more details refer to this [documentation](https://opensearch.org/docs/latest/clients/logstash/ship-to-opensearch/#opensearch-output-plugin)
96
113
 
97
114
  ## Code of Conduct
98
115
 
@@ -104,4 +121,4 @@ This project is licensed under the [Apache v2.0 License](LICENSE).
104
121
 
105
122
  ## Copyright
106
123
 
107
- Copyright OpenSearch Contributors. See [NOTICE](NOTICE) for details.
124
+ Copyright OpenSearch Contributors. See [NOTICE](NOTICE) for details.
@@ -0,0 +1,42 @@
1
+ # ECS Compatibility Support in logstash-output-opensearch
2
+ Compatibility for ECS v8 was added in release 1.3.0 of the plugin. This would enable the plugin to work with Logstash 8.x without the need to disable ecs_compatibility.
3
+ The output plugin doesn't create any events itself, but merely forwards events to OpenSearch that were shaped by plugins preceding it in the pipeline. So, it doesn't play a direct role in making the events ECS compatible.
4
+ However, the default index templates that the plugin installs into OpenSearch in the ecs_compatibility modes (v1 & v8) ensures that the document fields stored in the indices are ECS compatible. OpenSearch would throw errors for documents that have fields which are ECS incompatible and can't be coerced.
5
+
6
+ ## ECS index templates used by logstash-output-opensearch 1.3.0
7
+ * v8 [ECS 8.0.0](https://github.com/elastic/ecs/releases/tag/v8.0.0) [ecs-8.0.0/generated/elasticsearch/legacy/template.json](https://raw.githubusercontent.com/elastic/ecs/v8.0.0/generated/elasticsearch/legacy/template.json)
8
+ * v1 [ECS 1.9.0](https://github.com/elastic/ecs/releases/tag/v1.9.0) [ecs-1.9.0/generated/elasticsearch/7/template.json](https://raw.githubusercontent.com/elastic/ecs/v1.9.0/generated/elasticsearch/7/template.json)
9
+
10
+ ## ECS incompatibility
11
+ Incompatibility can arise for an event when it has fields with the same name as an ECS defined field but a type which can't be coerced into the ECS field.
12
+ It is Ok to have fields that are not defined in ECS [ref](https://www.elastic.co/guide/en/ecs/current/ecs-faq.html#addl-fields).
13
+ The dynamic template included in the ECS templates would dynamically map any non-ECS fields.
14
+
15
+ ### Example
16
+ [ECS defines the "server"](https://www.elastic.co/guide/en/ecs/current/ecs-server.html) field as an object. But let's say the plugin gets the event below, with a string in the `server` field. It will receive an error from OpenSearch as strings can't be coerced into an object and the ECS incompatible event won't be indexed.
17
+ ```
18
+ {
19
+ "@timestamp": "2022-08-22T15:39:18.142175244Z",
20
+ "@version": "1",
21
+ "message": "Doc1",
22
+ "server": "remoteserver.com"
23
+ }
24
+ ```
25
+
26
+ Error received from OpenSearch in the Logstash logs
27
+ ```
28
+ [2022-08-23T00:01:53,366][WARN ][logstash.outputs.opensearch][main][a36555c6fad3f301db8efff2dfbed768fd85e0b6f4ee35626abe62432f83b95d] Could not index event to OpenSearch. {:status=>400, :action=>["index", {:_id=>nil, :_index=>"ecs-logstash-2022.08.23", :routing=>nil}, {"@timestamp"=>2022-08-22T15:39:18.142175244Z, "@version"=>"1", "server"=>"remoteserver.com", "message"=>"Doc1"}], :response=>{"index"=>{"_index"=>"ecs-logstash-2022.08.23", "_id"=>"CAEUyYIBQM7JQrwxF5NR", "status"=>400, "error"=>{"type"=>"mapper_parsing_exception", "reason"=>"object mapping for [server] tried to parse field [server] as object, but found a concrete value"}}}}
29
+ ```
30
+ ## How to ensure ECS compatibility
31
+ * The plugins in the pipeline that create the events like the `input` and `codec` plugins should all use ECS defined fields.
32
+ * Filter plugins like [mutate](https://github.com/logstash-plugins/logstash-filter-mutate/blob/main/docs/index.asciidoc) can be used to map incompatible fields into ECS compatible ones.
33
+ In the above example the `server` field can be mapped to the `server.domain` field to make it compatible.
34
+ * You can use your own custom template in the plugin using the `template` and `template_name` configs.
35
+ [According to this](https://www.elastic.co/guide/en/ecs/current/ecs-faq.html#type-interop) some field types can be changed while staying compatible.
36
+
37
+ As a last resort the `ecs_compatibility` config for the logstash-output-opensearch can be set to `disabled`.
38
+
39
+
40
+ _______________
41
+ ## References
42
+ * [Elastic Common Schema (ECS) Reference](https://www.elastic.co/guide/en/ecs/current/index.html)
@@ -57,7 +57,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
57
57
  if options[:proxy]
58
58
  options[:proxy] = manticore_proxy_hash(options[:proxy])
59
59
  end
60
-
60
+
61
61
  @manticore = ::Manticore::Client.new(options)
62
62
  end
63
63
 
@@ -76,6 +76,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
76
76
  instance_cred_timeout = options[:auth_type]["instance_profile_credentials_timeout"] || AWS_DEFAULT_PROFILE_CREDENTIAL_TIMEOUT
77
77
  region = options[:auth_type]["region"] || AWS_DEFAULT_REGION
78
78
  set_aws_region(region)
79
+ set_service_name(options[:auth_type]["service_name"] || AWS_SERVICE)
79
80
 
80
81
  credential_config = AWSIAMCredential.new(aws_access_key_id, aws_secret_access_key, session_token, profile, instance_cred_retries, instance_cred_timeout, region)
81
82
  @credentials = Aws::CredentialProviderChain.new(credential_config).resolve
@@ -93,6 +94,14 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
93
94
  @region
94
95
  end
95
96
 
97
+ def set_service_name(service_name)
98
+ @service_name = service_name
99
+ end
100
+
101
+ def get_service_name()
102
+ @service_name
103
+ end
104
+
96
105
  def set_user_password(options)
97
106
  @user = options[:auth_type]["user"]
98
107
  @password = options[:auth_type]["password"]
@@ -105,7 +114,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
105
114
  def get_password()
106
115
  @password
107
116
  end
108
-
117
+
109
118
  # Transform the proxy option to a hash. Manticore's support for non-hash
110
119
  # proxy options is broken. This was fixed in https://github.com/cheald/manticore/commit/34a00cee57a56148629ed0a47c329181e7319af5
111
120
  # but this is not yet released
@@ -137,12 +146,12 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
137
146
  params[:body] = body if body
138
147
 
139
148
  if url.user
140
- params[:auth] = {
149
+ params[:auth] = {
141
150
  :user => CGI.unescape(url.user),
142
151
  # We have to unescape the password here since manticore won't do it
143
152
  # for us unless its part of the URL
144
- :password => CGI.unescape(url.password),
145
- :eager => true
153
+ :password => CGI.unescape(url.password),
154
+ :eager => true
146
155
  }
147
156
  elsif @type == BASIC_AUTH_TYPE
148
157
  add_basic_auth_to_params(params)
@@ -174,11 +183,17 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
174
183
 
175
184
  def sign_aws_request(request_uri, path, method, params)
176
185
  url = URI::HTTPS.build({:host=>URI(request_uri.to_s).host, :port=>AWS_DEFAULT_PORT.to_s, :path=>path})
177
- key = Seahorse::Client::Http::Request.new(options={:endpoint=>url, :http_method => method.to_s.upcase,
178
- :headers => params[:headers],:body => params[:body]})
179
- aws_signer = Aws::Signers::V4.new(@credentials, AWS_SERVICE, get_aws_region )
180
- signed_key = aws_signer.sign(key)
181
- params[:headers] = params[:headers].merge(signed_key.headers)
186
+ request = Seahorse::Client::Http::Request.new(options={:endpoint=>url, :http_method => method.to_s.upcase,
187
+ :headers => params[:headers],:body => params[:body]})
188
+
189
+ aws_signer = Aws::Sigv4::Signer.new(service: @service_name, region: @region, credentials_provider: @credentials)
190
+ signed_key = aws_signer.sign_request(
191
+ http_method: request.http_method,
192
+ url: url,
193
+ headers: params[:headers],
194
+ body: params[:body]
195
+ )
196
+ params[:headers] = params[:headers].merge(signed_key.headers)
182
197
  end
183
198
 
184
199
  def add_basic_auth_to_params(params)
@@ -192,7 +207,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
192
207
  # Returned urls from this method should be checked for double escaping.
193
208
  def format_url(url, path_and_query=nil)
194
209
  request_uri = url.clone
195
-
210
+
196
211
  # We excise auth info from the URL in case manticore itself tries to stick
197
212
  # sensitive data in a thrown exception or log data
198
213
  request_uri.user = nil
@@ -208,7 +223,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
208
223
  new_query_parts = [request_uri.query, parsed_path_and_query.query].select do |part|
209
224
  part && !part.empty? # Skip empty nil and ""
210
225
  end
211
-
226
+
212
227
  request_uri.query = new_query_parts.join("&") unless new_query_parts.empty?
213
228
 
214
229
  # use `raw_path`` as `path` will unescape any escaped '/' in the path
@@ -40,6 +40,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
40
40
  end
41
41
 
42
42
  attr_reader :logger, :adapter, :sniffing, :sniffer_delay, :resurrect_delay, :healthcheck_path, :sniffing_path, :bulk_path
43
+ attr_reader :default_server_major_version
43
44
 
44
45
  ROOT_URI_PATH = '/'.freeze
45
46
 
@@ -68,6 +69,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
68
69
  @resurrect_delay = merged[:resurrect_delay]
69
70
  @sniffing = merged[:sniffing]
70
71
  @sniffer_delay = merged[:sniffer_delay]
72
+ @default_server_major_version = merged[:default_server_major_version]
71
73
  end
72
74
 
73
75
  # Used for all concurrent operations in this class
@@ -412,8 +414,15 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
412
414
  end
413
415
 
414
416
  def get_version(url)
415
- request = perform_request_to_url(url, :get, ROOT_URI_PATH)
416
- LogStash::Json.load(request.body)["version"]["number"] # e.g. "7.10.0"
417
+ response = perform_request_to_url(url, :get, ROOT_URI_PATH)
418
+ if response.code != 404 && !response.body.empty?
419
+ return LogStash::Json.load(response.body)["version"]["number"] # e.g. "7.10.0"
420
+ end
421
+ if @default_server_major_version.nil?
422
+ @logger.error("Failed to get version from health_check endpoint and default_server_major_version is not configured.")
423
+ raise "get_version failed! no default_server_major_version configured."
424
+ end
425
+ "#{default_server_major_version}.0.0"
417
426
  end
418
427
 
419
428
  def last_version
@@ -328,7 +328,8 @@ module LogStash; module Outputs; class OpenSearch;
328
328
  :healthcheck_path => options[:healthcheck_path],
329
329
  :resurrect_delay => options[:resurrect_delay],
330
330
  :url_normalizer => self.method(:host_to_url),
331
- :metric => options[:metric]
331
+ :metric => options[:metric],
332
+ :default_server_major_version => options[:default_server_major_version]
332
333
  }
333
334
  pool_options[:scheme] = self.scheme if self.scheme
334
335
 
@@ -388,10 +389,16 @@ module LogStash; module Outputs; class OpenSearch;
388
389
  @pool.put(path, nil, LogStash::Json.dump(template))
389
390
  end
390
391
 
392
+ def legacy_template?()
393
+ # TODO: Also check Version and return true for < 7.8 even if :legacy_template=false
394
+ # Need to figure a way to distinguish between OpenSearch, OpenDistro and other
395
+ # variants, since they have version numbers in different ranges.
396
+ client_settings.fetch(:legacy_template, true)
397
+ end
398
+
391
399
  def template_endpoint
392
- # TODO: Check Version < 7.8 and use index template for >= 7.8 & OpenSearch
393
400
  # https://opensearch.org/docs/opensearch/index-templates/
394
- '_template'
401
+ legacy_template?() ? '_template' : '_index_template'
395
402
  end
396
403
 
397
404
  # check whether rollover alias already exists
@@ -18,7 +18,8 @@ module LogStash; module Outputs; class OpenSearch;
18
18
  :pool_max_per_route => params["pool_max_per_route"],
19
19
  :check_connection_timeout => params["validate_after_inactivity"],
20
20
  :http_compression => params["http_compression"],
21
- :headers => params["custom_headers"] || {}
21
+ :headers => params["custom_headers"] || {},
22
+ :legacy_template => params["legacy_template"]
22
23
  }
23
24
 
24
25
  client_settings[:proxy] = params["proxy"] if params["proxy"]
@@ -26,7 +27,8 @@ module LogStash; module Outputs; class OpenSearch;
26
27
  common_options = {
27
28
  :client_settings => client_settings,
28
29
  :metric => params["metric"],
29
- :resurrect_delay => params["resurrect_delay"]
30
+ :resurrect_delay => params["resurrect_delay"],
31
+ :default_server_major_version => params["default_server_major_version"]
30
32
  }
31
33
 
32
34
  if params["sniffing"]
@@ -18,7 +18,7 @@ module LogStash; module Outputs; class OpenSearch
18
18
  else
19
19
  plugin.logger.info("Using a default mapping template", :version => plugin.maximum_seen_major_version,
20
20
  :ecs_compatibility => plugin.ecs_compatibility)
21
- template = load_default_template(plugin.maximum_seen_major_version, plugin.ecs_compatibility)
21
+ template = load_default_template(plugin.maximum_seen_major_version, plugin.ecs_compatibility, plugin.client.legacy_template?)
22
22
  end
23
23
 
24
24
  plugin.logger.debug("Attempting to install template", template: template)
@@ -26,8 +26,8 @@ module LogStash; module Outputs; class OpenSearch
26
26
  end
27
27
 
28
28
  private
29
- def self.load_default_template(major_version, ecs_compatibility)
30
- template_path = default_template_path(major_version, ecs_compatibility)
29
+ def self.load_default_template(major_version, ecs_compatibility, legacy_template)
30
+ template_path = default_template_path(major_version, ecs_compatibility, legacy_template)
31
31
  read_template_file(template_path)
32
32
  rescue => e
33
33
  fail "Failed to load default template for OpenSearch v#{major_version} with ECS #{ecs_compatibility}; caused by: #{e.inspect}"
@@ -45,9 +45,10 @@ module LogStash; module Outputs; class OpenSearch
45
45
  plugin.template_name
46
46
  end
47
47
 
48
- def self.default_template_path(major_version, ecs_compatibility=:disabled)
48
+ def self.default_template_path(major_version, ecs_compatibility=:disabled, legacy_template=true)
49
49
  template_version = major_version
50
- default_template_name = "templates/ecs-#{ecs_compatibility}/#{template_version}x.json"
50
+ suffix = legacy_template ? "" : "_index"
51
+ default_template_name = "templates/ecs-#{ecs_compatibility}/#{template_version}x#{suffix}.json"
51
52
  ::File.expand_path(default_template_name, ::File.dirname(__FILE__))
52
53
  end
53
54
 
@@ -0,0 +1,66 @@
1
+ {
2
+ "index_patterns": "logstash-*",
3
+ "version": 60001,
4
+ "priority": 10,
5
+ "template": {
6
+ "settings": {
7
+ "index.refresh_interval": "5s",
8
+ "number_of_shards": 1
9
+ },
10
+ "mappings": {
11
+ "dynamic_templates": [
12
+ {
13
+ "message_field": {
14
+ "path_match": "message",
15
+ "match_mapping_type": "string",
16
+ "mapping": {
17
+ "type": "text",
18
+ "norms": false
19
+ }
20
+ }
21
+ },
22
+ {
23
+ "string_fields": {
24
+ "match": "*",
25
+ "match_mapping_type": "string",
26
+ "mapping": {
27
+ "type": "text",
28
+ "norms": false,
29
+ "fields": {
30
+ "keyword": {
31
+ "type": "keyword",
32
+ "ignore_above": 256
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ],
39
+ "properties": {
40
+ "@timestamp": {
41
+ "type": "date"
42
+ },
43
+ "@version": {
44
+ "type": "keyword"
45
+ },
46
+ "geoip": {
47
+ "dynamic": true,
48
+ "properties": {
49
+ "ip": {
50
+ "type": "ip"
51
+ },
52
+ "location": {
53
+ "type": "geo_point"
54
+ },
55
+ "latitude": {
56
+ "type": "half_float"
57
+ },
58
+ "longitude": {
59
+ "type": "half_float"
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "index_patterns": "logstash-*",
3
+ "version": 60001,
4
+ "priority": 10,
5
+ "template": {
6
+ "settings": {
7
+ "index.refresh_interval": "5s",
8
+ "number_of_shards": 1
9
+ },
10
+ "mappings": {
11
+ "dynamic_templates": [
12
+ {
13
+ "message_field": {
14
+ "path_match": "message",
15
+ "match_mapping_type": "string",
16
+ "mapping": {
17
+ "type": "text",
18
+ "norms": false
19
+ }
20
+ }
21
+ },
22
+ {
23
+ "string_fields": {
24
+ "match": "*",
25
+ "match_mapping_type": "string",
26
+ "mapping": {
27
+ "type": "text",
28
+ "norms": false,
29
+ "fields": {
30
+ "keyword": {
31
+ "type": "keyword",
32
+ "ignore_above": 256
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ],
39
+ "properties": {
40
+ "@timestamp": {
41
+ "type": "date"
42
+ },
43
+ "@version": {
44
+ "type": "keyword"
45
+ },
46
+ "geoip": {
47
+ "dynamic": true,
48
+ "properties": {
49
+ "ip": {
50
+ "type": "ip"
51
+ },
52
+ "location": {
53
+ "type": "geo_point"
54
+ },
55
+ "latitude": {
56
+ "type": "half_float"
57
+ },
58
+ "longitude": {
59
+ "type": "half_float"
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "index_patterns": "logstash-*",
3
+ "version": 60001,
4
+ "priority": 10,
5
+ "template": {
6
+ "settings": {
7
+ "index.refresh_interval": "5s",
8
+ "number_of_shards": 1
9
+ },
10
+ "mappings": {
11
+ "dynamic_templates": [
12
+ {
13
+ "message_field": {
14
+ "path_match": "message",
15
+ "match_mapping_type": "string",
16
+ "mapping": {
17
+ "type": "text",
18
+ "norms": false
19
+ }
20
+ }
21
+ },
22
+ {
23
+ "string_fields": {
24
+ "match": "*",
25
+ "match_mapping_type": "string",
26
+ "mapping": {
27
+ "type": "text",
28
+ "norms": false,
29
+ "fields": {
30
+ "keyword": {
31
+ "type": "keyword",
32
+ "ignore_above": 256
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ],
39
+ "properties": {
40
+ "@timestamp": {
41
+ "type": "date"
42
+ },
43
+ "@version": {
44
+ "type": "keyword"
45
+ },
46
+ "geoip": {
47
+ "dynamic": true,
48
+ "properties": {
49
+ "ip": {
50
+ "type": "ip"
51
+ },
52
+ "location": {
53
+ "type": "geo_point"
54
+ },
55
+ "latitude": {
56
+ "type": "half_float"
57
+ },
58
+ "longitude": {
59
+ "type": "half_float"
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }