fluent-plugin-opensearch 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56dc0da995d5f55c59e13afd75452b46e824f8337de6b074655dc8c92926eba8
4
- data.tar.gz: dffab1c953b558fe1001df5c59844f1d71f8a2847199afade1b74ff9a05f739a
3
+ metadata.gz: 9dc42f6d13cb540c456050657cd2079a7b755a77e4148122f486be2b15486db7
4
+ data.tar.gz: 76bc650e96fc7b35a84641f6b0916024985bdccb779e54ef4e49d2172eb6227f
5
5
  SHA512:
6
- metadata.gz: da67be6908b8000b6904655b0492cfedbedddae45dd7b408a41698e7c02ea1778b1fb8c64be4097b5cbfed1e58601c30a57892d07706de4782526cb0a6edd0c4
7
- data.tar.gz: f002f9ccec9f8dd7c292ef3d88d8425e0f05e3651cf831eb86204059726643db43502c3285b4ad8410840e7bb29d814f2e243c1b6671c24909abb1f1b7b14824
6
+ metadata.gz: dfa28860c87c55fcffba26a9d4990e64d909b8daf5e0ed68dfe309d6fcd3d78b61f41738bff3a88e6ffd780f1c870e0a95a151c5637c228f488253e2ac889a79
7
+ data.tar.gz: 77045d8ba592eaf9daf904b5d10ac36935c8d0ac13decff011e281cc0732e72f5b02ba69e196a8822a303dcb399752fe081d2bb846e0a19a93123513eac763e3
@@ -1,37 +1,29 @@
1
1
  ---
2
2
  name: Bug Report
3
- about: Create a report to help us improve. If you have questions about ES plugin on kubernetes, please direct these to https://discuss.kubernetes.io/ before sumbit kubernetes related issue.
3
+ about: Create a report to help us improve. If you have questions about OpenSearch plugin on kubernetes, please direct these to https://discuss.kubernetes.io/ before sumbit kubernetes related issue.
4
4
 
5
5
  ---
6
6
 
7
7
  (check apply)
