logstash-output-opensearch 1.3.0-java → 2.0.0-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.
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
+ }