8
- - [ ] read [the contribution guideline](https://github.com/uken/fluent-plugin-elasticsearch/blob/master/CONTRIBUTING.md)
8
+ - [ ] read [the contribution guideline](https://github.com/fluent/fluent-plugin-opensearch/blob/master/CONTRIBUTING.md)
9
9
  - [ ] (optional) already reported 3rd party upstream repository or mailing list if you use k8s addon or helm charts.
10
10
 
11
- #### Problem
12
-
13
- ...
14
-
15
11
  #### Steps to replicate
16
12
 
17
- Either clone and modify https://gist.github.com/pitr/9a518e840db58f435911
18
-
19
- **OR**
20
-
21
13
  Provide example config and message
22
14
 
23
15
  #### Expected Behavior or What you need to ask
24
16
 
25
17
  ...
26
18
 
27
- #### Using Fluentd and ES plugin versions
19
+ #### Using Fluentd and OpenSearch plugin versions
28
20
 
29
21
  * OS version
30
22
  * Bare Metal or within Docker or Kubernetes or others?
31
- * Fluentd v0.12 or v0.14/v1.0
23
+ * Fluentd v1.0 or later
32
24
  * paste result of ``fluentd --version`` or ``td-agent --version``
33
- * ES plugin 3.x.y/2.x.y or 1.x.y
25
+ * OpenSearch plugin version
34
26
  * paste boot log of fluentd or td-agent
35
27
  * paste result of ``fluent-gem list``, ``td-agent-gem list`` or your Gemfile.lock
36
- * ES version (optional)
37
- * ES template(s) (optional)
28
+ * OpenSearch version (optional)
29
+ * OpenSearch template(s) (optional)
data/History.md CHANGED
@@ -2,5 +2,10 @@
2
2
 
3
3
  ### [Unreleased]
4
4
 
5
+ ### 1.0.1
6
+ - Add testcases for hosts parameter (#10)
7
+ - Permit to handle @hosts parameter (#9)
8
+ - Retry creating data stream/template when OpenSearch is unreachable (#8)
9
+
5
10
  ### 1.0.0
6
11
  - Initial public gem release.
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  ![Testing on Ubuntu](https://github.com/fluent/fluent-plugin-opensearch/workflows/Testing%20on%20Ubuntu/badge.svg?branch=main)
7
7
  [![Coverage Status](https://coveralls.io/repos/github/fluent/fluent-plugin-opensearch/badge.svg?branch=upload-coverage-into-coveralls)](https://coveralls.io/github/fluent/fluent-plugin-opensearch?branch=main)
8
8
 
9
- Send your logs to OpenSearch (and search them with OpenSearch Dashboard maybe?)
9
+ Send your logs to OpenSearch (and search them with OpenSearch Dashboards maybe?)
10
10
 
11
11
  * [Installation](#installation)
12
12
  * [Usage](#usage)
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'fluent-plugin-opensearch'
6
- s.version = '1.0.0'
6
+ s.version = '1.0.1'
7
7
  s.authors = ['Hiroshi Hatake']
8
8
  s.email = ['cosmo0920.wp@gmail.com']
9
9
  s.description = %q{Opensearch output plugin for Fluent event collector}
@@ -29,18 +29,32 @@ module Fluent::Plugin
29
29
  @data_stream_names = []
30
30
  end
31
31
 
32
- @client = client
32
+ host = data_stream_connection
33
+
33
34
  unless @use_placeholder
34
35
  begin
35
36
  @data_stream_names = [@data_stream_name]
36
- create_index_template(@data_stream_name, @data_stream_template_name, @host)
37
- create_data_stream(@data_stream_name)
37
+ retry_operate(@max_retry_putting_template,
38
+ @fail_on_putting_template_retry_exceed,
39
+ @catch_transport_exception_on_retry) do
40
+ create_index_template(@data_stream_name, @data_stream_template_name, host)
41
+ create_data_stream(@data_stream_name, host)
42
+ end
38
43
  rescue => e
39
44
  raise Fluent::ConfigError, "Failed to create data stream: <#{@data_stream_name}> #{e.message}"
40
45
  end
41
46
  end
42
47
  end
43
48
 
49
+ # FIXME: Currently, the first element from hosts is only used and extracted.
50
+ def data_stream_connection
51
+ if host = get_connection_options[:hosts].first
52
+ "#{host[:scheme]}://#{host[:host]}:#{host[:port]}#{host[:path]}"
53
+ else
54
+ @host
55
+ end
56
+ end
57
+
44
58
  def validate_data_stream_parameters
45
59
  {"data_stream_name" => @data_stream_name,
46
60
  "data_stream_template_name"=> @data_stream_template_name}.each do |parameter, value|
@@ -65,7 +79,7 @@ module Fluent::Plugin
65
79
  end
66
80
  end
67
81
 
68
- def create_index_template(datastream_name, template_name, host)
82
+ def create_index_template(datastream_name, template_name, host = nil)
69
83
  return if data_stream_exist?(datastream_name) or template_exists?(template_name, host)
70
84
  body = {
71
85
  "index_patterns" => ["#{datastream_name}*"],
@@ -78,17 +92,17 @@ module Fluent::Plugin
78
92
  retry_operate(@max_retry_putting_template,
79
93
  @fail_on_putting_template_retry_exceed,
80
94
  @catch_transport_exception_on_retry) do
81
- @client.indices.put_index_template(params)
95
+ client(host).indices.put_index_template(params)
82
96
  end
83
97
  end
84
98
 
85
- def data_stream_exist?(datastream_name)
99
+ def data_stream_exist?(datastream_name, host = nil)
86
100
  params = {
87
101
  name: datastream_name
88
102
  }
89
103
  begin
90
104
  # TODO: Use X-Pack equivalent performing DataStream operation method on the following line
91
- response = @client.perform_request('GET', "/_data_stream/#{datastream_name}", {}, params)
105
+ response = client(host).perform_request('GET', "/_data_stream/#{datastream_name}", {}, params)
92
106
  return (not response.is_a?(OpenSearch::Transport::Transport::Errors::NotFound))
93
107
  rescue OpenSearch::Transport::Transport::Errors::NotFound => e
94
108
  log.info "Specified data stream does not exist. Will be created: <#{e}>"
@@ -96,8 +110,8 @@ module Fluent::Plugin
96
110
  end
97
111
  end
98
112
 
99
- def create_data_stream(datastream_name)
100
- return if data_stream_exist?(datastream_name)
113
+ def create_data_stream(datastream_name, host = nil)
114
+ return if data_stream_exist?(datastream_name, host)
101
115
  params = {
102
116
  name: datastream_name
103
117
  }
@@ -105,7 +119,7 @@ module Fluent::Plugin
105
119
  @fail_on_putting_template_retry_exceed,
106
120
  @catch_transport_exception_on_retry) do
107
121
  # TODO: Use X-Pack equivalent performing DataStream operation method on the following line
108
- @client.perform_request('PUT', "/_data_stream/#{datastream_name}", {}, params)
122
+ client(host).perform_request('PUT', "/_data_stream/#{datastream_name}", {}, params)
109
123
  end
110
124
  end
111
125
 
@@ -162,7 +176,7 @@ module Fluent::Plugin
162
176
  unless @data_stream_names.include?(data_stream_name)
163
177
  begin
164
178
  create_index_template(data_stream_name, data_stream_template_name, host)
165
- create_data_stream(data_stream_name)
179
+ create_data_stream(data_stream_name, host)
166
180
  @data_stream_names << data_stream_name
167
181
  rescue => e
168
182
  raise Fluent::ConfigError, "Failed to create data stream: <#{data_stream_name}> #{e.message}"
@@ -191,7 +205,7 @@ module Fluent::Plugin
191
205
  body: bulk_message
192
206
  }
193
207
  begin
194
- response = @client.bulk(params)
208
+ response = client(host).bulk(params)
195
209
  if response['errors']
196
210
  log.error "Could not bulk insert to Data Stream: #{data_stream_name} #{response}"
197
211
  end
@@ -61,38 +61,43 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
61
61
  DUPLICATED_DATA_STREAM_EXCEPTION = {"error": {}, "status": 400}
62
62
  NONEXISTENT_DATA_STREAM_EXCEPTION = {"error": {}, "status": 404}
63
63
 
64
- def stub_index_template(name="foo_tpl")
65
- stub_request(:put, "http://localhost:9200/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
64
+ def stub_index_template(name="foo_tpl", url="http://localhost:9200")
65
+ stub_request(:put, "#{url}/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
66
66
  end
67
67
 
68
- def stub_data_stream(name="foo")
69
- stub_request(:put, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
68
+ def stub_data_stream(name="foo", url="localhost:9200")
69
+ stub_request(:put, "#{url}/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
70
70
  end
71
71
 
72
- def stub_existent_data_stream?(name="foo")
73
- stub_request(:get, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
72
+ def stub_existent_data_stream?(name="foo", url="localhost:9200")
73
+ stub_request(:get, "#{url}/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
74
74
  end
75
75
 
76
- def stub_existent_template?(name="foo_tpl")
77
- stub_request(:get, "http://localhost:9200/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
76
+ def stub_existent_template?(name="foo_tpl", url="localhost:9200")
77
+ stub_request(:get, "#{url}/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
78
78
  end
79
79
 
80
- def stub_nonexistent_data_stream?(name="foo")
81
- stub_request(:get, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
80
+ def stub_nonexistent_data_stream?(name="foo", url="localhost:9200")
81
+ stub_request(:get, "#{url}/_data_stream/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
82
82
  end
83
83
 
84
- def stub_nonexistent_template?(name="foo_tpl")
85
- stub_request(:get, "http://localhost:9200/_index_template/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
84
+ def stub_nonexistent_template?(name="foo_tpl", url="http://localhost:9200")
85
+ stub_request(:get, "#{url}/_index_template/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
86
86
  end
87
87
 
88
- def stub_bulk_feed(datastream_name="foo", template_name="foo_tpl")
89
- stub_request(:post, "http://localhost:9200/#{datastream_name}/_bulk").with do |req|
88
+ def stub_nonexistent_template_retry?(name="foo_tpl", url="http://localhost:9200")
89
+ stub_request(:get, "#{url}/_index_template/#{name}").
90
+ to_return({ status: 500, body: 'Internal Server Error' }, { status: 404, body: '{}' })
91
+ end
92
+
93
+ def stub_bulk_feed(datastream_name="foo", template_name="foo_tpl", url="http://localhost:9200")
94
+ stub_request(:post, "#{url}/#{datastream_name}/_bulk").with do |req|
90
95
  # bulk data must be pair of OP and records
91
96
  # {"create": {}}\nhttp://localhost:9200/_data_stream/foo_bar
92
97
  # {"@timestamp": ...}
93
98
  @bulk_records += req.body.split("\n").size / 2
94
99
  end
95
- stub_request(:post, "http://localhost:9200/#{template_name}/_bulk").with do |req|
100
+ stub_request(:post, "http://#{url}#{template_name}/_bulk").with do |req|
96
101
  # bulk data must be pair of OP and records
97
102
  # {"create": {}}\nhttp://localhost:9200/_data_stream/foo_bar
98
103
  # {"@timestamp": ...}
@@ -100,13 +105,13 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
100
105
  end
101
106
  end
102
107
 
103
- def stub_elastic_info(url="http://localhost:9200/", version="1.2.2")
108
+ def stub_opensearch_info(url="http://localhost:9200/", version="1.2.2", headers={})
104
109
  body ="{\"version\":{\"number\":\"#{version}\", \"distribution\":\"opensearch\"},\"tagline\":\"The OpenSearch Project: https://opensearch.org/\"}"
105
- stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
110
+ stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' }.merge(headers) })
106
111
  end
107
112
 
108
113
  def stub_default(datastream_name="foo", template_name="foo_tpl", host="http://localhost:9200")
109
- stub_elastic_info(host)
114
+ stub_opensearch_info(host)
110
115
  stub_nonexistent_template?(template_name)
111
116
  stub_index_template(template_name)
112
117
  stub_nonexistent_data_stream?(datastream_name)
@@ -315,11 +320,58 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
315
320
  assert_equal "foo", driver(conf).instance.data_stream_name
316
321
  end
317
322
 
323
+ def test_hosts_list_configure
324
+ config = %{
325
+ hosts https://john:password@host1:443/elastic/,http://host2
326
+ path /default_path
327
+ user default_user
328
+ password default_password
329
+ data_stream_name default
330
+ }
331
+ stub_opensearch_info("https://host1:443/elastic//", "1.2.2",
332
+ {'Authorization'=>'Basic am9objpwYXNzd29yZA=='})
333
+ stub_opensearch_info("http://host2/default_path/_data_stream/default", "1.2.2",
334
+ {'Authorization'=>'Basic am9objpwYXNzd29yZA=='})
335
+ stub_existent_data_stream?("default", "https://host1/elastic/")
336
+ instance = driver(config).instance
337
+
338
+ assert_equal 2, instance.get_connection_options[:hosts].length
339
+ host1, host2 = instance.get_connection_options[:hosts]
340
+
341
+ assert_equal 'host1', host1[:host]
342
+ assert_equal 443, host1[:port]
343
+ assert_equal 'https', host1[:scheme]
344
+ assert_equal 'john', host1[:user]
345
+ assert_equal 'password', host1[:password]
346
+ assert_equal '/elastic/', host1[:path]
347
+
348
+ assert_equal 'host2', host2[:host]
349
+ assert_equal 'http', host2[:scheme]
350
+ assert_equal 'default_user', host2[:user]
351
+ assert_equal 'default_password', host2[:password]
352
+ assert_equal '/default_path', host2[:path]
353
+ end
354
+
355
+ def test_datastream_configure_retry
356
+ stub_opensearch_info
357
+ stub_nonexistent_template_retry?
358
+ stub_index_template
359
+ stub_nonexistent_data_stream?
360
+ stub_data_stream
361
+ conf = config_element(
362
+ 'ROOT', '', {
363
+ '@type' => OPENSEARCH_DATA_STREAM_TYPE,
364
+ 'data_stream_name' => 'foo',
365
+ 'data_stream_template_name' => "foo_tpl"
366
+ })
367
+ assert_equal "foo", driver(conf).instance.data_stream_name
368
+ end
369
+
318
370
  def test_existent_data_stream
319
371
  stub_index_template
320
372
  stub_existent_data_stream?
321
373
  stub_data_stream
322
- stub_elastic_info
374
+ stub_opensearch_info
323
375
  conf = config_element(
324
376
  'ROOT', '', {
325
377
  '@type' => OPENSEARCH_DATA_STREAM_TYPE,
@@ -333,7 +385,7 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
333
385
  stub_index_template
334
386
  stub_existent_data_stream?
335
387
  stub_data_stream
336
- stub_elastic_info
388
+ stub_opensearch_info
337
389
  conf = config_element(
338
390
  'ROOT', '', {
339
391
  '@type' => OPENSEARCH_DATA_STREAM_TYPE,
@@ -463,7 +515,7 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
463
515
  connection_resets += 1
464
516
  raise Faraday::ConnectionFailed, "Test message"
465
517
  end
466
- stub_elastic_info("https://logs.google.com:778/")
518
+ stub_opensearch_info("https://logs.google.com:778/")
467
519
 
468
520
  assert_raise(Fluent::Plugin::OpenSearchError::RetryableOperationExhaustedFailure) do
469
521
  driver(config)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-opensearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Hatake
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-13 00:00:00.000000000 Z
11
+ date: 2022-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -226,7 +226,7 @@ licenses:
226
226
  - Apache-2.0
227
227
  metadata:
228
228
  changelog_uri: https://github.com/fluent/fluent-plugin-opensearch/blob/master/History.md
229
- post_install_message:
229
+ post_install_message:
230
230
  rdoc_options: []
231
231
  require_paths:
232
232
  - lib
@@ -241,8 +241,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
241
  - !ruby/object:Gem::Version
242
242
  version: '0'
243
243
  requirements: []
244
- rubygems_version: 3.2.22
245
- signing_key:
244
+ rubygems_version: 3.2.30
245
+ signing_key:
246
246
  specification_version: 4
247
247
  summary: Opensearch output plugin for Fluent event collector
248
248
  test_files: